Merge remote-tracking branch 'upstream/master' into fix/workspace-context-rendered-change-proof

# Conflicts:
#	.agents/notes/implemented/feature/2026-06-24-workspace-context.i18n.yaml
#	.agents/notes/implemented/feature/2026-06-24-workspace-context.md
#	.agents/notes/implemented/feature/2026-06-24-workspace-context.zh.md
#	packages/context/workspace-context/README.i18n.yaml
#	packages/context/workspace-context/src/files.ts
#	packages/context/workspace-context/src/render.ts
This commit is contained in:
ZiyaZhang
2026-08-10 00:49:16 -07:00
4373 changed files with 161862 additions and 37324 deletions

View File

@@ -12,6 +12,10 @@ const SYSTEM_REMINDER_CLOSE = '</system-reminder>'
const WORKSPACE_CONTEXT_INTRO = 'The following workspace instructions may be relevant to your work. '
+ 'Use them as guidance when applicable. More specific instructions take precedence over broader ones. '
+ 'They do not override system, developer, or direct user instructions.'
const REPLACEMENT_WORKSPACE_CONTEXT_INTRO = 'This complete workspace instruction baseline replaces all earlier workspace instruction baselines. '
+ WORKSPACE_CONTEXT_INTRO
const EMPTY_REPLACEMENT_WORKSPACE_CONTEXT_INTRO = 'This complete workspace instruction baseline replaces all earlier workspace instruction baselines. '
+ 'No workspace instructions are currently active.'
const COMPACT_WORKSPACE_CONTEXT_INTRO = 'Workspace instructions were omitted or truncated to fit the configured byte budget.'
/** Byte-accounting record for one truncated instruction file. */
@@ -39,15 +43,6 @@ interface RenderedInstructionContext extends RenderedWorkspaceContext {
represented: LoadedInstructionFile[]
}
/**
* Rendered baseline plus files whose section retained content, or whose original content was empty.
* A partially rendered file keeps the digest of its complete original content.
*/
export interface RenderedInstructionSet {
rendered: RenderedWorkspaceContext
included: LoadedInstructionFile[]
}
/** Structured dynamic state persisted outside model-visible prompt prose. */
export interface WorkspaceInstructionChange {
action: 'set' | 'replace' | 'remove'
@@ -163,6 +158,16 @@ function additionalSectionText(file: LoadedInstructionFile): string {
const BASELINE_RENDER_STYLE: RenderStyle = { intro: WORKSPACE_CONTEXT_INTRO, section: sectionText }
function baselineRenderStyle(files: LoadedInstructionFile[], replacePreviousBaseline: boolean | undefined): RenderStyle {
if (replacePreviousBaseline !== true) return BASELINE_RENDER_STYLE
return {
...BASELINE_RENDER_STYLE,
intro: files.length === 0
? EMPTY_REPLACEMENT_WORKSPACE_CONTEXT_INTRO
: REPLACEMENT_WORKSPACE_CONTEXT_INTRO,
}
}
function changedSectionText(item: ChangeRenderItem): string {
const { change, file } = item
if (change.action === 'set') return additionalSectionText(file)
@@ -329,27 +334,28 @@ function renderInstructionContext(
/**
* Render a baseline together with the exact source files semantically represented in it.
* @param files - loaded files ordered from broadest to most specific.
* @param options - required rendering byte budget.
* @param options - rendering byte budget and whether this baseline supersedes a visible predecessor.
* @returns bounded public rendering plus files with surviving content, including genuinely empty files.
* @internal
*/
export function renderWorkspaceInstructionSet(
files: LoadedInstructionFile[],
options: { maxBytes: number },
): RenderedInstructionSet {
const { represented, ...rendered } = renderInstructionContext(files, options.maxBytes, BASELINE_RENDER_STYLE)
options: { maxBytes: number; replacePreviousBaseline?: boolean },
): { rendered: RenderedWorkspaceContext; included: LoadedInstructionFile[] } {
const style = baselineRenderStyle(files, options.replacePreviousBaseline)
const { represented, ...rendered } = renderInstructionContext(files, options.maxBytes, style)
return { rendered, included: represented }
}
/**
* Render the baseline instruction chain with deterministic precedence budgeting.
* @param files - loaded files ordered from broadest to most specific.
* @param options - required rendering byte budget.
* @param options - rendering byte budget and whether this baseline supersedes a visible predecessor.
* @returns bounded baseline prompt text and budget diagnostics.
*/
export function renderWorkspaceContext(
files: LoadedInstructionFile[],
options: { maxBytes: number },
options: { maxBytes: number; replacePreviousBaseline?: boolean },
): RenderedWorkspaceContext {
return renderWorkspaceInstructionSet(files, options).rendered
}