@ordewell/core 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{IFileSystem-DQEKyC6H.d.ts → IFileSystem-D4ADfTrX.d.ts} +1 -1
- package/dist/{IFileSystem-Qj2MWHn_.d.mts → IFileSystem-DgpX0BU7.d.mts} +1 -1
- package/dist/{ModeResolver-ByNpC0EP.d.ts → ModeResolver-BEcRAz1c.d.ts} +3 -3
- package/dist/{ModeResolver-rqaY_4Ex.d.mts → ModeResolver-Cv01ZDd9.d.mts} +3 -3
- package/dist/{Task-xqdxugt2.d.mts → Task-CoKhvBa1.d.mts} +275 -2
- package/dist/{Task-xqdxugt2.d.ts → Task-CoKhvBa1.d.ts} +275 -2
- package/dist/{chunk-M4KXBEFJ.mjs → chunk-J3YSTPCE.mjs} +41 -41
- package/dist/chunk-J3YSTPCE.mjs.map +1 -0
- package/dist/{chunk-I6U3PVHL.mjs → chunk-LSGY7AIZ.mjs} +74 -23
- package/dist/chunk-LSGY7AIZ.mjs.map +1 -0
- package/dist/{chunk-JRZPSNRO.mjs → chunk-YU4UKKKI.mjs} +1 -1
- package/dist/chunk-YU4UKKKI.mjs.map +1 -0
- package/dist/index.d.mts +250 -34
- package/dist/index.d.ts +250 -34
- package/dist/index.js +2011 -670
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1650 -365
- package/dist/index.mjs.map +1 -1
- package/dist/order-labels.d.mts +2 -1
- package/dist/order-labels.d.ts +2 -1
- package/dist/{parsing-DDZ1rUYa.d.mts → parsing-B4OCHH1_.d.mts} +24 -3
- package/dist/{parsing-COPG8-Ep.d.ts → parsing-DMdOq-BV.d.ts} +24 -3
- package/dist/parsing.d.mts +4 -3
- package/dist/parsing.d.ts +4 -3
- package/dist/parsing.js +36 -38
- package/dist/parsing.js.map +1 -1
- package/dist/parsing.mjs +2 -2
- package/dist/{plan-utils-Br8UAoiu.d.ts → plan-utils-BdYPRBno.d.ts} +28 -3
- package/dist/{plan-utils-DMgajMvd.d.mts → plan-utils-CD1Xu65s.d.mts} +28 -3
- package/dist/plan-utils.d.mts +4 -3
- package/dist/plan-utils.d.ts +4 -3
- package/dist/plan-utils.js +111 -58
- package/dist/plan-utils.js.map +1 -1
- package/dist/plan-utils.mjs +8 -2
- package/dist/testing.d.mts +11 -2
- package/dist/testing.d.ts +11 -2
- package/dist/testing.js +17 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +17 -0
- package/dist/testing.mjs.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-I6U3PVHL.mjs.map +0 -1
- package/dist/chunk-JRZPSNRO.mjs.map +0 -1
- package/dist/chunk-M4KXBEFJ.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/models/Usage.ts","../src/services/harness/agentTools.ts","../src/services/terminalRender.ts","../src/conversation/format.ts","../src/conversation/records.ts","../src/conversation/lanes.ts","../src/conversation/taskLog.ts","../src/services/conflictFiles.ts","../src/services/ModelAllowlistResolver.ts","../src/services/TaskOps.ts","../src/services/TaskEditValidator.ts","../src/services/researchStepSummary.ts","../src/services/continuation.ts","../src/services/SessionMessage.ts","../src/conversation/reduce.ts","../src/conversation/transcript.ts","../src/conversation/promptHold.ts","../src/conversation/turnGate.ts","../src/conversation/detail.ts","../src/conversation/notices.ts"],"sourcesContent":["/**\n * What one model call consumed, as its provider or runner reported it. Shared\n * by the planner's usage line (#49) and per-attempt task usage (#26): a record\n * says nothing about who asked for the call, so either can hold a list of them.\n *\n * Every measure is optional because backends report different subsets. An\n * absent field means \"not reported\" — never zero — so a total can tell the two\n * apart.\n */\nexport interface UsageRecord {\n /** The provider or runner id that reported the call — `openai`, `claude-code`, … */\n source: string;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n /** The share of `inputTokens` served from the provider's prompt cache. */\n cachedInputTokens?: number;\n /**\n * Filled only from a provider's or runner's own report, never from a price\n * table or an estimate: prices go stale, and a subscription runner has no\n * per-token price at all. No report means no cost, not a guessed one.\n */\n reportedCost?: { amount: number; currency: string };\n /** The model's context window, when the runner itself reports it. */\n contextWindow?: number;\n /** Set when a subagent made the call; its usage still counts toward the total. */\n subagentId?: string;\n}\n\n/**\n * A running sum of {@link UsageRecord}s. A measure stays absent until some\n * record reports it. Cost is kept per currency: two runners may bill in\n * different ones, and there is no honest exchange rate to fold them together.\n */\nexport interface UsageTotals {\n inputTokens?: number;\n outputTokens?: number;\n cachedInputTokens?: number;\n reportedCost?: Record<string, number>;\n}\n\n/**\n * The input side of a call whose provider reports its prompt in parts — the\n * uncached tail, with cache reads and cache writes beside it rather than inside\n * it (Anthropic, and OpenCode after it). The prompt the model saw is all three;\n * only the reads were served from cache, since a write is billed as fresh\n * input. A part left unreported adds nothing, and with no part reported there\n * is no measure at all.\n */\nexport function partedPromptUsage(parts: { uncached?: number; cacheRead?: number; cacheWrite?: number }): Pick<UsageRecord, 'inputTokens' | 'cachedInputTokens'> {\n const reported = [parts.uncached, parts.cacheRead, parts.cacheWrite].filter((n): n is number => n !== undefined);\n return {\n ...(reported.length > 0 ? { inputTokens: reported.reduce((a, b) => a + b, 0) } : {}),\n ...(parts.cacheRead !== undefined ? { cachedInputTokens: parts.cacheRead } : {}),\n };\n}\n\nconst TOKEN_FIELDS = ['inputTokens', 'outputTokens', 'cachedInputTokens'] as const;\n\nexport function addUsage(totals: UsageTotals, record: UsageRecord): UsageTotals {\n const next: UsageTotals = { ...totals };\n for (const field of TOKEN_FIELDS) {\n const reported = record[field];\n if (reported !== undefined) next[field] = (totals[field] ?? 0) + reported;\n }\n if (record.reportedCost) {\n const { amount, currency } = record.reportedCost;\n next.reportedCost = { ...totals.reportedCost, [currency]: (totals.reportedCost?.[currency] ?? 0) + amount };\n }\n return next;\n}\n\n/**\n * What the planner has consumed over a session (#49). `totals` includes every\n * `bySubagent` entry. `lastPromptTokens` and `contextWindow` track the\n * planner's own calls only — a subagent runs its own model, whose window says\n * nothing about the planner's.\n */\nexport interface PlannerUsage {\n totals: UsageTotals;\n bySubagent?: Record<string, UsageTotals>;\n lastPromptTokens?: number;\n contextWindow?: number;\n}\n\nexport function addPlannerUsage(usage: PlannerUsage, record: UsageRecord): PlannerUsage {\n const next: PlannerUsage = { ...usage, totals: addUsage(usage.totals, record) };\n if (record.subagentId) {\n next.bySubagent = { ...usage.bySubagent, [record.subagentId]: addUsage(usage.bySubagent?.[record.subagentId] ?? {}, record) };\n return next;\n }\n if (record.inputTokens !== undefined) next.lastPromptTokens = record.inputTokens;\n // A reported window of 0 means \"not known\", not \"no room\": keep it out so the\n // fill is omitted rather than shown against a guessed zero.\n if (record.contextWindow !== undefined && record.contextWindow > 0) next.contextWindow = record.contextWindow;\n return next;\n}\n\n/** Whether any measure was reported: a token line of nothing but blanks says nothing. */\nexport function isMeasured(totals: UsageTotals): boolean {\n return totals.inputTokens !== undefined || totals.outputTokens !== undefined || totals.cachedInputTokens !== undefined\n || Object.keys(totals.reportedCost ?? {}).length > 0;\n}\n\n/** What the token line shows of a ledger — live from its broadcast, or reloaded from the saved one. */\nexport interface UsageLine {\n totals: UsageTotals;\n bySubagent?: Record<string, UsageTotals>;\n contextFill?: { usedTokens: number; windowTokens: number };\n}\n\nexport function usageLine(usage: PlannerUsage): UsageLine {\n const contextFill = plannerContextFill(usage);\n return {\n totals: usage.totals,\n ...(usage.bySubagent ? { bySubagent: usage.bySubagent } : {}),\n ...(contextFill ? { contextFill } : {}),\n };\n}\n\n/**\n * The last planner prompt against its window, or undefined while either is\n * unknown. `usedTokens` is the prompt total as reported, cached tokens\n * included: a cached token still occupies the window, so subtracting the\n * cached share would understate how full the context is. A window of 0 is\n * treated as unknown — never guessed.\n */\nexport function plannerContextFill(usage: PlannerUsage): { usedTokens: number; windowTokens: number } | undefined {\n if (usage.lastPromptTokens === undefined || usage.contextWindow === undefined || usage.contextWindow <= 0) return undefined;\n return { usedTokens: usage.lastPromptTokens, windowTokens: usage.contextWindow };\n}\n","import type { ResearchToolType } from '../../models/Task';\n\n/**\n * Map a coding agent's own tool name onto Ordewell's research vocabulary\n * (ADR-0009, T5).\n *\n * A harness planner brings its own toolbox, and most of it overlaps ours: a\n * `Read` is a `read_file`, a `Grep` is a `grep`. Those map onto existing\n * members and render in every surface through the code path that is already\n * there. Everything else — `Edit`, `WebFetch`, `TodoWrite`, `Task`, whatever\n * ships next — becomes `agent_tool` carrying its real name.\n *\n * Nothing is relabelled as a tool it is not. Calling a web fetch a `bash` to\n * avoid adding a union member would put a lie in the timeline, which is the\n * point ADR-0008 spent its effort establishing.\n */\nconst KNOWN_TOOLS: Record<string, ResearchToolType> = {\n // Claude Code\n read: 'read_file',\n grep: 'grep',\n glob: 'glob',\n bash: 'bash',\n ls: 'list_dir',\n webfetch: 'fetch',\n websearch: 'web_search',\n // Codex — its sandboxed command tool is a shell by another name\n shell: 'bash',\n exec_command: 'bash',\n local_shell: 'bash',\n // OpenCode\n list: 'list_dir',\n fetch: 'fetch',\n};\n\nexport interface MappedTool {\n tool: ResearchToolType;\n /** The agent's own name, kept whenever it differs from the member it mapped to. */\n toolLabel?: string;\n}\n\n/**\n * Classify one agent tool name. Case- and separator-insensitive, because the\n * three agents disagree on `Read` vs `read` vs `read_file` for the same thing.\n */\nexport function mapAgentTool(name: string): MappedTool {\n const normalized = name.trim().toLowerCase().replace(/[_-]/g, '');\n const direct = KNOWN_TOOLS[normalized] ?? KNOWN_TOOLS[name.trim().toLowerCase()];\n if (direct) {\n // The label survives even on a mapped tool: `Read` and `read_file` render\n // the same way, but the transcript should still say which one ran.\n return { tool: direct, toolLabel: name };\n }\n return { tool: 'agent_tool', toolLabel: name };\n}\n\n/**\n * Normalize an agent's tool arguments into the shapes `summarizeToolCall`\n * already knows how to read, so a harness `Read` gets a one-line summary\n * instead of a bare tool name. Unknown keys are preserved — the raw args stay\n * visible under the surfaces' output chevron.\n */\nexport function normalizeAgentArgs(tool: ResearchToolType, args: Record<string, unknown>): Record<string, unknown> {\n const out = { ...args };\n const alias = (from: string, to: string) => {\n if (out[to] === undefined && out[from] !== undefined) out[to] = out[from];\n };\n if (tool === 'read_file' || tool === 'list_dir') {\n alias('filePath', 'path');\n alias('file_path', 'path');\n alias('target', 'path');\n }\n if (tool === 'bash') {\n alias('cmd', 'command');\n alias('script', 'command');\n // Codex hands the command over as an argv array; the summary wants a string.\n if (typeof out.command !== 'string' && Array.isArray(out.command)) {\n out.command = (out.command as unknown[]).join(' ');\n }\n }\n if (tool === 'fetch') alias('uri', 'url');\n if (tool === 'web_search') alias('q', 'query');\n return out;\n}\n","/*\n * Pure terminal rendering: turns raw PTY bytes into the text a user would see.\n * No state and no I/O, so the verdict scan and every output reader share it.\n */\n\n// eslint-disable-next-line no-control-regex\nexport const ANSI_OR_CTRL_RE = /\\x1b\\[[0-9;?]*[A-Za-z]|\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)?|\\x1b[()][AB012]|\\x1b[=>]|[\\x00-\\x08\\x0b-\\x1f\\x7f]/g;\n\n/**\n * Collapse terminal rendering out of raw PTY output: strip ANSI/OSC escape\n * sequences, box-drawing gutter characters, and ALL whitespace. Interactive\n * TUIs soft-wrap long lines, so a completion marker arrives split across\n * lines with escapes interleaved — a raw `includes()` never matches it.\n * Markers contain no whitespace, so this flattened view is safe to scan.\n */\nexport function flattenTerminalOutput(raw: string): string {\n return raw\n .replace(ANSI_OR_CTRL_RE, '')\n .replace(/[─-▟]/g, '') // box-drawing + block elements (TUI borders/gutters)\n .replace(/\\s+/g, '');\n}\n\n/**\n * Reconstruct the small terminal screen represented by a PTY output tail.\n *\n * Full-screen TUIs do not emit answer text as one chronological stream. They\n * paint fragments at absolute cursor positions and repaint unrelated widgets\n * between those writes. OpenCode, for example, may emit:\n *\n * row 9: \"<<<ORDEW\"\n * row 23: spinner repaint\n * row 9: \"ELL_DONE_...\"\n *\n * Flattening that byte stream inserts the spinner inside the marker. Rendering\n * the cursor-positioned writes first recovers the token the user actually sees.\n * This intentionally implements only the common cursor/erase subset used by\n * coding-agent TUIs; the chronological scanner remains the fallback for plain\n * output and soft-wrapped lines.\n */\nexport function renderTerminalOutput(raw: string): string {\n const rows = new Map<number, string[]>();\n let row = 1;\n let col = 1;\n let savedRow = 1;\n let savedCol = 1;\n\n const cells = (r: number): string[] => {\n let line = rows.get(r);\n if (!line) {\n line = [];\n rows.set(r, line);\n }\n return line;\n };\n const firstParam = (params: number[], fallback = 1): number => params[0] || fallback;\n const eraseLine = (mode: number): void => {\n const line = cells(row);\n if (mode === 2) {\n rows.set(row, []);\n } else if (mode === 1) {\n for (let c = 0; c < col; c++) line[c] = ' ';\n } else {\n line.length = Math.max(0, col - 1);\n }\n };\n\n for (let i = 0; i < raw.length;) {\n const ch = raw[i];\n if (ch === '\\x1b') {\n const kind = raw[i + 1];\n if (kind === '[') {\n let end = i + 2;\n while (end < raw.length) {\n const code = raw.charCodeAt(end);\n if (code >= 0x40 && code <= 0x7e) break;\n end++;\n }\n if (end >= raw.length) break;\n const final = raw[end];\n const body = raw.slice(i + 2, end).replace(/^[?<>=!]+/, '');\n const params = body.split(';').map((p) => Number.parseInt(p, 10) || 0);\n switch (final) {\n case 'H':\n case 'f':\n row = params[0] || 1;\n col = params[1] || 1;\n break;\n case 'G': col = firstParam(params); break;\n case 'd': row = firstParam(params); break;\n case 'A': row = Math.max(1, row - firstParam(params)); break;\n case 'B': row += firstParam(params); break;\n case 'C': col += firstParam(params); break;\n case 'D': col = Math.max(1, col - firstParam(params)); break;\n case 'E': row += firstParam(params); col = 1; break;\n case 'F': row = Math.max(1, row - firstParam(params)); col = 1; break;\n case 's': savedRow = row; savedCol = col; break;\n case 'u': row = savedRow; col = savedCol; break;\n case 'K': eraseLine(params[0] || 0); break;\n case 'J':\n if ((params[0] || 0) === 2 || (params[0] || 0) === 3) rows.clear();\n break;\n case 'X': {\n const line = cells(row);\n for (let c = 0; c < firstParam(params); c++) line[col - 1 + c] = ' ';\n break;\n }\n case 'P': {\n cells(row).splice(col - 1, firstParam(params));\n break;\n }\n case '@': {\n cells(row).splice(col - 1, 0, ...Array(firstParam(params)).fill(' '));\n break;\n }\n default:\n break;\n }\n i = end + 1;\n continue;\n }\n if (kind === ']' || kind === 'P' || kind === '^' || kind === '_') {\n let end = i + 2;\n while (end < raw.length && raw[end] !== '\\x07' && !(raw[end] === '\\x1b' && raw[end + 1] === '\\\\')) end++;\n if (end >= raw.length) break;\n i = raw[end] === '\\x07' ? end + 1 : end + 2;\n continue;\n }\n if (kind === '7') {\n savedRow = row;\n savedCol = col;\n } else if (kind === '8') {\n row = savedRow;\n col = savedCol;\n } else if (kind === 'c') {\n rows.clear();\n row = 1;\n col = 1;\n }\n // Character-set selection sequences carry one extra byte.\n i += kind === '(' || kind === ')' ? 3 : 2;\n continue;\n }\n if (ch === '\\r') {\n col = 1;\n i++;\n continue;\n }\n if (ch === '\\n') {\n row++;\n i++;\n continue;\n }\n if (ch === '\\b') {\n col = Math.max(1, col - 1);\n i++;\n continue;\n }\n if (ch === '\\t') {\n col += 8 - ((col - 1) % 8);\n i++;\n continue;\n }\n if (ch < ' ' || ch === '\\x7f') {\n i++;\n continue;\n }\n cells(row)[col - 1] = ch;\n col++;\n i++;\n }\n\n const populated = [...rows.keys()].sort((a, b) => a - b);\n return populated.map((r) => cells(r).join('')).join('\\n');\n}\n\n/**\n * Reconstruct what the user actually saw, then stop at the completion marker.\n * Used for anything captured as a task's durable output (outputSummary.logTail,\n * and any future planner read channel): the raw chronological PTY tail is\n * dominated by TUI paint — spinner lines, status bars, box-drawing borders,\n * cursor-positioned fragments — because screen-painting agents emit answer\n * text at absolute positions and repaint unrelated widgets around it.\n *\n * The marker row is the cut anchor: everything below it is the TUI's\n * persistent chrome, not task output. Falls back to the chronological\n * (stripAnsi'd) tail when neither render exposes the marker — the common case\n * for headless runners, whose raw stream IS meaningful.\n */\nexport function renderCleanCapture(raw: string, doneToken?: string): string {\n const rendered = renderTerminalOutput(raw).replace(/[\\s─-▟]+$/gm, '');\n if (!doneToken) return rendered.trim();\n const lines = rendered.split('\\n');\n const flat = (s: string) => flattenTerminalOutput(s);\n for (let i = 0; i < lines.length; i++) {\n // The marker may be split across two rendered rows (painted at a row\n // boundary): the first row alone won't match, so a two-row window is\n // scanned too. The cut is the last row that carries marker text — rows\n // above it are content, rows below are TUI chrome.\n const own = flat(lines[i]).includes(doneToken);\n if (own) return lines.slice(0, i).join('\\n').trim();\n const window = flat(lines[i]) + (i + 1 < lines.length ? flat(lines[i + 1]) : '');\n if (window.includes(doneToken)) return lines.slice(0, i + 1).join('\\n').trim();\n }\n return rendered.trim();\n}\n","import type { ToolHeadline } from './blocks';\nimport { ANSI_OR_CTRL_RE } from '../services/terminalRender';\n\n/**\n * How a command row names an Ordewell research tool. A harness planner's call\n * keeps the agent's own name instead (`toolLabel`, ADR-0009), so the row says\n * which tool actually ran.\n */\nconst DISPLAY_NAMES: Record<string, string> = {\n read_file: 'Read',\n read_files: 'Read',\n list_dir: 'List',\n glob: 'Glob',\n grep: 'Grep',\n find_symbol: 'Symbol',\n bash: 'Bash',\n fetch: 'Fetch',\n web_search: 'WebSearch',\n spawn_research_agent: 'Agent',\n};\n\n// Tried in order for a tool with no rule of its own: the field that names what\n// a call is about comes before the free text around it.\nconst HINT_FIELDS = ['file_path', 'filePath', 'path', 'url', 'pattern', 'query', 'command', 'description', 'prompt'] as const;\n\nfunction parseArgs(args: string): Record<string, unknown> | null {\n try {\n const parsed: unknown = JSON.parse(args);\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed as Record<string, unknown> : null;\n } catch {\n return null;\n }\n}\n\nfunction oneLine(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\n// A command's later lines can change what it does (a heredoc body, a chained\n// step), so they are counted rather than folded into the first.\nfunction firstLineOf(command: string): string {\n const lines = command.trim().split(/\\r?\\n/);\n const more = lines.length - 1;\n return more > 0 ? `${lines[0]} … +${more} line${more === 1 ? '' : 's'}` : lines[0];\n}\n\nfunction text(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\nfunction searchArg(pattern: string, path: string, include = ''): string {\n return `${pattern}${path ? ` in ${path}` : ''}${include ? ` (${include})` : ''}`;\n}\n\nfunction hintArg(args: Record<string, unknown>): string {\n for (const field of HINT_FIELDS) {\n const value = text(args[field]);\n if (value) return field === 'command' ? firstLineOf(value) : oneLine(value);\n }\n const firstText = Object.values(args).find((v): v is string => typeof v === 'string' && v.trim() !== '');\n return firstText ? oneLine(firstText) : '';\n}\n\nfunction keyArgOf(tool: string, args: Record<string, unknown>): string {\n switch (tool) {\n case 'bash':\n return firstLineOf(text(args.command));\n case 'read_file':\n case 'list_dir':\n return text(args.path);\n case 'read_files':\n return Array.isArray(args.paths) ? args.paths.map(String).join(', ') : '';\n case 'glob':\n return searchArg(text(args.pattern), text(args.path));\n case 'grep':\n return searchArg(text(args.pattern), text(args.path), text(args.include));\n case 'find_symbol':\n return `${text(args.symbol)}${text(args.language) ? ` [${text(args.language)}]` : ''}`;\n case 'fetch':\n return text(args.url);\n case 'web_search':\n return oneLine(text(args.query));\n case 'spawn_research_agent':\n return oneLine(text(args.prompt));\n default:\n return hintArg(args);\n }\n}\n\n/**\n * The one-line head of a command row, shared by every surface: the tool's name\n * and the argument that says what the call is about.\n *\n * @param args The call's arguments as announced (JSON). Anything that is not a\n * JSON object is shown as it came, on one line.\n * @param toolLabel A harness planner's own name for the tool (ADR-0009).\n */\nexport function toolHeadline(tool: string, args: string, toolLabel?: string): ToolHeadline {\n const name = toolLabel?.trim() || DISPLAY_NAMES[tool] || tool;\n const parsed = parseArgs(args);\n return { name, keyArg: parsed ? keyArgOf(tool, parsed) : oneLine(args) };\n}\n\nexport interface OutputPreview {\n lines: string[];\n hiddenLineCount: number;\n}\n\n/** The lines of a tool's output as a reader sees them — what {@link outputPreview} shows and counts. */\nexport function outputLines(output: string): string[] {\n // Line endings first: CR is itself a control character the escape pass drops.\n const lines = output.replace(/\\r\\n?/g, '\\n').replace(ANSI_OR_CTRL_RE, '').split('\\n');\n while (lines.length > 0 && lines[lines.length - 1].trim() === '') lines.pop();\n return lines;\n}\n\n/** The head of a tool's output for a collapsed row, and how many lines it leaves out. */\nexport function outputPreview(output: string, maxLines: number): OutputPreview {\n const lines = outputLines(output);\n const shown = lines.slice(0, Math.max(0, maxLines));\n return { lines: shown, hiddenLineCount: lines.length - shown.length };\n}\n","import type { ResearchStep, ResearchStepOutcome } from '../models/Task';\nimport type { UsageLine } from '../models/Usage';\nimport type { MessageBlock, MessageRole, PlanMarkerStatus, SubagentBlock, ToolBlock, ToolStatus, UsageBlock } from './blocks';\nimport { outputLines, toolHeadline } from './format';\n\n/*\n * How the session's records — messages, research steps, subagents, transcript\n * markers, usage totals — read as blocks. Shared by the live view and the\n * reload, so the two cannot disagree about what a record shows.\n */\n\n/** A line that is done: nothing streams into it any more. */\nexport function settledMessage(id: string, role: MessageRole, text: string, turnId?: string): MessageBlock {\n return { type: 'message', id, role, text, streaming: false, ...(turnId ? { turnId } : {}) };\n}\n\ntype SubagentFields = Omit<SubagentBlock, 'type' | 'id' | 'toolCallId' | 'model' | 'usage' | 'turnId'>\n & { toolCallId?: string; model?: string; usage?: SubagentBlock['usage']; turnId?: string };\n\nexport function subagentBlock(id: string, { toolCallId, model, usage, turnId, ...fields }: SubagentFields): SubagentBlock {\n return {\n type: 'subagent', id, ...fields,\n ...(toolCallId ? { toolCallId } : {}),\n ...(model ? { model } : {}),\n ...(usage ? { usage } : {}),\n ...(turnId ? { turnId } : {}),\n };\n}\n\nexport function usageBlock(id: string, { totals, bySubagent, contextFill }: UsageLine): UsageBlock {\n return { type: 'usage', id, totals, ...(bySubagent ? { bySubagent } : {}), ...(contextFill ? { contextFill } : {}) };\n}\n\nconst STATUS_OF_OUTCOME: Record<ResearchStepOutcome, ToolStatus> = {\n success: 'ok',\n failure: 'error',\n refused: 'denied',\n denied: 'denied',\n not_executed: 'interrupted',\n};\n\nexport function finishedTool(call: ToolBlock, output: string, outcome: ResearchStepOutcome): ToolBlock {\n return { ...call, status: STATUS_OF_OUTCOME[outcome], outcome, output, outputLineCount: outputLines(output).length };\n}\n\nexport function settledTool(call: ToolBlock, step: ResearchStep): ToolBlock {\n return finishedTool(call, step.result, step.outcome);\n}\n\nexport interface AnnouncedCall {\n tool: string;\n toolLabel?: string;\n args: string;\n toolCallId?: string;\n turnId?: string;\n}\n\nexport function pendingTool(id: string, { tool, toolLabel, args, toolCallId, turnId }: AnnouncedCall): ToolBlock {\n return {\n type: 'tool', id, tool, headline: toolHeadline(tool, args, toolLabel), args, status: 'pending', output: '', outputLineCount: 0,\n ...(toolCallId ? { toolCallId } : {}),\n ...(toolLabel ? { toolLabel } : {}),\n ...(turnId ? { turnId } : {}),\n };\n}\n\n/** The row of a call known only from its result — a reload, or a result whose call was never announced. */\nexport function toolFromStep(id: string, step: ResearchStep, turnId?: string): ToolBlock {\n return settledTool(pendingTool(id, { ...step, turnId }), step);\n}\n\n/**\n * What a plan marker says, read from the transcript entry `PlannerConversation`\n * writes for it (\"Plan generated with 2 tasks.\", \"Plan updated — now 1 task.\").\n * That entry is the only record of the marker a reload has, so the live view\n * reads the same text rather than counting tasks itself.\n */\nexport function planMarker(content: string): { status: Exclude<PlanMarkerStatus, 'building'>; taskCount?: number } {\n const count = /(\\d+) tasks?\\b/.exec(content);\n return { status: content.startsWith('Plan updated') ? 'updated' : 'generated', ...(count ? { taskCount: Number(count[1]) } : {}) };\n}\n","import type { UsageLine } from '../models/Usage';\nimport type { DisplayBlock, SubagentBlock, SubagentChild, SubagentStatus } from './blocks';\nimport { subagentBlock, usageBlock } from './records';\n\n/*\n * The block-list operations both reducers are built from — the planner\n * conversation (`reduce.ts`) and a structured task's log (`taskLog.ts`) — so\n * a subagent, a streaming run of text or the usage line behaves the same in\n * either view.\n */\n\n/** What every view over display blocks holds; each view adds its own state beside it. */\nexport interface BlockList {\n readonly blocks: readonly DisplayBlock[];\n readonly nextId: number;\n}\n\n/** The top level of the view (`null`), or the index of the subagent whose children are meant. */\nexport type Lane = number | null;\n\nexport function findLastIndex<T>(items: readonly T[], match: (item: T) => boolean): number {\n for (let i = items.length - 1; i >= 0; i--) if (match(items[i])) return i;\n return -1;\n}\n\nexport function replaceAt<T>(items: readonly T[], index: number, item: T): T[] {\n const next = items.slice();\n next[index] = item;\n return next;\n}\n\n// The usage line always sits last, so everything else lands above it.\nfunction insertTop(blocks: readonly DisplayBlock[], block: DisplayBlock): DisplayBlock[] {\n const last = blocks[blocks.length - 1];\n return last?.type === 'usage' ? [...blocks.slice(0, -1), block, last] : [...blocks, block];\n}\n\nexport function append<V extends BlockList>(view: V, make: (id: string) => DisplayBlock): V {\n return { ...view, blocks: insertTop(view.blocks, make(`b${view.nextId}`)), nextId: view.nextId + 1 };\n}\n\nexport function subagentAt(view: BlockList, lane: number): SubagentBlock {\n const block = view.blocks[lane];\n if (block.type !== 'subagent') throw new Error(`block ${lane} is not a subagent`);\n return block;\n}\n\nexport function laneBlocks(view: BlockList, lane: Lane): readonly DisplayBlock[] {\n return lane === null ? view.blocks : subagentAt(view, lane).children;\n}\n\nfunction setChildren<V extends BlockList>(view: V, lane: number, children: readonly SubagentChild[]): V {\n return { ...view, blocks: replaceAt(view.blocks, lane, { ...subagentAt(view, lane), children }) };\n}\n\nexport function laneReplace<V extends BlockList>(view: V, lane: Lane, index: number, block: SubagentChild): V {\n if (lane === null) return { ...view, blocks: replaceAt(view.blocks, index, block) };\n return setChildren(view, lane, replaceAt(subagentAt(view, lane).children, index, block));\n}\n\nexport function laneAppend<V extends BlockList>(view: V, lane: Lane, make: (id: string) => SubagentChild): V {\n if (lane === null) return append(view, make);\n const children = [...subagentAt(view, lane).children, make(`b${view.nextId}`)];\n return { ...setChildren(view, lane, children), nextId: view.nextId + 1 };\n}\n\nfunction isStreaming(block: DisplayBlock): boolean {\n return (block.type === 'message' || block.type === 'thinking') && block.streaming;\n}\n\nexport function sealed<B extends DisplayBlock>(block: B): B {\n return isStreaming(block) ? { ...block, streaming: false } : block;\n}\n\n/**\n * Output landed at `keep` in the lane, so nothing else there is still\n * streaming: one lane has one voice at a time, and a block left marked as\n * streaming would keep its cursor after its text had moved on.\n */\nexport function sealLane<V extends BlockList>(view: V, lane: Lane, keep: number): V {\n const blocks = laneBlocks(view, lane);\n if (!blocks.some((b, i) => i !== keep && isStreaming(b))) return view;\n if (lane === null) return { ...view, blocks: view.blocks.map((b, i) => (i === keep ? b : sealed(b))) };\n return setChildren(view, lane, subagentAt(view, lane).children.map((b, i) => (i === keep ? b : sealed(b))));\n}\n\n/** Append output to the lane, which then speaks through it alone. */\nexport function appendOutput<V extends BlockList>(view: V, lane: Lane, make: (id: string) => SubagentChild): V {\n const next = laneAppend(view, lane, make);\n return sealLane(next, lane, findLastIndex(laneBlocks(next, lane), (b) => b.type !== 'usage'));\n}\n\n/**\n * The subagent's block, created on first sighting: its activity can arrive\n * before (or without) its start. The call that spawns it becomes the block,\n * keeping the call's id and position — the call and the subagent are one\n * thing on screen.\n */\nexport function subagentLane<V extends BlockList>(view: V, subagentId: string, turnId?: string): [V, number] {\n const existing = findLastIndex(view.blocks, (b) => b.type === 'subagent' && b.subagentId === subagentId);\n if (existing >= 0) return [view, existing];\n const spawn = findLastIndex(view.blocks, (b) => b.type === 'tool' && (b.spawns === subagentId || b.toolCallId === subagentId));\n const call = view.blocks[spawn];\n if (call?.type === 'tool') {\n const block = subagentBlock(call.id, {\n subagentId, brief: call.headline.keyArg, status: 'running', children: [], digest: '', toolCallId: call.toolCallId, turnId: call.turnId,\n });\n return [{ ...view, blocks: replaceAt(view.blocks, spawn, block) }, spawn];\n }\n const next = append(view, (id) => subagentBlock(id, { subagentId, brief: '', status: 'running', children: [], digest: '', turnId }));\n return [next, findLastIndex(next.blocks, (b) => b.type === 'subagent' && b.subagentId === subagentId)];\n}\n\nexport function updateSubagent<V extends BlockList>(view: V, subagentId: string, turnId: string | undefined, update: (block: SubagentBlock) => SubagentBlock): V {\n const [next, lane] = subagentLane(view, subagentId, turnId);\n return { ...next, blocks: replaceAt(next.blocks, lane, update(subagentAt(next, lane))) };\n}\n\n/** The lane a subagent's activity lands in: its own block's children, or the top level. */\nexport function laneOf<V extends BlockList>(view: V, subagentId: string | undefined, turnId?: string): [V, Lane] {\n return subagentId ? subagentLane(view, subagentId, turnId) : [view, null];\n}\n\nexport function think<V extends BlockList>(view: V, text: string, turnId?: string, segmentId?: string, subagentId?: string): V {\n const [placed, lane] = laneOf(view, subagentId, turnId);\n const blocks = laneBlocks(placed, lane);\n const lastIndex = findLastIndex(blocks, (b) => b.type !== 'usage');\n const last = blocks[lastIndex];\n if (last?.type === 'thinking' && last.streaming && last.segmentId === segmentId) {\n return laneReplace(placed, lane, lastIndex, { ...last, text: last.text + text });\n }\n return appendOutput(placed, lane, (id) => ({\n type: 'thinking', id, text, streaming: true,\n ...(turnId ? { turnId } : {}),\n ...(segmentId ? { segmentId } : {}),\n ...(subagentId ? { subagentId } : {}),\n }));\n}\n\n/** The one usage line, replaced in place or added as the last block. */\nexport function setUsageLine<V extends BlockList>(view: V, line: UsageLine): V {\n const last = view.blocks[view.blocks.length - 1];\n const block = usageBlock(last?.type === 'usage' ? last.id : `b${view.nextId}`, line);\n if (last?.type === 'usage') return { ...view, blocks: replaceAt(view.blocks, view.blocks.length - 1, block) };\n return { ...view, blocks: [...view.blocks, block], nextId: view.nextId + 1 };\n}\n\nfunction closeBlock<B extends DisplayBlock>(block: B, interrupted: boolean): B {\n return interrupted && block.type === 'tool' && block.status === 'pending' ? { ...block, status: 'interrupted' } : sealed(block);\n}\n\nfunction closeSubagent(block: SubagentBlock, cut: SubagentStatus | null): SubagentBlock {\n const children = block.children.map((c) => closeBlock(c, cut !== null));\n const status = cut && block.status === 'running' ? cut : block.status;\n return status === block.status && children.every((c, i) => c === block.children[i]) ? block : { ...block, status, children };\n}\n\n/**\n * A turn is over, so whatever it left open is closed: streaming stops, and\n * when the turn was cut short (`cut`), its unanswered calls and running\n * subagents say so.\n */\nexport function closeOpenBlocks<V extends BlockList>(view: V, cut: SubagentStatus | null): V {\n const blocks = view.blocks.map((b) => (b.type === 'subagent' ? closeSubagent(b, cut) : closeBlock(b, cut !== null)));\n return blocks.every((b, i) => b === view.blocks[i]) ? view : { ...view, blocks };\n}\n","import type { QueuedTaskMessage, StructuredTurnEnd } from '../interfaces/ITerminalRunner';\nimport type { TaskLogEvent } from '../models/TaskLog';\nimport { addPlannerUsage, isMeasured, usageLine, type PlannerUsage } from '../models/Usage';\nimport { mapAgentTool, normalizeAgentArgs } from '../services/harness/agentTools';\nimport type { ApprovalBlock, MessageBlock, SubagentChild, SubagentStatus, ThinkingDisplayBlock } from './blocks';\nimport { toolHeadline } from './format';\nimport {\n append, appendOutput, replaceAt, closeOpenBlocks, findLastIndex, laneAppend, laneBlocks, laneOf, laneReplace, setUsageLine, updateSubagent, sealed,\n type BlockList, type Lane,\n} from './lanes';\nimport { finishedTool, pendingTool, settledMessage } from './records';\n\n/**\n * What a surface draws for one attempt of a structured task (ADR-0018, O1b):\n * the same display blocks as the planner conversation, built from the task's\n * {@link TaskLogEvent}s. No planner turn ids — a task's turns are its own,\n * one at a time.\n */\nexport interface TaskLogView extends BlockList {\n /** Messages waiting for the running turn to end, oldest first. */\n readonly queued: readonly QueuedTaskMessage[];\n /** A turn is running. */\n readonly working: boolean;\n /** How the last turn ended; absent before the first one does. */\n readonly lastTurnEnd?: StructuredTurnEnd;\n /** What the runner reported over the attempt, subagents included. */\n readonly usage?: PlannerUsage;\n /**\n * The block each run of deltas streams into, keyed by stream, so the run's\n * authoritative copy replaces it instead of repeating it below.\n */\n readonly streams: Readonly<Record<string, string>>;\n}\n\nexport const EMPTY_TASK_LOG: TaskLogView = { blocks: [], nextId: 1, queued: [], working: false, streams: {} };\n\ntype Event<T extends TaskLogEvent['type']> = Extract<TaskLogEvent, { type: T }>;\n\nconst TEXT_STREAM = 'text';\nconst thinkingStream = (subagentId: string | undefined) => `thinking:${subagentId ?? ''}`;\n\nfunction withoutStream(view: TaskLogView, key: string): TaskLogView {\n if (!(key in view.streams)) return view;\n return { ...view, streams: Object.fromEntries(Object.entries(view.streams).filter(([k]) => k !== key)) };\n}\n\n// A later text block of the same turn opens with a paragraph break (the\n// adapter joins a turn's messages that way); as a block of its own it needs none.\nfunction blockText(text: string): string {\n return text.replace(/^\\n+/, '');\n}\n\ntype Streamed = MessageBlock | ThinkingDisplayBlock;\n\n/** The lane's streaming block for `key`, while it is still the lane's latest output and still streaming. */\nfunction openStream(view: TaskLogView, lane: Lane, key: string): number {\n const id = view.streams[key];\n if (id === undefined) return -1;\n const blocks = laneBlocks(view, lane);\n const i = findLastIndex(blocks, (b) => b.type !== 'usage');\n const block = blocks[i];\n return block?.id === id && (block.type === 'message' || block.type === 'thinking') && block.streaming ? i : -1;\n}\n\nfunction streamDelta(view: TaskLogView, lane: Lane, key: string, text: string, make: (id: string, text: string) => Streamed): TaskLogView {\n const i = openStream(view, lane, key);\n const open = laneBlocks(view, lane)[i];\n if (open?.type === 'message' || open?.type === 'thinking') return laneReplace(view, lane, i, { ...open, text: open.text + text });\n const next = appendOutput(view, lane, (id) => make(id, blockText(text)));\n return { ...next, streams: { ...next.streams, [key]: `b${view.nextId}` } };\n}\n\n/**\n * A run's authoritative copy: it replaces the text its deltas built, wherever\n * that block now sits in the lane, and is added whole when nothing streamed.\n */\nfunction streamWhole(view: TaskLogView, lane: Lane, key: string, text: string, make: (id: string) => SubagentChild): TaskLogView {\n const id = view.streams[key];\n const blocks = laneBlocks(view, lane);\n const i = id === undefined ? -1 : findLastIndex(blocks, (b) => b.id === id);\n const streamed = blocks[i];\n const next = withoutStream(view, key);\n if (streamed?.type === 'message' || streamed?.type === 'thinking') {\n return laneReplace(next, lane, i, { ...streamed, text: blockText(text), streaming: false });\n }\n return appendOutput(next, lane, make);\n}\n\nfunction agentText(view: TaskLogView, text: string): TaskLogView {\n return streamWhole(view, null, TEXT_STREAM, text, (id) => settledMessage(id, 'agent', blockText(text)));\n}\n\nfunction agentTextDelta(view: TaskLogView, text: string): TaskLogView {\n return streamDelta(view, null, TEXT_STREAM, text, (id, t) => ({ type: 'message', id, role: 'agent', text: t, streaming: true }));\n}\n\nfunction thinkingBlock(id: string, text: string, streaming: boolean, subagentId: string | undefined): ThinkingDisplayBlock {\n return { type: 'thinking', id, text, streaming, ...(subagentId ? { subagentId } : {}) };\n}\n\nfunction thinkingDelta(view: TaskLogView, { text, subagentId }: Event<'thinking_delta'>): TaskLogView {\n const [placed, lane] = laneOf(view, subagentId);\n return streamDelta(placed, lane, thinkingStream(subagentId), text, (id, t) => thinkingBlock(id, t, true, subagentId));\n}\n\nfunction thinkingWhole(view: TaskLogView, { text, subagentId }: Event<'thinking'>): TaskLogView {\n const [placed, lane] = laneOf(view, subagentId);\n return streamWhole(placed, lane, thinkingStream(subagentId), text, (id) => thinkingBlock(id, blockText(text), false, subagentId));\n}\n\nfunction announceTool(view: TaskLogView, { id: toolCallId, name, args, subagentId }: Event<'tool_call'>): TaskLogView {\n const { tool, toolLabel } = mapAgentTool(name);\n const [placed, lane] = laneOf(view, subagentId);\n return appendOutput(placed, lane, (id) => {\n const call = pendingTool(id, { tool, toolLabel, args, toolCallId });\n const parsed = parseArgs(args);\n // Headline from the normalized arguments, as the harness planner's rows\n // are, so a `Read` or a Codex argv reads the same in both views.\n return parsed ? { ...call, headline: toolHeadline(tool, JSON.stringify(normalizeAgentArgs(tool, parsed)), toolLabel) } : call;\n });\n}\n\nfunction parseArgs(args: string): Record<string, unknown> | null {\n try {\n const parsed: unknown = JSON.parse(args);\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed as Record<string, unknown> : null;\n } catch {\n return null;\n }\n}\n\nfunction settleTool(view: TaskLogView, { id: toolCallId, output, success, subagentId }: Event<'tool_result'>): TaskLogView {\n const [placed, lane] = laneOf(view, subagentId);\n const blocks = laneBlocks(placed, lane);\n const i = findLastIndex(blocks, (b) => b.type === 'tool' && b.status === 'pending' && b.toolCallId === toolCallId);\n const pending = blocks[i];\n const outcome = success ? 'success' : 'failure';\n if (pending?.type === 'tool') return laneReplace(placed, lane, i, finishedTool(pending, output, outcome));\n // The call that spawned a subagent is shown by the subagent's block, and\n // only the subagent's own finish settles it: a backgrounded agent's call\n // returns at launch, long before the work ends.\n if (lane === null && blocks.some((b) => b.type === 'subagent' && b.toolCallId === toolCallId)) return view;\n return laneAppend(placed, lane, (id) => finishedTool(pendingTool(id, { tool: 'agent_tool', toolLabel: 'Tool', args: '', toolCallId }), output, outcome));\n}\n\nfunction startSubagent(view: TaskLogView, { subagentId, brief, model }: Event<'subagent_started'>): TaskLogView {\n return updateSubagent(view, subagentId, undefined, (block) => ({ ...block, ...(brief ? { brief } : {}), ...(model ? { model } : {}) }));\n}\n\nfunction finishSubagent(view: TaskLogView, { subagentId, outcome, digest }: Event<'subagent_finished'>): TaskLogView {\n const usage = view.usage?.bySubagent?.[subagentId];\n const next = updateSubagent(view, subagentId, undefined, (block) => ({\n ...block, status: outcome, digest, children: block.children.map(sealed), ...(usage ? { usage } : {}),\n }));\n return withoutStream(next, thinkingStream(subagentId));\n}\n\nfunction reportUsage(view: TaskLogView, { record }: Event<'usage'>): TaskLogView {\n const usage = addPlannerUsage(view.usage ?? { totals: {} }, record);\n const next = { ...view, usage };\n return isMeasured(usage.totals) ? setUsageLine(next, usageLine(usage)) : next;\n}\n\n/** A runner's tool request, read the way its call's row reads: `Bash(npm test)`. */\nexport function runnerToolSubject(tool: string, args: string): string {\n const { tool: mapped, toolLabel } = mapAgentTool(tool);\n const parsed = parseArgs(args);\n const headline = toolHeadline(mapped, parsed ? JSON.stringify(normalizeAgentArgs(mapped, parsed)) : args, toolLabel);\n return headline.keyArg ? `${headline.name}(${headline.keyArg})` : headline.name;\n}\n\nfunction requestApproval(view: TaskLogView, { approvalId, tool, args, allowForTask, toolCallId }: Event<'approval_requested'>): TaskLogView {\n if (view.blocks.some((b) => b.type === 'approval' && b.approvalId === approvalId)) return view;\n return append(view, (id) => ({\n type: 'approval', id, approvalId, kind: 'runner_tool',\n subject: runnerToolSubject(tool, args),\n scope: tool,\n status: 'pending',\n ...(allowForTask ? { allowForTask } : {}),\n ...(toolCallId ? { toolCallId } : {}),\n }));\n}\n\nfunction settleApproval(view: TaskLogView, approvalId: string, settle: (block: ApprovalBlock) => ApprovalBlock): TaskLogView {\n const i = findLastIndex(view.blocks, (b) => b.type === 'approval' && b.approvalId === approvalId);\n const block = view.blocks[i];\n if (block?.type !== 'approval' || block.status !== 'pending') return view;\n return { ...view, blocks: replaceAt(view.blocks, i, settle(block)) };\n}\n\nfunction decideApproval(view: TaskLogView, { approvalId, decision, note }: Event<'approval_decided'>): TaskLogView {\n return settleApproval(view, approvalId, (block) => ({\n ...block,\n status: decision === 'deny' ? 'denied' : 'granted',\n decidedBy: 'asked',\n ...(decision === 'allowForTask' ? { forTask: true } : {}),\n ...(note ? { note } : {}),\n }));\n}\n\nfunction startTurn(view: TaskLogView, { message, messageId }: Event<'turn_start'>): TaskLogView {\n const queued = messageId ? view.queued.filter((m) => m.id !== messageId) : view.queued;\n const working = { ...view, queued, working: true };\n // A turn the runner opened itself has no user message to show.\n return message ? append(working, (id) => settledMessage(id, 'user', message)) : working;\n}\n\nconst CUT: Record<StructuredTurnEnd, SubagentStatus | null> = { completed: null, interrupted: 'stopped', failed: 'failed' };\n\nfunction endTurn(view: TaskLogView, { reason }: Event<'turn_end'>): TaskLogView {\n const closed = closeOpenBlocks({ ...view, working: false, lastTurnEnd: reason, streams: {} }, CUT[reason]);\n return reason === 'interrupted' ? append(closed, (id) => settledMessage(id, 'system', 'Interrupted.')) : closed;\n}\n\nfunction queueMessage(view: TaskLogView, { messageId, text }: Event<'message_queued'>): TaskLogView {\n if (view.queued.some((m) => m.id === messageId)) return view;\n return { ...view, queued: [...view.queued, { id: messageId, text }] };\n}\n\nfunction unqueueMessage(view: TaskLogView, { messageId }: Event<'message_removed'>): TaskLogView {\n const queued = view.queued.filter((m) => m.id !== messageId);\n return queued.length === view.queued.length ? view : { ...view, queued };\n}\n\n/**\n * Fold one task-log event into the view. Pure and incremental, like\n * `reduceConversation`: an event that changes nothing returns `view` itself,\n * and an event of a type this build does not know is skipped — a log written\n * by a newer Ordewell still reads.\n */\nexport function reduceTaskLog(view: TaskLogView, event: TaskLogEvent): TaskLogView {\n switch (event.type) {\n case 'turn_start': return startTurn(view, event);\n case 'turn_end': return endTurn(view, event);\n case 'text_delta': return agentTextDelta(view, event.text);\n case 'text': return agentText(view, event.text);\n case 'thinking_delta': return thinkingDelta(view, event);\n case 'thinking': return thinkingWhole(view, event);\n case 'tool_call': return announceTool(view, event);\n case 'tool_result': return settleTool(view, event);\n case 'subagent_started': return startSubagent(view, event);\n case 'subagent_finished': return finishSubagent(view, event);\n case 'usage': return reportUsage(view, event);\n case 'message_queued': return queueMessage(view, event);\n case 'message_removed': return unqueueMessage(view, event);\n case 'error': return appendOutput(view, null, (id) => settledMessage(id, 'error', event.message));\n case 'approval_requested': return requestApproval(view, event);\n case 'approval_decided': return decideApproval(view, event);\n case 'approval_withdrawn': return settleApproval(view, event.approvalId, (block) => ({ ...block, status: 'withdrawn' }));\n default: return view;\n }\n}\n\n/** A whole attempt's events, folded from the start — what a reload shows. */\nexport function replayTaskLog(events: readonly TaskLogEvent[], from: TaskLogView = EMPTY_TASK_LOG): TaskLogView {\n return events.reduce(reduceTaskLog, from);\n}\n","/**\n * Pure, no-imports helper so a browser surface can format a conflict's files\n * without pulling `isolationRecord` — and its `path` import — into a webview\n * bundle. Kept out of `isolationRecord.ts` for exactly that reason.\n */\nexport function capConflictFiles(files: string[], max = 5): string {\n return files.length <= max ? files.join(', ') : `${files.slice(0, max).join(', ')}, +${files.length - max} more`;\n}\n","import type { DiscoveredModel, RunnerId, Task } from '../models/Task';\n\n/**\n * The ids a runner may actually run: the user's allowlist with the ids that\n * provably belong to a *different* runner dropped. `undefined` means no\n * restriction.\n *\n * Model ids are scoped to the agent that lists them, so an OpenRouter slug\n * allowlisted for Claude Code does not limit it — it points it at something it\n * cannot spawn, and the plan only dies once a task is already running. But\n * \"this runner didn't list it\" is not enough to call an id wrong: discovery can\n * be stale, and a plugin runner may have no list at all. What settles it is\n * whether *another* runner listed the id. So:\n *\n * - listed for this runner → keep;\n * - listed for no runner → unknown, and the user said it explicitly, so keep it\n * and let the runner validate last (the same call `coerceAssignments` and\n * `TaskRetarget` make);\n * - listed only for other runners → provably not this runner's, so drop it.\n *\n * When that leaves nothing, the whole allowlist was about some other runner\n * (a settings file written before a surface scoped its picker to one). No\n * restriction is the only safe reading — the alternative is handing the planner\n * a list of models that cannot run.\n */\nexport function effectiveAllowlist(\n allowlist: string[] | undefined,\n runner: string,\n modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>> | undefined,\n): string[] | undefined {\n if (!allowlist || allowlist.length === 0) return undefined;\n if (!modelsByRunner) return allowlist;\n\n const own = new Set((modelsByRunner[runner] ?? []).map((m) => m.modelId));\n const elsewhere = new Set<string>();\n for (const [other, models] of Object.entries(modelsByRunner)) {\n if (other === runner) continue;\n for (const m of models ?? []) elsewhere.add(m.modelId);\n }\n\n const kept = allowlist.filter((id) => own.has(id) || !elsewhere.has(id));\n return kept.length > 0 ? kept : undefined;\n}\n\nexport function filterModelsForPrompt(\n modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>,\n perRunnerAllowlist: Partial<Record<RunnerId, string[]>>,\n): Partial<Record<RunnerId, DiscoveredModel[]>> {\n const result: Partial<Record<RunnerId, DiscoveredModel[]>> = {};\n for (const [runner, models] of Object.entries(modelsByRunner)) {\n if (!models) continue;\n const allowed = effectiveAllowlist(perRunnerAllowlist[runner], runner, modelsByRunner);\n if (!allowed) {\n result[runner] = models;\n continue;\n }\n const allowedSet = new Set(allowed);\n const intersection = models.filter((m) => allowedSet.has(m.modelId));\n // A set allowlist is a hard constraint: the planner must never see models\n // outside it. An allowed id no runner has listed is one discovery doesn't\n // cover, so synthesize an entry rather than leaking the full list.\n const covered = new Set(intersection.map((m) => m.modelId));\n const missing = allowed\n .filter((id) => !covered.has(id))\n .map((id) => ({ modelId: id, modelLabel: id.split('/').pop() || id, variants: [] }));\n result[runner] = [...intersection, ...missing];\n }\n return result;\n}\n\n/** Canonical low→high ordering of the well-known effort ladder. */\nconst EFFORT_LADDER = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra'];\n/** Runner-specific spellings mapped onto the ladder. */\nconst EFFORT_ALIASES: Record<string, string> = { disabled: 'none', adaptive: 'medium' };\n\n/**\n * Clamp a planner/user-supplied thinking effort to what the model actually\n * offers. Invalid values map to the nearest rung the model supports (so a\n * Claude-style \"xhigh\" on a low/medium/high model becomes \"high\") and fall\n * back to undefined — the runner's own default — when no mapping exists.\n */\nexport function clampThinkingEffort(\n effort: string | undefined,\n variants: { id: string }[],\n): string | undefined {\n if (!effort) return undefined;\n if (variants.length === 0) return undefined;\n const ids = new Set(variants.map((v) => v.id));\n if (ids.has(effort)) return effort;\n const canon = EFFORT_ALIASES[effort] ?? effort;\n if (ids.has(canon)) return canon;\n const idx = EFFORT_LADDER.indexOf(canon);\n if (idx < 0) return undefined;\n for (let d = 1; d < EFFORT_LADDER.length; d++) {\n const lower = EFFORT_LADDER[idx - d];\n if (lower && ids.has(lower)) return lower;\n const higher = EFFORT_LADDER[idx + d];\n if (higher && ids.has(higher)) return higher;\n }\n return undefined;\n}\n\nexport function coerceAssignments(\n tasks: readonly Task[],\n perRunnerAllowlist: Partial<Record<RunnerId, string[]>>,\n allowedRunners?: RunnerId[],\n modelsByRunner?: Partial<Record<RunnerId, DiscoveredModel[]>>,\n): Task[] {\n // When the discovered catalog is available, snap each assignment's\n // thinkingEffort to a variant the model really has and stamp the model's\n // variant ids on the assignment (runners need them at spawn time); a model\n // we can't find in the catalog keeps its effort untouched (the runner\n // validates last).\n const clampVariant = (task: Task): Task => {\n if (!task.assignedModel || !modelsByRunner) return task;\n const model = modelsByRunner[task.assignedRunner]?.find(\n (m) => m.modelId === task.assignedModel!.modelId,\n );\n if (!model) return task;\n const clamped = clampThinkingEffort(task.assignedModel.thinkingEffort, model.variants);\n return {\n ...task,\n assignedModel: {\n ...task.assignedModel,\n thinkingEffort: clamped,\n availableVariants: model.variants.map((v) => v.id),\n },\n };\n };\n\n // One reading of the allowlist for the whole pass, so the models a task is\n // snapped to are the same ones the planner was shown (`filterModelsForPrompt`).\n const allowedFor = (runner: RunnerId): string[] | undefined =>\n effectiveAllowlist(perRunnerAllowlist[runner], runner, modelsByRunner);\n\n // A snapped-to model keeps the catalog's label and variant list where we have\n // one — an id alone reads as the model's name in every surface, and leaves the\n // effort picker with nothing to offer.\n const assignmentFor = (runner: RunnerId, modelId: string): NonNullable<Task['assignedModel']> => {\n const known = modelsByRunner?.[runner]?.find((m) => m.modelId === modelId);\n return {\n modelId,\n modelLabel: known?.modelLabel ?? modelId,\n thinkingEffort: undefined,\n ...(known ? { availableVariants: known.variants.map((v) => v.id) } : {}),\n };\n };\n\n return tasks.map((task) => {\n if (task.type === 'user') return task;\n\n if (allowedRunners && !allowedRunners.includes(task.assignedRunner)) {\n const fallbackRunner = allowedRunners[0];\n const fallbackModels = allowedFor(fallbackRunner);\n const fallbackModel = fallbackModels?.length\n ? assignmentFor(fallbackRunner, fallbackModels[0])\n : modelsByRunner?.[fallbackRunner]?.[0]\n ? assignmentFor(fallbackRunner, modelsByRunner[fallbackRunner]![0].modelId)\n : task.assignedModel;\n return clampVariant({\n ...task,\n assignedRunner: fallbackRunner,\n assignedModel: fallbackModel,\n });\n }\n\n const allowlist = allowedFor(task.assignedRunner);\n // No model assigned: fill in from the allowlist or discovered catalog so\n // merge/split/add outputs (which may omit assignedModel) always land with a\n // valid model for the task's runner.\n if (!task.assignedModel) {\n if (allowlist && allowlist.length > 0) {\n return clampVariant({ ...task, assignedModel: assignmentFor(task.assignedRunner, allowlist[0]) });\n }\n const discovered = modelsByRunner?.[task.assignedRunner]?.[0];\n if (discovered) {\n return clampVariant({ ...task, assignedModel: assignmentFor(task.assignedRunner, discovered.modelId) });\n }\n return task;\n }\n if (!allowlist || allowlist.length === 0) return clampVariant(task);\n if (allowlist.includes(task.assignedModel.modelId)) return clampVariant(task);\n return { ...task, assignedModel: assignmentFor(task.assignedRunner, allowlist[0]) };\n });\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport {\n Task, RunnerId, flattenTasks,\n addTaskToPlan, removeTaskFromPlan, updateTaskInPlan, renumberTasks,\n createTask,\n} from '../models/Task';\nimport { extractObjectsWithKey, stripTrailingCommas, escapeControlCharsInStrings, PlanParseError, TASK_OPS_ENVELOPE_KEY } from './JsonExtractor';\nimport { validateTaskEdit, checkModelAndModeValidity, type EditCatalog } from './TaskEditValidator';\n\n/**\n * Targeted task edits emitted by the planner conversation (the 'task_ops'\n * ConversationTurn). Task references accept a task id, a \"#<order>\" ref, or a\n * bare order number — cheap models rarely echo UUIDs correctly.\n */\nexport type TaskOp =\n | { op: 'update'; taskId: string; changes: Partial<Task> }\n | { op: 'add'; task: Partial<Task>; handle?: string }\n | { op: 'remove'; taskId: string }\n | { op: 'reorder'; taskIds: string[] }\n | { op: 'merge'; taskIds: string[]; merged: Partial<Task>; handle?: string }\n | { op: 'split'; taskId: string; parts: Partial<Task>[]; handle?: string }\n | { op: 'rearm'; taskId: string; changes?: Partial<Task> };\n\n/** Fields the planner may change on an existing task. Everything else (id, status, verdict…) is system-owned. */\nexport const UPDATABLE_FIELDS: (keyof Task)[] = [\n 'title', 'description', 'prompt', 'dependencies', 'assignedRunner', 'assignedModel', 'taskMode', 'thinkingEffort', 'type', 'userSteps', 'autonomy', 'sliceType', 'ops',\n];\n\n/**\n * The edit protocol as the planner reads it, kept beside the applier so the\n * prose can never undersell (or oversell) what {@link applyTaskOps} accepts.\n * `executionNote` rides on the ordering rule because that is the rule a\n * running execution changes.\n */\nexport function taskOpsProtocol(executionNote = ''): string[] {\n const updateChanges = UPDATABLE_FIELDS\n .map((f) => (f === 'dependencies' ? '\"dependencies\"?:[\"<id or #order>\"]' : `\"${f}\"?`))\n .join(',');\n return [\n '- To modify specific tasks, reply with ONLY this JSON object:',\n ' {\"taskOps\": [',\n ` {\"op\":\"update\",\"taskId\":\"<id or #order>\",\"changes\":{${updateChanges}}},`,\n ' {\"op\":\"add\",\"task\":{\"title\",\"description\",\"prompt\",\"dependencies\":[\"<id or #order>\"],\"assignedRunner\"?,\"assignedModel\"?,\"ops\"?},\"handle\"?:\"<name>\"},',\n ' {\"op\":\"remove\",\"taskId\":\"<id or #order>\"},',\n ' {\"op\":\"reorder\",\"taskIds\":[\"<id or #order>\", \"... every task exactly once\"]}, // only to re-prioritise INDEPENDENT tasks',\n ' {\"op\":\"merge\",\"taskIds\":[\"<id or #order>\", \"...\"],\"merged\":{\"title\",\"description\",\"prompt\"?,\"assignedRunner\"?,\"assignedModel\"?,...},\"handle\"?:\"<name>\"},',\n ' {\"op\":\"split\",\"taskId\":\"<id or #order>\",\"parts\":[{\"title\",\"description\",\"prompt\"?,\"assignedRunner\"?,\"assignedModel\"?,...}, ...],\"handle\"?:\"<name>\"},',\n ` {\"op\":\"rearm\",\"taskId\":\"<id or #order>\",\"changes\"?:{${updateChanges}}}`,\n ' ]}',\n '- For sweeping changes, you may instead emit a full {\"tasks\":[...]} plan JSON.',\n 'Every \"<id or #order>\" ref in a batch resolves against the plan shown above, before any op in the batch runs — an earlier remove/merge/split never shifts what a later \"#N\" means.',\n 'Give \"add\", \"merge\", or \"split\" a \"handle\" (any name you choose, unused elsewhere in this batch) to let a LATER op in the same batch reference the task it produces — for \"split\", the handle names its last part. A handle used before its defining op is rejected.',\n 'When creating or changing tasks, set \"assignedRunner\" and \"assignedModel\" ({\"modelId\",\"modelLabel\",\"thinkingEffort\"?}) using only the runners and models listed in <available_models>.',\n 'Keep dependencies consistent: no cycles, no references to removed tasks, and never touch running or completed tasks — \"rearm\" is the one exception, below.',\n 'Just declare the dependencies you want — display order is repaired for you afterwards, so a rewire or a newly added prerequisite never needs a \"reorder\" op. Only a task that is running or completed cannot be shifted, so an edit that would need one to move is rejected.' + executionNote,\n 'Flipping \"type\" between \"ai\" and \"user\" is a content change, not just a label: an update to \"user\" needs \"userSteps\" in the SAME op, and an update to \"ai\" needs \"prompt\" in the SAME op — the model/mode/effort/autonomy fields (flipping to \"user\") or the userSteps (flipping to \"ai\") are cleared automatically.',\n '\"rearm\" puts a failed OR completed task back to pending — verdict and output summary are cleared, any dependents it had blocked are released, and it may carry field changes (e.g. a corrected \"prompt\") applied in the same op. A running task cannot be re-armed. Never rearm a task just to relabel it — only when it should actually run again.',\n ];\n}\n\nexport function textHasTaskOps(text: string): boolean {\n return text.includes(`\"${TASK_OPS_ENVELOPE_KEY}\"`);\n}\n\n/** Parse a `{\"taskOps\":[...]}` reply. Throws PlanParseError when the JSON is unusable. */\nexport function parseTaskOpsJson(text: string): TaskOp[] {\n // Extract by the taskOps key specifically — a reply may also carry a\n // tasks-keyed object (schema echo, example), which must not shadow the ops.\n // Candidates are tried back to front: the last emission is the final answer.\n const { matches, fallback } = extractObjectsWithKey(text, TASK_OPS_ENVELOPE_KEY);\n const candidates = matches.length > 0 ? [...matches].reverse() : [fallback.json];\n\n let lastError: PlanParseError | null = null;\n for (const json of candidates) {\n try {\n return parseTaskOpsObject(json, text);\n } catch (err) {\n if (!(err instanceof PlanParseError)) throw err;\n if (!lastError) lastError = err;\n }\n }\n throw lastError ?? new PlanParseError('No JSON object found in task-ops reply', text);\n}\n\nfunction parseTaskOpsObject(json: string, text: string): TaskOp[] {\n let parsed: unknown;\n try {\n parsed = JSON.parse(escapeControlCharsInStrings(stripTrailingCommas(json)));\n } catch (err) {\n throw new PlanParseError(`Task-ops JSON is invalid: ${err instanceof Error ? err.message : String(err)}`, text);\n }\n const ops = (parsed as { taskOps?: unknown }).taskOps;\n if (!Array.isArray(ops) || ops.length === 0) {\n throw new PlanParseError('\"taskOps\" must be a non-empty array', text);\n }\n for (const op of ops) {\n if (typeof op !== 'object' || op === null || typeof (op as { op?: unknown }).op !== 'string') {\n throw new PlanParseError('Every task op needs an \"op\" field (update | add | remove | reorder | merge | split)', text);\n }\n }\n return ops as TaskOp[];\n}\n\ntype RefResolution = { id: string } | { error: string };\n\n/**\n * Resolve a task reference (id, \"#3\", \"3\", or a batch handle) to a task id.\n *\n * `#order` and title matches are pinned to `originalScope` — the plan as it\n * stood before the batch began — so an earlier op's renumbering can never\n * make a later op's \"#4\" land on a different task than the planner saw. A\n * literal id has no such drift (ids are stable across mutations), so id\n * matches check `liveScope` — the batch's current, mutated tasks — which is\n * also how a later op reaches a task created earlier in the same batch\n * without a handle (e.g. a split's own chained parts).\n */\nfunction resolveRef(\n ref: unknown,\n originalScope: readonly Task[],\n liveScope: Task[],\n handleOwner: Map<string, number>,\n handleId: Map<string, string>,\n opIndex: number,\n): RefResolution {\n if (typeof ref !== 'string' && typeof ref !== 'number') return { error: `invalid reference \"${String(ref)}\"` };\n const s = String(ref).trim();\n\n const ownerIdx = handleOwner.get(s);\n if (ownerIdx !== undefined) {\n if (ownerIdx >= opIndex) {\n return { error: `handle \"${s}\" is defined later in this batch (op ${ownerIdx + 1}) and cannot be referenced yet` };\n }\n const id = handleId.get(s);\n if (!id) return { error: `handle \"${s}\" was never resolved` };\n return { id };\n }\n\n const byLiveId = liveScope.find((t) => t.id === s);\n if (byLiveId) return { id: byLiveId.id };\n const orderStr = s.startsWith('#') ? s.slice(1) : s;\n if (/^\\d+$/.test(orderStr)) {\n const order = Number(orderStr);\n const byOrder = originalScope.filter((t) => t.order === order);\n if (byOrder.length === 1) return { id: byOrder[0].id };\n }\n const byTitle = originalScope.find((t) => t.title === s);\n if (byTitle) return { id: byTitle.id };\n return { error: `task \"${s}\" not found` };\n}\n\n/**\n * The task references an op carries, before a batch handle resolves; an `add`\n * names none. Used to tell whether a batch reaches a task a runner is running.\n */\nexport function taskOpRefs(op: TaskOp): string[] {\n switch (op.op) {\n case 'update':\n case 'remove':\n case 'split':\n case 'rearm':\n return [op.taskId];\n case 'merge':\n case 'reorder':\n return op.taskIds;\n case 'add':\n return [];\n }\n}\n\n/** Whether a written reference names `task` by id, `#order`, bare order, or title. */\nexport function refMatchesTask(ref: unknown, task: Pick<Task, 'id' | 'order' | 'title'>): boolean {\n if (typeof ref !== 'string' && typeof ref !== 'number') return false;\n const s = String(ref).trim();\n if (task.id === s) return true;\n const orderStr = s.startsWith('#') ? s.slice(1) : s;\n return (/^\\d+$/.test(orderStr) && task.order === Number(orderStr)) || task.title === s;\n}\n\n/** Whether `name` already denotes an existing task by id, `#order`, or title. */\nfunction refCollidesWithExisting(name: string, originalFlatAll: Task[]): boolean {\n if (originalFlatAll.some((t) => t.id === name)) return true;\n const orderStr = name.startsWith('#') ? name.slice(1) : name;\n if (/^\\d+$/.test(orderStr) && originalFlatAll.some((t) => t.order === Number(orderStr))) return true;\n return originalFlatAll.some((t) => t.title === name);\n}\n\n/**\n * The fields of a planner's `changes` it may set. `ops` decides where a task\n * runs, so anything but a literal true reads as a change task, as a parsed\n * plan reads it (ADR-0020).\n */\nfunction updatableChanges(raw: Partial<Task> | undefined): Partial<Task> {\n const changes: Partial<Task> = {};\n for (const key of UPDATABLE_FIELDS) {\n if (raw && key in raw) (changes as Record<string, unknown>)[key] = (raw as Record<string, unknown>)[key];\n }\n if ('ops' in changes) changes.ops = changes.ops === true ? true : undefined;\n return changes;\n}\n\nfunction findInTasks(tasks: Task[], id: string): Task | undefined {\n return flattenTasks(tasks).find((t) => t.id === id);\n}\n\nfunction findTopLevel(tasks: Task[], id: string): Task | undefined {\n return tasks.find((t) => t.id === id);\n}\n\nfunction detectCycle(tasks: Task[]): string | null {\n const byId = new Map(tasks.map((t) => [t.id, t]));\n const visiting = new Set<string>();\n const done = new Set<string>();\n const visit = (id: string): string | null => {\n if (done.has(id)) return null;\n if (visiting.has(id)) return id;\n visiting.add(id);\n for (const dep of byId.get(id)?.dependencies ?? []) {\n const hit = visit(dep);\n if (hit) return hit;\n }\n visiting.delete(id);\n done.add(id);\n return null;\n };\n for (const t of tasks) {\n const hit = visit(t.id);\n if (hit) return byId.get(hit)?.title ?? hit;\n }\n return null;\n}\n\n/** A task the repair may not reposition: execution has already reached it. */\nfunction isPinned(t: Task): boolean {\n return t.status === 'in_progress' || t.status === 'completed';\n}\n\n/**\n * Reorder top-level tasks so every dependency comes before its dependents,\n * moving as little as possible: pinned tasks keep the exact slot they are in,\n * and each free slot goes to the earliest-listed movable task whose\n * dependencies are already placed — so tasks the graph does not constrain keep\n * their relative order. Assumes an acyclic graph (the caller checks first).\n */\nfunction repairOrder(tasks: Task[]): { tasks: Task[] } | { error: string } {\n const byId = new Map(tasks.map((t) => [t.id, t]));\n const placed = new Set<string>();\n const movable = tasks.filter((t) => !isPinned(t));\n const result: Task[] = [];\n // Dependencies outside this list (a subtask id) constrain nothing here.\n const blockerOf = (t: Task): Task | undefined => {\n const id = t.dependencies.find((d) => byId.has(d) && !placed.has(d));\n return id ? byId.get(id) : undefined;\n };\n const place = (t: Task) => { result.push(t); placed.add(t.id); };\n\n for (const occupant of tasks) {\n if (isPinned(occupant)) {\n const blocker = blockerOf(occupant);\n if (blocker) return { error: pinnedRefusal(blocker, occupant, 'before') };\n place(occupant);\n continue;\n }\n const next = movable.findIndex((t) => !blockerOf(t));\n if (next < 0) {\n // Nothing is schedulable and the graph is acyclic, so every movable task\n // left waits — directly or through others — on a pinned task further down\n // that would have to come up to free this slot.\n const [stuck, pin] = trailToPin(movable[0], blockerOf);\n return { error: pinnedRefusal(stuck, pin, 'after') };\n }\n place(movable.splice(next, 1)[0]);\n }\n return { tasks: result };\n}\n\n/** Walk the waiting-on chain from `task` down to the pinned task holding it up. */\nfunction trailToPin(task: Task, blockerOf: (t: Task) => Task | undefined): [Task, Task] {\n let at = task;\n for (;;) {\n const blocker = blockerOf(at);\n if (!blocker || isPinned(blocker)) return [at, blocker ?? at];\n at = blocker;\n }\n}\n\n/** `\"B\" #2→#1, \"A\" #1→#3` for every task the repair actually moved, or null. */\nfunction describeMoves(before: Task[], after: Task[]): string | null {\n const wasAt = new Map(before.map((t, i) => [t.id, i + 1]));\n const moved = after\n .map((t, i) => ({ t, from: wasAt.get(t.id)!, to: i + 1 }))\n .filter((m) => m.from !== m.to);\n return moved.length ? moved.map((m) => `\"${m.t.title}\" #${m.from}→#${m.to}`).join(', ') : null;\n}\n\nfunction pinnedRefusal(other: Task, pin: Task, side: 'before' | 'after'): string {\n const word = pin.status === 'in_progress' ? 'running' : 'completed';\n return `\"${other.title}\" would have to run ${side} \"${pin.title}\", which is ${word} and cannot be moved`;\n}\n\nexport interface ApplyTaskOpsResult {\n ok: boolean;\n tasks: readonly Task[];\n errors: string[];\n /** Human-readable summary of what changed, for the chat transcript. */\n summary: string[];\n}\n\n/**\n * Pre-flight check for a merge: would collapsing the selected tasks into one\n * (rewiring every dependent of any selected task to the survivor) keep the\n * dependency graph valid? Rejects locked tasks and merges whose rewiring would\n * introduce a cycle. Display order is NOT checked here — neither\n * consecutiveness (a UI concern) nor a dependency the merge pulls out of order,\n * which {@link applyTaskOps} repairs; refusing on order would make this\n * pre-flight stricter than the applier it stands in for.\n */\nexport function canMergeTasks(tasks: readonly Task[], selectedIds: string[]): { ok: boolean; error?: string } {\n if (selectedIds.length < 2) return { ok: false, error: 'Select at least two tasks to merge' };\n const idSet = new Set(selectedIds);\n const toMerge = tasks.filter((t) => idSet.has(t.id));\n if (toMerge.length < 2) return { ok: false, error: 'At least two valid tasks are required to merge' };\n for (const t of toMerge) {\n if (t.status === 'in_progress') return { ok: false, error: `\"${t.title}\" is running and cannot be merged` };\n if (t.status === 'completed') return { ok: false, error: `\"${t.title}\" is completed and cannot be merged` };\n }\n const ordered = [...toMerge].sort((a, b) => a.order - b.order);\n const survivorId = '__merge_sim__';\n const sim: Task[] = tasks\n .filter((t) => !idSet.has(t.id))\n .map((t) => ({ ...t, dependencies: t.dependencies.map((d) => (idSet.has(d) ? survivorId : d)).filter((d) => d !== t.id) }));\n const unionDeps = [...new Set(toMerge.flatMap((t) => t.dependencies))].filter((d) => !idSet.has(d));\n sim.push({ ...ordered[0], id: survivorId, title: '__merge_sim__', order: ordered[0].order, dependencies: unionDeps });\n const cycle = detectCycle(sim);\n if (cycle) return { ok: false, error: `Merging would create a dependency cycle involving \"${cycle}\"` };\n return { ok: true };\n}\n\n/**\n * The shape the dependency helpers below read. Structural rather than `Task`,\n * because the TUI projects tasks into its own `TaskView`: a surface's\n * dependency picker and the API's validation must agree on which dependencies\n * are legal, and a signature only core can satisfy would have forced the TUI\n * to keep a second copy of the rule.\n */\nexport interface TaskRef {\n id: string;\n order: number;\n title: string;\n dependencies: string[];\n}\n\n/** The tasks listing `taskId` as a dependency — exactly what removing it detaches. */\nexport function dependentsOf<T extends Pick<TaskRef, 'id' | 'dependencies'>>(tasks: T[], taskId: string): T[] {\n return tasks.filter((t) => t.id !== taskId && t.dependencies.includes(taskId));\n}\n\n/**\n * The tasks that may become dependencies of `taskId`: those displayed before it.\n *\n * Offering only earlier tasks is what keeps a hand-edited graph valid without a\n * cycle check — dependencies then only ever point backwards in display order,\n * the same invariant `applyTaskOps` enforces. Omit `taskId` for a task that does\n * not exist yet: it lands last, so every current task is a candidate.\n */\nexport function dependencyCandidates<T extends Pick<TaskRef, 'id' | 'order'>>(tasks: readonly T[], taskId?: string): T[] {\n if (!taskId) return [...tasks];\n const target = tasks.find((t) => t.id === taskId);\n return target ? tasks.filter((t) => t.order < target.order) : [];\n}\n\n/** Pre-flight check for a hand-edited dependency list: every id exists and comes earlier. */\nexport function canSetDependencies<T extends TaskRef>(\n tasks: readonly T[],\n taskId: string,\n dependencies: string[],\n): { ok: boolean; error?: string } {\n const target = tasks.find((t) => t.id === taskId);\n if (!target) return { ok: false, error: 'Task not found' };\n const allowed = new Set(dependencyCandidates(tasks, taskId).map((t) => t.id));\n for (const dep of dependencies) {\n if (dep === taskId) return { ok: false, error: `\"${target.title}\" cannot depend on itself` };\n const found = tasks.find((t) => t.id === dep);\n if (!found) return { ok: false, error: `Unknown dependency \"${dep}\"` };\n if (!allowed.has(dep)) {\n return { ok: false, error: `\"${target.title}\" cannot depend on \"${found.title}\", which comes after it in the plan` };\n }\n }\n return { ok: true };\n}\n\n/** Pre-flight check for a split: the task exists and is not locked by execution. */\nexport function canSplitTask(tasks: readonly Task[], taskId: string): { ok: boolean; error?: string } {\n const target = tasks.find((t) => t.id === taskId);\n if (!target) return { ok: false, error: 'Task not found' };\n if (target.status === 'in_progress') return { ok: false, error: `\"${target.title}\" is running and cannot be split` };\n if (target.status === 'completed') return { ok: false, error: `\"${target.title}\" is completed and cannot be split` };\n return { ok: true };\n}\n\n/**\n * Apply task ops to a snapshot of the plan, atomically: either every op\n * applies and the result validates (deps resolve, no cycles, running and\n * completed tasks untouched), or nothing is returned and `errors` explains\n * why. The caller commits `tasks` on ok.\n */\nexport function applyTaskOps(currentTasks: readonly Task[], ops: TaskOp[], runners: RunnerId[], catalog?: EditCatalog): ApplyTaskOpsResult {\n let tasks: Task[] = JSON.parse(JSON.stringify(currentTasks));\n const errors: string[] = [];\n const summary: string[] = [];\n\n // Frozen snapshot every ref resolves `#order`/title matches against, so an\n // earlier op's renumbering can never shift what a later op's \"#N\" means.\n const originalFlatAll = flattenTasks(currentTasks);\n\n // Batch handles: planner-chosen names for a task an add/merge/split op is\n // about to create, so a later op in the same batch can reference it before\n // it has a real id. Pre-scanned up front — a bad handle refuses the whole\n // batch before anything mutates.\n const handleOwner = new Map<string, number>();\n const handleId = new Map<string, string>();\n for (const [i, op] of ops.entries()) {\n const handle = (op as { handle?: unknown }).handle;\n if (handle === undefined) continue;\n if (typeof handle !== 'string' || !handle.trim()) {\n errors.push(`op ${i + 1} (${op.op}): handle must be a non-empty string`);\n continue;\n }\n if (handleOwner.has(handle)) {\n errors.push(`op ${i + 1} (${op.op}): handle \"${handle}\" is already used earlier in this batch`);\n continue;\n }\n if (refCollidesWithExisting(handle, originalFlatAll)) {\n errors.push(`op ${i + 1} (${op.op}): handle \"${handle}\" collides with an existing task reference`);\n continue;\n }\n handleOwner.set(handle, i);\n }\n if (errors.length) return { ok: false, tasks: currentTasks, errors, summary: [] };\n\n const resolveDeps = (deps: unknown, opIndex: number): { ids: string[]; bad: string[] } => {\n const ids: string[] = [];\n const bad: string[] = [];\n const liveFlat = flattenTasks(tasks);\n for (const d of Array.isArray(deps) ? deps : []) {\n const r = resolveRef(d, originalFlatAll, liveFlat, handleOwner, handleId, opIndex);\n if ('error' in r) { bad.push(`${String(d)} (${r.error})`); continue; }\n if (!liveFlat.some((t) => t.id === r.id)) { bad.push(`${String(d)} (no longer exists in this batch)`); continue; }\n ids.push(r.id);\n }\n return { ids, bad };\n };\n\n for (const [i, op] of ops.entries()) {\n const label = `op ${i + 1} (${op.op})`;\n switch (op.op) {\n case 'update': {\n const ref = resolveRef(op.taskId, originalFlatAll, flattenTasks(tasks), handleOwner, handleId, i);\n if ('error' in ref) { errors.push(`${label}: ${ref.error}`); break; }\n const target = findInTasks(tasks, ref.id);\n if (!target) { errors.push(`${label}: task \"${op.taskId}\" no longer exists in this batch (removed, merged, or split by an earlier op)`); break; }\n const changes = updatableChanges(op.changes);\n if (changes.assignedRunner && !runners.includes(changes.assignedRunner)) {\n errors.push(`${label}: runner \"${changes.assignedRunner}\" is not in this plan's runner set [${runners.join(', ')}]`);\n break;\n }\n // Dependency refs are still unresolved (e.g. \"#3\") at this point, so\n // this check runs on everything but them; resolveDeps below handles\n // dependency well-formedness once they're real ids.\n const changesForCheck: Partial<Task> = { ...changes };\n delete changesForCheck.dependencies;\n const check = validateTaskEdit('planner', flattenTasks(tasks), target.id, changesForCheck, catalog);\n if (!check.ok) { errors.push(`${label}: ${check.error}`); break; }\n for (const field of check.clear ?? []) (changes as Record<string, unknown>)[field] = undefined;\n if ('dependencies' in changes) {\n const { ids, bad } = resolveDeps(changes.dependencies, i);\n if (bad.length) { errors.push(`${label}: unknown dependencies: ${bad.join(', ')}`); break; }\n changes.dependencies = ids.filter((id) => id !== target.id);\n }\n if (Object.keys(changes).length === 0) { errors.push(`${label}: no valid changes provided`); break; }\n tasks = updateTaskInPlan(tasks, target.id, changes);\n const clearedNote = check.clear?.length ? `; cleared ${check.clear.join(', ')}` : '';\n summary.push(`Updated \"${target.title}\" (${Object.keys(changes).join(', ')})${clearedNote}`);\n break;\n }\n case 'add': {\n const spec = op.task ?? {};\n if (!spec.title) { errors.push(`${label}: new task needs a title`); break; }\n const { ids, bad } = resolveDeps(spec.dependencies, i);\n if (bad.length) { errors.push(`${label}: unknown dependencies: ${bad.join(', ')}`); break; }\n const runner = spec.assignedRunner && runners.includes(spec.assignedRunner) ? spec.assignedRunner : runners[0];\n const validity = checkModelAndModeValidity(runner, spec.assignedModel, spec.taskMode, catalog);\n if (!validity.ok) { errors.push(`${label}: ${validity.error}`); break; }\n const newId = uuidv4();\n tasks = addTaskToPlan(tasks, {\n ...spec,\n id: newId,\n dependencies: ids,\n assignedRunner: runner,\n description: spec.description ?? spec.title,\n prompt: spec.prompt ?? spec.description ?? spec.title,\n });\n if (op.handle) handleId.set(op.handle, newId);\n summary.push(`Added \"${spec.title}\"`);\n break;\n }\n case 'remove': {\n const ref = resolveRef(op.taskId, originalFlatAll, flattenTasks(tasks), handleOwner, handleId, i);\n if ('error' in ref) { errors.push(`${label}: ${ref.error}`); break; }\n const target = findInTasks(tasks, ref.id);\n if (!target) { errors.push(`${label}: task \"${op.taskId}\" no longer exists in this batch (removed, merged, or split by an earlier op)`); break; }\n if (target.status === 'in_progress') { errors.push(`${label}: \"${target.title}\" is running and cannot be removed`); break; }\n if (target.status === 'completed') { errors.push(`${label}: \"${target.title}\" is completed and cannot be removed`); break; }\n tasks = removeTaskFromPlan(tasks, target.id);\n summary.push(`Removed \"${target.title}\"`);\n break;\n }\n case 'reorder': {\n const refs = (op.taskIds ?? []).map((r) => resolveRef(r, currentTasks, tasks, handleOwner, handleId, i));\n const badRef = refs.find((r): r is { error: string } => 'error' in r);\n if (badRef) { errors.push(`${label}: ${badRef.error}`); break; }\n const resolved = (refs as { id: string }[]).map((r) => findTopLevel(tasks, r.id));\n if (resolved.some((t) => !t)) { errors.push(`${label}: unknown task in reorder list`); break; }\n const orderIds = resolved.map((t) => t!.id);\n if (new Set(orderIds).size !== tasks.length) {\n errors.push(`${label}: reorder must list every top-level task exactly once (${tasks.length} tasks)`);\n break;\n }\n const byId = new Map(tasks.map((t) => [t.id, t]));\n tasks = renumberTasks(orderIds.map((id) => byId.get(id)!));\n summary.push('Reordered tasks');\n break;\n }\n case 'merge': {\n const refs = (op.taskIds ?? []).map((r) => resolveRef(r, currentTasks, tasks, handleOwner, handleId, i));\n const badRef = refs.find((r): r is { error: string } => 'error' in r);\n if (badRef) { errors.push(`${label}: ${badRef.error}`); break; }\n const resolved = (refs as { id: string }[]).map((r) => findTopLevel(tasks, r.id));\n if (resolved.some((t) => !t)) { errors.push(`${label}: unknown task in merge list (already removed, merged, or split by an earlier op)`); break; }\n const toMerge = resolved.map((t) => t!).sort((a, b) => a.order - b.order);\n if (toMerge.length < 2) { errors.push(`${label}: merge needs at least two tasks`); break; }\n const locked = toMerge.find((t) => t.status === 'in_progress' || t.status === 'completed');\n if (locked) {\n errors.push(`${label}: \"${locked.title}\" is ${locked.status === 'in_progress' ? 'running' : 'completed'} and cannot be merged`);\n break;\n }\n const idSet = new Set(toMerge.map((t) => t.id));\n const unionDepsRaw = [...new Set(toMerge.flatMap((t) => t.dependencies))].filter((d) => !idSet.has(d));\n const { ids, bad } = resolveDeps(unionDepsRaw, i);\n if (bad.length) { errors.push(`${label}: unknown dependencies: ${bad.join(', ')}`); break; }\n const spec = op.merged ?? {};\n if (!spec.title) { errors.push(`${label}: merged task needs a title`); break; }\n const runner = spec.assignedRunner && runners.includes(spec.assignedRunner) ? spec.assignedRunner : toMerge[0].assignedRunner;\n const mergedTask = createTask({\n title: spec.title,\n description: spec.description ?? toMerge.map((t) => t.description).filter(Boolean).join('\\n\\n'),\n prompt: spec.prompt ?? (toMerge.map((t) => t.prompt).filter(Boolean).join('\\n\\n---\\n\\n') || undefined),\n type: spec.type ?? (toMerge.some((t) => t.type === 'user') ? 'user' : 'ai'),\n dependencies: ids,\n assignedRunner: runner,\n assignedModel: spec.assignedModel ?? toMerge.find((t) => t.assignedModel)?.assignedModel,\n thinkingEffort: spec.thinkingEffort ?? toMerge.find((t) => t.thinkingEffort)?.thinkingEffort,\n taskMode: spec.taskMode ?? toMerge[0].taskMode,\n autonomy: spec.autonomy ?? toMerge.find((t) => t.autonomy)?.autonomy,\n sliceType: spec.sliceType ?? toMerge.find((t) => t.sliceType)?.sliceType,\n ops: spec.ops ?? toMerge.every((t) => t.ops),\n userStoriesCovered: spec.userStoriesCovered ?? (toMerge.flatMap((t) => t.userStoriesCovered ?? []).length\n ? [...new Set(toMerge.flatMap((t) => t.userStoriesCovered ?? []))]\n : undefined),\n });\n const mergedId = mergedTask.id;\n const firstId = toMerge[0].id;\n const result: Task[] = [];\n let inserted = false;\n for (const t of tasks) {\n if (idSet.has(t.id)) {\n if (!inserted && t.id === firstId) { result.push(mergedTask); inserted = true; }\n continue;\n }\n result.push({ ...t, dependencies: t.dependencies.map((d) => (idSet.has(d) ? mergedId : d)) });\n }\n if (!inserted) result.push(mergedTask);\n tasks = renumberTasks(result);\n if (op.handle) handleId.set(op.handle, mergedId);\n summary.push(`Merged ${toMerge.length} tasks into \"${spec.title}\"`);\n break;\n }\n case 'split': {\n const ref = resolveRef(op.taskId, currentTasks, tasks, handleOwner, handleId, i);\n if ('error' in ref) { errors.push(`${label}: ${ref.error}`); break; }\n const target = findTopLevel(tasks, ref.id);\n if (!target) { errors.push(`${label}: task \"${op.taskId}\" not found`); break; }\n if (target.status === 'in_progress') { errors.push(`${label}: \"${target.title}\" is running and cannot be split`); break; }\n if (target.status === 'completed') { errors.push(`${label}: \"${target.title}\" is completed and cannot be split`); break; }\n const parts = op.parts ?? [];\n if (parts.length < 2) { errors.push(`${label}: split needs at least two parts`); break; }\n const newTasks: Task[] = [];\n let prevId: string | undefined;\n let buildError = false;\n for (let p = 0; p < parts.length; p++) {\n const spec = parts[p];\n if (!spec || !spec.title) { errors.push(`${label}: split part ${p + 1} needs a title`); buildError = true; break; }\n // Part 0 inherits the original's (external) dependencies, resolved\n // against the current plan. Later parts chain onto the previous part\n // — a sibling id created in this same op, so it needs no resolution.\n let deps: string[];\n if (p === 0) {\n const { ids, bad } = resolveDeps(target.dependencies, i);\n if (bad.length) { errors.push(`${label}: split part 1 unknown dependencies: ${bad.join(', ')}`); buildError = true; break; }\n deps = ids;\n } else {\n deps = prevId ? [prevId] : [];\n }\n const runner = spec.assignedRunner && runners.includes(spec.assignedRunner) ? spec.assignedRunner : target.assignedRunner;\n const nt = createTask({\n title: spec.title,\n description: spec.description ?? spec.title,\n prompt: spec.prompt ?? spec.description ?? spec.title,\n type: spec.type ?? target.type,\n dependencies: deps,\n assignedRunner: runner,\n assignedModel: spec.assignedModel ?? target.assignedModel,\n taskMode: spec.taskMode ?? target.taskMode,\n autonomy: spec.autonomy ?? target.autonomy,\n sliceType: spec.sliceType ?? target.sliceType,\n ops: spec.ops ?? target.ops,\n userStoriesCovered: spec.userStoriesCovered ?? target.userStoriesCovered,\n });\n newTasks.push(nt);\n prevId = nt.id;\n }\n if (buildError) break;\n const tailId = newTasks[newTasks.length - 1].id;\n const result: Task[] = [];\n for (const t of tasks) {\n if (t.id === target.id) { result.push(...newTasks); continue; }\n result.push({ ...t, dependencies: t.dependencies.map((d) => (d === target.id ? tailId : d)) });\n }\n tasks = renumberTasks(result);\n if (op.handle) handleId.set(op.handle, tailId);\n summary.push(`Split \"${target.title}\" into ${newTasks.length} tasks`);\n break;\n }\n case 'rearm': {\n const ref = resolveRef(op.taskId, originalFlatAll, flattenTasks(tasks), handleOwner, handleId, i);\n if ('error' in ref) { errors.push(`${label}: ${ref.error}`); break; }\n const target = findInTasks(tasks, ref.id);\n if (!target) { errors.push(`${label}: task \"${op.taskId}\" no longer exists in this batch (removed, merged, or split by an earlier op)`); break; }\n if (target.status === 'in_progress') { errors.push(`${label}: \"${target.title}\" is running and cannot be re-armed`); break; }\n const changes = updatableChanges(op.changes);\n if (changes.assignedRunner && !runners.includes(changes.assignedRunner)) {\n errors.push(`${label}: runner \"${changes.assignedRunner}\" is not in this plan's runner set [${runners.join(', ')}]`);\n break;\n }\n // Validated as a direct edit (not 'planner'): re-arming is the sanctioned\n // exception to the planner lock — its whole point is to touch a task the\n // lock would otherwise refuse. Well-formedness (type coherence, model/mode\n // validity, dependency shape) still applies, same as every other edit.\n const changesForCheck: Partial<Task> = { ...changes };\n delete changesForCheck.dependencies;\n const check = validateTaskEdit('direct', flattenTasks(tasks), target.id, changesForCheck, catalog);\n if (!check.ok) { errors.push(`${label}: ${check.error}`); break; }\n for (const field of check.clear ?? []) (changes as Record<string, unknown>)[field] = undefined;\n if ('dependencies' in changes) {\n const { ids, bad } = resolveDeps(changes.dependencies, i);\n if (bad.length) { errors.push(`${label}: unknown dependencies: ${bad.join(', ')}`); break; }\n changes.dependencies = ids.filter((id) => id !== target.id);\n }\n tasks = updateTaskInPlan(tasks, target.id, { ...changes, status: 'pending', verdict: undefined, outputSummary: undefined, awaitingReason: undefined });\n // Dependents parked at 'blocked' by this task's earlier failure have\n // nothing else to release them — the scheduler reads `status` directly,\n // not a live recomputation of the dependency graph.\n for (const dep of flattenTasks(tasks)) {\n if (dep.status === 'blocked' && dep.dependencies.includes(target.id)) {\n tasks = updateTaskInPlan(tasks, dep.id, { status: 'pending' });\n }\n }\n const clearedNote = check.clear?.length ? `; cleared ${check.clear.join(', ')}` : '';\n const changedNote = Object.keys(changes).length ? ` (${Object.keys(changes).join(', ')})` : '';\n summary.push(`Re-armed \"${target.title}\"${changedNote}${clearedNote}`);\n break;\n }\n default:\n errors.push(`${label}: unknown op \"${(op as { op: string }).op}\"`);\n }\n if (errors.length) break;\n }\n\n if (!errors.length) {\n const flat = flattenTasks(tasks);\n const idSet = new Set(flat.map((t) => t.id));\n for (const t of flat) {\n for (const dep of t.dependencies) {\n if (!idSet.has(dep)) errors.push(`\"${t.title}\" depends on a task that no longer exists (${dep})`);\n }\n }\n const cycleAt = detectCycle(flat);\n if (cycleAt) errors.push(`Dependency cycle detected involving \"${cycleAt}\"`);\n // Display order is maintained, not demanded: whatever the batch produced,\n // the plan comes back with dependencies ahead of their dependents. The\n // planner never has to re-declare the whole order to move one task.\n if (!errors.length) {\n const repaired = repairOrder(tasks);\n if ('error' in repaired) {\n errors.push(repaired.error);\n } else {\n const moves = describeMoves(tasks, repaired.tasks);\n if (moves) summary.push(`Reordered to keep dependencies first: ${moves}`);\n tasks = renumberTasks(repaired.tasks);\n }\n }\n }\n\n return errors.length\n ? { ok: false, tasks: currentTasks, errors, summary: [] }\n : { ok: true, tasks, errors: [], summary };\n}\n","import { Task, RunnerId, DiscoveredModel, TaskModelAssignment, TaskMode } from '../models/Task';\nimport { canSetDependencies } from './TaskOps';\nimport { effectiveAllowlist } from './ModelAllowlistResolver';\nimport type { RunnerModeInfo } from './ModeResolver';\n\n/**\n * Who is making the edit. The planner (`applyTaskOps`) and the direct-edit\n * path (`Session.updateTask`/`setTaskDependencies`, reached by the TUI, the\n * webview task card, and `PUT /tasks/:taskId`) are deliberately asymmetric —\n * see CONTEXT.md, \"Direct edit vs planner edit\". The planner may not reach\n * into a task that is running or already finished; the direct path may,\n * because it is the user editing their own plan, and pays what that costs at\n * the call site (cancelling a live runner, releasing blocked dependents).\n */\nexport type TaskEditActor = 'planner' | 'direct';\n\nexport interface TaskEditCheck {\n ok: boolean;\n error?: string;\n /**\n * Fields a type flip strips of meaning, to be force-cleared by the caller\n * (set to `undefined` in the applied changes) and named in whatever summary\n * reaches the transcript. Only lists fields the target actually had a value\n * for — nothing to clear reads as nothing lost.\n */\n clear?: (keyof Task)[];\n}\n\nconst AI_ONLY_FIELDS = ['assignedModel', 'thinkingEffort', 'taskMode', 'autonomy', 'ops'] as const satisfies readonly (keyof Task)[];\n\n/**\n * The catalog a model/task-mode edit is checked against — the same discovered\n * models and manifest modes the planner was shown in the per-turn catalog\n * block (`PlannerConversation.catalogBlock`), so a refusal here can never name something\n * as invalid that the planner was never told about, or vice versa.\n */\nexport interface EditCatalog {\n modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>;\n runnerModes: Partial<Record<RunnerId, RunnerModeInfo[]>>;\n /** Raw (unfiltered) allowlist, keyed by runner — the same shape `coerceAssignments` takes. */\n perRunnerAllowlist?: Partial<Record<RunnerId, string[]>>;\n}\n\n/**\n * Whether an assigned model and task mode are things the target runner\n * actually offers. Invented ids are refused rather than silently substituted\n * downstream (`coerceAssignments` remains the safety net for paths that never\n * go through this validator) — the planner gets the refusal, with the runner\n * named, through the same repair loop as every other edit rejection.\n *\n * `catalog` is optional: callers with no discovered catalog on hand (most unit\n * tests, a runner with no manifest modes) skip these checks rather than\n * refusing everything sight-unseen.\n */\nexport function checkModelAndModeValidity(\n runner: RunnerId,\n assignedModel: TaskModelAssignment | undefined,\n taskMode: TaskMode | undefined,\n catalog: EditCatalog | undefined,\n): TaskEditCheck {\n if (!catalog) return { ok: true };\n\n if (assignedModel) {\n const models = catalog.modelsByRunner[runner];\n if (models) {\n const modelId = assignedModel.modelId;\n const allowed = effectiveAllowlist(catalog.perRunnerAllowlist?.[runner], runner, catalog.modelsByRunner);\n // An allowlisted id discovery doesn't list is one `filterModelsForPrompt`\n // shows the planner anyway — refusing it here would contradict the\n // catalog block; the runner validates it last.\n if (!models.some((m) => m.modelId === modelId) && !allowed?.includes(modelId)) {\n return { ok: false, error: `Runner \"${runner}\" does not offer model \"${modelId}\"` };\n }\n if (allowed && !allowed.includes(modelId)) {\n return { ok: false, error: `Model \"${modelId}\" is excluded by the allowlist for runner \"${runner}\"` };\n }\n }\n }\n\n if (taskMode !== undefined) {\n const modes = catalog.runnerModes[runner];\n if (modes && modes.length > 0 && !modes.some((m) => m.id === taskMode)) {\n return { ok: false, error: `Runner \"${runner}\" has no task mode \"${taskMode}\" — valid modes: ${modes.map((m) => m.id).join(', ')}` };\n }\n }\n\n return { ok: true };\n}\n\n/**\n * Coherence between `type` and the fields that only make sense for one side\n * of it. Deriving user steps from an AI prompt (or vice versa) would fabricate\n * instructions nobody wrote (ADR-0001: the plan is the source of truth), so a\n * flip that lacks the content the new type needs is refused rather than\n * silently patched — the planner gets that refusal back through the repair\n * loop; a direct edit gets it as a thrown reason. A flip that IS well-formed\n * clears the fields that stopped meaning anything, named for the caller.\n */\nfunction typeCoherenceCheck(target: Task, changes: Partial<Task>): TaskEditCheck | null {\n if (!changes.type || changes.type === target.type) return null;\n\n if (changes.type === 'user') {\n if (!Array.isArray(changes.userSteps) || changes.userSteps.length === 0) {\n return { ok: false, error: `\"${target.title}\" cannot become a manual task without user steps — include \"userSteps\" in this edit` };\n }\n return { ok: true, clear: AI_ONLY_FIELDS.filter((f) => target[f] !== undefined) };\n }\n\n // changes.type === 'ai'\n if (!changes.prompt || !changes.prompt.trim()) {\n return { ok: false, error: `\"${target.title}\" cannot become an AI task without a prompt — include \"prompt\" in this edit` };\n }\n return { ok: true, clear: target.userSteps && target.userSteps.length > 0 ? ['userSteps'] : [] };\n}\n\n/** Statuses of a task that has not started: the only ones whose ops flag may still change (ADR-0020). */\nconst NOT_STARTED: ReadonlySet<Task['status']> = new Set<Task['status']>(['pending', 'approved', 'blocked']);\n\n/**\n * Whether a task may become an ops task, or stop being one (ADR-0020). Only a\n * top-level AI task can be ops, and the flag decides where the task runs, so\n * once it has started it is fixed, like its transport.\n */\nfunction opsCheck(tasks: readonly Task[], target: Task, changes: Partial<Task>): TaskEditCheck | null {\n if (!('ops' in changes) || !!changes.ops === !!target.ops) return null;\n if (!NOT_STARTED.has(target.status)) {\n return { ok: false, error: `\"${target.title}\" has started, so whether it is an ops task is fixed` };\n }\n if (!changes.ops) return null;\n if ((changes.type ?? target.type) !== 'ai') return { ok: false, error: `\"${target.title}\" is a manual task — only an AI task can be an ops task` };\n if (tasks.some((t) => t.subtasks?.some((s) => s.id === target.id))) {\n return { ok: false, error: `\"${target.title}\" is a subtask, which runs with its parent — only a top-level task can be an ops task` };\n }\n return null;\n}\n\n/**\n * The rules governing one task edit, shared by both actors. Lock rules\n * (running/completed) apply to the planner only. Well-formedness rules — like\n * a hand-set dependency list, the one edit that can leave the plan\n * unschedulable, and type/content coherence on an AI↔MAN flip — describe the\n * task rather than who asked, so they run for both, through the same\n * {@link canSetDependencies} guard the pickers and the API read.\n */\nexport function validateTaskEdit(\n actor: TaskEditActor,\n tasks: readonly Task[],\n taskId: string,\n changes: Partial<Task>,\n catalog?: EditCatalog,\n): TaskEditCheck {\n const target = tasks.find((t) => t.id === taskId);\n if (!target) return { ok: false, error: 'Task not found' };\n\n if (actor === 'planner') {\n if (target.status === 'in_progress') return { ok: false, error: `\"${target.title}\" is running and cannot be modified` };\n if (target.status === 'completed') return { ok: false, error: `\"${target.title}\" is completed and cannot be modified` };\n }\n\n if (changes.dependencies) {\n const depCheck = canSetDependencies(tasks, taskId, changes.dependencies);\n if (!depCheck.ok) return depCheck;\n }\n\n const coherence = typeCoherenceCheck(target, changes);\n if (coherence && !coherence.ok) return coherence;\n\n const ops = opsCheck(tasks, target, changes);\n if (ops) return ops;\n\n const runner = changes.assignedRunner ?? target.assignedRunner;\n const validity = checkModelAndModeValidity(runner, changes.assignedModel, changes.taskMode, catalog);\n if (!validity.ok) return validity;\n\n return coherence ?? { ok: true };\n}\n","import type { ResearchStepOutcome } from '../models/Task';\n\n/**\n * One-line human summary of a research tool call, shared by every surface that\n * renders live planner progress (VS Code webview, CLI, TUI). Kept in core so\n * the arg-shape heuristics (file path vs. pattern vs. shell command) live in\n * one place instead of being re-derived per surface — which also means a new\n * tool becomes readable in all three UIs by being handled here once.\n */\n\nfunction ellipsize(text: string, max: number): string {\n const oneLine = text.replace(/\\s+/g, ' ').trim();\n return oneLine.length > max ? `${oneLine.slice(0, max)}…` : oneLine;\n}\n\n/**\n * @param toolLabel The agent's own name for the tool, when a harness planner\n * produced the call (ADR-0009). It replaces the member name in the summary, so\n * the timeline says `Edit` rather than the catch-all `agent_tool` — and says\n * `WebFetch` rather than claiming a shell command ran.\n */\nexport function summarizeToolCall(tool: string, argsJson: string, toolLabel?: string): string {\n const display = toolLabel?.trim() || tool;\n if (tool === 'agent_tool') {\n // No Ordewell equivalent, so no arg shape to rely on: show the agent's name\n // plus whichever conventional field the call happens to carry.\n try {\n const args = JSON.parse(argsJson);\n const hint = args.path ?? args.file_path ?? args.filePath ?? args.pattern ?? args.query ?? args.url ?? args.command;\n if (hint) return `${display} ${ellipsize(String(hint), 50)}`;\n } catch {\n // fall through to the bare name\n }\n return display;\n }\n\n if (tool === 'spawn_research_agent') {\n try {\n const args = JSON.parse(argsJson);\n const prompt = typeof args.prompt === 'string' ? args.prompt : '';\n const oneLine = prompt.replace(/\\s+/g, ' ').trim();\n return `spawn: \"${oneLine.slice(0, 60)}${oneLine.length > 60 ? '…' : ''}\"`;\n } catch {\n return 'spawn_research_agent';\n }\n }\n\n try {\n const args = JSON.parse(argsJson);\n\n // Ordered by specificity: a tool's defining argument wins over the generic\n // `path`, which several of the newer tools also accept as a search root.\n if (tool === 'find_symbol' && args.symbol) {\n return `find_symbol ${args.symbol}${args.language ? ` [${args.language}]` : ''}`;\n }\n if (tool === 'web_search' && args.query) {\n return `web_search \"${ellipsize(String(args.query), 50)}\"`;\n }\n if (tool === 'fetch' && args.url) {\n return `fetch ${ellipsize(String(args.url), 60)}`;\n }\n // The pattern is what a glob is about; the generic `path` below is only its\n // search root, and reporting that read as \"glob src\" for every call.\n if (tool === 'glob' && args.pattern) {\n return `glob ${ellipsize(String(args.pattern), 50)}`;\n }\n if (tool === 'grep' && args.pattern) {\n const mode = args.output_mode && args.output_mode !== 'content' ? ` (${args.output_mode})` : '';\n const scope = args.include ? ` in ${args.include}` : '';\n return `grep ${ellipsize(String(args.pattern), 40)}${scope}${mode}`;\n }\n\n const path = args.filePath || args.file_path || args.path;\n if (path) {\n const basename = String(path).split('/').pop() || String(path);\n return `${display} ${basename}`;\n }\n if (args.pattern) {\n return `${display} ${args.pattern}`;\n }\n if (args.command) {\n return `bash: ${String(args.command).slice(0, 40)}`;\n }\n } catch {\n // fall through to the bare tool name below\n }\n return display;\n}\n\n/**\n * Classify a tool outcome from its result text and success flag, so a surface\n * can render a refused `rm` or a denied `npm test` distinctly from a\n * successful run without re-deriving the refusal signatures per surface. The\n * refusal/denial strings come from `commandPolicy.ts`, `BaseFileSystem.ts`,\n * and the research-subagent wrapper — keeping the matching here means the\n * signatures stay in one place alongside the human summary.\n */\nexport function classifyOutcome(success: boolean, output: string): ResearchStepOutcome {\n if (!success) {\n if (/^Command refused:/.test(output) || /is not available\\. You are a read-only research subagent/.test(output)) return 'refused';\n if (/not approved/i.test(output) || /^Access denied:/.test(output) || /needs user approval/i.test(output)) return 'denied';\n return 'failure';\n }\n return 'success';\n}\n","import type { Task } from '../models/Task';\n\n/** Whether a task can be continued in its saved runner session (ADR-0018, K1), and in which. */\nexport type Continuability = { ok: true; sessionId: string } | { ok: false; reason: string };\n\n/**\n * The rule every surface offers Continue by and the orchestrator enforces: a\n * completed or failed task whose last attempt ran structured and left a\n * session id behind. A conflict is resolved by its repair, not a new turn, and\n * a terminal task has no session Ordewell can reach — Retry covers both.\n */\nexport function continuability(task: Task): Continuability {\n const refuse = (reason: string): Continuability => ({ ok: false, reason: `Task \"${task.title}\" cannot be continued: ${reason}` });\n if (task.type !== 'ai') return refuse('it is not run by an agent.');\n if (task.status === 'awaiting_user' && task.awaitingReason === 'conflict') {\n return refuse('its work is waiting on a merge conflict. Resolve or repair the conflict instead.');\n }\n if (task.status !== 'completed' && task.status !== 'failed') return refuse('only a completed or failed task can be.');\n if (task.transport?.kind !== 'structured') return refuse('it ran in a terminal, so there is no saved session to resume. Use Retry instead.');\n if (!task.transport.nativeSessionId) return refuse('its runner left no saved session to resume. Use Retry instead.');\n return { ok: true, sessionId: task.transport.nativeSessionId };\n}\n\nexport function canContinue(task: Task): boolean {\n return continuability(task).ok;\n}\n","import type { AwaitingReason, LegacyPlanState, QueuedMessage, ResearchStep, RunnerId, SubagentOutcome, Task, TaskTransport, Verdict } from '../models/Task';\nimport type { UsageTotals } from '../models/Usage';\nimport type { TaskLogEvent } from '../models/TaskLog';\nimport type { ApprovalKind } from '../interfaces/IApproval';\nimport type { ApprovalSource } from './ApprovalPolicy';\nimport type { IsolationHandoff, IsolationMergeResult, TaskIsolation } from '../interfaces/IWorktreeIsolation';\nimport type { QueuedTaskMessage } from '../interfaces/ITerminalRunner';\nimport { canContinue } from './continuation';\n\nexport type SerializedTaskStatus = {\n id: string;\n status: string;\n verdict: { outcome: 'pass' | 'fail'; reason: string; checks: Verdict['checks'] } | null;\n /** Advisory silence timestamp from VerdictEngine — not part of task status semantics. */\n idleSince?: string | null;\n /** Absent unless the plan has an isolation run, so a shared-root plan's updates are unchanged. */\n isolation?: TaskIsolation;\n /** Absent unless the task's plan asked for the structured transport (ADR-0018): what it ran on, or why it fell back. */\n transport?: Pick<TaskTransport, 'kind' | 'fallback'>;\n /** What an `awaiting_user` task waits on, when it was saved (ADR-0018, W1). */\n awaitingReason?: AwaitingReason;\n /** Messages waiting for a structured task's turn to end, oldest first; absent when there are none. */\n queued?: QueuedTaskMessage[];\n /** Set when the task can be continued in its saved runner session (ADR-0018, K1); the id itself stays in the daemon. */\n continuable?: true;\n /**\n * How many of a structured task's runner requests wait for an answer\n * (ADR-0018, A1) — \"waiting for approval\", which leaves `status` alone.\n * Absent when none do.\n */\n awaitingApproval?: number;\n /**\n * The dependencies an ops or user task waits on at its merge gate: their\n * work has landed but is not merged into the user's branch (ADR-0020).\n * Absent when it waits for no Merge all.\n */\n mergeGate?: string[];\n /** The dependencies, by title, a force start went past the merge gate of (ADR-0020). */\n forcedPastGate?: string[];\n};\n\n/**\n * A run with tasks at a merge gate (ADR-0020), as a surface offers Merge all\n * mid-run: what has landed and is not merged yet, and whether nothing else is\n * running, so the run waits on the user alone.\n */\nexport interface MergeGateView {\n paused: boolean;\n repos: IsolationHandoff['repos'];\n landed: IsolationHandoff['landed'];\n}\n\nexport type SerializedTask = {\n id: string;\n order: number;\n title: string;\n type: string;\n description: string;\n dependencies: string[];\n assignedRunner: RunnerId;\n assignedModel: Task['assignedModel'] | null;\n taskMode: string;\n prompt: string | null;\n subtasks: SerializedTask[];\n userSteps: Task['userSteps'];\n thinkingEffort: Task['thinkingEffort'];\n autonomy: Task['autonomy'];\n sliceType: Task['sliceType'];\n userStoriesCovered: Task['userStoriesCovered'];\n /** Set only on an ops task (ADR-0020). */\n ops?: true;\n};\n\nexport type SerializedPlan = {\n tasks: SerializedTask[];\n runners: RunnerId[];\n generatedAt: string;\n conversationHistory?: LegacyPlanState['conversationHistory'];\n prdMarkdown?: string;\n queuedMessages?: QueuedMessage[];\n};\n\n/** How a planner turn ended: the reply kind it settled on, a user stop, or a failure. */\nexport type PlannerTurnOutcome = 'message' | 'plan' | 'task_ops' | 'stopped' | 'error';\n\n/**\n * Everything a session tells its surfaces, over one broadcast seam.\n *\n * A planner turn (#47) streams between `planner_turn_started` and\n * `planner_turn_ended` with the same `turnId`; every turn-scoped message in\n * between carries it. The stream is provisional and the settled messages are\n * authoritative:\n * - `planner_message` replaces the streamed text of the turn's final segment —\n * a surface drops what it accumulated and shows the message instead.\n * - A reply that is a JSON envelope (plan, taskOps, taskQuery) never arrives\n * as `planner_text_delta`; it streams as `plan_token`, the \"building plan\"\n * display.\n * - A subagent's own text never appears in the reply; its activity arrives\n * tagged with its `subagentId`.\n */\nexport type SessionMessage =\n /**\n * The plan, whole. `turnId` names the planner turn whose commit this\n * broadcast carries, so the turn's building plan becomes the marker; it is\n * absent on every other broadcast of the plan.\n */\n | { type: 'plan_generated'; plan: SerializedPlan; goal: string; runners: RunnerId[]; turnId?: string }\n /**\n * The settled reply of a planner turn, emitted by the session once the turn\n * is classified. Authoritative over any `planner_text_delta` of its turn's\n * final segment. `turnId` is absent for replies sent outside a streamed turn.\n */\n | { type: 'planner_message'; content: string; timestamp: string; turnId?: string }\n /**\n * A planner turn began. Emitted once per turn by whoever runs the turn,\n * before any other message carrying its `turnId`. `prompt` is the user's\n * message when the turn answers one.\n */\n | { type: 'planner_turn_started'; turnId: string; prompt?: string }\n /**\n * A planner turn is over; nothing more carries its `turnId`. Emitted exactly\n * once per `planner_turn_started`, stop and failure included, after the\n * turn's `planner_message` when it has one.\n */\n | { type: 'planner_turn_ended'; turnId: string; outcome: PlannerTurnOutcome }\n /**\n * Reply prose as it streams, appended in order within its segment. A segment\n * is one continuous run of model text; text before a tool call is its own\n * segment, and a later segment never rewrites an earlier one. Never carries\n * a JSON envelope or a subagent's text (see the union's invariants).\n */\n | { type: 'planner_text_delta'; turnId: string; segmentId: string; text: string }\n /**\n * Exposed reasoning as it streams, from the planner or — tagged with\n * `subagentId` — from one of its subagents. Never part of the reply. The one\n * thinking message for every backend: `segmentId` is set only where the\n * backend streams thinking in segments (the API loops; harness planners do\n * not), and `turnId` is absent for thinking outside a turn (one-shot plans).\n */\n | { type: 'planner_thinking_delta'; turnId?: string; segmentId?: string; subagentId?: string; text: string }\n /**\n * Text streamed for an attempt the turn discarded (a corrective retry) is\n * taken back: a surface removes it. With `segmentId`, only that segment;\n * without, all of the turn's text not yet settled by a `planner_message`.\n * A segment that streamed to the plan display (`plan_token`) takes the\n * turn's building plan with it.\n */\n | { type: 'planner_text_retracted'; turnId: string; segmentId?: string }\n /**\n * The planner's running usage for the session, subagents included, emitted\n * after a model call reports usage. `totals` already contains every\n * `bySubagent` entry. `contextFill` is the last planner prompt against the\n * model's window, omitted when the window is unknown. Cost appears only as\n * reported by a provider or runner (see `UsageRecord`).\n */\n | {\n type: 'planner_usage';\n turnId?: string;\n totals: UsageTotals;\n bySubagent?: Record<string, UsageTotals>;\n contextFill?: { usedTokens: number; windowTokens: number };\n }\n /**\n * A subagent began work on `brief`. Emitted by the planner backend that\n * spawned it (ADR-0005 research agents, or a harness planner's own), before\n * any message tagged with its `subagentId`.\n */\n | { type: 'subagent_started'; turnId?: string; subagentId: string; brief: string; model?: string }\n /**\n * A subagent is done; nothing more is tagged with its `subagentId`. Emitted\n * once per `subagent_started`. `digest` is what it handed back to the\n * planner; `usage` is its own share, already counted in `planner_usage`.\n */\n | { type: 'subagent_finished'; turnId?: string; subagentId: string; outcome: SubagentOutcome; digest: string; usage?: UsageTotals }\n // `gate` is present while a task waits at a merge gate (ADR-0020): what Merge\n // all would merge now, and whether the run is paused there with nothing else\n // running.\n | { type: 'status_update'; tasks: SerializedTaskStatus[]; gate?: MergeGateView }\n | { type: 'review_needed'; tasks: SerializedTask[] }\n | { type: 'review_approved' }\n | { type: 'checkpoint'; taskId: string; taskTitle: string; summary: string }\n | { type: 'execution_complete'; summary: { total: number; completed: number; failed: number } }\n | { type: 'execution_stopped' }\n | { type: 'queue_ready' }\n | { type: 'task_updated'; taskId: string; changes: Record<string, unknown> }\n | { type: 'task_started'; taskId: string; order: number; title: string; runner: RunnerId; modelId?: string }\n | { type: 'task_output'; taskId: string; text: string }\n /**\n * A structured task's log as it happens (ADR-0018, P1): the next events of\n * the task's attempt `attempt`, in order — the same ones appended to that\n * attempt's file, so a surface folding these and one replaying the file\n * draw the same blocks. Terminal-transport tasks send none.\n */\n | { type: 'task_log'; taskId: string; attempt: number; events: TaskLogEvent[] }\n // A run did not start because tracked files are modified. It waits for the\n // user to stash (`continueWithStash`) or to run without isolation this once\n // (`continueWithoutIsolation`); nothing is spawned until then. `repos` names\n // the dirty repos of a group; a group of one names none.\n | { type: 'isolation_blocked'; reason: 'dirty'; repos?: string[]; message: string }\n // An isolated run settled: for each repo, the branch its work landed on and\n // the commit that branch forked from; and what landed, in plan order. Sent\n // before `execution_complete`, which surfaces treat as the end of the stream.\n | { type: 'isolation_handoff'; repos: IsolationHandoff['repos']; landed: IsolationHandoff['landed'] }\n // What \"Merge all\" did, for every surface watching rather than only the one\n // that asked: merged, blocked with each repo and why, or stopped part-way\n // with the repos that stay merged.\n | { type: 'isolation_merge'; result: IsolationMergeResult }\n // Carries no content — see `ResearchProgress['liveness']`. Exists only so a\n // surface's idle watchdog sees the harness process working even during a\n // stretch that produces nothing visible.\n | { type: 'planner_liveness' }\n // `toolLabel` carries a harness planner's own name for the tool (ADR-0009) —\n // always set when `tool` is `agent_tool`, so no surface has to render the\n // catch-all member name at the user.\n | { type: 'research_step'; tool: string; toolLabel?: string; args: string; subagentId?: string; toolCallId?: string; turnId?: string }\n // The \"building plan\" display only: a JSON envelope as it streams, never\n // reply prose. `turnId` is absent for a one-shot plan, which has no turn.\n // `segmentId` names the segment the envelope streams in; a turn's next\n // envelope is a new segment, and the display starts over with it.\n | { type: 'plan_token'; token: string; turnId?: string; segmentId?: string }\n | { type: 'research_step_done'; step: ResearchStep; subagentId?: string; turnId?: string }\n // Planner research wants something outside its default envelope and is\n // blocked until a human answers. Broadcast rather than returned, because the\n // human may be on any surface (or several at once) and the request outlives\n // whichever HTTP call triggered it.\n | { type: 'approval_request'; id: string; kind: ApprovalKind; subject: string; scope: string; detail?: string; turnId?: string }\n | { type: 'approval_settled'; id: string; granted: boolean }\n // A decision reached with no round-trip prompt: pre-approved via config,\n // remembered from earlier in this session, or the operator's mode floor\n // (allow/deny skipping the human entirely). The interactive path above\n // already has full visibility via approval_request/approval_settled; this\n // is the one that previously had none — a model silently auto-running\n // `npm test` because the scope was already granted looked identical, from\n // every UI, to it never having been asked in the first place.\n | {\n type: 'approval_decided';\n kind: ApprovalKind;\n subject: string;\n scope: string;\n detail?: string;\n granted: boolean;\n source: Exclude<ApprovalSource, 'asked'>;\n };\n\n/**\n * A line a run wants the user to read — how it isolates, what it shares. Not a\n * {@link SessionMessage}: hosts that show notices as toasts already do, and\n * widening the union would break every exhaustive switch over it. A host with\n * no toast channel (the daemon) hands these to its clients by its own means.\n */\nexport type SessionNotice = { type: 'notice'; level: 'info' | 'warn' | 'error'; message: string };\n\nexport type SessionBroadcaster = (msg: SessionMessage) => void;\n\nexport function serializeTask(t: Task): SerializedTask {\n return {\n id: t.id,\n order: t.order,\n title: t.title,\n type: t.type,\n description: t.description,\n dependencies: t.dependencies || [],\n assignedRunner: t.assignedRunner,\n assignedModel: t.assignedModel || null,\n taskMode: t.taskMode || 'build',\n prompt: t.prompt || null,\n subtasks: (t.subtasks || []).map(serializeTask),\n userSteps: t.userSteps || undefined,\n thinkingEffort: t.thinkingEffort || undefined,\n autonomy: t.autonomy || undefined,\n sliceType: t.sliceType || undefined,\n userStoriesCovered: t.userStoriesCovered || undefined,\n ...(t.ops ? { ops: true as const } : {}),\n };\n}\n\nexport function serializeTaskStatus(\n t: Task,\n idleSince: string | null = null,\n isolation: TaskIsolation | null = null,\n queued: readonly QueuedTaskMessage[] = [],\n awaitingApproval = 0,\n mergeGate: readonly string[] = [],\n): SerializedTaskStatus {\n return {\n id: t.id,\n status: t.status,\n verdict: t.verdict\n ? { outcome: t.verdict.outcome, reason: t.verdict.reason, checks: t.verdict.checks || [] }\n : null,\n idleSince,\n ...(isolation ? { isolation } : {}),\n ...(t.transport ? { transport: t.transport.fallback ? { kind: t.transport.kind, fallback: t.transport.fallback } : { kind: t.transport.kind } } : {}),\n ...(t.status === 'awaiting_user' && t.awaitingReason ? { awaitingReason: t.awaitingReason } : {}),\n ...(queued.length > 0 ? { queued: queued.map((m) => ({ ...m })) } : {}),\n ...(canContinue(t) ? { continuable: true as const } : {}),\n ...(awaitingApproval > 0 ? { awaitingApproval } : {}),\n ...(mergeGate.length > 0 ? { mergeGate: [...mergeGate] } : {}),\n ...(t.forcedPastGate?.length ? { forcedPastGate: [...t.forcedPastGate] } : {}),\n };\n}\n\nexport function serializePlan(plan: LegacyPlanState): SerializedPlan {\n return {\n tasks: plan.tasks.map(serializeTask),\n runners: plan.runners,\n generatedAt: plan.generatedAt,\n conversationHistory: plan.conversationHistory,\n prdMarkdown: plan.prdMarkdown,\n queuedMessages: plan.queuedMessages,\n };\n}\n\nexport function executionSummary(tasks: readonly Task[]): { total: number; completed: number; failed: number } {\n return {\n total: tasks.length,\n completed: tasks.filter((t) => t.status === 'completed').length,\n failed: tasks.filter((t) => t.status === 'failed').length,\n };\n}\n\nexport const CHECKPOINT_TRUNCATE_LENGTH = 120;\n\n/** Truncate a checkpoint summary to a single line of at most CHECKPOINT_TRUNCATE_LENGTH chars. */\nexport function truncateCheckpointSummary(summary: string): string {\n // Take the first line only (checkpoint summaries often contain reasoning across lines)\n const firstLine = summary.split('\\n')[0].trim();\n if (firstLine.length <= CHECKPOINT_TRUNCATE_LENGTH) return firstLine;\n return firstLine.slice(0, CHECKPOINT_TRUNCATE_LENGTH - 1) + '…';\n}\n","import type { ResearchStep } from '../models/Task';\nimport type { SessionMessage } from '../services/SessionMessage';\nimport { isMeasured } from '../models/Usage';\nimport type { DisplayBlock, MessageBlock, PlanBlock, ToolBlock } from './blocks';\nimport { pendingTool, planMarker, settledMessage, settledTool, toolFromStep } from './records';\nimport {\n append, appendOutput, closeOpenBlocks, findLastIndex, laneBlocks, laneOf, laneAppend, laneReplace, replaceAt, sealLane, sealed, setUsageLine,\n think, updateSubagent, type BlockList,\n} from './lanes';\n\n/**\n * A line a surface adds to the conversation itself rather than receiving from\n * the session: the user's prompt as it is sent, a notice, an error.\n */\nexport interface LocalEntry {\n type: 'local_entry';\n role: 'user' | 'system' | 'error';\n text: string;\n}\n\nexport type ConversationInput = SessionMessage | LocalEntry;\n\nexport interface ConversationView extends BlockList {\n /**\n * The newest transcript entry the view accounts for. Plan markers and system\n * notes reach a surface only inside the transcript a `plan_generated`\n * carries, so entries after this one are what is new in it.\n */\n readonly transcriptAt?: string;\n}\n\nexport const EMPTY_CONVERSATION: ConversationView = { blocks: [], nextId: 1 };\n\ntype Message<T extends SessionMessage['type']> = Extract<SessionMessage, { type: T }>;\n\nfunction isUnsettledSegment(block: DisplayBlock, turnId: string): block is MessageBlock {\n return block.type === 'message' && block.turnId === turnId && block.segmentId !== undefined;\n}\n\nfunction isBuildingPlan(block: DisplayBlock, turnId: string | undefined): block is PlanBlock {\n return block.type === 'plan' && block.status === 'building' && block.turnId === turnId;\n}\n\n/**\n * Where the turn's final segment is, if its text streamed: the turn's latest\n * block, when that is streamed text. Anything the turn did after a segment —\n * a tool call, a plan envelope — means a later segment follows it, and a later\n * segment never rewrites an earlier one. `pastPlan` looks past the turn's plan\n * block, for a plan that settled after its own text.\n */\nfunction finalSegmentIndex(blocks: readonly DisplayBlock[], turnId: string, pastPlan = false): number {\n for (let i = blocks.length - 1; i >= 0; i--) {\n const block = blocks[i];\n if (block.type === 'usage' || block.type === 'thinking' || block.type === 'approval' || (pastPlan && block.type === 'plan')) continue;\n if (block.turnId !== turnId) continue;\n return isUnsettledSegment(block, turnId) ? i : -1;\n }\n return -1;\n}\n\nfunction openTurn(view: ConversationView, turnId: string, prompt: string): ConversationView {\n // A surface shows its user's prompt the moment it is sent; the turn that\n // answers it adopts that line rather than repeating it.\n const i = findLastIndex(view.blocks, (b) => b.type === 'message' && b.role === 'user');\n const sent = view.blocks[i];\n if (sent?.type === 'message' && sent.turnId === undefined && sent.text === prompt) {\n return { ...view, blocks: replaceAt(view.blocks, i, { ...sent, turnId }) };\n }\n return append(view, (id) => settledMessage(id, 'user', prompt, turnId));\n}\n\nfunction streamText(view: ConversationView, { turnId, segmentId, text }: Message<'planner_text_delta'>): ConversationView {\n const i = findLastIndex(view.blocks, (b) => isUnsettledSegment(b, turnId) && b.segmentId === segmentId);\n const segment = view.blocks[i];\n if (segment?.type === 'message') {\n return sealLane(laneReplace(view, null, i, { ...segment, text: segment.text + text, streaming: true }), null, i);\n }\n return appendOutput(view, null, (id) => ({ type: 'message', id, role: 'planner', text, streaming: true, turnId, segmentId }));\n}\n\n/**\n * Drop the turn's plan display while it is still building: whatever streamed\n * there did not become a plan — a task-ops or task-query envelope, or, from a\n * daemon older than turns, the reply's prose.\n */\nfunction dropBuildingPlan(view: ConversationView, turnId: string | undefined, segmentId?: string): ConversationView {\n const blocks = view.blocks.filter((b) => !(isBuildingPlan(b, turnId) && (segmentId === undefined || b.segmentId === segmentId)));\n return blocks.length === view.blocks.length ? view : { ...view, blocks };\n}\n\nfunction settleReply(view: ConversationView, { content, turnId }: Message<'planner_message'>): ConversationView {\n if (turnId !== undefined) {\n const i = finalSegmentIndex(view.blocks, turnId);\n if (i >= 0) {\n return dropBuildingPlan({ ...view, blocks: replaceAt(view.blocks, i, settledMessage(view.blocks[i].id, 'planner', content, turnId)) }, turnId);\n }\n }\n return append(dropBuildingPlan(view, turnId), (id) => settledMessage(id, 'planner', content, turnId));\n}\n\n// A retracted envelope takes the turn's plan display with it, or its retry\n// would build on the botched JSON and the partial-plan rows read both.\nfunction retractText(view: ConversationView, { turnId, segmentId }: Message<'planner_text_retracted'>): ConversationView {\n const blocks = view.blocks.filter((b) => !(isUnsettledSegment(b, turnId) && (segmentId === undefined || b.segmentId === segmentId)));\n return dropBuildingPlan(blocks.length === view.blocks.length ? view : { ...view, blocks }, turnId, segmentId);\n}\n\nfunction startSubagent(view: ConversationView, { subagentId, brief, model, turnId }: Message<'subagent_started'>): ConversationView {\n return updateSubagent(view, subagentId, turnId, (block) => ({ ...block, ...(brief ? { brief } : {}), ...(model ? { model } : {}) }));\n}\n\nfunction finishSubagent(view: ConversationView, { subagentId, outcome, digest, usage, turnId }: Message<'subagent_finished'>): ConversationView {\n return updateSubagent(view, subagentId, turnId, (block) => ({\n ...block, status: outcome, digest, children: block.children.map(sealed), ...(usage ? { usage } : {}),\n }));\n}\n\nfunction announceTool(view: ConversationView, call: Message<'research_step'>): ConversationView {\n // A spawn call names the subagent it starts; any other call tagged with a\n // subagent is that subagent's own.\n const spawns = call.tool === 'spawn_research_agent' ? call.subagentId : undefined;\n const [placed, lane] = laneOf(view, spawns ? undefined : call.subagentId, call.turnId);\n return appendOutput(placed, lane, (id) => ({ ...pendingTool(id, call), ...(spawns ? { spawns } : {}) }));\n}\n\n// By the call's id: results of a parallel round return in any order, and a\n// name match would put one call's output on another's row (ADR-0008). The\n// name scan survives only for calls that announced no id.\nfunction isPendingCallOf(block: DisplayBlock, step: ResearchStep): block is ToolBlock {\n if (block.type !== 'tool' || block.status !== 'pending') return false;\n return step.toolCallId ? block.toolCallId === step.toolCallId : block.toolCallId === undefined && block.tool === step.tool;\n}\n\nfunction settleTool(view: ConversationView, { step, turnId }: Message<'research_step_done'>): ConversationView {\n const [placed, lane] = laneOf(view, step.subagentId, turnId);\n const blocks = laneBlocks(placed, lane);\n const i = findLastIndex(blocks, (b) => isPendingCallOf(b, step));\n const pending = blocks[i];\n if (pending?.type === 'tool') return laneReplace(placed, lane, i, settledTool(pending, step));\n // The call that spawned a subagent is shown by the subagent's block, and\n // only the subagent's own finish settles it: a backgrounded agent's call\n // returns at launch, long before the work ends.\n if (lane === null && step.toolCallId && blocks.some((b) => b.type === 'subagent' && b.toolCallId === step.toolCallId)) return view;\n return laneAppend(placed, lane, (id) => toolFromStep(id, step, turnId));\n}\n\n/**\n * The building display shows one envelope: the segment streaming now. A turn's\n * later envelope (a plan after a read it asked for) starts it over, below\n * whatever the turn did in between, rather than running on from the last one.\n */\nfunction streamPlan(view: ConversationView, { token, turnId, segmentId }: Message<'plan_token'>): ConversationView {\n const i = findLastIndex(view.blocks, (b) => isBuildingPlan(b, turnId));\n const building = view.blocks[i];\n if (building?.type === 'plan' && building.segmentId === segmentId) {\n return { ...view, blocks: replaceAt(view.blocks, i, { ...building, text: building.text + token }) };\n }\n return append(dropBuildingPlan(view, turnId), (id) => ({\n type: 'plan', id, status: 'building', text: token, ...(turnId ? { turnId } : {}), ...(segmentId ? { segmentId } : {}),\n }));\n}\n\n/** A plan landed: the building display of the turn that committed it becomes its marker. */\nfunction markPlan(view: ConversationView, content: string, turnId: string | undefined): ConversationView {\n const marker = planMarker(content);\n const i = findLastIndex(view.blocks, (b) => isBuildingPlan(b, turnId));\n const building = view.blocks[i];\n if (building?.type === 'plan') {\n const settled: PlanBlock = { type: 'plan', id: building.id, ...marker, text: '', ...(building.turnId ? { turnId: building.turnId } : {}) };\n return { ...view, blocks: replaceAt(view.blocks, i, settled) };\n }\n return append(view, (id) => ({ type: 'plan', id, text: '', ...marker }));\n}\n\nfunction requestApproval(view: ConversationView, { id: approvalId, kind, subject, scope, detail, turnId }: Message<'approval_request'>): ConversationView {\n return append(view, (id) => ({\n type: 'approval', id, approvalId, kind, subject, scope, status: 'pending',\n ...(detail ? { detail } : {}),\n ...(turnId ? { turnId } : {}),\n }));\n}\n\nfunction settleApproval(view: ConversationView, { id, granted }: Message<'approval_settled'>): ConversationView {\n const i = findLastIndex(view.blocks, (b) => b.type === 'approval' && b.approvalId === id);\n const request = view.blocks[i];\n if (request?.type !== 'approval') return view;\n return { ...view, blocks: replaceAt(view.blocks, i, { ...request, status: granted ? 'granted' : 'denied', decidedBy: 'asked' }) };\n}\n\nfunction decideApproval(view: ConversationView, { kind, subject, scope, detail, granted, source }: Message<'approval_decided'>): ConversationView {\n return append(view, (id) => ({\n type: 'approval', id, kind, subject, scope, status: granted ? 'granted' : 'denied', decidedBy: source,\n ...(detail ? { detail } : {}),\n }));\n}\n\nfunction reportUsage(view: ConversationView, message: Message<'planner_usage'>): ConversationView {\n return isMeasured(message.totals) ? setUsageLine(view, message) : view;\n}\n\n/**\n * Nothing carries the turn's id after this, so whatever it left open is closed:\n * streaming stops, and on a stop or failure its unanswered calls and running\n * subagents say they were cut short. A plan reply that streamed as text (a\n * prose preamble decides a segment's route) gives way to its plan block, as a\n * settled message would have replaced it.\n */\nfunction endTurn(view: ConversationView, { turnId, outcome }: Message<'planner_turn_ended'>): ConversationView {\n let next = dropBuildingPlan(view, turnId);\n const planText = outcome === 'plan' ? finalSegmentIndex(next.blocks, turnId, true) : -1;\n if (planText >= 0) next = { ...next, blocks: next.blocks.filter((_, i) => i !== planText) };\n return closeOpenBlocks(next, outcome === 'stopped' ? 'stopped' : outcome === 'error' ? 'failed' : null);\n}\n\n// The summary is announced as a planner message before the transcript it now\n// heads arrives; the transcript records it as a notice, and so does the view.\nfunction markCompaction(view: ConversationView, summary: string): ConversationView {\n const i = findLastIndex(view.blocks, (b) => b.type === 'message' && b.role === 'planner' && b.turnId === undefined && b.text === summary);\n const announced = view.blocks[i];\n if (announced?.type === 'message') return { ...view, blocks: replaceAt(view.blocks, i, { ...announced, role: 'system' }) };\n return append(view, (id) => settledMessage(id, 'system', summary));\n}\n\nfunction syncTranscript(view: ConversationView, { plan, turnId }: Message<'plan_generated'>): ConversationView {\n const history = plan.conversationHistory ?? [];\n // Only the newest marker can be the committing turn's; older ones a surface\n // is only now catching up on belong to turns long over.\n const committed = findLastIndex(history, (e) => e.kind === 'plan_generated');\n let next = view;\n let latest = view.transcriptAt;\n for (const [i, entry] of history.entries()) {\n const isNew = view.transcriptAt === undefined || entry.timestamp > view.transcriptAt;\n if (isNew && entry.kind === 'plan_generated') next = markPlan(next, entry.content, i === committed ? turnId : undefined);\n if (isNew && entry.kind === 'system') next = append(next, (id) => settledMessage(id, 'system', entry.content));\n if (isNew && entry.kind === 'compaction') next = markCompaction(next, entry.content);\n if (latest === undefined || entry.timestamp > latest) latest = entry.timestamp;\n }\n return next === view && latest === view.transcriptAt ? view : { ...next, transcriptAt: latest };\n}\n\n/**\n * Fold one input into the view. Pure and incremental: blocks the input does\n * not touch keep their identity, and an input that changes nothing returns\n * `view` itself — surfaces memoize their drawing on that, and text deltas\n * arrive quickly.\n */\nexport function reduceConversation(view: ConversationView, input: ConversationInput): ConversationView {\n switch (input.type) {\n case 'local_entry':\n return append(view, (id) => settledMessage(id, input.role, input.text));\n case 'planner_turn_started':\n return input.prompt === undefined ? view : openTurn(view, input.turnId, input.prompt);\n case 'planner_text_delta':\n return streamText(view, input);\n case 'planner_message':\n return settleReply(view, input);\n case 'planner_text_retracted':\n return retractText(view, input);\n case 'planner_thinking_delta':\n return think(view, input.text, input.turnId, input.segmentId, input.subagentId);\n case 'research_step':\n return announceTool(view, input);\n case 'research_step_done':\n return settleTool(view, input);\n case 'subagent_started':\n return startSubagent(view, input);\n case 'subagent_finished':\n return finishSubagent(view, input);\n case 'plan_token':\n return streamPlan(view, input);\n case 'plan_generated':\n return syncTranscript(view, input);\n case 'planner_turn_ended':\n return endTurn(view, input);\n case 'approval_request':\n return requestApproval(view, input);\n case 'approval_settled':\n return settleApproval(view, input);\n case 'approval_decided':\n return decideApproval(view, input);\n case 'planner_usage':\n return reportUsage(view, input);\n default:\n return view;\n }\n}\n","import type { ConversationMessage, ResearchLogEntry, ResearchStep, SubagentLogEntry } from '../models/Task';\nimport { isMeasured, usageLine, type PlannerUsage } from '../models/Usage';\nimport type { DisplayBlock } from './blocks';\nimport { planMarker, settledMessage, subagentBlock, toolFromStep, usageBlock } from './records';\nimport type { ConversationView } from './reduce';\n\n/** One top-level block before it has an id, and where it falls in time. */\ninterface Placed {\n at: string;\n /** Breaks a tie in `at`: a user's message, then the research it caused, then what the turn settled on. */\n rank: number;\n build: (nextId: () => string) => DisplayBlock;\n}\n\nconst USER = 0;\nconst RESEARCH = 1;\nconst SETTLED = 2;\n\nfunction fromEntry(entry: ConversationMessage): Placed['build'] {\n if (entry.kind === 'plan_generated') return (id) => ({ type: 'plan', id: id(), text: '', ...planMarker(entry.content) });\n const role = entry.kind === 'system' || entry.kind === 'compaction' ? 'system' : entry.role === 'user' ? 'user' : 'planner';\n return (id) => settledMessage(id(), role, entry.content);\n}\n\nfunction spawnBrief(step: ResearchStep): string | undefined {\n try {\n const args: unknown = JSON.parse(step.args);\n const prompt = args && typeof args === 'object' ? (args as Record<string, unknown>).prompt : undefined;\n return typeof prompt === 'string' ? prompt.trim() : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Which subagent a planner step started, if it did. The log keeps no link: a\n * harness planner's subagent takes its call's id, and an ADR-0005 research\n * agent is briefed with its spawn call's prompt, trimmed.\n */\nfunction spawnedBy(step: ResearchStep, unclaimed: SubagentLogEntry[]): SubagentLogEntry | undefined {\n const byId = unclaimed.find((e) => e.subagentId === step.toolCallId);\n if (byId) return byId;\n if (step.tool !== 'spawn_research_agent') return undefined;\n const brief = spawnBrief(step);\n return brief === undefined ? undefined : unclaimed.find((e) => e.brief === brief);\n}\n\nfunction research(log: readonly ResearchLogEntry[]): Placed[] {\n const subagents = log.filter((e): e is SubagentLogEntry => 'type' in e && e.type === 'subagent');\n const ownSubagent = new Set(subagents.map((e) => e.subagentId));\n const unclaimed = [...subagents];\n const spawnCall = new Map<string, string | undefined>();\n const placed: Placed[] = [];\n\n for (const entry of log) {\n if ('type' in entry) {\n if (entry.type === 'system') placed.push({ at: entry.timestamp, rank: RESEARCH, build: (id) => settledMessage(id(), 'system', entry.content) });\n continue;\n }\n if (entry.subagentId && ownSubagent.has(entry.subagentId)) continue;\n const spawned = spawnedBy(entry, unclaimed);\n if (spawned) {\n unclaimed.splice(unclaimed.indexOf(spawned), 1);\n spawnCall.set(spawned.subagentId, entry.toolCallId);\n continue;\n }\n placed.push({ at: entry.timestamp, rank: RESEARCH, build: (id) => toolFromStep(id(), entry) });\n }\n\n // A subagent stands where it started, which is where its spawn call was\n // announced; the call's own record is written only once the subagent is done.\n for (const entry of subagents) {\n const toolCallId = spawnCall.get(entry.subagentId);\n const steps = log.filter((e): e is ResearchStep => !('type' in e) && e.subagentId === entry.subagentId);\n placed.push({\n at: entry.timestamp,\n rank: RESEARCH,\n build: (id) => subagentBlock(id(), {\n subagentId: entry.subagentId, brief: entry.brief, status: entry.outcome, digest: entry.digest,\n children: steps.map((step) => toolFromStep(id(), step)),\n toolCallId, model: entry.model, usage: entry.usage,\n }),\n });\n }\n return placed;\n}\n\n/**\n * The view a saved session reopens with: what its transcript and research log\n * kept, in the order it happened — messages, notices and the compaction\n * summary, plan markers, tool calls with each subagent's calls nested under\n * it, and the token line. Reasoning and streamed text were never saved, so a\n * reload has none.\n *\n * The research log interleaves with the transcript by time. Entries older than\n * a compaction's first kept message went with the turns it condensed.\n */\nexport function fromTranscript(\n conversationHistory: readonly ConversationMessage[] | undefined,\n researchLog: readonly ResearchLogEntry[] | undefined,\n plannerUsage?: PlannerUsage,\n): ConversationView {\n const history = conversationHistory ?? [];\n const compacted = history[0]?.kind === 'compaction' ? history[0] : undefined;\n const kept = compacted ? history.slice(1) : history;\n const cutoff = compacted ? (kept[0]?.timestamp ?? compacted.timestamp) : '';\n\n const placed: Placed[] = [\n ...kept.map((entry) => ({ at: entry.timestamp, rank: entry.role === 'user' && !entry.kind ? USER : SETTLED, build: fromEntry(entry) })),\n ...research(researchLog ?? []).filter((item) => item.at >= cutoff),\n ];\n placed.sort((a, b) => (a.at < b.at ? -1 : a.at > b.at ? 1 : a.rank - b.rank));\n // The summary stands where the condensed turns were, ahead of everything kept.\n if (compacted) placed.unshift({ at: '', rank: SETTLED, build: fromEntry(compacted) });\n\n let nextId = 1;\n const id = () => `b${nextId++}`;\n const blocks = placed.map((item) => item.build(id));\n\n if (plannerUsage && isMeasured(plannerUsage.totals)) blocks.push(usageBlock(id(), usageLine(plannerUsage)));\n\n const transcriptAt = history.reduce<string | undefined>((latest, e) => (latest === undefined || e.timestamp > latest ? e.timestamp : latest), undefined);\n return { blocks, nextId, ...(transcriptAt ? { transcriptAt } : {}) };\n}\n","/**\n * Prompts the user sent while a planner turn was in flight, waiting to be the\n * next turn's input. The hold is a plain immutable list, oldest first, so a\n * pure reducer can keep it in state and a host can keep it in a field — and\n * either can draw it as is.\n */\nexport type PromptHold = readonly string[];\n\nexport const EMPTY_HOLD: PromptHold = [];\n\n/** One prompt taken out of the hold, and what is left behind. */\nexport interface TakenPrompt {\n text: string;\n rest: PromptHold;\n}\n\nexport function holdPrompt(hold: PromptHold, text: string): PromptHold {\n return [...hold, text];\n}\n\n/** The prompt a settled turn sends next: the oldest, so they go in the order typed. */\nexport function drainNext(hold: PromptHold): TakenPrompt | undefined {\n const [text, ...rest] = hold;\n return text === undefined ? undefined : { text, rest };\n}\n\n/**\n * Takes back the newest prompt — the one the user most likely just regretted —\n * while the older ones stay queued behind the turn.\n */\nexport function unsendLatest(hold: PromptHold): TakenPrompt | undefined {\n if (hold.length === 0) return undefined;\n return { text: hold[hold.length - 1], rest: hold.slice(0, -1) };\n}\n\n/**\n * A stopped turn takes its queue with it: the prompts were written against a\n * turn that no longer exists, so they come back as one draft to edit and\n * resend rather than firing off after the stop.\n */\nexport function unsendAll(hold: PromptHold): TakenPrompt | undefined {\n if (hold.length === 0) return undefined;\n return { text: hold.join('\\n'), rest: EMPTY_HOLD };\n}\n\n/** Where an unsent prompt lands in the drafting input: above what is being typed, never replacing it. */\nexport function aheadOfDraft(text: string, draft: string): string {\n return draft ? `${text}\\n${draft}` : text;\n}\n","import type { SessionMessage } from '../services/SessionMessage';\nimport { reduceConversation, type ConversationInput, type ConversationView } from './reduce';\n\n/**\n * The planner turn a surface has open, and the one its user stopped. Kept\n * beside the view rather than in it: the view is what a turn drew, this is\n * whether the surface still wants to hear from it.\n */\nexport interface TurnGate {\n readonly open: string | null;\n readonly stopped: string | null;\n}\n\nexport const NO_TURN: TurnGate = { open: null, stopped: null };\n\nexport interface GatedConversation {\n view: ConversationView;\n gate: TurnGate;\n}\n\n/** What a turn streams — everything a stop cuts off. Usage, approvals and transcript markers are facts and still land. */\nconst TURN_STREAM = new Set<SessionMessage['type']>([\n 'planner_text_delta', 'planner_thinking_delta', 'planner_text_retracted', 'planner_message', 'plan_token',\n 'research_step', 'research_step_done', 'subagent_started', 'subagent_finished', 'planner_turn_ended',\n]);\n\n// A message with no turn id while a stop stands can only be the stopped\n// turn's: a new turn announces itself first, and that lifts the stop.\nfunction cutOff(gate: TurnGate, input: ConversationInput): boolean {\n if (gate.stopped === null || !TURN_STREAM.has(input.type as SessionMessage['type'])) return false;\n const turnId = 'turnId' in input ? input.turnId : undefined;\n return turnId === undefined || turnId === gate.stopped;\n}\n\nfunction withGate(live: GatedConversation, gate: TurnGate): GatedConversation {\n return gate.open === live.gate.open && gate.stopped === live.gate.stopped ? live : { ...live, gate };\n}\n\n/**\n * One input into the view, the stop rule applied: a turn the user stopped is\n * over on screen, and whatever it streams until the backend notices is\n * dropped. An input that changes nothing hands back the same view and gate.\n */\nexport function followTurn(view: ConversationView, gate: TurnGate, input: ConversationInput): GatedConversation {\n const live = { view, gate };\n if (input.type === 'planner_turn_started') {\n return withGate({ view: reduceConversation(view, input), gate }, { open: input.turnId, stopped: null });\n }\n if (cutOff(gate, input)) {\n return input.type === 'planner_turn_ended' ? withGate(live, { ...gate, stopped: null }) : live;\n }\n const next = { view: reduceConversation(view, input), gate };\n return input.type === 'planner_turn_ended' && input.turnId === gate.open ? withGate(next, { ...gate, open: null }) : next;\n}\n\n/**\n * The user stopped the planner. The turn ends on screen now rather than when\n * the backend notices the abort, so the surface is free at once and the\n * turn's late output never lands. Nothing changes when no turn is open.\n */\nexport function stopTurn(view: ConversationView, gate: TurnGate): GatedConversation {\n if (gate.open === null) return { view, gate };\n return {\n view: reduceConversation(view, { type: 'planner_turn_ended', turnId: gate.open, outcome: 'stopped' }),\n gate: { open: null, stopped: gate.open },\n };\n}\n","import type { DisplayBlock } from './blocks';\n\n/**\n * Whether the conversation holds anything the collapsed view hides — thinking,\n * a command row's arguments and output, a subagent's children and digest. The\n * detail toggle is the only expansion control (ADR-0017, X1), so a surface\n * offers it only when it would do something.\n */\nexport function hasHiddenDetail(blocks: readonly DisplayBlock[]): boolean {\n return blocks.some((b) => b.type === 'thinking' || b.type === 'tool' || b.type === 'subagent');\n}\n","/** The conversation line for a task starting, worded the same on every surface. */\nexport function taskStartedNotice(title: string, runner?: string): string {\n return runner ? `Started \"${title}\" · ${runner}` : `Started \"${title}\"`;\n}\n"],"mappings":"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","names":["text","text","text","text","parseArgs","text","text","oneLine","text","startSubagent","finishSubagent","announceTool","settleTool","requestApproval","settleApproval","decideApproval","reportUsage","endTurn","text"]}
|