mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* [comment audit] Align legacy failure-read counts with cached display * [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci] * [comment audit] Condense shared generation, path and preview comments [skip ci] * [comment audit] Condense host, file and Git contract rationale [skip ci] * [comment audit] Tighten Git lifecycle and provider contract comments [skip ci] * [comment audit] Clarify shared host authority and launch isolation [skip ci] * [comment audit] simplify local access mobile and native chat contracts [skip ci] * [comment audit] simplify native chat presentation and state contracts [skip ci] * [comment audit] simplify native runtime and provider contracts [skip ci] * [comment audit] simplify migration and orchestration contracts [skip ci] * [comment audit] simplify plugin trust and process capture rationale [skip ci] * [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci] * [comment audit] clarify remote recovery and launch wire rationale [skip ci] * [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci] * [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci] * [comment audit] clarify sidebar, skill and SSH invariants [skip ci] * [comment audit] condense structured chat delivery and timing rationale [skip ci] * [comment audit] condense terminal replay and telemetry invariants [skip ci] * [comment audit] clarify launch permission and terminal delivery rationale [skip ci] * [comment audit] clarify workspace ownership and layout contracts [skip ci] * [comment audit] wait for fitted and painted SSH terminal links * [comment audit] clarify layout persistence and session ownership [skip ci] * [comment audit] clarify host routing and workspace lifecycle contracts [skip ci] * [comment audit] clarify startup persistence and app lifetime comments [skip ci] * [comment audit] clarify recovery and activity boundaries [skip ci] * [comment audit] condense activity and artifact invariants [skip ci] * [comment audit] condense automation authority contracts [skip ci] * [comment audit] simplify automation scheduling and history contracts [skip ci] * [comment audit] clarify browser chrome and annotation lifecycles [skip ci] * [comment audit] clarify browser routing and retained guest ownership [skip ci] * [comment audit] clarify browser recovery and document ownership comments [skip ci] * [comment audit] restore hosted runners required by native IME fixtures * [comment audit] shorten preview, palette and dashboard invariants [skip ci] * [comment audit] clarify terminal preview, dashboard and retention comments [skip ci] * [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci] * [comment audit] shorten rich-text and combined-diff ownership comments [skip ci] * [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci] * [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci] * [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci] * [comment audit] clarify rich Markdown source and selection safeguards [skip ci] * [comment audit] clarify editor loading and emulator stream lifetimes [skip ci] * [comment audit] trim emulator and feature tour narration [skip ci] * [comment audit] clarify floating workspace and GitHub cache ownership [skip ci] * [comment audit] trim provider controls and Linear filter explanations [skip ci] * [comment audit] clarify pairing and chat resume lifetimes [skip ci] * [comment audit] clarify chat delivery and transcript lifetimes [skip ci] * [comment audit] clarify session options and host-owned status [skip ci] * [comment audit] clarify draft durability and live-status precedence [skip ci] * [comment audit] Trim chat send and model ownership explanations [skip ci] * [comment audit] Shorten transcript ownership and send recovery comments [skip ci] * [comment audit] Simplify native chat composer and transcript hook comments [skip ci] * [comment audit] Shorten native chat scroll and structured session explanations [skip ci] * [comment audit] Trim workspace picker and onboarding commentary [skip ci] * [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci] * [comment audit] Trim sidebar and session history explanations [skip ci] * [comment audit] Condense session resume and review checks comments [skip ci] * [comment audit] Shorten checks state and file explorer refresh comments [skip ci] * [comment audit] Trim plugin bridge and source-control action rationale [skip ci] * [comment audit] Trim source-control listing and review rationale [skip ci] * [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci] * [comment audit] Condense Settings account and appearance rationale [skip ci] * [comment audit] Trim pairing and repository Settings explanations [skip ci] * [comment audit] Condense Settings search SSH and terminal safeguards [skip ci] * [comment audit] Shorten Settings voice and provider ownership comments [skip ci] * [comment audit] Condense Settings draft persistence and host-state rationale [skip ci] * [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci] * [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci] * [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci] * [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci] * [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci] * [comment audit] Prune focus-read baseline after comment cleanup * [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci] * [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci] * [comment audit] Clarify viewport geometry and skill update safeguards [skip ci] * [comment audit] Tighten skill inventory, usage and host status comments [skip ci] * [comment audit] Clarify usage ownership and resource kill safeguards [skip ci] * [comment audit] Tighten tab selection, rename and search contracts [skip ci] * [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci] * [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci] * [comment audit] Tighten provider loading and terminal recovery comments [skip ci] * [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci] * [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci] * [comment audit] Tighten PTY startup and replay explanations [skip ci] * [comment audit] Clarify PTY identity and delivery ownership [skip ci] * [comment audit] Shorten remote reconnect and input replay rationale [skip ci] * [comment audit] Condense terminal parking clipboard and file link comments [skip ci] * [comment audit] Clarify IME ownership and trim trace history [skip ci] * [comment audit] Shorten pane recovery and parked watcher explanations [skip ci] * [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci] * [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci] * [comment audit] Trim renderer lifecycle and menu rationale [skip ci] * [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci] * [comment audit] Clarify renderer hook evidence and source ownership [skip ci] * [comment audit] Tighten IPC ownership and reconnect explanations [skip ci] * [comment audit] Trim renderer focus, paste and attention comments [skip ci] * [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci] * [comment audit] Trim agent launch, resume and ownership commentary [skip ci] * [comment audit] Shorten account, browser and editor comments [skip ci] * [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci] * [comment audit] Condense launch recovery and editor tokenization comments [skip ci] * [comment audit] Condense workspace selection and terminal pane rationale [skip ci] * [comment audit] Condense terminal fitting and rendering recovery comments [skip ci] * [comment audit] Condense terminal input and host routing explanations [skip ci] * [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci] * [comment audit] Condense structured launch and terminal link explanations [skip ci] * [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci] * [comment audit] Condense session persistence and workspace activation rationale [skip ci] * [comment audit] Condense workspace routing and browser ownership rationale [skip ci] * [comment audit] Condense mirror recovery and layout authority rationale [skip ci] * [comment audit] Condense runtime transport and file safety rationale [skip ci] * [comment audit] Condense runtime graph and structured session rationale [skip ci] * [comment audit] Condense browser creation and remote tab recovery rationale [skip ci] * [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci] * [comment audit] Condense frame, startup and provider cache rationale [skip ci] * [comment audit] Condense host twin and agent lifecycle rationale [skip ci] * [comment audit] Condense browser authority and editor cleanup rationale [skip ci] * [comment audit] Condense editor buffer identity and review cache rationale [skip ci] * [comment audit] Condense provider lifetime and repository ownership rationale [skip ci] * [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci] * [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci] * [comment audit] Condense cleanup ownership and listing admission rationale [skip ci] * [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci] * [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci] * [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci] * [comment audit] Condense cloud rollout and assignment safety rationale [skip ci] * [comment audit] Condense relay session and database recovery rationale [skip ci] * [comment audit] Condense relay placement and protocol compatibility rationale [skip ci] * [comment audit] Condense build and packaging constraints [skip ci] * [comment audit] Condense CI gates and validation isolation rationale [skip ci] * [comment audit] Condense catalog identity and browser validation rationale [skip ci] * [comment audit] Condense mobile browser and frame-budget rationale [skip ci] * [comment audit] Shorten mobile route and browser test explanations [skip ci] * [comment audit] Condense editor and session seam test rationale [skip ci] * [comment audit] Trim session and terminal closure history [skip ci] * [comment audit] Shorten terminal browser and census explanations [skip ci] * [comment audit] Preserve root-only E2E diagnostic baseline * [comment audit] Condense mobile seam and HTML preview test rationale [skip ci] * [comment audit] Condense preview instrumentation and render harness rationale [skip ci] * [comment audit] Condense bundle contracts and native-build constraints [skip ci] * [comment audit] Shorten native packaging and CI routing rationale [skip ci] * [comment audit] Condense release tooling and benchmark constraints [skip ci] * [comment audit] Condense packaging and platform gate rationale [skip ci] * [comment audit] Shorten mobile route and history rationale [skip ci] * [comment audit] Condense mobile browser and component rationale [skip ci] * [comment audit] Shorten drawer and workspace-form rationale [skip ci] * [comment audit] Trim mobile review and editor-document explanations [skip ci] * [comment audit] Condense editor lifecycle and Markdown explanations [skip ci] * [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci] * [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci] * [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci] * [comment audit] Condense bridge stream, native request and audio rationale [skip ci] * [comment audit] Reduce bridge schema and page-client commentary [skip ci] * [comment audit] Tighten mobile page bridge contracts [skip ci] * [comment audit] Clarify mobile cache and session constraints [skip ci] * [comment audit] Condense mobile route and lifecycle rationale [skip ci] * [comment audit] Tighten mobile shell hook timing rationale [skip ci] * [comment audit] Clarify route handoff and notification compatibility [skip ci] * [comment audit] Clarify push registration and dictation cleanup constraints [skip ci] * [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci] * [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci] * [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci] * [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci] * [comment audit] Tighten stream replay and queued session ownership rationale [skip ci] * [comment audit] Condense mobile composer and reply-schema constraints [skip ci] * [comment audit] Clarify mobile transcript recovery and session ownership [skip ci] * [comment audit] Clarify mobile queue and source-control compatibility [skip ci] * [comment audit] Condense storage and task launch constraints [skip ci] * [comment audit] Clarify task schemas and terminal document ownership [skip ci] * [comment audit] Tighten terminal input and viewport rationale [skip ci] * [comment audit] Shorten terminal and RPC recorder contracts [skip ci] * [comment audit] Condense recorder engine and connection contracts [skip ci] * [comment audit] Shorten host credential and relay recovery comments [skip ci] * [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci] * [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci] * [comment audit] Condense catalog and relay entry contracts [skip ci] * [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci] * [comment audit] Condense WSL relay and E2E regression rationale [skip ci] * [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci] * [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci] * [comment audit] Shorten layout oracle and regression explanations [skip ci] * [comment audit] Condense paired recovery and ownership regression contracts [skip ci] * [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci] * [comment audit] Condense terminal rendering and IME regression rationale [skip ci] * [comment audit] Shorten terminal recovery and benchmark contracts [skip ci] * [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci] * [comment audit] Condense workflow routing and release rationale [skip ci] * [comment audit] Condense mobile security and installer contracts [skip ci] * [comment audit] Shorten native rationale and stylesheet workarounds [skip ci] * [comment audit] Shorten Windows visibility probe rationale [skip ci] * [comment audit] Condense embedded release and signing rationale [skip ci] * [comment audit] Retain current main test behavior in final reconciliation [skip ci] * [comment audit] Complete final comment review across current source inventory * [comment audit] Handle consolidated audit reports before final CI * [comment audit] Preserve credential storage census detail [skip ci] * [comment audit] Scale broad changed E2E selections with verified timing shards * [comment audit] Align E2E assertions with browser close and settled session metadata * [comment audit] Match existing E2Es to current resource and windowing contracts * [comment audit] Observe the shared server outage notice in reconnect coverage * [comment audit] Make existing renderer probes measure settled tab and PTY work * [comment audit] Align palette E2E selector with task search * [comment audit] Refresh remaining palette search selectors * [comment audit] Keep selector correction within selected audit specs * [comment audit] Await emoji fixture settings inside renderer evaluation * [comment audit] Cancel fixture fit retries between terminal tests --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
313 lines
9.9 KiB
TypeScript
313 lines
9.9 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
||
import { tmpdir } from 'node:os'
|
||
import { join } from 'node:path'
|
||
import type { WebSocket } from 'ws'
|
||
import type { AgentStatusEntry } from '../../src/shared/agent-status-types'
|
||
import type { NativeChatMessage } from '../../src/shared/native-chat-types'
|
||
import type {
|
||
RuntimeMobileSessionTabsResult,
|
||
RuntimeMobileSessionTerminalClientTab
|
||
} from '../../src/shared/runtime-types'
|
||
import type { RpcRequest, RpcResponse } from './mock-server-rpc-handlers'
|
||
|
||
// Read send behavior from control file per request: restarting mock rekeys E2EE and forces re-pair, preventing mid-session native chat repros.
|
||
const SEND_MODE_FILE = process.env.MOCK_SEND_MODE_FILE ?? join(tmpdir(), 'orca-mock-send-mode')
|
||
const TERMINAL_LIST_MODE_FILE =
|
||
process.env.MOCK_TERMINAL_LIST_MODE_FILE ?? join(tmpdir(), 'orca-mock-terminal-list-mode')
|
||
// Write dead to model subscribed→end for gone PTY, exercising rearm bound and terminal pruning.
|
||
const TERMINAL_STREAM_MODE_FILE =
|
||
process.env.MOCK_TERMINAL_STREAM_MODE_FILE ?? join(tmpdir(), 'orca-mock-terminal-stream-mode')
|
||
const TERMINAL_HANDLE = 'chat-term-1'
|
||
const TAB_ID = 'chat-tab-1'
|
||
const SESSION_ID = 'mock-chat-session'
|
||
const TRANSCRIPT_PATH = join(tmpdir(), 'mock-transcript.jsonl')
|
||
const MOCK_IMAGE_PATH = join(tmpdir(), 'mock-image.png')
|
||
// Exercise legacy OMP hooks without a transcript path; current hooks may include one.
|
||
const CHAT_AGENT = process.env.MOCK_CHAT_AGENT === 'omp' ? 'omp' : 'claude'
|
||
const CHAT_TITLE = CHAT_AGENT === 'omp' ? 'OMP' : 'Claude Code'
|
||
const TRANSCRIPT_START = Date.now() - 1000 * 60 * 5
|
||
|
||
function readControl(file: string): string {
|
||
try {
|
||
return readFileSync(file, 'utf-8').trim()
|
||
} catch {
|
||
return ''
|
||
}
|
||
}
|
||
|
||
const tabsSnapshots = new Map<string, { version: number; signature: string }>()
|
||
const agentStatus: AgentStatusEntry = {
|
||
state: 'done',
|
||
prompt: '',
|
||
updatedAt: Date.now(),
|
||
stateStartedAt: Date.now(),
|
||
agentType: CHAT_AGENT,
|
||
paneKey: `${TAB_ID}:leaf-1`,
|
||
terminalHandle: TERMINAL_HANDLE,
|
||
stateHistory: [],
|
||
providerSession:
|
||
CHAT_AGENT === 'omp'
|
||
? { key: 'session_id', id: SESSION_ID }
|
||
: { key: 'session_id', id: SESSION_ID, transcriptPath: TRANSCRIPT_PATH }
|
||
}
|
||
|
||
function buildTab(): RuntimeMobileSessionTerminalClientTab {
|
||
return {
|
||
type: 'terminal',
|
||
id: TAB_ID,
|
||
title: CHAT_TITLE,
|
||
parentTabId: TAB_ID,
|
||
leafId: 'leaf-1',
|
||
ptyId: 'pty-1',
|
||
status: 'ready',
|
||
terminal: TERMINAL_HANDLE,
|
||
launchAgent: CHAT_AGENT,
|
||
agentStatus,
|
||
viewMode: 'chat',
|
||
isActive: true
|
||
}
|
||
}
|
||
|
||
// Advance per-worktree versions only on content changes; runtime has no fake rerender heartbeat.
|
||
function buildTabsResult(worktree: string): RuntimeMobileSessionTabsResult {
|
||
const result: RuntimeMobileSessionTabsResult = {
|
||
worktree,
|
||
publicationEpoch: 'mock-epoch-1',
|
||
snapshotVersion: 0,
|
||
activeGroupId: 'group-1',
|
||
activeTabId: TAB_ID,
|
||
activeTabType: 'terminal',
|
||
tabGroups: [{ id: 'group-1', activeTabId: TAB_ID, tabOrder: [TAB_ID] }],
|
||
tabs: [buildTab()]
|
||
}
|
||
const signature = JSON.stringify(result)
|
||
const previous = tabsSnapshots.get(worktree)
|
||
const current =
|
||
previous?.signature === signature
|
||
? previous
|
||
: { version: (previous?.version ?? 0) + 1, signature }
|
||
tabsSnapshots.set(worktree, current)
|
||
result.snapshotVersion = current.version
|
||
return result
|
||
}
|
||
|
||
function tabsResultIfChanged(worktree: string): RuntimeMobileSessionTabsResult | null {
|
||
const before = tabsSnapshots.get(worktree)?.version
|
||
const result = buildTabsResult(worktree)
|
||
return result.snapshotVersion === before ? null : result
|
||
}
|
||
|
||
function worktreeOf(request: RpcRequest): string {
|
||
const raw = request.params?.worktree
|
||
return typeof raw === 'string' ? raw : 'id:mock-worktree'
|
||
}
|
||
|
||
// Mirror OMP decoder’s thinking/text/toolCall/toolResult shapes so phone exercises production render path.
|
||
function mockTranscript(): NativeChatMessage[] {
|
||
if (CHAT_AGENT !== 'omp') {
|
||
return []
|
||
}
|
||
const t = TRANSCRIPT_START
|
||
return [
|
||
{
|
||
id: 'omp-1',
|
||
role: 'user',
|
||
blocks: [{ type: 'text', text: 'why is my deploy failing?' }],
|
||
timestamp: t,
|
||
source: 'transcript'
|
||
},
|
||
{
|
||
id: 'omp-2',
|
||
role: 'assistant',
|
||
blocks: [
|
||
{ type: 'text', text: 'Let me check the deploy logs first.' },
|
||
{ type: 'tool-call', name: 'bash', input: { command: 'kubectl get pods' } }
|
||
],
|
||
timestamp: t + 1000,
|
||
source: 'transcript'
|
||
},
|
||
{
|
||
id: 'omp-3',
|
||
role: 'tool',
|
||
blocks: [{ type: 'tool-result', output: 'api-7f9c 0/1 CrashLoopBackOff' }],
|
||
timestamp: t + 2000,
|
||
source: 'transcript'
|
||
},
|
||
{
|
||
id: 'omp-4',
|
||
role: 'assistant',
|
||
blocks: [
|
||
{ type: 'text', text: 'The API pod is crash-looping. Check its logs with kubectl logs.' }
|
||
],
|
||
timestamp: t + 3000,
|
||
source: 'transcript'
|
||
}
|
||
]
|
||
}
|
||
|
||
// Cancel by worktree, not request id, so A→B→A navigation cannot stack push loops.
|
||
const tabsPushLoops = new Map<WebSocket, Map<string, ReturnType<typeof setInterval>>>()
|
||
|
||
function stopTabsPushLoop(ws: WebSocket, worktree: string): void {
|
||
const loops = tabsPushLoops.get(ws)
|
||
const existing = loops?.get(worktree)
|
||
if (existing !== undefined) {
|
||
clearInterval(existing)
|
||
loops?.delete(worktree)
|
||
}
|
||
}
|
||
|
||
function startTabsPushLoop(ws: WebSocket, worktree: string, push: () => void): void {
|
||
stopTabsPushLoop(ws, worktree)
|
||
const interval = setInterval(() => {
|
||
if (ws.readyState !== ws.OPEN) {
|
||
stopTabsPushLoop(ws, worktree)
|
||
return
|
||
}
|
||
push()
|
||
}, 3000)
|
||
let loops = tabsPushLoops.get(ws)
|
||
if (!loops) {
|
||
loops = new Map()
|
||
tabsPushLoops.set(ws, loops)
|
||
ws.once('close', () => {
|
||
for (const timer of tabsPushLoops.get(ws)?.values() ?? []) {
|
||
clearInterval(timer)
|
||
}
|
||
tabsPushLoops.delete(ws)
|
||
})
|
||
}
|
||
loops.set(worktree, interval)
|
||
}
|
||
|
||
type Respond = (response: RpcResponse) => void
|
||
type Success = (id: string, result: unknown, streaming?: boolean) => RpcResponse
|
||
type Failure = (id: string, code: string, message: string) => RpcResponse
|
||
|
||
// Opt-in MOCK_NATIVE_CHAT=1 replaces terminal fixtures with native chat tabs/transcript/send/upload; pushes no transcript/output frames. Return false for unowned methods.
|
||
export function handleMockNativeChatRequest(
|
||
request: RpcRequest,
|
||
respond: Respond,
|
||
success: Success,
|
||
error: Failure,
|
||
ws: WebSocket
|
||
): boolean {
|
||
if (process.env.MOCK_NATIVE_CHAT !== '1') {
|
||
return false
|
||
}
|
||
switch (request.method) {
|
||
case 'session.tabs.list':
|
||
respond(success(request.id, buildTabsResult(worktreeOf(request))))
|
||
return true
|
||
|
||
case 'session.tabs.subscribe': {
|
||
const worktree = worktreeOf(request)
|
||
respond(success(request.id, buildTabsResult(worktree), true))
|
||
startTabsPushLoop(ws, worktree, () => {
|
||
const changed = tabsResultIfChanged(worktree)
|
||
if (changed) {
|
||
respond(success(request.id, changed, true))
|
||
}
|
||
})
|
||
return true
|
||
}
|
||
|
||
case 'session.tabs.unsubscribe':
|
||
stopTabsPushLoop(ws, worktreeOf(request))
|
||
respond(success(request.id, { ok: true }))
|
||
return true
|
||
|
||
case 'session.tabs.activate':
|
||
case 'nativeChat.unsubscribe':
|
||
respond(success(request.id, { ok: true }))
|
||
return true
|
||
|
||
case 'terminal.list': {
|
||
// omit means empty list; other means live list without this handle, matching a handle scoped to another worktree.
|
||
const mode = readControl(TERMINAL_LIST_MODE_FILE)
|
||
const worktreeId = worktreeOf(request).replace(/^id:/, '')
|
||
const entry = (handle: string) => ({
|
||
handle,
|
||
worktreeId,
|
||
title: CHAT_TITLE,
|
||
isActive: true,
|
||
hasRunningProcess: true
|
||
})
|
||
const terminals =
|
||
mode === 'omit'
|
||
? []
|
||
: mode === 'other'
|
||
? [entry('some-other-term')]
|
||
: [entry(TERMINAL_HANDLE)]
|
||
respond(success(request.id, { terminals, totalCount: terminals.length, truncated: false }))
|
||
return true
|
||
}
|
||
|
||
case 'nativeChat.subscribe':
|
||
respond(
|
||
success(request.id, { type: 'snapshot', messages: mockTranscript(), hasMore: false }, true)
|
||
)
|
||
return true
|
||
|
||
case 'nativeChat.readSession':
|
||
respond(success(request.id, { messages: mockTranscript(), hasMore: false }))
|
||
return true
|
||
|
||
case 'terminal.subscribe': {
|
||
// The `subscribed` frame is what releases mobile's native-chat input lease.
|
||
respond(success(request.id, { type: 'subscribed', terminal: TERMINAL_HANDLE }, true))
|
||
if (readControl(TERMINAL_STREAM_MODE_FILE) === 'dead') {
|
||
respond(success(request.id, { type: 'end' }))
|
||
return true
|
||
}
|
||
respond(
|
||
success(
|
||
request.id,
|
||
{ type: 'scrollback', serialized: '', cols: 80, rows: 24, seq: 1 },
|
||
true
|
||
)
|
||
)
|
||
return true
|
||
}
|
||
|
||
case 'terminal.send': {
|
||
const mode = readControl(SEND_MODE_FILE) || 'accept'
|
||
console.log(`[mock] terminal.send mode=${mode} text=${JSON.stringify(request.params?.text)}`)
|
||
if (mode === 'error') {
|
||
respond(error(request.id, 'mobile_input_floor_unavailable', 'Mobile input floor is held'))
|
||
return true
|
||
}
|
||
respond(
|
||
success(request.id, {
|
||
send: {
|
||
handle: TERMINAL_HANDLE,
|
||
accepted: mode === 'accept',
|
||
bytesWritten: mode === 'accept' ? String(request.params?.text ?? '').length : 0
|
||
}
|
||
})
|
||
)
|
||
return true
|
||
}
|
||
|
||
case 'clipboard.startImageUpload':
|
||
respond(success(request.id, { uploadId: 'mock-upload-1' }))
|
||
return true
|
||
|
||
case 'clipboard.appendImageUploadChunk':
|
||
respond(success(request.id, { ok: true }))
|
||
return true
|
||
|
||
case 'clipboard.commitImageUpload':
|
||
case 'clipboard.saveImageAsTempFile':
|
||
respond(success(request.id, MOCK_IMAGE_PATH))
|
||
return true
|
||
|
||
case 'clipboard.abortImageUpload':
|
||
respond(success(request.id, { ok: true }))
|
||
return true
|
||
|
||
default:
|
||
return false
|
||
}
|
||
}
|