Revert "Fix Claude PR hyperlinks in terminal" (#5826)
This commit is contained in:
parent
2226e3cbc2
commit
5dbff5d8ea
|
|
@ -21,7 +21,6 @@ import { resolveEffectiveWindowsPowerShell } from '../providers/windows-powershe
|
|||
import { isPwshAvailable } from '../pwsh'
|
||||
import { isHostCodexHomeForWsl, isWslCodexHomeForHost } from '../pty/codex-home-wsl-env'
|
||||
import { removeInheritedNoColor } from '../pty/terminal-color-env'
|
||||
import { buildTerminalCapabilityEnv } from '../../shared/terminal-capability-env'
|
||||
import { parseWslPath } from '../wsl'
|
||||
import { addWslEnvKeys } from '../wsl-env'
|
||||
import { getWslContextFromSessionId } from './wsl-session-context'
|
||||
|
|
@ -402,7 +401,21 @@ export function createPtySubprocess(opts: PtySubprocessOptions): SubprocessHandl
|
|||
const env: Record<string, string> = {
|
||||
...process.env,
|
||||
...opts.env,
|
||||
...buildTerminalCapabilityEnv(process.env.ORCA_APP_VERSION ?? '0.0.0-dev')
|
||||
TERM: 'xterm-256color',
|
||||
COLORTERM: 'truecolor',
|
||||
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',
|
||||
// Why: opt tools (Claude Code, ls --hyperlink, etc.) into emitting OSC 8
|
||||
// hyperlinks. The `supports-hyperlinks` npm package gates on a hard-coded
|
||||
// TERM_PROGRAM allowlist (iTerm.app / WezTerm / vscode) and returns false
|
||||
// for TERM_PROGRAM=Orca, so callers drop OSC 8 output entirely and emit
|
||||
// bare text instead. xterm.js in Orca parses OSC 8 and the pane's
|
||||
// linkHandler routes clicks, so forcing the advertisement is safe and
|
||||
// restores clickable refs like `owner/repo#123` / `PR#123`.
|
||||
FORCE_HYPERLINK: '1'
|
||||
} as Record<string, string>
|
||||
for (const key of opts.envToDelete ?? []) {
|
||||
delete env[key]
|
||||
|
|
|
|||
|
|
@ -629,30 +629,31 @@ describe('registerPtyHandlers', () => {
|
|||
expect(env.LANG).toBe('fr_FR.UTF-8')
|
||||
})
|
||||
|
||||
it('advertises xterm.js-compatible terminal capabilities while preserving Orca identity', async () => {
|
||||
it('always sets TERM and COLORTERM regardless of env', async () => {
|
||||
const env = await spawnAndGetEnv()
|
||||
expect(env.TERM).toBe('xterm-256color')
|
||||
expect(env.COLORTERM).toBe('truecolor')
|
||||
expect(env.TERM_PROGRAM).toBe('vscode')
|
||||
expect(env.TERM_PROGRAM_VERSION).toBe('1.100.0')
|
||||
expect(env.ORCA_TERM_PROGRAM).toBe('Orca')
|
||||
expect(env.TERM_PROGRAM).toBe('Orca')
|
||||
})
|
||||
|
||||
it('advertises OSC 8 hyperlink support via FORCE_HYPERLINK', async () => {
|
||||
// Why: some hyperlink detectors still miss Electron embedders even with
|
||||
// xterm.js-compatible TERM_PROGRAM values; Orca routes OSC 8 natively.
|
||||
// Why: the supports-hyperlinks npm package hard-codes a TERM_PROGRAM
|
||||
// allowlist (iTerm.app / WezTerm / vscode) and reports false for
|
||||
// TERM_PROGRAM=Orca, so tools like Claude Code emit plain text instead
|
||||
// of ESC]8;; wrappers. Setting FORCE_HYPERLINK=1 forces the detector to
|
||||
// return true; xterm.js + our linkHandler handle the sequences natively.
|
||||
const env = await spawnAndGetEnv()
|
||||
expect(env.FORCE_HYPERLINK).toBe('1')
|
||||
})
|
||||
|
||||
it('surfaces ORCA_APP_VERSION as ORCA_TERM_PROGRAM_VERSION for Orca identity', async () => {
|
||||
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.ORCA_TERM_PROGRAM_VERSION).toBe('1.2.3-test')
|
||||
expect(env.TERM_PROGRAM_VERSION).toBe('1.2.3-test')
|
||||
})
|
||||
|
||||
it('falls back to a placeholder Orca version when ORCA_APP_VERSION is unset', async () => {
|
||||
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.ORCA_TERM_PROGRAM_VERSION).toBe('0.0.0-dev')
|
||||
expect(env.TERM_PROGRAM_VERSION).toBe('0.0.0-dev')
|
||||
})
|
||||
|
||||
it('injects the selected Codex home into Orca terminal PTYs', async () => {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import {
|
|||
STARTUP_COMMAND_READY_MAX_WAIT_MS
|
||||
} from './local-pty-shell-ready'
|
||||
import { removeInheritedNoColor } from '../pty/terminal-color-env'
|
||||
import { buildTerminalCapabilityEnv } from '../../shared/terminal-capability-env'
|
||||
import { isHostCodexHomeForWsl, isWslCodexHomeForHost } from '../pty/codex-home-wsl-env'
|
||||
import { addWslEnvKeys } from '../wsl-env'
|
||||
import {
|
||||
|
|
@ -407,7 +406,22 @@ export class LocalPtyProvider implements IPtyProvider {
|
|||
const spawnEnv: Record<string, string> = {
|
||||
...process.env,
|
||||
...args.env,
|
||||
...buildTerminalCapabilityEnv(process.env.ORCA_APP_VERSION ?? '0.0.0-dev')
|
||||
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',
|
||||
// Why: opt tools (Claude Code, ls --hyperlink, etc.) into emitting OSC 8
|
||||
// hyperlinks. The `supports-hyperlinks` npm package gates on a hard-coded
|
||||
// TERM_PROGRAM allowlist (iTerm.app / WezTerm / vscode) and returns false
|
||||
// for TERM_PROGRAM=Orca, so callers drop OSC 8 output entirely and emit
|
||||
// bare text instead. xterm.js in Orca parses OSC 8 and the pane's
|
||||
// linkHandler routes clicks, so forcing the advertisement is safe and
|
||||
// restores clickable refs like `owner/repo#123` / `PR#123`.
|
||||
FORCE_HYPERLINK: '1'
|
||||
} as Record<string, string>
|
||||
// Why: Orca can be launched from an Orca terminal while developing. Pane
|
||||
// identity belongs to the child PTY, not the parent shell that spawned app.
|
||||
|
|
|
|||
|
|
@ -162,15 +162,6 @@ describe('PtyHandler', () => {
|
|||
const result = await dispatcher.callRequest('pty.spawn', { cols: 80, rows: 24 })
|
||||
expect(result).toEqual({ id: 'pty-1' })
|
||||
expect(mockPtySpawn).toHaveBeenCalled()
|
||||
const spawnOptions = mockPtySpawn.mock.calls[0]?.[2]
|
||||
expect(spawnOptions?.env).toMatchObject({
|
||||
TERM: 'xterm-256color',
|
||||
COLORTERM: 'truecolor',
|
||||
TERM_PROGRAM: 'vscode',
|
||||
TERM_PROGRAM_VERSION: '1.100.0',
|
||||
ORCA_TERM_PROGRAM: 'Orca',
|
||||
FORCE_HYPERLINK: '1'
|
||||
})
|
||||
expect(handler.activePtyCount).toBe(1)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import {
|
|||
import { getRelayShellLaunchConfig } from './pty-shell-launch'
|
||||
import { DEFAULT_SSH_RELAY_GRACE_PERIOD_SECONDS } from '../shared/ssh-types'
|
||||
import { shouldUseShellReadyStartupDelivery } from '../shared/codex-startup-delivery'
|
||||
import { buildTerminalCapabilityEnv } from '../shared/terminal-capability-env'
|
||||
|
||||
// Why: node-pty is a native addon that may not be installed on the remote.
|
||||
// Dynamic import keeps the require() lazy so loadPty() returns null gracefully
|
||||
|
|
@ -209,11 +208,7 @@ export class PtyHandler {
|
|||
rendererEnv: Record<string, string> | undefined,
|
||||
ctx: { id: string; paneKey?: string; shell: string; command?: string }
|
||||
): Record<string, string> {
|
||||
const baseEnv = {
|
||||
...process.env,
|
||||
...rendererEnv,
|
||||
...buildTerminalCapabilityEnv(process.env.ORCA_APP_VERSION ?? '0.0.0-dev')
|
||||
} as Record<string, string>
|
||||
const baseEnv = { ...process.env, ...rendererEnv } as Record<string, string>
|
||||
const augmented: Record<string, string> = {}
|
||||
for (const augmenter of this.envAugmenters) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
import { buildTerminalCapabilityEnv } from './terminal-capability-env'
|
||||
|
||||
describe('buildTerminalCapabilityEnv', () => {
|
||||
it('advertises xterm.js-compatible hyperlink capabilities and Orca identity', () => {
|
||||
const env = buildTerminalCapabilityEnv('1.2.3')
|
||||
|
||||
expect(env).toEqual({
|
||||
TERM: 'xterm-256color',
|
||||
COLORTERM: 'truecolor',
|
||||
TERM_PROGRAM: 'vscode',
|
||||
TERM_PROGRAM_VERSION: '1.100.0',
|
||||
ORCA_TERM_PROGRAM: 'Orca',
|
||||
ORCA_TERM_PROGRAM_VERSION: '1.2.3',
|
||||
FORCE_HYPERLINK: '1'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
const XTERM_JS_COMPATIBLE_TERM_PROGRAM = 'vscode'
|
||||
const XTERM_JS_COMPATIBLE_TERM_PROGRAM_VERSION = '1.100.0'
|
||||
|
||||
export function buildTerminalCapabilityEnv(appVersion: string): Record<string, string> {
|
||||
return {
|
||||
TERM: 'xterm-256color',
|
||||
COLORTERM: 'truecolor',
|
||||
// Why: Claude Code and other CLIs gate OSC 8 links on known xterm.js
|
||||
// embedders. Do not change this back to "Orca": that makes PR links
|
||||
// render as plain text. ORCA_* keeps our real app identity available.
|
||||
TERM_PROGRAM: XTERM_JS_COMPATIBLE_TERM_PROGRAM,
|
||||
TERM_PROGRAM_VERSION: XTERM_JS_COMPATIBLE_TERM_PROGRAM_VERSION,
|
||||
ORCA_TERM_PROGRAM: 'Orca',
|
||||
ORCA_TERM_PROGRAM_VERSION: appVersion,
|
||||
// Why: supports-hyperlinks can still miss Electron embedders; force OSC 8
|
||||
// output because Orca parses and routes those links natively.
|
||||
FORCE_HYPERLINK: '1'
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue