fix(agents): keep WorktreeCreate hooks authoritative

Revert silent git fallback after hook failure. Treat WorktreeCreate hook
errors as recoverable in AgentTool so multi-repo cwd overrides still work
without bypassing configured hooks at the worktree layer.
This commit is contained in:
jatmn
2026-07-28 22:28:03 -07:00
parent 8704745a40
commit 3bd6b47503
3 changed files with 22 additions and 21 deletions
+6 -1
View File
@@ -179,12 +179,17 @@ describe('AgentTool input schema isolation contract', () => {
).toThrow('cwd must be an existing directory.')
})
test('detects missing-git worktree errors for fallback', () => {
test('detects missing-git and WorktreeCreate hook worktree errors for fallback', () => {
expect(
isMissingGitAgentWorktreeError(
'Cannot create agent worktree: not in a git repository and no WorktreeCreate hooks are configured.',
),
).toBe(true)
expect(
isMissingGitAgentWorktreeError(
'WorktreeCreate hook failed: no successful output',
),
).toBe(true)
expect(isMissingGitAgentWorktreeError('some other failure')).toBe(false)
})
+7 -2
View File
@@ -198,9 +198,14 @@ export function resolveAgentToolCwdOverride(
return worktreeInfo?.worktreePath ?? cwd;
}
/** True when worktree creation failed only because no git root was available. */
/** True when worktree creation failed in a way AgentTool can recover from by
* falling back to a cwd override (missing git root, or WorktreeCreate hook
* failure in a non-git / multi-repo parent session). */
export function isMissingGitAgentWorktreeError(message: string): boolean {
return message.includes('Cannot create agent worktree: not in a git repository');
return (
message.includes('Cannot create agent worktree: not in a git repository') ||
message.includes('WorktreeCreate hook failed:')
);
}
// Output schema - multi-agent spawned schema added dynamically at runtime when enabled
+9 -18
View File
@@ -1066,26 +1066,17 @@ export async function createAgentWorktree(
// Try hook-based worktree creation first (allows user-configured VCS).
// Forward sessionCwd so hooks operating from a multi-repo parent can target
// the selected child repository (#2052). If the hook fails but the cwd is a
// git repo, fall through to the git worktree path instead of hard-failing.
// the selected child repository (#2052). Hook failure remains terminal here —
// AgentTool decides whether to fall back to a cwd override.
if (hasWorktreeCreateHook()) {
try {
const hookResult = await executeWorktreeCreateHook(slug, {
cwd: sessionCwd,
})
logForDebugging(
`Created hook-based agent worktree at: ${hookResult.worktreePath}`,
)
const hookResult = await executeWorktreeCreateHook(slug, {
cwd: sessionCwd,
})
logForDebugging(
`Created hook-based agent worktree at: ${hookResult.worktreePath}`,
)
return { worktreePath: hookResult.worktreePath, hookBased: true }
} catch (error) {
if (!findCanonicalGitRoot(sessionCwd)) {
throw error
}
logForDebugging(
`WorktreeCreate hook failed; falling back to git worktree at ${sessionCwd}: ${error instanceof Error ? error.message : String(error)}`,
)
}
return { worktreePath: hookResult.worktreePath, hookBased: true }
}
// Fall back to git worktree