Files
orca/src/main/native-chat/structured-agent-cli-source.ts
T
OrcaWinandOrcaWin 3286f3b259 [comment audit] Clean up IPC, host lifecycle and native-chat comments (#32966)
* [comment audit] Tighten watcher lifetime and file-write constraints [skip ci]

* [comment audit] Clarify IPC routing and notification comments [skip ci]

* [comment audit] Shorten watcher, preflight and PTY comments [skip ci]

* [comment audit] Clarify PTY delivery and restore ownership [skip ci]

* [comment audit] Tighten PTY environment and flow-control rationale [skip ci]

* [comment audit] Clarify IPC spawn and stable-pane guarantees [skip ci]

* [comment audit] Tighten PTY provider and filesystem ownership rationale [skip ci]

* [comment audit] Clarify clone ownership and remote runtime recovery [skip ci]

* [comment audit] Condense upload, settings and SSH lifecycle comments [skip ci]

* [comment audit] Shorten shutdown, preview and worktree watcher rationale [skip ci]

* [comment audit] Clarify worktree identity, remote ownership and copy limits [skip ci]

* [comment audit] Shorten worktree catalog, removal and WSL routing rationale [skip ci]

* [comment audit] Tighten Linear credential, pagination and export comments [skip ci]

* [comment audit] Condense managed-server activation, snapshot and launch rationale [skip ci]

* [comment audit] Trim runtime installation and managed-server lifecycle comments [skip ci]

* [comment audit] Simplify managed tunnel, memory and menu comments [skip ci]

* [comment audit] Condense integration, model catalog and attachment rationale [skip ci]

* [comment audit] Shorten journal persistence, replay and queue rationale [skip ci]

* [comment audit] Condense journal ordering and timeline lifecycle comments [skip ci]

* [comment audit] Trim timeline and subscriber delivery explanations [skip ci]

* [comment audit] Shorten Stop, child-exit and recovery contracts [skip ci]

* [comment audit] Simplify handover and host recovery comments [skip ci]

* [comment audit] Trim queue delivery and provider startup commentary [skip ci]

* [comment audit] Clarify restart and rewind safety comments [skip ci]

* [comment audit] Trim status, Stop and completion commentary [skip ci]

* [comment audit] Simplify transcript lookup and visual containment comments [skip ci]

* [comment audit] Trim transcript reader, watcher and WSL transport commentary [skip ci]

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-23 19:07:32 -07:00

98 lines
3.3 KiB
TypeScript

import type { AgentStatusIpcPayload } from '../../shared/agent-status-types'
import type { StructuredAgentSessionResumeSource } from '../../shared/structured-agent-session-create'
import type { StructuredAgentId } from '../../shared/agent-session-provider-handle'
import { agentSessionRefusalError } from '../../shared/agent-session-wire-refusals'
import {
adoptsCliConversations,
chatAgentsShareConversations,
CLI_CONVERSATION_ADOPTING_AGENTS
} from '../../shared/structured-agent-cli-conversation-adoption'
import { isWslUncPath } from '../../shared/wsl-paths'
import { needsWslHostResolution } from './host-readable-transcript-path'
import { parseSshTranscriptPath } from './ssh-transcript-path'
export type StructuredAgentCliSourceEvidence =
| { readonly rows: readonly Readonly<AgentStatusIpcPayload>[] }
| { readonly error: unknown }
export function captureStructuredAgentCliSource(
readRows: () => readonly AgentStatusIpcPayload[]
): StructuredAgentCliSourceEvidence {
try {
return Object.freeze({
rows: Object.freeze(
readRows().map((row) =>
Object.freeze({
...row,
...(row.providerSession
? { providerSession: Object.freeze({ ...row.providerSession }) }
: {})
})
)
)
})
} catch (error) {
return Object.freeze({ error })
}
}
export function structuredAgentCliSourcePathFromEvidence(input: {
agent: StructuredAgentId
resumeFrom: StructuredAgentSessionResumeSource
workspaceId: string
evidence?: StructuredAgentCliSourceEvidence
}): string | undefined {
const evidence = input.evidence
if (input.resumeFrom.cliSource && evidence && 'error' in evidence) {
throw evidence.error
}
return structuredAgentCliSourcePath({
...input,
rows: evidence && 'rows' in evidence ? evidence.rows : []
})
}
/** Derive provider paths from host evidence; clients may name only panes. */
export function structuredAgentCliSourcePath(input: {
agent: StructuredAgentId
resumeFrom: StructuredAgentSessionResumeSource
workspaceId: string
rows: readonly AgentStatusIpcPayload[]
}): string | undefined {
const source = input.resumeFrom.cliSource
if (!source) {
return undefined
}
const row = input.rows.find(
(candidate) =>
source.workspaceId === input.workspaceId &&
candidate.worktreeId === source.workspaceId &&
candidate.paneKey === source.paneKey &&
!candidate.connectionId &&
!candidate.structuredHost &&
adoptsCliConversations(candidate.agentType) &&
// OpenCode 2 may report the legacy opencode name for the same conversation.
CLI_CONVERSATION_ADOPTING_AGENTS[candidate.agentType].some((agent) =>
chatAgentsShareConversations(agent, input.agent)
) &&
candidate.providerSession?.id === input.resumeFrom.providerSessionId
)
if (!row) {
throw agentSessionRefusalError(
'agent_session_identity_required',
{ reason: 'transcriptUnreadable' },
'The source conversation is no longer available.'
)
}
const path = row.providerSession?.transcriptPath?.trim()
if (
path &&
(isWslUncPath(path) || needsWslHostResolution(path) || parseSshTranscriptPath(path))
) {
throw agentSessionRefusalError('structured_agent_session_unsupported', {
reason: 'hostUnsupported'
})
}
return path || undefined
}