diff --git a/src/cli/index-terminal-list-host-scope.test.ts b/src/cli/index-terminal-list-host-scope.test.ts index e442ab11ab2..b38cd71451f 100644 --- a/src/cli/index-terminal-list-host-scope.test.ts +++ b/src/cli/index-terminal-list-host-scope.test.ts @@ -122,7 +122,7 @@ describe('orca terminal list host scope', () => { await main(['terminal', 'list'], '/tmp/repo') const printed = String(logSpy.mock.calls[0]?.[0]) - expect(printed).toContain('scope: unknown') + expect(printed).toContain('scope: unverifiable') expect(printed).not.toContain('scope: local') }) }) diff --git a/src/cli/terminal-format.ts b/src/cli/terminal-format.ts index 4f136e96c65..a4df4ba6951 100644 --- a/src/cli/terminal-format.ts +++ b/src/cli/terminal-format.ts @@ -24,7 +24,7 @@ export function formatTerminalList(result: RuntimeTerminalListResult): string { const body = result.terminals .map( (terminal) => - `${terminal.handle} ${terminal.title ?? '(untitled)'} ${terminal.connected ? 'connected' : 'disconnected'} host=${terminal.executionHostId ?? 'unknown'} ${terminal.worktreePath}\n${terminal.preview ? `preview: ${terminal.preview}` : 'preview: '}` + `${terminal.handle} ${terminal.title ?? '(untitled)'} ${terminal.connected ? 'connected' : 'disconnected'} host=${terminal.executionHostId ?? 'unverifiable'} ${terminal.worktreePath}\n${terminal.preview ? `preview: ${terminal.preview}` : 'preview: '}` ) .join('\n\n') const visualLayout = formatTerminalVisualLayouts(result.visualLayouts) @@ -39,7 +39,7 @@ export function formatTerminalList(result: RuntimeTerminalListResult): string { // absent scope means the host is too old to know — not that it covered everything. function formatTerminalListHostScope(scope: RuntimeTerminalListHostScope | undefined): string { if (!scope) { - return 'scope: unknown — this host does not report which hosts it lists' + return 'scope: unverifiable — this host does not report which hosts it lists' } const covered = scope.hostIds.length > 0 ? scope.hostIds.join(', ') : 'none' const omitted = diff --git a/src/cli/terminal-list-host-scope-format.test.ts b/src/cli/terminal-list-host-scope-format.test.ts index 30a7564a69b..dc3b72c44cf 100644 --- a/src/cli/terminal-list-host-scope-format.test.ts +++ b/src/cli/terminal-list-host-scope-format.test.ts @@ -36,7 +36,7 @@ describe('formatTerminalList host identity', () => { it('prints unknown, not local, for a row whose host the runtime could not name', () => { const output = formatTerminalList(listResult({ terminals: [terminal()] })) - expect(output).toContain('host=unknown') + expect(output).toContain('host=unverifiable') expect(output).not.toContain('host=local') }) }) @@ -70,7 +70,7 @@ describe('formatTerminalList scope declaration', () => { it('says the scope is unknown when the host predates the field', () => { const output = formatTerminalList(listResult()) - expect(output).toContain('scope: unknown') + expect(output).toContain('scope: unverifiable') expect(output).not.toContain('scope: local') }) }) diff --git a/src/main/runtime/terminal-list-execution-host-scope.test.ts b/src/main/runtime/terminal-list-execution-host-scope.test.ts index 10bdc84c21c..11df97a3bb8 100644 --- a/src/main/runtime/terminal-list-execution-host-scope.test.ts +++ b/src/main/runtime/terminal-list-execution-host-scope.test.ts @@ -140,6 +140,19 @@ describe('listTerminals execution-host identity', () => { expect(terminals[0]?.executionHostId).toBeUndefined() }) + + it.each(['remote:env@@%E0%A4%A', 'ssh:%E0%A4%A@@pty-7'])( + 'leaves the host unset for a malformed foreign PTY id: %s', + async (ptyId) => { + const runtime = makeRuntime([ + { worktreeId: LOCAL_WORKTREE_ID, leafId: REMOTE_LEAF_ID, ptyId } + ]) + + const { terminals } = await runtime.listTerminals() + + expect(terminals[0]?.executionHostId).toBeUndefined() + } + ) }) describe('listTerminals scope declaration', () => { diff --git a/src/shared/runtime-types.ts b/src/shared/runtime-types.ts index b66b117a556..945e3b76c7b 100644 --- a/src/shared/runtime-types.ts +++ b/src/shared/runtime-types.ts @@ -532,7 +532,7 @@ export type RuntimeTerminalListResult = { topologyRevisions?: Record totalCount: number truncated: boolean - /** Absent from hosts that predate the field — treat that as unknown scope. */ + /** Absent from hosts that predate the field — treat that scope as unverifiable. */ hostScope?: RuntimeTerminalListHostScope } diff --git a/src/shared/terminal-execution-host.ts b/src/shared/terminal-execution-host.ts index 26686191ca3..d3e77a615af 100644 --- a/src/shared/terminal-execution-host.ts +++ b/src/shared/terminal-execution-host.ts @@ -24,5 +24,8 @@ export function getPtyExecutionHost(ptyId: string | null | undefined): PtyExecut if (remote) { return remote.environmentId ? toRuntimeExecutionHostId(remote.environmentId) : 'foreign' } + if (ptyId.startsWith('ssh:') || ptyId.startsWith('remote:')) { + return 'foreign' + } return null }