fix(omp): preserve zsh startup with global aliases (#20621)

Validated and independently reviewed OMP integration fix.
This commit is contained in:
Neil
2026-09-14 13:56:22 -07:00
committed by GitHub
parent 3632311d0b
commit fc4519cda4
10 changed files with 41 additions and 14 deletions
+1
View File
@@ -56,6 +56,7 @@ jobs:
--exclude=src/main/daemon/node-pty-fd-leak.test.ts \
--exclude=src/main/providers/local-pty-shell-ready-zsh-launch-environment.test.ts \
--exclude=src/main/providers/__tests__/shell-ready-framework-example.test.ts \
--exclude=src/main/pty/omp-shell-wrapper-alias-safety.test.ts \
--exclude=src/main/pty/omp-shell-wrapper.node-pty.test.ts \
--exclude=src/main/shell-startup-feature-channel.test.ts \
--exclude=src/main/terminal-history-fish-session.node-pty.test.ts \
@@ -15,6 +15,7 @@ const shellContractFiles = [
'src/main/daemon/shell-ready.test.ts',
'src/main/providers/local-pty-shell-ready-zsh-launch-environment.test.ts',
'src/main/providers/__tests__/shell-ready-framework-example.test.ts',
'src/main/pty/omp-shell-wrapper-alias-safety.test.ts',
'src/main/pty/omp-shell-wrapper.node-pty.test.ts',
'src/main/shell-startup-feature-channel.test.ts',
'src/main/zsh-scoped-histfile.live-shell.test.ts',
@@ -39,8 +39,8 @@ __orca_restore_agent_teams_path
# their normal argv shape.
__orca_omp_should_skip_extension() {
case "${1:-}" in
help|--help|-h|--version|-v) return 0 ;;
__complete|acp|agents|auth-broker|auth-gateway|bench|commit|completions|config|dry-balance|gallery|grep|grievances|install|join|models|plugin|read|say|search|setup|shell|ssh|stats|tiny-models|token|ttsr|update|usage|worktree|q|wt) return 0 ;;
'help'|'--help'|'-h'|'--version'|'-v') return 0 ;;
'__complete'|'acp'|'agents'|'auth-broker'|'auth-gateway'|'bench'|'commit'|'completions'|'config'|'dry-balance'|'gallery'|'grep'|'grievances'|'install'|'join'|'models'|'plugin'|'read'|'say'|'search'|'setup'|'shell'|'ssh'|'stats'|'tiny-models'|'token'|'ttsr'|'update'|'usage'|'worktree'|'q'|'wt') return 0 ;;
esac
return 1
}
@@ -77,8 +77,8 @@ __orca_deferred_init() {
# their normal argv shape.
__orca_omp_should_skip_extension() {
case "${1:-}" in
help|--help|-h|--version|-v) return 0 ;;
__complete|acp|agents|auth-broker|auth-gateway|bench|commit|completions|config|dry-balance|gallery|grep|grievances|install|join|models|plugin|read|say|search|setup|shell|ssh|stats|tiny-models|token|ttsr|update|usage|worktree|q|wt) return 0 ;;
'help'|'--help'|'-h'|'--version'|'-v') return 0 ;;
'__complete'|'acp'|'agents'|'auth-broker'|'auth-gateway'|'bench'|'commit'|'completions'|'config'|'dry-balance'|'gallery'|'grep'|'grievances'|'install'|'join'|'models'|'plugin'|'read'|'say'|'search'|'setup'|'shell'|'ssh'|'stats'|'tiny-models'|'token'|'ttsr'|'update'|'usage'|'worktree'|'q'|'wt') return 0 ;;
esac
return 1
}
@@ -42,8 +42,8 @@ __orca_restore_agent_teams_path
# their normal argv shape.
__orca_omp_should_skip_extension() {
case "${1:-}" in
help|--help|-h|--version|-v) return 0 ;;
__complete|acp|agents|auth-broker|auth-gateway|bench|commit|completions|config|dry-balance|gallery|grep|grievances|install|join|models|plugin|read|say|search|setup|shell|ssh|stats|tiny-models|token|ttsr|update|usage|worktree|q|wt) return 0 ;;
'help'|'--help'|'-h'|'--version'|'-v') return 0 ;;
'__complete'|'acp'|'agents'|'auth-broker'|'auth-gateway'|'bench'|'commit'|'completions'|'config'|'dry-balance'|'gallery'|'grep'|'grievances'|'install'|'join'|'models'|'plugin'|'read'|'say'|'search'|'setup'|'shell'|'ssh'|'stats'|'tiny-models'|'token'|'ttsr'|'update'|'usage'|'worktree'|'q'|'wt') return 0 ;;
esac
return 1
}
@@ -77,8 +77,8 @@ __orca_deferred_init() {
# their normal argv shape.
__orca_omp_should_skip_extension() {
case "${1:-}" in
help|--help|-h|--version|-v) return 0 ;;
__complete|acp|agents|auth-broker|auth-gateway|bench|commit|completions|config|dry-balance|gallery|grep|grievances|install|join|models|plugin|read|say|search|setup|shell|ssh|stats|tiny-models|token|ttsr|update|usage|worktree|q|wt) return 0 ;;
'help'|'--help'|'-h'|'--version'|'-v') return 0 ;;
'__complete'|'acp'|'agents'|'auth-broker'|'auth-gateway'|'bench'|'commit'|'completions'|'config'|'dry-balance'|'gallery'|'grep'|'grievances'|'install'|'join'|'models'|'plugin'|'read'|'say'|'search'|'setup'|'shell'|'ssh'|'stats'|'tiny-models'|'token'|'ttsr'|'update'|'usage'|'worktree'|'q'|'wt') return 0 ;;
esac
return 1
}
@@ -31,8 +31,8 @@ fi
# their normal argv shape.
__orca_omp_should_skip_extension() {
case "${1:-}" in
help|--help|-h|--version|-v) return 0 ;;
__complete|acp|agents|auth-broker|auth-gateway|bench|commit|completions|config|dry-balance|gallery|grep|grievances|install|join|models|plugin|read|say|search|setup|shell|ssh|stats|tiny-models|token|ttsr|update|usage|worktree|q|wt) return 0 ;;
'help'|'--help'|'-h'|'--version'|'-v') return 0 ;;
'__complete'|'acp'|'agents'|'auth-broker'|'auth-gateway'|'bench'|'commit'|'completions'|'config'|'dry-balance'|'gallery'|'grep'|'grievances'|'install'|'join'|'models'|'plugin'|'read'|'say'|'search'|'setup'|'shell'|'ssh'|'stats'|'tiny-models'|'token'|'ttsr'|'update'|'usage'|'worktree'|'q'|'wt') return 0 ;;
esac
return 1
}
@@ -51,8 +51,8 @@ __orca_deferred_init() {
# their normal argv shape.
__orca_omp_should_skip_extension() {
case "${1:-}" in
help|--help|-h|--version|-v) return 0 ;;
__complete|acp|agents|auth-broker|auth-gateway|bench|commit|completions|config|dry-balance|gallery|grep|grievances|install|join|models|plugin|read|say|search|setup|shell|ssh|stats|tiny-models|token|ttsr|update|usage|worktree|q|wt) return 0 ;;
'help'|'--help'|'-h'|'--version'|'-v') return 0 ;;
'__complete'|'acp'|'agents'|'auth-broker'|'auth-gateway'|'bench'|'commit'|'completions'|'config'|'dry-balance'|'gallery'|'grep'|'grievances'|'install'|'join'|'models'|'plugin'|'read'|'say'|'search'|'setup'|'shell'|'ssh'|'stats'|'tiny-models'|'token'|'ttsr'|'update'|'usage'|'worktree'|'q'|'wt') return 0 ;;
esac
return 1
}
@@ -68,3 +68,28 @@ describe.skipIf(process.platform === 'win32')('omp wrapper under a user alias na
expectAliasedOmpNameSurvives('/bin/zsh', 'setopt aliases')
})
})
describe.skipIf(process.platform === 'win32' || !zshAvailable)('OMP wrapper global aliases', () => {
it.each(['--help', '-v', 'models'])('parses with hostile global alias %s', (token) => {
const root = mkdtempSync(join(tmpdir(), 'orca-omp-global-alias-'))
roots.push(root)
const startup = join(root, 'startup.zsh')
writeFileSync(
startup,
[
`alias -g -- ${token}='${token} 2>&1 | cat'`,
getPosixOmpShellWrapper(),
`if ! __orca_omp_should_skip_extension '${token}'; then exit 1; fi`,
'printf "parsed\\n"',
`alias -g -- '${token}'`
].join('\n')
)
const result = spawnSync('/bin/zsh', ['-f', startup], {
encoding: 'utf8',
env: { ...process.env, HOME: root, ZDOTDIR: root }
})
expect(result.status, result.stderr).toBe(0)
expect(result.stdout).toContain('parsed')
expect(result.stdout).toContain('2>&1 | cat')
})
})
+2 -2
View File
@@ -40,13 +40,13 @@ const OMP_SUBCOMMANDS = [
] as const
export function getPosixOmpShellWrapper(): string {
const subcommands = OMP_SUBCOMMANDS.join('|')
const subcommands = OMP_SUBCOMMANDS.map((value) => `'${value}'`).join('|')
return `# Why: OMP does not auto-load Orca's managed status extension; wrap only
# interactive launch invocations so subcommands such as \`omp config\` keep
# their normal argv shape.
__orca_omp_should_skip_extension() {
case "\${1:-}" in
help|--help|-h|--version|-v) return 0 ;;
'help'|'--help'|'-h'|'--version'|'-v') return 0 ;;
${subcommands}) return 0 ;;
esac
return 1