diff --git a/src/main/daemon/pty-subprocess.ts b/src/main/daemon/pty-subprocess.ts index 181d4b05bbd..58849ba9ca0 100644 --- a/src/main/daemon/pty-subprocess.ts +++ b/src/main/daemon/pty-subprocess.ts @@ -35,7 +35,11 @@ export function createPtySubprocess(opts: PtySubprocessOptions): SubprocessHandl ...opts.env, TERM: 'xterm-256color', COLORTERM: 'truecolor', - TERM_PROGRAM: 'Orca' + TERM_PROGRAM: 'Orca', + // Why: TUIs feature-gate on TERM_PROGRAM_VERSION. The daemon is forked + // by main (daemon-init.ts:93) with the parent's env, so ORCA_APP_VERSION + // — set in src/main/index.ts from app.getVersion() — is inherited here. + TERM_PROGRAM_VERSION: process.env.ORCA_APP_VERSION ?? '0.0.0-dev' } as Record env.LANG ??= 'en_US.UTF-8' diff --git a/src/main/index.ts b/src/main/index.ts index efbd2809057..f18dcda3025 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -55,6 +55,11 @@ let runtimeRpc: OrcaRuntimeRpcServer | null = null let starNag: StarNagService | null = null installUncaughtPipeErrorGuard() +// Why: propagate the Orca app version into `process.env` so PTY-env +// construction in both main (local-pty-provider) and the forked daemon +// (pty-subprocess) can set `TERM_PROGRAM_VERSION` without re-importing +// electron. The daemon inherits `process.env` via fork (daemon-init.ts:93). +process.env.ORCA_APP_VERSION = app.getVersion() patchPackagedProcessPath() // Why: patchPackagedProcessPath seeds a minimal list of well-known system // dirs synchronously so early IPC (e.g. preflight before the shell spawn diff --git a/src/main/ipc/pty.test.ts b/src/main/ipc/pty.test.ts index 8a3c19611db..b0ccf736b7f 100644 --- a/src/main/ipc/pty.test.ts +++ b/src/main/ipc/pty.test.ts @@ -261,6 +261,16 @@ describe('registerPtyHandlers', () => { expect(env.TERM_PROGRAM).toBe('Orca') }) + it('surfaces ORCA_APP_VERSION as TERM_PROGRAM_VERSION for TUI feature gating', async () => { + const env = await spawnAndGetEnv(undefined, { ORCA_APP_VERSION: '1.2.3-test' }) + expect(env.TERM_PROGRAM_VERSION).toBe('1.2.3-test') + }) + + it('falls back to a placeholder version when ORCA_APP_VERSION is unset', async () => { + const env = await spawnAndGetEnv(undefined, { ORCA_APP_VERSION: undefined }) + expect(env.TERM_PROGRAM_VERSION).toBe('0.0.0-dev') + }) + it('injects the selected Codex home into Orca terminal PTYs', async () => { const env = await spawnAndGetEnv(undefined, undefined, () => '/tmp/orca-codex-home') expect(env.CODEX_HOME).toBe('/tmp/orca-codex-home') diff --git a/src/main/providers/local-pty-provider.ts b/src/main/providers/local-pty-provider.ts index 7de4b68d64c..58b11901e37 100644 --- a/src/main/providers/local-pty-provider.ts +++ b/src/main/providers/local-pty-provider.ts @@ -173,6 +173,11 @@ export class LocalPtyProvider implements IPtyProvider { TERM: 'xterm-256color', COLORTERM: 'truecolor', TERM_PROGRAM: 'Orca', + // Why: TUIs feature-gate on TERM_PROGRAM_VERSION (Neovim's termcap + // autodetection, bat/delta paging hints). Sourced from ORCA_APP_VERSION + // which main/index.ts seeds from app.getVersion() at startup; the + // fallback keeps tests and non-Electron runs working. + TERM_PROGRAM_VERSION: process.env.ORCA_APP_VERSION ?? '0.0.0-dev', FORCE_HYPERLINK: '1' } as Record