Files
orca/src/shared/structured-agent-cli-conversation-adoption.ts
T
Brennan Benson af211d6b82 Close the terminal before continuing its conversation in chat (#36732)
* Stop only the identified Windows pane agent before chat continuation

* Stop terminal agents before continuing their conversations in chat

* Continue in chat without confirmation while stopping the old agent

* Wire Windows stopping through the execution host and preflight permissions

* Scope chat continuation admission to proven terminal survivors

* Continue in chat after ordinary terminal close and verified exit

* Continue in chat without a stop prompt for the agent and keep the user on the new chat

Only work in other panes of the tab asks before the close; the worktree stays selected so the chat shows when it opens; an open chat for the conversation is opened instead of closing the terminal; the pre-close check skips the rows the host skips and counts restored ones; the preparation deadline no longer runs while a close dialog is open; failure messages say what happened once and point to Session History.

* Remove terminal-writer bookkeeping nothing reads after store-only admission

The hook server no longer tags OpenCode and tmux conversation bindings with a writer topology, the admission check drops its unused source pane argument, and the hook that clears a saved launch result is named for what it does.

* Keep the hook server's writer-topology tagging unchanged in this change

Another open change still reads it, so its removal waits for that one.

* Keep the terminal when its agent already quit, and refuse only an agent that is still running

Continue in Chat UI closes the terminal tab only while the clicked pane still shows its agent on this conversation; otherwise the chat opens and the terminal stays, as before. The host now refuses a takeover only when the agent's process is proven running: an agent with no recorded process, one that reported its own end, or one that can't be checked no longer blocks Session History or a chat.

* Prove a paired terminal's exit even when the close reaches the host first

A terminal handle a pane issued now keeps naming its process after the pane is removed, until that process record is pruned or replaced, so a late exit wait reads the recorded exit instead of failing. Before closing for Continue in Chat UI, only an open chat for the conversation is answered; whether another terminal still holds it is left to the host. A run that was already retired says nothing when its old confirmation is answered.

* Shrink the flaky-test pattern baseline for two cleaned-up test files

* Merge a duplicate import in the chat-continue run

* Keep unshown terminals usable and say how to recover when another terminal holds the conversation

A terminal that no pane shows is listed, read and controlled through its own handle again, as before; the closed pane's handle still answers a late exit wait and nothing else, and only for a known process incarnation. After Continue in Chat UI closes the terminal, a conversation still running in another terminal names that terminal and the remedy. A continuation retired with no newer one for the same tab says once that the terminal changed when its confirmed close is refused.

* Fix test types and retire translations whose English changed

* Keep the terminal when its agent's status is only restored from before a restart

Continue in Chat UI closes the terminal only while its agent is confirmed running there; a status row carried over a restart, with no live update since, now takes the keep-the-terminal path.

* Revert "Keep the terminal when its agent's status is only restored from before a restart"

This reverts commit c19d708ecb.

* Expect the new other-terminal copy in the Session History continue test

* Point a still-running terminal refusal to Session History, which old hosts still offer
2026-10-31 18:47:18 -07:00

56 lines
2.2 KiB
TypeScript

/** Adoption order by Session History row agent; registration tests require a transcript importer for every target.
* Conversations stay on their recording host, which validates importer availability before adoption. */
export const CLI_CONVERSATION_ADOPTING_AGENTS = {
claude: ['claude'],
codex: ['codex'],
grok: ['grok'],
omp: ['omp'],
opencode: ['opencode'],
// OpenCode 2 chats require 2.x; ordinary OpenCode chats can adopt when their installed opencode is 2.x.
opencode2: ['opencode2', 'opencode'],
pi: ['pi']
} as const
/** A Session History row agent whose conversations a chat can take over. */
export type CliConversationRowAgent = keyof typeof CLI_CONVERSATION_ADOPTING_AGENTS
export function adoptsCliConversations(agent: unknown): agent is CliConversationRowAgent {
return typeof agent === 'string' && Object.hasOwn(CLI_CONVERSATION_ADOPTING_AGENTS, agent)
}
/** Whether chats of the two agents can hold one conversation: both take over one row's. */
export function chatAgentsShareConversations(left: string, right: string): boolean {
return (
left === right ||
Object.values(CLI_CONVERSATION_ADOPTING_AGENTS).some(
(agents: readonly string[]) => agents.includes(left) && agents.includes(right)
)
)
}
/** Whether two rows' conversations can be one: a chat that takes over either takes over both. */
export function cliConversationRowsShareAgent(
left: CliConversationRowAgent,
right: CliConversationRowAgent
): boolean {
const rightAgents: readonly string[] = CLI_CONVERSATION_ADOPTING_AGENTS[right]
return CLI_CONVERSATION_ADOPTING_AGENTS[left].some((agent) => rightAgents.includes(agent))
}
/** A local status row naming the conversation a chat of `agent` would take over: the host's
* writer admission and the renderer's open-chat lookup read rows the same way. */
export function namesCliConversation(
row: { connectionId?: string | null; agentType?: string; providerSession?: { id: string } },
agent: string,
providerSessionId: string
): boolean {
return (
!row.connectionId &&
adoptsCliConversations(row.agentType) &&
row.providerSession?.id === providerSessionId &&
CLI_CONVERSATION_ADOPTING_AGENTS[row.agentType].some((chat) =>
chatAgentsShareConversations(chat, agent)
)
)
}