diff --git a/src/main/agent-hooks/installer-utils.test.ts b/src/main/agent-hooks/installer-utils.test.ts index 05125b861f2..9b90d892645 100644 --- a/src/main/agent-hooks/installer-utils.test.ts +++ b/src/main/agent-hooks/installer-utils.test.ts @@ -148,13 +148,13 @@ describe('createManagedCommandMatcher', () => { }) it('matches the guarded launcher form so wrapped commands sweep correctly', () => { - // Why: wrapPosixHookCommand wraps the launcher in `[ -x ... ] && ... || true` + // Why: wrapPosixHookCommand wraps the launcher in `if [ -x ... ]; then ...; fi` // so a stale entry no-ops instead of returning exit 127. The sweep on // install() must still recognize the guarded form as managed, otherwise // repeated installs would accumulate one guarded + one unguarded entry. expect( match( - '[ -x "/Users/alice/Library/Application Support/Orca/agent-hooks/claude-hook.sh" ] && /bin/sh "/Users/alice/Library/Application Support/Orca/agent-hooks/claude-hook.sh" || true' + 'if [ -x "/Users/alice/Library/Application Support/Orca/agent-hooks/claude-hook.sh" ]; then /bin/sh "/Users/alice/Library/Application Support/Orca/agent-hooks/claude-hook.sh"; fi' ) ).toBe(true) }) @@ -163,7 +163,7 @@ describe('createManagedCommandMatcher', () => { describe('wrapPosixHookCommand', () => { it('produces a guarded command that no-ops when the script is missing', () => { const cmd = wrapPosixHookCommand('/does/not/exist.sh') - expect(cmd).toBe('[ -x "/does/not/exist.sh" ] && /bin/sh "/does/not/exist.sh" || true') + expect(cmd).toBe('if [ -x "/does/not/exist.sh" ]; then /bin/sh "/does/not/exist.sh"; fi') }) it('preserves spaces in the script path (Library/Application Support case)', () => { diff --git a/src/main/agent-hooks/installer-utils.ts b/src/main/agent-hooks/installer-utils.ts index 3df19d3d3e0..8cdc8a1184a 100644 --- a/src/main/agent-hooks/installer-utils.ts +++ b/src/main/agent-hooks/installer-utils.ts @@ -69,12 +69,12 @@ export function createManagedCommandMatcher( // switched dev↔prod installs, or had a partial install fail) used to fire // `/bin/sh ""` on every tool call, which exits 127 and surfaces // as `PreToolUse hook (failed) error: hook exited with code 127` in the agent -// transcript. Wrapping the launcher in `[ -x ... ] && ... || true` makes a +// transcript. Wrapping the launcher in `if [ -x ... ]; then ...; fi` makes a // missing/non-executable script a silent no-op so a broken install never // poisons the user's session. Failures inside the script itself are // unaffected — only the missing-script case short-circuits. export function wrapPosixHookCommand(scriptPath: string): string { - return `[ -x "${scriptPath}" ] && /bin/sh "${scriptPath}" || true` + return `if [ -x "${scriptPath}" ]; then /bin/sh "${scriptPath}"; fi` } export function removeManagedCommands(