refactor(shell): build every zsh startup wrapper from one shared builder

Local PTY, daemon/SSH, and relay each had their own copy of the zsh
ZDOTDIR wrapper templates, and the copies had drifted. buildZshStartupWrapperFiles
now produces .zshenv/.zprofile/.zshrc/.zlogin for all three, with every
real difference expressed as a field on ZshStartupWrapperSpec.

No behavior change: the generated text is byte-for-byte identical for
every configuration, pinned by the snapshots committed in the previous
commit (captured from the pre-refactor generators).
This commit is contained in:
Neil
2026-08-17 22:36:19 -07:00
parent da44b375a8
commit c3f41e9edd
7 changed files with 334 additions and 242 deletions
@@ -1,52 +0,0 @@
import { getPosixOmpShellWrapper } from '../pty/omp-shell-wrapper'
import { getPosixCodexShellLaunchPreflight } from '../pty/codex-shell-launch-preflight'
import {
getZshFinalZdotdirRestoreBlock,
getZshStartupFileSourceBlock,
ZSH_HISTFILE_RESTORE_BLOCK
} from '../shell-templates'
export function getDaemonZshShellReadyRcfileContent(): string {
return `# Orca daemon zsh shell-ready wrapper
${getZshStartupFileSourceBlock({
fileName: '.zshrc',
interactiveOnly: true,
skipWhenHomeIsCurrentZdotdir: true
})}
__orca_restore_agent_teams_path() {
[[ -n "\${ORCA_AGENT_TEAMS_SHIM_DIR:-}" ]] || return 0
case "$PATH" in
"\${ORCA_AGENT_TEAMS_SHIM_DIR}"|"\${ORCA_AGENT_TEAMS_SHIM_DIR}:"*) return 0 ;;
esac
export PATH="\${ORCA_AGENT_TEAMS_SHIM_DIR}:$PATH"
}
[[ ! -o login ]] && __orca_restore_agent_teams_path
if [[ ! -o login ]]; then
# Why: ~/.zshrc can export the user's default OpenCode config after spawn.
[[ -n "\${ORCA_OPENCODE_CONFIG_DIR:-}" ]] && export OPENCODE_CONFIG_DIR="\${ORCA_OPENCODE_CONFIG_DIR}"
[[ -n "\${ORCA_MIMOCODE_HOME:-}" ]] && export MIMOCODE_HOME="\${ORCA_MIMOCODE_HOME}"
${getPosixOmpShellWrapper()}
[[ -n "\${ORCA_CODEX_HOME:-}" ]] && export CODEX_HOME="\${ORCA_CODEX_HOME}"
${ZSH_HISTFILE_RESTORE_BLOCK}
${getPosixCodexShellLaunchPreflight()}
fi
__orca_osc133_precmd() {
local exit_code=$?
if [[ -n "\${__orca_in_command:-}" ]]; then
printf "\\033]133;D;%s\\007" "$exit_code"
unset __orca_in_command
fi
printf "\\033]133;A\\007"
}
__orca_osc133_preexec() {
printf "\\033]133;C\\007"
__orca_in_command=1
}
# Why: prepend so Orca captures $? before user prompt hooks can overwrite it.
precmd_functions=(__orca_osc133_precmd \${precmd_functions[@]})
preexec_functions=(__orca_osc133_preexec \${preexec_functions[@]})
if [[ ! -o login ]]; then
${getZshFinalZdotdirRestoreBlock()}
fi
`
}
@@ -0,0 +1,25 @@
import type { ZshStartupWrapperSpec } from '../zsh-startup-wrapper-builder'
import { SHELL_READY_MARKER } from './daemon-shell-ready-marker'
/** The zsh wrapper the daemon (local fork and SSH host) launches shells with. */
export function getDaemonZshWrapperSpec(zshDir: string): ZshStartupWrapperSpec {
return {
headerLabel: 'Orca daemon zsh shell-ready wrapper',
zshDir,
zshenvStrategy: 'discover-user-zdotdir',
readyMarkerEscaped: SHELL_READY_MARKER,
osc133CommandMarkers: true,
skipUserZshrcWhenHomeIsWrapperDir: true,
interactiveRestoreComment:
"# Why: ~/.zshrc can export the user's default OpenCode config after spawn.",
loginRestoreComment:
'# Why: .zlogin is the final login startup file before the prompt is shown.',
restores: {
agentTeamsPath: true,
remoteCliBinDir: false,
codexHome: true,
codexLaunchPreflight: true
},
readyMarkerOrder: 'before-zdotdir-restore'
}
}
+9 -43
View File
@@ -6,22 +6,12 @@ import {
getPowerShellOsc133Bootstrap,
isPowerShellExecutableName
} from '../powershell-osc133-bootstrap'
import { getPosixOmpShellWrapper } from '../pty/omp-shell-wrapper'
import {
getFishCodexShellLaunchPreflight,
getPosixCodexShellLaunchPreflight
} from '../pty/codex-shell-launch-preflight'
import {
getFishShellReadyInitCommand,
getZshEnvTemplate,
getZshFinalZdotdirRestoreBlock,
getZshShellReadyMarkerRegistrationBlock,
getZshStartupFileSourceBlock,
ZSH_HISTFILE_RESTORE_BLOCK
} from '../shell-templates'
import { getFishCodexShellLaunchPreflight } from '../pty/codex-shell-launch-preflight'
import { getFishShellReadyInitCommand } from '../shell-templates'
import { buildZshStartupWrapperFiles } from '../zsh-startup-wrapper-builder'
import { SHELL_READY_MARKER } from './daemon-shell-ready-marker'
import { getDaemonBashShellReadyRcfileContent } from './daemon-bash-shell-ready-rcfile'
import { getDaemonZshShellReadyRcfileContent } from './daemon-zsh-shell-ready-rcfile'
import { getDaemonZshWrapperSpec } from './daemon-zsh-shell-ready-wrapper-spec'
const ORCA_USER_DATA_PATH_ENV = 'ORCA_USER_DATA_PATH'
@@ -102,38 +92,14 @@ function ensureShellReadyWrappers(): void {
const zshDir = join(root, 'zsh')
const bashDir = join(root, 'bash')
const zshEnv = getZshEnvTemplate(zshDir, 'daemon')
const zshProfile = `# Orca daemon zsh shell-ready wrapper
${getZshStartupFileSourceBlock({ fileName: '.zprofile' })}
`
const zshRc = getDaemonZshShellReadyRcfileContent()
const zshLogin = `# Orca daemon zsh shell-ready wrapper
${getZshStartupFileSourceBlock({ fileName: '.zlogin', interactiveOnly: true })}
__orca_restore_agent_teams_path() {
[[ -n "\${ORCA_AGENT_TEAMS_SHIM_DIR:-}" ]] || return 0
case "$PATH" in
"\${ORCA_AGENT_TEAMS_SHIM_DIR}"|"\${ORCA_AGENT_TEAMS_SHIM_DIR}:"*) return 0 ;;
esac
export PATH="\${ORCA_AGENT_TEAMS_SHIM_DIR}:$PATH"
}
__orca_restore_agent_teams_path
# Why: .zlogin is the final login startup file before the prompt is shown.
[[ -n "\${ORCA_OPENCODE_CONFIG_DIR:-}" ]] && export OPENCODE_CONFIG_DIR="\${ORCA_OPENCODE_CONFIG_DIR}"
[[ -n "\${ORCA_MIMOCODE_HOME:-}" ]] && export MIMOCODE_HOME="\${ORCA_MIMOCODE_HOME}"
${getPosixOmpShellWrapper()}
[[ -n "\${ORCA_CODEX_HOME:-}" ]] && export CODEX_HOME="\${ORCA_CODEX_HOME}"
${ZSH_HISTFILE_RESTORE_BLOCK}
${getPosixCodexShellLaunchPreflight()}
${getZshShellReadyMarkerRegistrationBlock(SHELL_READY_MARKER)}
${getZshFinalZdotdirRestoreBlock()}
`
const zsh = buildZshStartupWrapperFiles(getDaemonZshWrapperSpec(zshDir))
const bashRc = getDaemonBashShellReadyRcfileContent()
const files = [
[join(zshDir, '.zshenv'), zshEnv],
[join(zshDir, '.zprofile'), zshProfile],
[join(zshDir, '.zshrc'), zshRc],
[join(zshDir, '.zlogin'), zshLogin],
[join(zshDir, '.zshenv'), zsh.zshenv],
[join(zshDir, '.zprofile'), zsh.zprofile],
[join(zshDir, '.zshrc'), zsh.zshrc],
[join(zshDir, '.zlogin'), zsh.zlogin],
[join(bashDir, 'rcfile'), bashRc]
] as const
@@ -5,15 +5,10 @@
* readiness scanner watches for before a startup command is written.
*/
import { mkdirSync, writeFileSync, chmodSync } from 'node:fs'
import { getPosixOmpShellWrapper } from '../pty/omp-shell-wrapper'
import { getPosixCodexShellLaunchPreflight } from '../pty/codex-shell-launch-preflight'
import {
getZshEnvTemplate,
getZshFinalZdotdirRestoreBlock,
getZshShellReadyMarkerRegistrationBlock,
getZshStartupFileSourceBlock,
ZSH_HISTFILE_RESTORE_BLOCK
} from '../shell-templates'
buildZshStartupWrapperFiles,
type ZshStartupWrapperSpec
} from '../zsh-startup-wrapper-builder'
import { getBashShellReadyRcfileContent } from './local-pty-shell-ready-bash-rcfile'
import {
getShellReadyWrapperRoot,
@@ -23,50 +18,36 @@ import {
let didEnsureShellReadyWrappers = false
function getLocalZshWrapperSpec(zshDir: string): ZshStartupWrapperSpec {
return {
headerLabel: 'Orca zsh shell-ready wrapper',
zshDir,
zshenvStrategy: 'discover-user-zdotdir',
readyMarkerEscaped: SHELL_READY_MARKER_ESCAPED,
osc133CommandMarkers: true,
skipUserZshrcWhenHomeIsWrapperDir: true,
interactiveRestoreComment:
"# Why: ~/.zshrc can export the user's default OpenCode config after spawn.",
loginRestoreComment:
'# Why: .zlogin is the final login startup file before the prompt is shown.',
restores: {
agentTeamsPath: true,
remoteCliBinDir: false,
codexHome: true,
codexLaunchPreflight: true
},
readyMarkerOrder: 'before-zdotdir-restore',
legacyFormatting: {
unindentedMimocodeRestore: true,
codexHomeRestoreComment:
"# Why: Codex must keep using Orca's runtime CODEX_HOME after rc files."
}
}
}
export function getZshShellReadyRcfileContent(): string {
return `# Orca zsh shell-ready wrapper
${getZshStartupFileSourceBlock({
fileName: '.zshrc',
interactiveOnly: true,
skipWhenHomeIsCurrentZdotdir: true
})}
__orca_restore_agent_teams_path() {
[[ -n "\${ORCA_AGENT_TEAMS_SHIM_DIR:-}" ]] || return 0
case "$PATH" in
"\${ORCA_AGENT_TEAMS_SHIM_DIR}"|"\${ORCA_AGENT_TEAMS_SHIM_DIR}:"*) return 0 ;;
esac
export PATH="\${ORCA_AGENT_TEAMS_SHIM_DIR}:$PATH"
}
[[ ! -o login ]] && __orca_restore_agent_teams_path
if [[ ! -o login ]]; then
# Why: ~/.zshrc can export the user's default OpenCode config after spawn.
[[ -n "\${ORCA_OPENCODE_CONFIG_DIR:-}" ]] && export OPENCODE_CONFIG_DIR="\${ORCA_OPENCODE_CONFIG_DIR}"
[[ -n "\${ORCA_MIMOCODE_HOME:-}" ]] && export MIMOCODE_HOME="\${ORCA_MIMOCODE_HOME}"
${getPosixOmpShellWrapper()}
# Why: Codex must keep using Orca's runtime CODEX_HOME after rc files.
[[ -n "\${ORCA_CODEX_HOME:-}" ]] && export CODEX_HOME="\${ORCA_CODEX_HOME}"
${ZSH_HISTFILE_RESTORE_BLOCK}
${getPosixCodexShellLaunchPreflight()}
fi
__orca_osc133_precmd() {
local exit_code=$?
if [[ -n "\${__orca_in_command:-}" ]]; then
printf "\\033]133;D;%s\\007" "$exit_code"
unset __orca_in_command
fi
printf "\\033]133;A\\007"
}
__orca_osc133_preexec() {
printf "\\033]133;C\\007"
__orca_in_command=1
}
# Why: prepend so Orca captures $? before user prompt hooks can overwrite it.
precmd_functions=(__orca_osc133_precmd \${precmd_functions[@]})
preexec_functions=(__orca_osc133_preexec \${preexec_functions[@]})
if [[ ! -o login ]]; then
${getZshFinalZdotdirRestoreBlock()}
fi
`
return buildZshStartupWrapperFiles(getLocalZshWrapperSpec(`${getShellReadyWrapperRoot()}/zsh`))
.zshrc
}
export function ensureShellReadyWrappersAt(root = getShellReadyWrapperRoot()): void {
@@ -78,38 +59,14 @@ export function ensureShellReadyWrappersAt(root = getShellReadyWrapperRoot()): v
const zshDir = `${root}/zsh`
const bashDir = `${root}/bash`
const zshEnv = getZshEnvTemplate(zshDir)
const zshProfile = `# Orca zsh shell-ready wrapper
${getZshStartupFileSourceBlock({ fileName: '.zprofile' })}
`
const zshRc = getZshShellReadyRcfileContent()
const zshLogin = `# Orca zsh shell-ready wrapper
${getZshStartupFileSourceBlock({ fileName: '.zlogin', interactiveOnly: true })}
__orca_restore_agent_teams_path() {
[[ -n "\${ORCA_AGENT_TEAMS_SHIM_DIR:-}" ]] || return 0
case "$PATH" in
"\${ORCA_AGENT_TEAMS_SHIM_DIR}"|"\${ORCA_AGENT_TEAMS_SHIM_DIR}:"*) return 0 ;;
esac
export PATH="\${ORCA_AGENT_TEAMS_SHIM_DIR}:$PATH"
}
__orca_restore_agent_teams_path
# Why: .zlogin is the final login startup file before the prompt is shown.
[[ -n "\${ORCA_OPENCODE_CONFIG_DIR:-}" ]] && export OPENCODE_CONFIG_DIR="\${ORCA_OPENCODE_CONFIG_DIR}"
[[ -n "\${ORCA_MIMOCODE_HOME:-}" ]] && export MIMOCODE_HOME="\${ORCA_MIMOCODE_HOME}"
${getPosixOmpShellWrapper()}
[[ -n "\${ORCA_CODEX_HOME:-}" ]] && export CODEX_HOME="\${ORCA_CODEX_HOME}"
${ZSH_HISTFILE_RESTORE_BLOCK}
${getPosixCodexShellLaunchPreflight()}
${getZshShellReadyMarkerRegistrationBlock(SHELL_READY_MARKER_ESCAPED)}
${getZshFinalZdotdirRestoreBlock()}
`
const zsh = buildZshStartupWrapperFiles(getLocalZshWrapperSpec(zshDir))
const bashRc = getBashShellReadyRcfileContent()
const files = [
[`${zshDir}/.zshenv`, zshEnv],
[`${zshDir}/.zprofile`, zshProfile],
[`${zshDir}/.zshrc`, zshRc],
[`${zshDir}/.zlogin`, zshLogin],
[`${zshDir}/.zshenv`, zsh.zshenv],
[`${zshDir}/.zprofile`, zsh.zprofile],
[`${zshDir}/.zshrc`, zsh.zshrc],
[`${zshDir}/.zlogin`, zsh.zlogin],
[`${bashDir}/rcfile`, bashRc]
] as const
+29 -5
View File
@@ -12,11 +12,11 @@ fi`
// Why: daemon, local, and relay wrappers must preserve one Bash prompt-hook contract.
export { BASH_PROMPT_COMMAND_COMPOSITION_BLOCK } from './bash-prompt-command-composition'
export function getZshEnvTemplate(zshDir: string, headerPrefix = ''): string {
const header = headerPrefix
? `Orca ${headerPrefix} zsh shell-ready wrapper`
: 'Orca zsh shell-ready wrapper'
return `# ${header}
export function getZshEnvTemplate(
zshDir: string,
headerLabel = 'Orca zsh shell-ready wrapper'
): string {
return `# ${headerLabel}
${SHELL_STARTUP_IDENTITY_MARKER_BLOCK}
# Why: capture the runtime wrapper dir before it is unset below. On WSL this
# file is generated with a Windows path but sourced via /mnt/c, so the baked
@@ -103,6 +103,30 @@ unset _orca_spawn_orig_zdotdir _orca_user_zdotdir _orca_zshenv_source_dir _orca_
`
}
/**
* The relay variant of the .zshenv above: it trusts the ZDOTDIR the remote
* shell already inherited instead of re-deriving one, and republishes it as
* ORCA_USER_ZDOTDIR for the later wrapper files.
*
* Why separate: this diverged from the discovery template before unification
* and is preserved verbatim here — reconciling the two is a follow-up.
*/
export function getZshOverlayEnvTemplate(zshDir: string, headerLabel: string): string {
return `# ${headerLabel}
${SHELL_STARTUP_IDENTITY_MARKER_BLOCK}
export ORCA_ORIG_ZDOTDIR="\${ORCA_ORIG_ZDOTDIR:-$HOME}"
case "\${ORCA_ORIG_ZDOTDIR%/}" in
*/shell-ready/zsh) export ORCA_ORIG_ZDOTDIR="$HOME" ;;
esac
[[ -f "$ORCA_ORIG_ZDOTDIR/.zshenv" ]] && source "$ORCA_ORIG_ZDOTDIR/.zshenv"
export ORCA_USER_ZDOTDIR="\${ZDOTDIR:-\${ORCA_ORIG_ZDOTDIR:-$HOME}}"
case "\${ORCA_USER_ZDOTDIR%/}" in
*/shell-ready/zsh) export ORCA_USER_ZDOTDIR="$HOME" ;;
esac
export ZDOTDIR=${quotePosixSingle(zshDir)}
`
}
/**
* Restores the worktree-scoped HISTFILE that macOS `/etc/zshrc` destroys.
*
+200
View File
@@ -0,0 +1,200 @@
/**
* The single source of the zsh startup wrapper files (.zshenv/.zprofile/.zshrc/
* .zlogin) Orca writes for every transport: local PTY, daemon/SSH, and relay.
*
* Why: the three generators were copies that drifted apart, so a fix landed in
* one transport and silently missed the other two. Everything they genuinely
* disagree on is a field on ZshStartupWrapperSpec, so the disagreements are
* visible in one place instead of spread across three template literals.
*/
import { getPosixOmpShellWrapper } from './pty/omp-shell-wrapper'
import { getPosixCodexShellLaunchPreflight } from './pty/codex-shell-launch-preflight'
import {
getZshEnvTemplate,
getZshFinalZdotdirRestoreBlock,
getZshOverlayEnvTemplate,
getZshShellReadyMarkerRegistrationBlock,
getZshStartupFileSourceBlock,
ZSH_HISTFILE_RESTORE_BLOCK
} from './shell-templates'
/** Runtime values the wrapper re-exports after the user's own startup files ran. */
export type ZshWrapperRestoreSpec = {
/** Orca's agent-teams shim dir back onto PATH. */
agentTeamsPath: boolean
/** Remote CLI bin dir onto PATH — relay hosts only. */
remoteCliBinDir: boolean
/** Orca's runtime CODEX_HOME. */
codexHome: boolean
/** The `codex()` wrapper that runs Orca's launch preflight. */
codexLaunchPreflight: boolean
}
/**
* Pre-existing cosmetic drift in the .zshrc restore block. Carried as explicit
* fields so unifying the generators stays byte-identical; normalizing these
* away is a follow-up, not part of the unification.
*/
export type ZshWrapperLegacyFormatting = {
/** Local .zshrc lost the two-space indent on the MIMOCODE_HOME restore. */
unindentedMimocodeRestore?: boolean
/** Only local .zshrc carries a comment above the CODEX_HOME restore. */
codexHomeRestoreComment?: string
}
export type ZshStartupWrapperSpec = {
/** First line of every generated file, e.g. `# Orca zsh shell-ready wrapper`. */
headerLabel: string
/** Wrapper ZDOTDIR baked into .zshenv as the fallback literal. */
zshDir: string
/**
* How .zshenv finds the user's real ZDOTDIR. `discover-user-zdotdir` sources
* the user .zshenv and reads what it exported; `overlay-user-zdotdir` trusts
* the inherited ZDOTDIR and republishes it as ORCA_USER_ZDOTDIR.
*/
zshenvStrategy: 'discover-user-zdotdir' | 'overlay-user-zdotdir'
/** zsh expression the wrapper resolves the user's startup-file dir from. */
homeExpression?: string
readyMarkerEscaped: string
/** OSC 133 command-lifecycle hooks in .zshrc. */
osc133CommandMarkers: boolean
/** Skip the user .zshrc when its dir is already the wrapper ZDOTDIR. */
skipUserZshrcWhenHomeIsWrapperDir: boolean
/** Comment heading the non-login restore block in .zshrc. */
interactiveRestoreComment: string
/** Comment heading the restore block in .zlogin. */
loginRestoreComment: string
restores: ZshWrapperRestoreSpec
/** Where the ready-marker widget lands relative to the final ZDOTDIR restore. */
readyMarkerOrder: 'before-zdotdir-restore' | 'after-zdotdir-restore'
legacyFormatting?: ZshWrapperLegacyFormatting
}
export type ZshStartupWrapperFiles = {
zshenv: string
zprofile: string
zshrc: string
zlogin: string
}
const AGENT_TEAMS_PATH_RESTORE_FUNCTION = `__orca_restore_agent_teams_path() {
[[ -n "\${ORCA_AGENT_TEAMS_SHIM_DIR:-}" ]] || return 0
case "$PATH" in
"\${ORCA_AGENT_TEAMS_SHIM_DIR}"|"\${ORCA_AGENT_TEAMS_SHIM_DIR}:"*) return 0 ;;
esac
export PATH="\${ORCA_AGENT_TEAMS_SHIM_DIR}:$PATH"
}`
const OPENCODE_CONFIG_DIR_RESTORE = `[[ -n "\${ORCA_OPENCODE_CONFIG_DIR:-}" ]] && export OPENCODE_CONFIG_DIR="\${ORCA_OPENCODE_CONFIG_DIR}"`
const MIMOCODE_HOME_RESTORE = `[[ -n "\${ORCA_MIMOCODE_HOME:-}" ]] && export MIMOCODE_HOME="\${ORCA_MIMOCODE_HOME}"`
const REMOTE_CLI_BIN_DIR_RESTORE = `[[ -n "\${ORCA_REMOTE_CLI_BIN_DIR:-}" ]] && case ":$PATH:" in *:"\${ORCA_REMOTE_CLI_BIN_DIR}":*) ;; *) export PATH="\${ORCA_REMOTE_CLI_BIN_DIR}:$PATH" ;; esac`
const CODEX_HOME_RESTORE = `[[ -n "\${ORCA_CODEX_HOME:-}" ]] && export CODEX_HOME="\${ORCA_CODEX_HOME}"`
const ZSH_OSC133_COMMAND_MARKER_BLOCK = `__orca_osc133_precmd() {
local exit_code=$?
if [[ -n "\${__orca_in_command:-}" ]]; then
printf "\\033]133;D;%s\\007" "$exit_code"
unset __orca_in_command
fi
printf "\\033]133;A\\007"
}
__orca_osc133_preexec() {
printf "\\033]133;C\\007"
__orca_in_command=1
}
# Why: prepend so Orca captures $? before user prompt hooks can overwrite it.
precmd_functions=(__orca_osc133_precmd \${precmd_functions[@]})
preexec_functions=(__orca_osc133_preexec \${preexec_functions[@]})`
/**
* Blocks already carrying a trailing newline (the omp wrapper, the codex
* preflight, the shared source/restore templates) keep it, so joining on a
* single newline reproduces the blank-line spacing of the originals.
*/
function joinBlocks(blocks: (string | null)[]): string {
return blocks.filter((block): block is string => block !== null).join('\n')
}
/** The env/PATH restores that must outlast the user's own startup files. */
function getRestoreLines(
spec: ZshStartupWrapperSpec,
indent: string,
legacyFormatting?: ZshWrapperLegacyFormatting
): (string | null)[] {
const mimocodeIndent = legacyFormatting?.unindentedMimocodeRestore ? '' : indent
const codexHomeComment = legacyFormatting?.codexHomeRestoreComment
return [
`${indent}${OPENCODE_CONFIG_DIR_RESTORE}`,
`${mimocodeIndent}${MIMOCODE_HOME_RESTORE}`,
spec.restores.remoteCliBinDir ? `${indent}${REMOTE_CLI_BIN_DIR_RESTORE}` : null,
`${indent}${getPosixOmpShellWrapper()}`,
spec.restores.codexHome && codexHomeComment ? `${indent}${codexHomeComment}` : null,
spec.restores.codexHome ? `${indent}${CODEX_HOME_RESTORE}` : null,
ZSH_HISTFILE_RESTORE_BLOCK,
spec.restores.codexLaunchPreflight ? `${indent}${getPosixCodexShellLaunchPreflight()}` : null
]
}
function buildZshrc(spec: ZshStartupWrapperSpec): string {
return `${joinBlocks([
`# ${spec.headerLabel}`,
getZshStartupFileSourceBlock({
fileName: '.zshrc',
homeExpression: spec.homeExpression,
interactiveOnly: true,
skipWhenHomeIsCurrentZdotdir: spec.skipUserZshrcWhenHomeIsWrapperDir
}),
spec.restores.agentTeamsPath
? `${AGENT_TEAMS_PATH_RESTORE_FUNCTION}\n[[ ! -o login ]] && __orca_restore_agent_teams_path`
: null,
joinBlocks([
'if [[ ! -o login ]]; then',
` ${spec.interactiveRestoreComment}`,
...getRestoreLines(spec, ' ', spec.legacyFormatting),
'fi'
]),
spec.osc133CommandMarkers ? ZSH_OSC133_COMMAND_MARKER_BLOCK : null,
`if [[ ! -o login ]]; then\n${getZshFinalZdotdirRestoreBlock(spec.homeExpression)}\nfi`
])}\n`
}
function buildZlogin(spec: ZshStartupWrapperSpec): string {
const finalZdotdirRestore = getZshFinalZdotdirRestoreBlock(spec.homeExpression)
const readyMarker = getZshShellReadyMarkerRegistrationBlock(spec.readyMarkerEscaped)
const tail =
spec.readyMarkerOrder === 'before-zdotdir-restore'
? [readyMarker, finalZdotdirRestore]
: [finalZdotdirRestore, readyMarker]
return `${joinBlocks([
`# ${spec.headerLabel}`,
getZshStartupFileSourceBlock({
fileName: '.zlogin',
homeExpression: spec.homeExpression,
interactiveOnly: true
}),
spec.restores.agentTeamsPath
? `${AGENT_TEAMS_PATH_RESTORE_FUNCTION}\n__orca_restore_agent_teams_path`
: null,
joinBlocks([spec.loginRestoreComment, ...getRestoreLines(spec, '')]),
...tail
])}\n`
}
export function buildZshStartupWrapperFiles(spec: ZshStartupWrapperSpec): ZshStartupWrapperFiles {
return {
zshenv:
spec.zshenvStrategy === 'discover-user-zdotdir'
? getZshEnvTemplate(spec.zshDir, spec.headerLabel)
: getZshOverlayEnvTemplate(spec.zshDir, spec.headerLabel),
zprofile: `${joinBlocks([
`# ${spec.headerLabel}`,
getZshStartupFileSourceBlock({
fileName: '.zprofile',
homeExpression: spec.homeExpression
})
])}\n`,
zshrc: buildZshrc(spec),
zlogin: buildZlogin(spec)
}
}
+34 -62
View File
@@ -3,12 +3,13 @@ import { dirname, join } from 'node:path'
import { getPosixOmpShellWrapper } from '../main/pty/omp-shell-wrapper'
import {
BASH_PROMPT_COMMAND_COMPOSITION_BLOCK,
getZshFinalZdotdirRestoreBlock,
getZshShellReadyMarkerRegistrationBlock,
SHELL_STARTUP_IDENTITY_MARKER_BLOCK,
ZSH_HISTFILE_RESTORE_BLOCK,
getZshStartupFileSourceBlock
ZSH_HISTFILE_RESTORE_BLOCK
} from '../main/shell-templates'
import {
buildZshStartupWrapperFiles,
type ZshStartupWrapperSpec
} from '../main/zsh-startup-wrapper-builder'
/** Writes the zsh/bash overlay wrapper files a relay-spawned shell sources.
* Split from pty-shell-launch.ts so the launch-config decisions stay readable
@@ -16,66 +17,37 @@ import {
const SHELL_READY_MARKER_ESCAPED = '\\033]777;orca-shell-ready\\007'
function quotePosixSingle(value: string): string {
return `'${value.replace(/'/g, `'\\''`)}'`
// Why: the relay .zshenv republishes the inherited ZDOTDIR as ORCA_USER_ZDOTDIR,
// so later wrapper files prefer it over the spawn-time ORCA_ORIG_ZDOTDIR.
const RELAY_HOME_EXPRESSION = '"${ORCA_USER_ZDOTDIR:-${ORCA_ORIG_ZDOTDIR:-$HOME}}"'
function getRelayZshWrapperSpec(zshDir: string): ZshStartupWrapperSpec {
return {
headerLabel: 'Orca relay zsh overlay wrapper',
zshDir,
zshenvStrategy: 'overlay-user-zdotdir',
homeExpression: RELAY_HOME_EXPRESSION,
readyMarkerEscaped: SHELL_READY_MARKER_ESCAPED,
osc133CommandMarkers: false,
skipUserZshrcWhenHomeIsWrapperDir: false,
interactiveRestoreComment:
'# Why: remote startup files can re-export user defaults after relay spawn.',
loginRestoreComment: '# Why: .zlogin is the final zsh login startup file before the prompt.',
restores: {
agentTeamsPath: false,
remoteCliBinDir: true,
codexHome: false,
codexLaunchPreflight: false
},
readyMarkerOrder: 'after-zdotdir-restore'
}
}
export function ensureOverlayRestoreWrappers(root: string): void {
const zshDir = join(root, 'zsh')
const bashDir = join(root, 'bash')
const zshEnv = `# Orca relay zsh overlay wrapper
${SHELL_STARTUP_IDENTITY_MARKER_BLOCK}
export ORCA_ORIG_ZDOTDIR="\${ORCA_ORIG_ZDOTDIR:-$HOME}"
case "\${ORCA_ORIG_ZDOTDIR%/}" in
*/shell-ready/zsh) export ORCA_ORIG_ZDOTDIR="$HOME" ;;
esac
[[ -f "$ORCA_ORIG_ZDOTDIR/.zshenv" ]] && source "$ORCA_ORIG_ZDOTDIR/.zshenv"
export ORCA_USER_ZDOTDIR="\${ZDOTDIR:-\${ORCA_ORIG_ZDOTDIR:-$HOME}}"
case "\${ORCA_USER_ZDOTDIR%/}" in
*/shell-ready/zsh) export ORCA_USER_ZDOTDIR="$HOME" ;;
esac
export ZDOTDIR=${quotePosixSingle(zshDir)}
`
const zshProfile = `# Orca relay zsh overlay wrapper
${getZshStartupFileSourceBlock({
fileName: '.zprofile',
homeExpression: '"${ORCA_USER_ZDOTDIR:-${ORCA_ORIG_ZDOTDIR:-$HOME}}"'
})}
`
const zshRc = `# Orca relay zsh overlay wrapper
${getZshStartupFileSourceBlock({
fileName: '.zshrc',
homeExpression: '"${ORCA_USER_ZDOTDIR:-${ORCA_ORIG_ZDOTDIR:-$HOME}}"',
interactiveOnly: true
})}
if [[ ! -o login ]]; then
# Why: remote startup files can re-export user defaults after relay spawn.
[[ -n "\${ORCA_OPENCODE_CONFIG_DIR:-}" ]] && export OPENCODE_CONFIG_DIR="\${ORCA_OPENCODE_CONFIG_DIR}"
[[ -n "\${ORCA_MIMOCODE_HOME:-}" ]] && export MIMOCODE_HOME="\${ORCA_MIMOCODE_HOME}"
[[ -n "\${ORCA_REMOTE_CLI_BIN_DIR:-}" ]] && case ":$PATH:" in *:"\${ORCA_REMOTE_CLI_BIN_DIR}":*) ;; *) export PATH="\${ORCA_REMOTE_CLI_BIN_DIR}:$PATH" ;; esac
${getPosixOmpShellWrapper()}
${ZSH_HISTFILE_RESTORE_BLOCK}
fi
if [[ ! -o login ]]; then
${getZshFinalZdotdirRestoreBlock('"${ORCA_USER_ZDOTDIR:-${ORCA_ORIG_ZDOTDIR:-$HOME}}"')}
fi
`
const zshLogin = `# Orca relay zsh overlay wrapper
${getZshStartupFileSourceBlock({
fileName: '.zlogin',
homeExpression: '"${ORCA_USER_ZDOTDIR:-${ORCA_ORIG_ZDOTDIR:-$HOME}}"',
interactiveOnly: true
})}
# Why: .zlogin is the final zsh login startup file before the prompt.
[[ -n "\${ORCA_OPENCODE_CONFIG_DIR:-}" ]] && export OPENCODE_CONFIG_DIR="\${ORCA_OPENCODE_CONFIG_DIR}"
[[ -n "\${ORCA_MIMOCODE_HOME:-}" ]] && export MIMOCODE_HOME="\${ORCA_MIMOCODE_HOME}"
[[ -n "\${ORCA_REMOTE_CLI_BIN_DIR:-}" ]] && case ":$PATH:" in *:"\${ORCA_REMOTE_CLI_BIN_DIR}":*) ;; *) export PATH="\${ORCA_REMOTE_CLI_BIN_DIR}:$PATH" ;; esac
${getPosixOmpShellWrapper()}
${ZSH_HISTFILE_RESTORE_BLOCK}
${getZshFinalZdotdirRestoreBlock('"${ORCA_USER_ZDOTDIR:-${ORCA_ORIG_ZDOTDIR:-$HOME}}"')}
${getZshShellReadyMarkerRegistrationBlock(SHELL_READY_MARKER_ESCAPED)}
`
const zsh = buildZshStartupWrapperFiles(getRelayZshWrapperSpec(zshDir))
const bashRc = `# Orca relay bash overlay wrapper
${SHELL_STARTUP_IDENTITY_MARKER_BLOCK}
[[ -f /etc/profile ]] && source /etc/profile
@@ -181,10 +153,10 @@ unset __orca_initializing_wrapper
`
const files = [
[join(zshDir, '.zshenv'), zshEnv],
[join(zshDir, '.zprofile'), zshProfile],
[join(zshDir, '.zshrc'), zshRc],
[join(zshDir, '.zlogin'), zshLogin],
[join(zshDir, '.zshenv'), zsh.zshenv],
[join(zshDir, '.zprofile'), zsh.zprofile],
[join(zshDir, '.zshrc'), zsh.zshrc],
[join(zshDir, '.zlogin'), zsh.zlogin],
[join(bashDir, 'rcfile'), bashRc]
] as const