fix(terminal): fail closed on unverifiable hosts

This commit is contained in:
Brennan Benson
2026-08-16 18:41:32 -07:00
parent 147a140f0e
commit 794ea13023
6 changed files with 22 additions and 6 deletions
@@ -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')
})
})
+2 -2
View File
@@ -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: <empty>'}`
`${terminal.handle} ${terminal.title ?? '(untitled)'} ${terminal.connected ? 'connected' : 'disconnected'} host=${terminal.executionHostId ?? 'unverifiable'} ${terminal.worktreePath}\n${terminal.preview ? `preview: ${terminal.preview}` : 'preview: <empty>'}`
)
.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 =
@@ -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')
})
})
@@ -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', () => {
+1 -1
View File
@@ -532,7 +532,7 @@ export type RuntimeTerminalListResult = {
topologyRevisions?: Record<string, number>
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
}
+3
View File
@@ -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
}