@buildaharness/aielia 0.3.1 → 0.3.3

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.
Files changed (71) hide show
  1. package/README.md +31 -8
  2. package/dist/agent-loop.d.ts +8 -8
  3. package/dist/ask-clarification-service.d.ts +1 -1
  4. package/dist/ask-mode-flag.d.ts +1 -1
  5. package/dist/assistant-session.d.ts +1 -1
  6. package/dist/assistant-types.d.ts +3 -3
  7. package/dist/assistant.d.ts +12 -12
  8. package/dist/batch-research-fixtures.d.ts +1 -1
  9. package/dist/benchmark-injected-failure.d.ts +1 -1
  10. package/dist/bin-Btzhiyzi.js +2108 -0
  11. package/dist/bin-Btzhiyzi.js.map +1 -0
  12. package/dist/bin-sea-bootstrap.d.ts +1 -0
  13. package/dist/bin.d.ts +1 -0
  14. package/dist/claude-cli-llm-client.d.ts +2 -2
  15. package/dist/cli-args.d.ts +20 -0
  16. package/dist/cli-icons.d.ts +28 -0
  17. package/dist/{cli-session-D0uLdT2A.js → cli-session-DnSc6Hhx.js} +607 -127
  18. package/dist/cli-session-DnSc6Hhx.js.map +1 -0
  19. package/dist/cli.d.ts +31 -1
  20. package/dist/cli.js +1 -1691
  21. package/dist/cli.js.map +1 -1
  22. package/dist/config.d.ts +14 -6
  23. package/dist/contradiction-checker.d.ts +1 -1
  24. package/dist/diff-format.d.ts +16 -0
  25. package/dist/execution-mode.d.ts +1 -1
  26. package/dist/fact-extraction.d.ts +4 -4
  27. package/dist/failure-mode-matcher.d.ts +1 -1
  28. package/dist/file-tools-mcp-server.mjs +2 -2
  29. package/dist/file-tools.d.ts +10 -2
  30. package/dist/harness-bridge.d.ts +21 -4
  31. package/dist/index.js +68 -68
  32. package/dist/index.js.map +1 -1
  33. package/dist/ink-select-prompt.d.ts +21 -0
  34. package/dist/markdown-line.d.ts +42 -0
  35. package/dist/mcp-server-asset.d.ts +24 -0
  36. package/dist/memory-service.d.ts +12 -2
  37. package/dist/network-containment.d.ts +1 -1
  38. package/dist/node-display-names.d.ts +1 -1
  39. package/dist/one-loop-flag.d.ts +1 -1
  40. package/dist/plan-drafting-service.d.ts +1 -1
  41. package/dist/plan-drafting.d.ts +4 -4
  42. package/dist/plan-mode-flag.d.ts +1 -1
  43. package/dist/plan-sketch-service.d.ts +1 -1
  44. package/dist/plan-sketch.d.ts +1 -1
  45. package/dist/plan-store.d.ts +2 -2
  46. package/dist/plan-templates/index.d.ts +1 -1
  47. package/dist/plan-verification.d.ts +1 -1
  48. package/dist/review-checker.d.ts +10 -0
  49. package/dist/scripted-llm-client.d.ts +1 -1
  50. package/dist/sea-cache.d.ts +9 -0
  51. package/dist/self-update.d.ts +101 -0
  52. package/dist/semantic-criterion-coverage.d.ts +10 -0
  53. package/dist/shell-tools.d.ts +1 -1
  54. package/dist/spike.js.map +1 -1
  55. package/dist/tool-control-plane.d.ts +1 -1
  56. package/dist/tool-policy.d.ts +1 -1
  57. package/dist/tool-step.d.ts +10 -0
  58. package/dist/trace-events.d.ts +5 -5
  59. package/dist/trust-tagging.d.ts +1 -1
  60. package/dist/{tui-app-DxLPSGh2.js → tui-app-CFfOP2DC.js} +176 -20
  61. package/dist/tui-app-CFfOP2DC.js.map +1 -0
  62. package/dist/tui-app.d.ts +34 -9
  63. package/dist/tui-mode-flag.d.ts +1 -1
  64. package/dist/turn-intent-classifier.d.ts +5 -5
  65. package/dist/turn-interpreter.d.ts +12 -0
  66. package/dist/turn-policy.d.ts +1 -1
  67. package/dist/update-check-flag.d.ts +11 -0
  68. package/dist/version.d.ts +6 -0
  69. package/package.json +7 -3
  70. package/dist/cli-session-D0uLdT2A.js.map +0 -1
  71. package/dist/tui-app-DxLPSGh2.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"tui-app-DxLPSGh2.js","sources":["../src/tui-output-capture.ts","../src/tui-input.tsx","../src/tui-app.tsx"],"sourcesContent":["import { format } from 'node:util'\n\n/**\n * One classified write, mirroring the three writer patterns `cli.ts` already uses (see that\n * file's `writeProgress`/`clearProgress`, `writeToolStep`, `writeToken`) — not a new convention,\n * just naming what's already there so Phase 3's Ink shell can route each kind to the right\n * region (transient status line, transient streamed-reply buffer, permanent scrollback).\n */\nexport type CaptureEvent =\n | {\n /** `writeProgress`'s `\\r`-overwritten step counter, or `clearProgress`'s blank-out of it. */\n type: 'progress'\n /** The current progress text with the `\\r` control character and `padEnd` filler removed — `''` once cleared. */\n text: string\n }\n | {\n /** `writeToken`'s raw incremental streamed characters — no trailing newline until the turn ends. */\n type: 'token'\n text: string\n }\n | {\n /** A `console.log`/`console.error` call, or any write that completes with a trailing newline — one or more committed, permanently-scrolled lines. */\n type: 'line'\n lines: string[]\n /** Which global function produced this — `'stderr'` only for `console.error`, everything else (`console.log`, raw `process.stdout.write`) is `'stdout'`. Lets a consumer (Phase 3's `EventLogBridge`) style error output distinctly without guessing from content. */\n stream: 'stdout' | 'stderr'\n }\n\n/**\n * Classifies a single already-formatted write exactly the way the three writer patterns in\n * `cli.ts` are told apart from each other (see this file's `CaptureEvent` doc comment): a\n * leading `\\r` means progress, a trailing `\\n` means one or more committed lines, and everything\n * else (streamed reply tokens — the only writer left that produces neither) is a token.\n */\nfunction classify(raw: string, stream: 'stdout' | 'stderr'): CaptureEvent {\n if (raw.startsWith('\\r')) {\n // `padEnd`'s filler spaces exist only to overwrite a longer previous line on a real\n // terminal — Ink re-renders the whole frame every time, so that artifact would just show up\n // as trailing whitespace with no purpose. `clearProgress`'s `\\r${spaces}\\r` collapses to ''.\n return { type: 'progress', text: raw.replace(/\\r/g, '').trimEnd() }\n }\n if (raw.endsWith('\\n')) {\n // Drop only the one trailing empty element `split` produces because the string itself ends\n // in '\\n' — any other blank lines in the middle (e.g. a call site's own leading/trailing\n // '\\n' for spacing) are real committed blank lines, not a split artifact.\n return { type: 'line', lines: raw.slice(0, -1).split('\\n'), stream }\n }\n return { type: 'token', text: raw }\n}\n\ntype StdoutWrite = typeof process.stdout.write\n\n/**\n * Monkey-patches `console.log`, `console.error`, and `process.stdout.write` for the duration of\n * the interactive Ink session, classifying every write via {@link classify} and routing it to\n * `onEvent` instead of the real terminal — Ink owns the frame once this is active (Decision 1:\n * every command handler still calls the same global functions unmodified). Returns a restore\n * function that puts the originals back; call it on exit and in every test's `afterEach`.\n */\nexport function startCapture(onEvent: (event: CaptureEvent) => void): () => void {\n const originalLog = console.log\n const originalError = console.error\n const originalWrite = process.stdout.write\n\n const makeCaptureConsole = (stream: 'stdout' | 'stderr') => (...args: unknown[]): void => {\n onEvent(classify(`${format(...(args as [unknown, ...unknown[]]))}\\n`, stream))\n }\n console.log = makeCaptureConsole('stdout')\n console.error = makeCaptureConsole('stderr')\n\n const captureWrite: StdoutWrite = ((chunk: unknown, ...rest: unknown[]): boolean => {\n onEvent(classify(typeof chunk === 'string' ? chunk : String(chunk), 'stdout'))\n // Honor process.stdout.write's real contract (an optional trailing callback) even though no\n // call site in cli.ts currently passes one — costs nothing and avoids a silent hang for any\n // future one that does.\n const callback = rest.find((arg): arg is () => void => typeof arg === 'function')\n callback?.()\n return true\n }) as StdoutWrite\n process.stdout.write = captureWrite\n\n return () => {\n console.log = originalLog\n console.error = originalError\n process.stdout.write = originalWrite\n }\n}\n","import { useRef, useState } from 'react'\nimport { Box, Text, useInput, usePaste, useWindowSize } from 'ink'\n\n/** @default 5 — the plan's own \"grows up to 5 rows, then scrolls internally\" number. */\nconst DEFAULT_MAX_ROWS = 5\n/** Round border (1 col each side) + paddingX (1 col each side) eaten out of the terminal width before wrapping text. */\nconst BOX_CHROME_WIDTH = 4\n\n/**\n * One word-wrapped visual row of the draft. `wraps: true` means the next row is a continuation\n * of the same logical (`\\n`-delimited) line — no real newline between `end` and the next row's\n * `start` — which is what lets {@link offsetToRowCol} tell a wrap boundary (cursor snaps to the\n * start of the next row) apart from a real end-of-line (cursor stays put at this row's end).\n */\nexport interface DraftRow {\n text: string\n start: number\n end: number\n wraps: boolean\n}\n\n/**\n * Splits `value` into visual rows at `\\n` boundaries and, within each logical line, at every\n * `columns`-wide chunk — plain character wrapping (not word-boundary wrapping): a real terminal\n * hard-wraps by character when a row overflows, so this matches what the terminal will actually\n * show rather than reflowing at word boundaries the way a GUI text area would.\n */\nexport function wrapDraftIntoRows(value: string, columns: number): DraftRow[] {\n const width = Math.max(1, columns)\n const rows: DraftRow[] = []\n const logicalLines = value.split('\\n')\n let offset = 0\n logicalLines.forEach((line, li) => {\n if (line.length === 0) {\n rows.push({ text: '', start: offset, end: offset, wraps: false })\n } else {\n for (let i = 0; i < line.length; i += width) {\n const text = line.slice(i, i + width)\n const start = offset + i\n const end = start + text.length\n rows.push({ text, start, end, wraps: end < offset + line.length })\n }\n }\n offset += line.length\n if (li < logicalLines.length - 1) offset += 1 // the '\\n' itself\n })\n return rows\n}\n\n/** Maps a character offset into `value` to its (row, col) among `rows` — see {@link DraftRow.wraps} for the wrap-vs-newline distinction this leans on. */\nexport function offsetToRowCol(rows: DraftRow[], cursor: number): { row: number; col: number } {\n for (let r = 0; r < rows.length; r++) {\n const row = rows[r]!\n if (cursor < row.end) return { row: r, col: cursor - row.start }\n if (cursor === row.end && !row.wraps) return { row: r, col: cursor - row.start }\n }\n const last = rows[rows.length - 1]\n return last ? { row: rows.length - 1, col: last.text.length } : { row: 0, col: 0 }\n}\n\n/** Inverse of {@link offsetToRowCol}, clamping both row and column into range — used to preserve column when moving the cursor a visual row up/down. */\nexport function rowColToOffset(rows: DraftRow[], row: number, col: number): number {\n const clampedRow = Math.max(0, Math.min(row, rows.length - 1))\n const target = rows[clampedRow]\n if (!target) return 0\n return target.start + Math.max(0, Math.min(col, target.text.length))\n}\n\n/** Home = start of the current logical (`\\n`-delimited) line, not the current visual row. */\nexport function homeOffset(value: string, cursor: number): number {\n return value.lastIndexOf('\\n', cursor - 1) + 1\n}\n\n/** End = end of the current logical (`\\n`-delimited) line, not the current visual row. */\nexport function endOffset(value: string, cursor: number): number {\n const idx = value.indexOf('\\n', cursor)\n return idx === -1 ? value.length : idx\n}\n\n/**\n * Keeps the cursor's row inside a `maxRows`-tall window, scrolling the minimum amount needed —\n * matches an ordinary scrolling textarea rather than re-centering on every keystroke.\n */\nexport function computeViewportStart(prevStart: number, cursorRow: number, totalRows: number, maxRows: number): number {\n if (totalRows <= maxRows) return 0\n let start = prevStart\n if (cursorRow < start) start = cursorRow\n if (cursorRow > start + maxRows - 1) start = cursorRow - maxRows + 1\n return Math.max(0, Math.min(start, totalRows - maxRows))\n}\n\nexport interface TuiInputProps {\n /** Question text for a pending askYesNo/askLine prompt (Decision 1's override seam) — undefined means ordinary chat mode. Shown as a label above the box, since it's real information (the question being asked), unlike chat mode's old static \"you\" label, which was dropped in favor of a placeholder inside the box (see `placeholder` below). */\n promptLabel?: string\n /** Faint placeholder shown inside the (empty) box in chat mode, replacing the old \"you\" label above it. */\n placeholder?: string\n /** Called when Enter submits a non-empty draft in chat mode. Also appended to in-session history. */\n onSubmitChat: (line: string) => void\n /** Called when Enter resolves a pending prompt (promptLabel set). Not added to chat history. */\n onSubmitPrompt: (line: string) => void\n /** Terminal width; defaults to the live width from Ink's useWindowSize. Pass explicitly for a deterministic wrap width in tests. */\n columns?: number\n /** Max input box height in rows before internal scrolling kicks in. */\n maxRows?: number\n isActive?: boolean\n}\n\nexport function TuiInput(props: TuiInputProps): React.JSX.Element {\n const { promptLabel, placeholder = 'Type your message here', onSubmitChat, onSubmitPrompt, maxRows = DEFAULT_MAX_ROWS, isActive = true } = props\n\n const [value, setValue] = useState('')\n const [cursor, setCursor] = useState(0)\n const [history, setHistory] = useState<string[]>([])\n const [historyIndex, setHistoryIndex] = useState<number | null>(null)\n const [pendingDraft, setPendingDraft] = useState('')\n\n const windowSize = useWindowSize()\n const terminalColumns = props.columns ?? windowSize.columns\n const wrapWidth = Math.max(1, terminalColumns - BOX_CHROME_WIDTH)\n\n const rows = wrapDraftIntoRows(value, wrapWidth)\n const { row: cursorRow, col: cursorCol } = offsetToRowCol(rows, cursor)\n\n // Mutated during render, not via setState — this is a derived scroll cache keyed off the\n // current row layout/cursor, not independent state, so it doesn't need its own re-render.\n const viewportStartRef = useRef(0)\n viewportStartRef.current = computeViewportStart(viewportStartRef.current, cursorRow, rows.length, maxRows)\n const viewportStart = viewportStartRef.current\n\n function insertText(text: string): void {\n setValue(value.slice(0, cursor) + text + value.slice(cursor))\n setCursor(cursor + text.length)\n }\n\n function handleReturn(): void {\n if (cursor > 0 && value[cursor - 1] === '\\\\') {\n // Trailing-backslash convention: swap it for a literal newline instead of submitting.\n setValue(value.slice(0, cursor - 1) + '\\n' + value.slice(cursor))\n return\n }\n if (value.length === 0) return\n const submitted = value\n if (promptLabel !== undefined) {\n onSubmitPrompt(submitted)\n } else {\n onSubmitChat(submitted)\n setHistory([...history, submitted])\n }\n setValue('')\n setCursor(0)\n setHistoryIndex(null)\n setPendingDraft('')\n }\n\n function recallHistory(index: number): void {\n const entry = history[index]!\n setHistoryIndex(index)\n setValue(entry)\n setCursor(entry.length)\n }\n\n function handleUp(): void {\n if (cursorRow > 0) {\n setCursor(rowColToOffset(rows, cursorRow - 1, cursorCol))\n return\n }\n if (promptLabel !== undefined || history.length === 0) return\n if (historyIndex === null) {\n setPendingDraft(value)\n recallHistory(history.length - 1)\n return\n }\n if (historyIndex > 0) recallHistory(historyIndex - 1)\n }\n\n function handleDown(): void {\n if (cursorRow < rows.length - 1) {\n setCursor(rowColToOffset(rows, cursorRow + 1, cursorCol))\n return\n }\n if (promptLabel !== undefined || historyIndex === null) return\n if (historyIndex < history.length - 1) {\n recallHistory(historyIndex + 1)\n return\n }\n setHistoryIndex(null)\n setValue(pendingDraft)\n setCursor(pendingDraft.length)\n }\n\n usePaste(\n (text) => {\n insertText(text.replace(/\\r\\n?/g, '\\n'))\n },\n { isActive },\n )\n\n useInput(\n (input, key) => {\n if (key.upArrow) return handleUp()\n if (key.downArrow) return handleDown()\n if (key.leftArrow) return setCursor(Math.max(0, cursor - 1))\n if (key.rightArrow) return setCursor(Math.min(value.length, cursor + 1))\n if (key.home) return setCursor(homeOffset(value, cursor))\n if (key.end) return setCursor(endOffset(value, cursor))\n if (key.backspace) {\n if (cursor === 0) return\n setValue(value.slice(0, cursor - 1) + value.slice(cursor))\n setCursor(cursor - 1)\n return\n }\n if (key.delete) {\n setValue(value.slice(0, cursor) + value.slice(cursor + 1))\n return\n }\n if (key.return) return handleReturn()\n if (key.ctrl || key.meta || key.tab || key.escape || key.pageUp || key.pageDown) return\n if (input.length > 0) insertText(input)\n },\n { isActive },\n )\n\n const visibleRows = rows.slice(viewportStart, viewportStart + maxRows)\n\n return (\n <Box flexDirection=\"column\">\n {promptLabel !== undefined && (\n <Text bold color=\"yellow\">\n {promptLabel}\n </Text>\n )}\n <Box borderStyle=\"round\" borderColor={promptLabel !== undefined ? 'yellow' : 'cyan'} flexDirection=\"column\" paddingX={1}>\n {promptLabel === undefined && value.length === 0 ? (\n <Text dimColor>{placeholder}</Text>\n ) : (\n visibleRows.map((row, i) => {\n const absoluteRow = viewportStart + i\n if (absoluteRow !== cursorRow) {\n return <Text key={absoluteRow}>{row.text.length > 0 ? row.text : ' '}</Text>\n }\n const before = row.text.slice(0, cursorCol)\n const atCursor = row.text[cursorCol] ?? ' '\n const after = row.text.slice(cursorCol + 1)\n return (\n <Text key={absoluteRow}>\n {before}\n <Text inverse>{atCursor}</Text>\n {after}\n </Text>\n )\n })\n )}\n </Box>\n </Box>\n )\n}\n","import { Readable, Writable } from 'node:stream'\nimport { useCallback, useSyncExternalStore } from 'react'\nimport { Box, Static, Text, render as inkRender, useInput, useWindowSize } from 'ink'\nimport { runCli, type CliInstance, type RunCliOptions } from './cli.js'\nimport { startCapture, type CaptureEvent } from './tui-output-capture.js'\nimport { TuiInput } from './tui-input.js'\n\n/**\n * A minimal pub/sub store, one per piece of state the Ink tree needs — deliberately not React\n * state, because the values that drive it arrive from outside React entirely: `startCapture`\n * (Phase 1) calls its `onEvent` callback synchronously from a monkey-patched `console.log`/\n * `process.stdout.write`, and `askYesNo`/`askLine` (Decision 1's override seam) are plain\n * functions handed to `runCli()` before any component has mounted. `useSyncExternalStore` is the\n * React-correct way to subscribe a component to state that's mutated from outside React's own\n * render cycle, without the chicken-and-egg problem of needing a `setState` that only exists\n * after the first render.\n */\ninterface Store<T> {\n subscribe: (listener: () => void) => () => void\n getSnapshot: () => T\n}\n\nfunction useStore<T>(store: Store<T>): T {\n return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot)\n}\n\n/**\n * Which visual style a committed scrollback line gets (this task's ask: \"different formats for\n * user text vs aielia response vs tool call details\"). `'margin'` is a blank spacer line between\n * turns, not a real writer's output — kept as its own kind rather than reusing `'system'` so\n * rendering never has to guess a blank line's intent from empty text alone.\n */\nexport type LineKind = 'user' | 'assistant' | 'tool' | 'error' | 'system' | 'margin'\n\nexport interface LogLine {\n text: string\n kind: LineKind\n}\n\nexport interface TuiLogState {\n /** Every permanently-committed scrollback line, oldest first — fed straight into `<Static>`. */\n lines: LogLine[]\n /** `writeProgress`'s current `\\r`-overwritten line — shown in the transient region, never committed. */\n progressText: string\n /** `writeToken`'s not-yet-newline-terminated streamed reply text — shown in the transient region until the next committed-line event closes it out. */\n transientText: string\n}\n\nconst EMPTY_LOG: TuiLogState = { lines: [], progressText: '', transientText: '' }\n\n/** `writeToolStep`'s own indent+glyph (see cli.ts) — matched after trimming so a `'line'` event's kind survives cli.ts adding/removing leading whitespace. */\nconst TOOL_STEP_PREFIX = '⚙'\n/** cli.ts hardcodes this literal label for every assistant-reply write, streamed or not (`writeToken`'s opening write and the non-streaming `console.log` fallback both start with it) — see this class's `handleEvent` doc comment for why streaming state alone isn't a reliable-enough signal on its own. */\nconst ASSISTANT_REPLY_PREFIX = 'Aielia>'\n\n/** Classifies one already-merged, already-stream-tagged committed block into a `LineKind` — shared by every resulting split line, since a multi-line reply/tool/system block reads as one unit, not a mix of styles line to line. */\nfunction classifyLineKind(mergedText: string, streamedReplyWasOpen: boolean, stream: 'stdout' | 'stderr'): LineKind {\n if (stream === 'stderr') return 'error'\n // Streaming state alone would miss the non-streaming `console.log('\\nAielia>…')` fallback path\n // (harness_d2's non-one-loop path) that never opens a `'token'` stream at all — checked first\n // since it's the more specific, unambiguous signal when it does apply.\n if (streamedReplyWasOpen || mergedText.trimStart().startsWith(ASSISTANT_REPLY_PREFIX)) return 'assistant'\n if (mergedText.trimStart().startsWith(TOOL_STEP_PREFIX)) return 'tool'\n return 'system'\n}\n\n/**\n * Strips cli.ts's hardcoded \"Aielia>\" reply label (plus a leading blank-line artifact — the\n * streaming path's opening write is literally `'\\nAielia> '`, and `\\s*` below eats that leading\n * `\\n` along with the label) so the assistant's reply displays as just its own text, no label —\n * explicit feedback that spelling out \"you\"/\"Aielia\" wasn't wanted (see `LogLineText`'s doc\n * comment for the full styling rationale). Applied to already-classified `'assistant'` text only;\n * never called on anything else, so it can't accidentally eat real reply content that happens to\n * start the same way.\n */\nfunction stripAssistantLabel(text: string): string {\n return text.replace(/^\\s*Aielia>\\s?/, '')\n}\n\n/**\n * Classifies and accumulates `CaptureEvent`s (Phase 1) into the three regions Phase 3's layout\n * needs: permanent scrollback, the transient progress line, and the transient in-progress\n * streamed reply. A `'line'` event closes out whatever streamed-token text is currently pending\n * (see `cli.ts`'s `writeToken`/`handleTurn`: a streamed reply is one or more raw `'token'` writes\n * followed by exactly one final `'line'` write for the trailing hint text) — merging the two\n * before committing is what turns \"Hi the|re!\\n\\n\" (streamed \"Hi the\" + committed \"re!\\n\\n\") into\n * one correct committed line instead of two garbled ones.\n */\nexport class EventLogBridge implements Store<TuiLogState> {\n private lines: LogLine[] = []\n private progressText = ''\n private transientText = ''\n private snapshot: TuiLogState = EMPTY_LOG\n private listeners = new Set<() => void>()\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n getSnapshot = (): TuiLogState => this.snapshot\n\n private commit(): void {\n this.snapshot = { lines: this.lines, progressText: this.progressText, transientText: this.transientText }\n for (const listener of this.listeners) listener()\n }\n\n /**\n * A blank spacer line (\"some margins between different conversations\", later extended to \"at\n * least one line spacing between the user and system messages\") — called from three places in\n * `handleSubmitChat` (never from a resolved approval/clarification prompt answer, which stays\n * visually grouped with the turn it belongs to): once before a new turn's echo (separating it\n * from the previous turn's reply) and once right after it (separating the echo from whatever\n * system/tool/assistant output follows). A no-op on an empty log or if the last line is already\n * a margin, so calling it from both of those spots back-to-back across turns can't stack blank\n * lines — the \"before next turn\" and \"after this turn\" calls collapse into the same one line.\n */\n pushTurnMargin(): void {\n const last = this.lines[this.lines.length - 1]\n if (!last || last.kind === 'margin') return\n this.lines = [...this.lines, { text: '', kind: 'margin' }]\n this.commit()\n }\n\n /** Records a line the user just submitted (chat or a resolved prompt answer) into permanent scrollback — mirrors a real terminal's own line-echo, which the inert (non-TTY) input stream this shell uses never produces on its own. `prefix` is `''` for an ordinary chat line (no \"you>\" label — see `LogLineText`'s doc comment) and `'> '` for a resolved prompt answer, which keeps its prefix since it's answering a question printed just above it, not identifying whose turn it is. */\n pushEchoLine(prefix: string, text: string): void {\n this.lines = [...this.lines, { text: `${prefix}${text}`, kind: 'user' }]\n this.commit()\n }\n\n handleEvent(event: CaptureEvent): void {\n if (event.type === 'progress') {\n this.progressText = event.text\n this.commit()\n return\n }\n if (event.type === 'token') {\n this.transientText += event.text\n this.commit()\n return\n }\n const streamedReplyWasOpen = this.transientText.length > 0\n const merged = this.transientText + event.lines.join('\\n')\n const kind = classifyLineKind(merged, streamedReplyWasOpen, event.stream)\n const displayText = kind === 'assistant' ? stripAssistantLabel(merged) : merged\n this.lines = [...this.lines, ...displayText.split('\\n').map((text) => ({ text, kind }))]\n this.transientText = ''\n // Any committed line means the progress indicator that was describing the still-in-flight\n // turn is now stale — cli.ts's own clearProgress() deliberately skips itself once a reply has\n // streamed (real-terminal reasoning: clearing would \\r back onto the tail of the just-printed\n // reply and blank it — see handleTurn's `if (!streamedAnyTokens) clearProgress()` comment).\n // That reasoning doesn't apply here: the TUI's progress line lives in its own state-driven\n // transient region, decoupled from real cursor position, so nothing needs to \"not corrupt\" —\n // it just needs to stop displaying a step counter for a turn that has already finished.\n // Clearing on every commit is safe even when cli.ts's own clearProgress() *did* already fire\n // (writeToolStep's case): progressText is already '' then, so this is a no-op.\n this.progressText = ''\n this.commit()\n // A blank line after the assistant's own reply, mirroring the one already pushed after the\n // user's echo (pushTurnMargin's own no-op-on-consecutive-margin guard means this and the next\n // turn's pre-echo pushTurnMargin() call collapse into the same single line, never stacking).\n if (kind === 'assistant') this.pushTurnMargin()\n }\n}\n\nexport type PendingPrompt = { question: string } | undefined\n\n/**\n * Bridges `runCli()`'s `askYesNo`/`askLine` override seam (Decision 1) to Ink: each call parks\n * a resolver and exposes the pending question to the component tree via `getSnapshot()`, instead\n * of the original `rl.question`-based implementation. `TuiInput`'s own `promptLabel` prop\n * (Phase 2) already knows how to render this state and route Enter to `onSubmitPrompt` instead\n * of `onSubmitChat` — this class only needs to supply the question text and resolve the answer.\n */\nexport class PromptBridge implements Store<PendingPrompt> {\n private pending: PendingPrompt\n private resolve: ((answer: string) => void) | undefined\n private listeners = new Set<() => void>()\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n getSnapshot = (): PendingPrompt => this.pending\n\n private ask(question: string): Promise<string> {\n return new Promise((resolve) => {\n this.pending = { question }\n this.resolve = resolve\n for (const listener of this.listeners) listener()\n })\n }\n\n /** Matches `RunCliOptions.askYesNo`'s exact parsing convention (`answer.trim().toLowerCase().startsWith('y')`) — same fail-closed shape, just answered via the Ink prompt instead of `rl.question`. */\n askYesNo = (question: string): Promise<boolean> => this.ask(question).then((answer) => answer.trim().toLowerCase().startsWith('y'))\n\n askLine = (question: string): Promise<string> => this.ask(question)\n\n submit(answer: string): void {\n const resolve = this.resolve\n this.pending = undefined\n this.resolve = undefined\n for (const listener of this.listeners) listener()\n resolve?.(answer)\n }\n}\n\n/** The status line's short indicator list (Phase 3 step 5) — polled from `CliInstance.getStatusIndicators()` after every dispatched line, since plan/spend-cap state only changes as a side effect of a turn. */\nexport class StatusBridge implements Store<string[]> {\n private indicators: string[] = []\n private listeners = new Set<() => void>()\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n getSnapshot = (): string[] => this.indicators\n\n set(indicators: string[]): void {\n this.indicators = indicators\n for (const listener of this.listeners) listener()\n }\n}\n\nexport interface TuiAppProps {\n eventLog: EventLogBridge\n prompt: PromptBridge\n status: StatusBridge\n onSubmitChat: (line: string) => void\n onExit: () => void\n /** Overrides the live terminal width for tests — same seam `TuiInput` already accepts. */\n columns?: number\n}\n\n/**\n * One committed scrollback line, styled by `LineKind` (this task's ask: \"different formats for\n * user text vs aielia response vs tool call details\"). Several earlier versions are worth\n * recording since they were each explicit feedback, not guesses: (1) colored 'user'/'assistant'\n * cyan/green — rejected as arbitrary; (2) dropped color for bold-only-on-the-label-line —\n * rejected in favor of dropping the \"you>\"/\"Aielia>\" labels themselves entirely (see\n * `stripAssistantLabel` — the label text no longer exists in `'assistant'`-kind text at all, and\n * `'user'`-kind text is pushed with no prefix in chat mode — `EventLogBridge.pushEchoLine`'s doc\n * comment); (3) a dark gray foreground, then (4) a dark gray *background* highlight band instead\n * (through three shades — plain 'gray', then near-black, then a midpoint — before the whole\n * background-band approach was set aside); (5) **current**: a bordered `<Box>` around the user's\n * own text, echoing `TuiInput`'s own box chrome (round border, `paddingX={1}`) but in a muted gray\n * border instead of the live input box's cyan, so a past message reads as \"the same kind of\n * thing, already said\" rather than \"still being typed.\" Ink's `Box` fills the parent's width by\n * default (no explicit `width` set, same as `TuiInput`'s own box), so this box's border\n * automatically spans the same width as the live input box below it with no manual padding\n * needed. Position — the old label used to carry — is now conveyed by `pushTurnMargin`'s\n * blank-line spacing instead. `'tool'`/`'error'` still use dim/red respectively — not what the\n * feedback was about (a functional error signal, not a stylistic user/assistant split). A\n * `'margin'` line renders a bare blank row (a real space, not empty — Ink/terminal rows with\n * truly empty text can collapse to zero width, the same reasoning `TuiInput` already applies to\n * its own empty draft rows).\n */\n/**\n * `width` is passed explicitly (from `TuiApp`'s own `columns ?? windowSize.columns`, the same\n * value the separator and `TuiInput`'s box use) rather than relying on `Box`'s usual\n * fill-parent-width default — confirmed live that a `<Static>` item's `Box` sizes to its content\n * instead of stretching, unlike a `Box` in the main persistent tree (`TuiInput`'s own), so without\n * this every message box shrink-wrapped to its own text length instead of matching the input box.\n */\nfunction UserMessageBox({ text, width }: { text: string; width: number }): React.JSX.Element {\n return (\n <Box borderStyle=\"round\" borderColor=\"gray\" flexDirection=\"column\" paddingX={1} width={width}>\n {text.split('\\n').map((line, i) => (\n <Text key={i}>{line.length > 0 ? line : ' '}</Text>\n ))}\n </Box>\n )\n}\n\nfunction LogLineText({ line, width }: { line: LogLine; width: number }): React.JSX.Element {\n switch (line.kind) {\n case 'user':\n return <UserMessageBox text={line.text} width={width} />\n case 'assistant':\n case 'system':\n return <Text>{line.text}</Text>\n case 'tool':\n return <Text dimColor>{line.text}</Text>\n case 'error':\n return <Text color=\"red\">{line.text}</Text>\n case 'margin':\n return <Text> </Text>\n }\n}\n\n/** The reserved status line (Phase 3 step 5) — each indicator its own `<Text>` so a `⚠`-prefixed warning (currently only the dangerouslySkipPermissions notice) can stand out in yellow while the rest stay dim, without string-parsing a single joined line. */\nfunction StatusLine({ indicators }: { indicators: string[] }): React.JSX.Element {\n return (\n <Text>\n {indicators.map((indicator, index) => (\n <Text key={indicator}>\n {index > 0 ? ' ' : ''}\n <Text color={indicator.startsWith('⚠') ? 'yellow' : undefined} dimColor={!indicator.startsWith('⚠')}>\n {indicator}\n </Text>\n </Text>\n ))}\n </Text>\n )\n}\n\n/**\n * The top-level Ink app (Phase 3): a `<Static>` scrollback of every committed line, a transient\n * region for the in-progress progress line/streamed reply, a one-row separator, the Phase 2\n * multiline input box pinned to the bottom, and a reserved status line under that. Composition\n * only — command parsing/dispatch stays entirely inside `cli.ts`'s `dispatchLine()` (Decision 1),\n * and this component never re-implements it.\n */\nexport function TuiApp(props: TuiAppProps): React.JSX.Element {\n const { eventLog, prompt, status, onSubmitChat, onExit, columns } = props\n const log = useStore(eventLog)\n const pending = useStore(prompt)\n const statusIndicators = useStore(status)\n const windowSize = useWindowSize()\n const width = columns ?? windowSize.columns\n\n // Always active, regardless of chat-vs-prompt mode — Ctrl+C must exit either way, unlike\n // TuiInput's own useInput, which deliberately ignores every ctrl/meta/tab/escape key (its\n // job is draft editing, not process control).\n useInput((input, key) => {\n if (key.ctrl && input === 'c') onExit()\n })\n\n const handleSubmitChat = useCallback(\n (line: string) => {\n // Only a genuine new chat turn gets blank margins around it — a resolved\n // approval/clarification prompt answer (handleSubmitPrompt below) stays visually grouped\n // with the turn it belongs to, not treated as a turn of its own. No \"you>\" prefix (see\n // `LogLineText`'s doc comment) — the gray shading plus these margins on both sides do the\n // job the label used to.\n eventLog.pushTurnMargin()\n eventLog.pushEchoLine('', line)\n eventLog.pushTurnMargin()\n onSubmitChat(line)\n },\n [eventLog, onSubmitChat],\n )\n\n const handleSubmitPrompt = useCallback(\n (line: string) => {\n eventLog.pushEchoLine('> ', line)\n prompt.submit(line)\n },\n [eventLog, prompt],\n )\n\n const hasTransient = log.progressText.length > 0 || log.transientText.length > 0\n\n return (\n <Box flexDirection=\"column\">\n <Static items={log.lines}>{(line, index) => <LogLineText key={index} line={line} width={width} />}</Static>\n {hasTransient && (\n <Box flexDirection=\"column\">\n {log.progressText.length > 0 && <Text dimColor>{log.progressText}</Text>}\n {log.transientText.length > 0 && <Text>{stripAssistantLabel(log.transientText)}</Text>}\n </Box>\n )}\n <Text dimColor>{'─'.repeat(Math.max(1, width))}</Text>\n <TuiInput\n promptLabel={pending?.question}\n onSubmitChat={handleSubmitChat}\n onSubmitPrompt={handleSubmitPrompt}\n columns={columns}\n />\n <StatusLine indicators={statusIndicators} />\n </Box>\n )\n}\n\n/**\n * `startCapture` (Phase 1) monkey-patches the *global* `process.stdout.write` so it can intercept\n * `cli.ts`'s ~108 existing call sites without touching each one (Decision 1) — but Ink itself also\n * paints every frame through that same global `process.stdout.write` by default. Left unpatched,\n * Ink's own frame writes would loop back through `startCapture`'s `onEvent` into\n * `EventLogBridge.handleEvent`/`commit()`, which notifies the very `TuiApp` subscribers that\n * caused the frame in the first place — triggering another render, another write, another event,\n * forever, until React's update-depth guard throws `Maximum update depth exceeded`. This wraps the\n * *real* `process.stdout` in a `Proxy` that resolves every property normally (so `columns`,\n * `isTTY`, `on('resize', …)` etc. all still hit the genuine stream, preserving correct `this`\n * binding for its internal EventEmitter state) except `write`, which is pinned to the pristine\n * function captured *before* `startCapture` ran — so Ink paints the real terminal directly and\n * never re-enters the capture/bridge loop.\n */\nfunction createUnpatchedStdout(originalWrite: NodeJS.WriteStream['write']): NodeJS.WriteStream {\n return new Proxy(process.stdout, {\n get(target, prop, receiver) {\n if (prop === 'write') return originalWrite.bind(target)\n const value = Reflect.get(target, prop, receiver)\n return typeof value === 'function' ? value.bind(target) : value\n },\n })\n}\n\n/**\n * Inert stand-ins for `RunCliOptions.input`/`.output`: the Ink shell drives every chat line\n * through `CliInstance.dispatchLine()` and every approval/clarification prompt through\n * `PromptBridge` (Decision 1's override seam), so `runCli()`'s own internal `readline` interface\n * never needs to read real keystrokes or write real prompts — Ink owns the real terminal\n * exclusively (raw mode for keystrokes, direct ANSI writes for frames). Leaving `runCli()`'s\n * `createInterface({ input: process.stdin, output: process.stdout })` default in place here\n * would fight Ink for both: `readline` auto-enables terminal/raw mode whenever its `output` is a\n * TTY, which would race Ink's own `setRawMode` calls on the same `stdin`. Neither stream declares\n * `isTTY`, so `createInterface`'s terminal-mode auto-detection (`Boolean(output.isTTY)`) comes\n * out false and it never tries.\n */\nfunction createInertStreams(): { input: NodeJS.ReadableStream; output: NodeJS.WritableStream } {\n const input = new Readable({ read: () => {} })\n const output = new Writable({\n write: (_chunk, _encoding, callback) => callback(),\n })\n return { input, output }\n}\n\nexport type RunTuiAppOptions = Omit<RunCliOptions, 'askYesNo' | 'askLine'>\n\n/**\n * Constructs `runCli()` wired to this file's Ink shell (Phase 4 calls this once, behind the\n * `tuiMode` rollout flag) and renders it. Resolves once the user exits (Ctrl+C — see `TuiApp`'s\n * `onExit`), after the same graceful-exit steps `cli.ts`'s own `rl.on('SIGINT', ...)` handler\n * performs: restore the captured `console`/`process.stdout`, close the underlying `CliInstance`,\n * then exit the process.\n */\nexport async function runTuiApp(options: RunTuiAppOptions = {}): Promise<void> {\n const eventLog = new EventLogBridge()\n const prompt = new PromptBridge()\n const status = new StatusBridge()\n\n // Captured before startCapture patches process.stdout.write — this is the pristine function\n // Ink itself will paint frames through (see createUnpatchedStdout's doc comment above).\n const originalWrite = process.stdout.write.bind(process.stdout)\n\n // Started before runCli() is ever called — runCli() itself prints the startup banner\n // (backend, capabilities, undo-log carryover) via plain console.log, which must land in the\n // Static scrollback like everything else, not leak to the real terminal underneath Ink's frame.\n const restoreCapture = startCapture((event) => eventLog.handleEvent(event))\n\n let instance: CliInstance\n try {\n const inert = createInertStreams()\n instance = await runCli({\n ...options,\n input: options.input ?? inert.input,\n output: options.output ?? inert.output,\n askYesNo: prompt.askYesNo,\n askLine: prompt.askLine,\n })\n } catch (err) {\n restoreCapture()\n throw err\n }\n\n const refreshStatus = async (): Promise<void> => {\n status.set(await instance.getStatusIndicators())\n }\n await refreshStatus()\n\n const handleSubmitChat = (line: string): void => {\n void instance.dispatchLine(line).then(refreshStatus)\n }\n\n let exiting = false\n const exit = (): void => {\n if (exiting) return\n exiting = true\n restoreCapture()\n instance.close()\n app.unmount()\n process.exit(0)\n }\n\n const app = inkRender(<TuiApp eventLog={eventLog} prompt={prompt} status={status} onSubmitChat={handleSubmitChat} onExit={exit} />, {\n // Phase 1's startCapture already routes every console.log/process.stdout.write call into\n // eventLog — ink's own patchConsole would double-intercept the same calls with a competing\n // mechanism (writing them above its own Static area independently), not compose with it.\n patchConsole: false,\n exitOnCtrlC: false,\n // Bypass startCapture's patched process.stdout.write for Ink's own frame painting — see\n // createUnpatchedStdout's doc comment for why leaving this as the default (real\n // process.stdout, whose .write is the patched one) causes an infinite render loop.\n stdout: createUnpatchedStdout(originalWrite),\n })\n\n await app.waitUntilExit()\n}\n"],"names":["inkRender"],"mappings":"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"}