ExecutionMetadataからProject Rootを削除
worktreeモードでタスク実行時、エージェントがmainディレクトリで 作業してしまうバグの修正。metadataでProject Rootを見せていたため Claudeがそちらで作業していた可能性がある。 - ExecutionMetadataインターフェースからprojectRootを削除 - buildExecutionMetadataからprojectRoot設定を削除 - METADATA_STRINGSからprojectRootとmodeを削除 - renderExecutionMetadataからProject Root表示を削除 - 関連テストを更新
This commit is contained in:
parent
588d157daa
commit
277d490eeb
@ -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' });
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user