From 277d490eeb1491cbf9ded7fb7ea507095473507d Mon Sep 17 00:00:00 2001 From: nrslib <38722970+nrslib@users.noreply.github.com> Date: Thu, 29 Jan 2026 00:49:34 +0900 Subject: [PATCH] =?UTF-8?q?ExecutionMetadata=E3=81=8B=E3=82=89Project=20Ro?= =?UTF-8?q?ot=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit worktreeモードでタスク実行時、エージェントがmainディレクトリで 作業してしまうバグの修正。metadataでProject Rootを見せていたため Claudeがそちらで作業していた可能性がある。 - ExecutionMetadataインターフェースからprojectRootを削除 - buildExecutionMetadataからprojectRoot設定を削除 - METADATA_STRINGSからprojectRootとmodeを削除 - renderExecutionMetadataからProject Root表示を削除 - 関連テストを更新 --- src/__tests__/instructionBuilder.test.ts | 86 +++--------------------- src/workflow/instruction-builder.ts | 16 ----- 2 files changed, 8 insertions(+), 94 deletions(-) diff --git a/src/__tests__/instructionBuilder.test.ts b/src/__tests__/instructionBuilder.test.ts index 646ef94..c348516 100644 --- a/src/__tests__/instructionBuilder.test.ts +++ b/src/__tests__/instructionBuilder.test.ts @@ -47,7 +47,7 @@ describe('instruction-builder', () => { expect(result).toContain('Do some work'); }); - it('should include Project Root and Mode when cwd !== projectCwd', () => { + it('should NOT include Project Root even when cwd !== projectCwd', () => { const step = createMinimalStep('Do some work'); const context = createMinimalContext({ cwd: '/worktree-path', @@ -58,36 +58,11 @@ describe('instruction-builder', () => { expect(result).toContain('## Execution Context'); expect(result).toContain('Working Directory: /worktree-path'); - expect(result).toContain('Project Root: /project-path'); - expect(result).toContain('Mode: worktree'); + expect(result).not.toContain('Project Root'); + expect(result).not.toContain('Mode:'); expect(result).toContain('Do some work'); }); - it('should NOT include Project Root or Mode when cwd === projectCwd', () => { - const step = createMinimalStep('Do some work'); - const context = createMinimalContext({ - cwd: '/project', - projectCwd: '/project', - }); - - const result = buildInstruction(step, context); - - expect(result).toContain('Working Directory: /project'); - expect(result).not.toContain('Project Root'); - expect(result).not.toContain('Mode:'); - }); - - it('should NOT include Project Root or Mode when projectCwd is not set', () => { - const step = createMinimalStep('Do some work'); - const context = createMinimalContext({ cwd: '/project' }); - - const result = buildInstruction(step, context); - - expect(result).toContain('Working Directory: /project'); - expect(result).not.toContain('Project Root'); - expect(result).not.toContain('Mode:'); - }); - it('should prepend metadata before the instruction body', () => { const step = createMinimalStep('Do some work'); const context = createMinimalContext({ cwd: '/project' }); @@ -133,7 +108,8 @@ describe('instruction-builder', () => { '- Report: /project/.takt/reports/20260128-worktree-report/00-plan.md' ); expect(result).toContain('Working Directory: /project/.takt/worktrees/my-task'); - expect(result).toContain('Project Root: /project'); + // Project Root should NOT be included in metadata (to avoid agent confusion) + expect(result).not.toContain('Project Root'); }); it('should replace multiple .takt/reports/{report_dir} occurrences', () => { @@ -183,15 +159,14 @@ describe('instruction-builder', () => { }); describe('buildExecutionMetadata', () => { - it('should set workingDirectory and omit projectRoot in normal mode', () => { + it('should set workingDirectory', () => { const context = createMinimalContext({ cwd: '/project' }); const metadata = buildExecutionMetadata(context); expect(metadata.workingDirectory).toBe('/project'); - expect(metadata.projectRoot).toBeUndefined(); }); - it('should set projectRoot in worktree mode', () => { + it('should use cwd as workingDirectory even in worktree mode', () => { const context = createMinimalContext({ cwd: '/worktree-path', projectCwd: '/project-path', @@ -199,27 +174,6 @@ describe('instruction-builder', () => { const metadata = buildExecutionMetadata(context); expect(metadata.workingDirectory).toBe('/worktree-path'); - expect(metadata.projectRoot).toBe('/project-path'); - }); - - it('should omit projectRoot when projectCwd is not set', () => { - const context = createMinimalContext({ cwd: '/project' }); - // projectCwd is undefined by default - const metadata = buildExecutionMetadata(context); - - expect(metadata.workingDirectory).toBe('/project'); - expect(metadata.projectRoot).toBeUndefined(); - }); - - it('should omit projectRoot when cwd equals projectCwd', () => { - const context = createMinimalContext({ - cwd: '/same-path', - projectCwd: '/same-path', - }); - const metadata = buildExecutionMetadata(context); - - expect(metadata.workingDirectory).toBe('/same-path'); - expect(metadata.projectRoot).toBeUndefined(); }); it('should default language to en when not specified', () => { @@ -238,7 +192,7 @@ describe('instruction-builder', () => { }); describe('renderExecutionMetadata', () => { - it('should render normal mode without Project Root or Mode', () => { + it('should render Working Directory only', () => { const rendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'en' }); expect(rendered).toContain('## Execution Context'); @@ -247,19 +201,6 @@ describe('instruction-builder', () => { expect(rendered).not.toContain('Mode:'); }); - it('should render worktree mode with Project Root and Mode', () => { - const rendered = renderExecutionMetadata({ - workingDirectory: '/worktree', - projectRoot: '/project', - language: 'en', - }); - - expect(rendered).toContain('## Execution Context'); - expect(rendered).toContain('- Working Directory: /worktree'); - expect(rendered).toContain('- Project Root: /project'); - expect(rendered).toContain('- Mode: worktree'); - }); - it('should end with a trailing empty line', () => { const rendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'en' }); @@ -275,17 +216,6 @@ describe('instruction-builder', () => { expect(rendered).not.toContain('Working Directory'); }); - it('should render worktree mode in Japanese', () => { - const rendered = renderExecutionMetadata({ - workingDirectory: '/worktree', - projectRoot: '/project', - language: 'ja', - }); - - expect(rendered).toContain('- プロジェクトルート: /project'); - expect(rendered).toContain('モード: worktree'); - }); - it('should include English note only for en, not for ja', () => { const enRendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'en' }); const jaRendered = renderExecutionMetadata({ workingDirectory: '/project', language: 'ja' }); diff --git a/src/workflow/instruction-builder.ts b/src/workflow/instruction-builder.ts index ab3dc6d..651d4f0 100644 --- a/src/workflow/instruction-builder.ts +++ b/src/workflow/instruction-builder.ts @@ -39,8 +39,6 @@ export interface InstructionContext { export interface ExecutionMetadata { /** The agent's working directory (may be a worktree) */ readonly workingDirectory: string; - /** Project root where .takt/ lives. Present only in worktree mode. */ - readonly projectRoot?: string; /** Language for metadata rendering */ readonly language: Language; } @@ -49,15 +47,10 @@ export interface ExecutionMetadata { * Build execution metadata from instruction context. * * Pure function: InstructionContext → ExecutionMetadata. - * Sets `projectRoot` only when cwd differs from projectCwd (worktree mode). */ export function buildExecutionMetadata(context: InstructionContext): ExecutionMetadata { - const projectRoot = context.projectCwd ?? context.cwd; - const isWorktree = context.cwd !== projectRoot; - return { workingDirectory: context.cwd, - ...(isWorktree ? { projectRoot } : {}), language: context.language ?? 'en', }; } @@ -67,15 +60,11 @@ const METADATA_STRINGS = { en: { heading: '## Execution Context', workingDirectory: 'Working Directory', - projectRoot: 'Project Root', - mode: 'Mode: worktree (source edits in Working Directory, reports in Project Root)', note: 'Note: This section is metadata. Follow the language used in the rest of the prompt.', }, ja: { heading: '## 実行コンテキスト', workingDirectory: '作業ディレクトリ', - projectRoot: 'プロジェクトルート', - mode: 'モード: worktree(ソース編集は作業ディレクトリ、レポートはプロジェクトルート)', note: '', }, } as const; @@ -85,7 +74,6 @@ const METADATA_STRINGS = { * * Pure function: ExecutionMetadata → string. * Always includes heading + Working Directory. - * Adds Project Root and Mode only in worktree mode (when projectRoot is present). * Language determines the output language; 'en' includes a note about language consistency. */ export function renderExecutionMetadata(metadata: ExecutionMetadata): string { @@ -94,10 +82,6 @@ export function renderExecutionMetadata(metadata: ExecutionMetadata): string { strings.heading, `- ${strings.workingDirectory}: ${metadata.workingDirectory}`, ]; - if (metadata.projectRoot !== undefined) { - lines.push(`- ${strings.projectRoot}: ${metadata.projectRoot}`); - lines.push(`- ${strings.mode}`); - } if (strings.note) { lines.push(''); lines.push(strings.note);