@inbrowser/agent 0.0.0-placeholder → 0.2.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.
Files changed (267) hide show
  1. package/AGENTS.md +270 -0
  2. package/LICENSE +21 -0
  3. package/README.md +117 -2
  4. package/bin/agent.ts +10 -0
  5. package/dist/cli/commands/describe.d.ts +14 -0
  6. package/dist/cli/commands/describe.d.ts.map +1 -0
  7. package/dist/cli/commands/describe.js +179 -0
  8. package/dist/cli/commands/describe.js.map +1 -0
  9. package/dist/cli/commands/events.d.ts +21 -0
  10. package/dist/cli/commands/events.d.ts.map +1 -0
  11. package/dist/cli/commands/events.js +59 -0
  12. package/dist/cli/commands/events.js.map +1 -0
  13. package/dist/cli/commands/fleet.d.ts +15 -0
  14. package/dist/cli/commands/fleet.d.ts.map +1 -0
  15. package/dist/cli/commands/fleet.js +149 -0
  16. package/dist/cli/commands/fleet.js.map +1 -0
  17. package/dist/cli/commands/help.d.ts +15 -0
  18. package/dist/cli/commands/help.d.ts.map +1 -0
  19. package/dist/cli/commands/help.js +93 -0
  20. package/dist/cli/commands/help.js.map +1 -0
  21. package/dist/cli/commands/migrate.d.ts +27 -0
  22. package/dist/cli/commands/migrate.d.ts.map +1 -0
  23. package/dist/cli/commands/migrate.js +109 -0
  24. package/dist/cli/commands/migrate.js.map +1 -0
  25. package/dist/cli/commands/run.d.ts +38 -0
  26. package/dist/cli/commands/run.d.ts.map +1 -0
  27. package/dist/cli/commands/run.js +535 -0
  28. package/dist/cli/commands/run.js.map +1 -0
  29. package/dist/cli/commands/schema.d.ts +8 -0
  30. package/dist/cli/commands/schema.d.ts.map +1 -0
  31. package/dist/cli/commands/schema.js +12 -0
  32. package/dist/cli/commands/schema.js.map +1 -0
  33. package/dist/cli/commands/serve.d.ts +39 -0
  34. package/dist/cli/commands/serve.d.ts.map +1 -0
  35. package/dist/cli/commands/serve.js +65 -0
  36. package/dist/cli/commands/serve.js.map +1 -0
  37. package/dist/cli/commands/undo.d.ts +36 -0
  38. package/dist/cli/commands/undo.d.ts.map +1 -0
  39. package/dist/cli/commands/undo.js +132 -0
  40. package/dist/cli/commands/undo.js.map +1 -0
  41. package/dist/cli/fixtures.d.ts +17 -0
  42. package/dist/cli/fixtures.d.ts.map +1 -0
  43. package/dist/cli/fixtures.js +107 -0
  44. package/dist/cli/fixtures.js.map +1 -0
  45. package/dist/cli/hardening.d.ts +39 -0
  46. package/dist/cli/hardening.d.ts.map +1 -0
  47. package/dist/cli/hardening.js +68 -0
  48. package/dist/cli/hardening.js.map +1 -0
  49. package/dist/cli/index.d.ts +28 -0
  50. package/dist/cli/index.d.ts.map +1 -0
  51. package/dist/cli/index.js +19 -0
  52. package/dist/cli/index.js.map +1 -0
  53. package/dist/cli/llm/openrouter.d.ts +33 -0
  54. package/dist/cli/llm/openrouter.d.ts.map +1 -0
  55. package/dist/cli/llm/openrouter.js +285 -0
  56. package/dist/cli/llm/openrouter.js.map +1 -0
  57. package/dist/cli/main.d.ts +32 -0
  58. package/dist/cli/main.d.ts.map +1 -0
  59. package/dist/cli/main.js +106 -0
  60. package/dist/cli/main.js.map +1 -0
  61. package/dist/cli/output.d.ts +36 -0
  62. package/dist/cli/output.d.ts.map +1 -0
  63. package/dist/cli/output.js +95 -0
  64. package/dist/cli/output.js.map +1 -0
  65. package/dist/cli/parse.d.ts +26 -0
  66. package/dist/cli/parse.d.ts.map +1 -0
  67. package/dist/cli/parse.js +160 -0
  68. package/dist/cli/parse.js.map +1 -0
  69. package/dist/cli/session-log.d.ts +34 -0
  70. package/dist/cli/session-log.d.ts.map +1 -0
  71. package/dist/cli/session-log.js +52 -0
  72. package/dist/cli/session-log.js.map +1 -0
  73. package/dist/cli/spec.d.ts +62 -0
  74. package/dist/cli/spec.d.ts.map +1 -0
  75. package/dist/cli/spec.js +510 -0
  76. package/dist/cli/spec.js.map +1 -0
  77. package/dist/cli/ui/RunView.d.ts +134 -0
  78. package/dist/cli/ui/RunView.d.ts.map +1 -0
  79. package/dist/cli/ui/RunView.js +341 -0
  80. package/dist/cli/ui/RunView.js.map +1 -0
  81. package/dist/diagnostics/index.d.ts +5 -0
  82. package/dist/diagnostics/index.d.ts.map +1 -0
  83. package/dist/diagnostics/index.js +3 -0
  84. package/dist/diagnostics/index.js.map +1 -0
  85. package/dist/diagnostics/timing.d.ts +48 -0
  86. package/dist/diagnostics/timing.d.ts.map +1 -0
  87. package/dist/diagnostics/timing.js +85 -0
  88. package/dist/diagnostics/timing.js.map +1 -0
  89. package/dist/diagnostics/truthfulness.d.ts +36 -0
  90. package/dist/diagnostics/truthfulness.d.ts.map +1 -0
  91. package/dist/diagnostics/truthfulness.js +180 -0
  92. package/dist/diagnostics/truthfulness.js.map +1 -0
  93. package/dist/dispatch-memoization.d.ts +84 -0
  94. package/dist/dispatch-memoization.d.ts.map +1 -0
  95. package/dist/dispatch-memoization.js +197 -0
  96. package/dist/dispatch-memoization.js.map +1 -0
  97. package/dist/eval/comparison-report.d.ts +164 -0
  98. package/dist/eval/comparison-report.d.ts.map +1 -0
  99. package/dist/eval/comparison-report.js +316 -0
  100. package/dist/eval/comparison-report.js.map +1 -0
  101. package/dist/eval/fixture.d.ts +74 -0
  102. package/dist/eval/fixture.d.ts.map +1 -0
  103. package/dist/eval/fixture.js +217 -0
  104. package/dist/eval/fixture.js.map +1 -0
  105. package/dist/eval/index.d.ts +13 -0
  106. package/dist/eval/index.d.ts.map +1 -0
  107. package/dist/eval/index.js +7 -0
  108. package/dist/eval/index.js.map +1 -0
  109. package/dist/eval/load-node.d.ts +16 -0
  110. package/dist/eval/load-node.d.ts.map +1 -0
  111. package/dist/eval/load-node.js +58 -0
  112. package/dist/eval/load-node.js.map +1 -0
  113. package/dist/eval/metric-collector.d.ts +209 -0
  114. package/dist/eval/metric-collector.d.ts.map +1 -0
  115. package/dist/eval/metric-collector.js +293 -0
  116. package/dist/eval/metric-collector.js.map +1 -0
  117. package/dist/eval/run-record.d.ts +76 -0
  118. package/dist/eval/run-record.d.ts.map +1 -0
  119. package/dist/eval/run-record.js +32 -0
  120. package/dist/eval/run-record.js.map +1 -0
  121. package/dist/eval/runner.d.ts +140 -0
  122. package/dist/eval/runner.d.ts.map +1 -0
  123. package/dist/eval/runner.js +310 -0
  124. package/dist/eval/runner.js.map +1 -0
  125. package/dist/eval/spec-framework.d.ts +113 -0
  126. package/dist/eval/spec-framework.d.ts.map +1 -0
  127. package/dist/eval/spec-framework.js +100 -0
  128. package/dist/eval/spec-framework.js.map +1 -0
  129. package/dist/eval/spec-helpers.d.ts +245 -0
  130. package/dist/eval/spec-helpers.d.ts.map +1 -0
  131. package/dist/eval/spec-helpers.js +605 -0
  132. package/dist/eval/spec-helpers.js.map +1 -0
  133. package/dist/events/codec.d.ts +79 -0
  134. package/dist/events/codec.d.ts.map +1 -0
  135. package/dist/events/codec.js +142 -0
  136. package/dist/events/codec.js.map +1 -0
  137. package/dist/events/log-core.d.ts +76 -0
  138. package/dist/events/log-core.d.ts.map +1 -0
  139. package/dist/events/log-core.js +73 -0
  140. package/dist/events/log-core.js.map +1 -0
  141. package/dist/events/log.d.ts +60 -0
  142. package/dist/events/log.d.ts.map +1 -0
  143. package/dist/events/log.js +193 -0
  144. package/dist/events/log.js.map +1 -0
  145. package/dist/events/replay.d.ts +106 -0
  146. package/dist/events/replay.d.ts.map +1 -0
  147. package/dist/events/replay.js +137 -0
  148. package/dist/events/replay.js.map +1 -0
  149. package/dist/events/wrap.d.ts +100 -0
  150. package/dist/events/wrap.d.ts.map +1 -0
  151. package/dist/events/wrap.js +141 -0
  152. package/dist/events/wrap.js.map +1 -0
  153. package/dist/index.d.ts +73 -0
  154. package/dist/index.d.ts.map +1 -0
  155. package/dist/index.js +47 -0
  156. package/dist/index.js.map +1 -0
  157. package/dist/llm-adapter.d.ts +96 -0
  158. package/dist/llm-adapter.d.ts.map +1 -0
  159. package/dist/llm-adapter.js +132 -0
  160. package/dist/llm-adapter.js.map +1 -0
  161. package/dist/mcp/serve.d.ts +70 -0
  162. package/dist/mcp/serve.d.ts.map +1 -0
  163. package/dist/mcp/serve.js +154 -0
  164. package/dist/mcp/serve.js.map +1 -0
  165. package/dist/metrics/runs.d.ts +58 -0
  166. package/dist/metrics/runs.d.ts.map +1 -0
  167. package/dist/metrics/runs.js +99 -0
  168. package/dist/metrics/runs.js.map +1 -0
  169. package/dist/metrics.d.ts +38 -0
  170. package/dist/metrics.d.ts.map +1 -0
  171. package/dist/metrics.js +123 -0
  172. package/dist/metrics.js.map +1 -0
  173. package/dist/node.d.ts +23 -0
  174. package/dist/node.d.ts.map +1 -0
  175. package/dist/node.js +23 -0
  176. package/dist/node.js.map +1 -0
  177. package/dist/planner-executor.d.ts +132 -0
  178. package/dist/planner-executor.d.ts.map +1 -0
  179. package/dist/planner-executor.js +274 -0
  180. package/dist/planner-executor.js.map +1 -0
  181. package/dist/session.d.ts +10 -0
  182. package/dist/session.d.ts.map +1 -0
  183. package/dist/session.js +179 -0
  184. package/dist/session.js.map +1 -0
  185. package/dist/skill-catalog.d.ts +81 -0
  186. package/dist/skill-catalog.d.ts.map +1 -0
  187. package/dist/skill-catalog.js +388 -0
  188. package/dist/skill-catalog.js.map +1 -0
  189. package/dist/skill-router.d.ts +95 -0
  190. package/dist/skill-router.d.ts.map +1 -0
  191. package/dist/skill-router.js +130 -0
  192. package/dist/skill-router.js.map +1 -0
  193. package/dist/storage.d.ts +14 -0
  194. package/dist/storage.d.ts.map +1 -0
  195. package/dist/storage.js +58 -0
  196. package/dist/storage.js.map +1 -0
  197. package/dist/strategy.d.ts +45 -0
  198. package/dist/strategy.d.ts.map +1 -0
  199. package/dist/strategy.js +520 -0
  200. package/dist/strategy.js.map +1 -0
  201. package/dist/tools.d.ts +40 -0
  202. package/dist/tools.d.ts.map +1 -0
  203. package/dist/tools.js +147 -0
  204. package/dist/tools.js.map +1 -0
  205. package/dist/types/agent.d.ts +94 -0
  206. package/dist/types/agent.d.ts.map +1 -0
  207. package/dist/types/agent.js +17 -0
  208. package/dist/types/agent.js.map +1 -0
  209. package/dist/types/capabilities.d.ts +17 -0
  210. package/dist/types/capabilities.d.ts.map +1 -0
  211. package/dist/types/capabilities.js +13 -0
  212. package/dist/types/capabilities.js.map +1 -0
  213. package/dist/types/chat.d.ts +74 -0
  214. package/dist/types/chat.d.ts.map +1 -0
  215. package/dist/types/chat.js +10 -0
  216. package/dist/types/chat.js.map +1 -0
  217. package/dist/types/events.d.ts +115 -0
  218. package/dist/types/events.d.ts.map +1 -0
  219. package/dist/types/events.js +30 -0
  220. package/dist/types/events.js.map +1 -0
  221. package/dist/types/llm.d.ts +89 -0
  222. package/dist/types/llm.d.ts.map +1 -0
  223. package/dist/types/llm.js +12 -0
  224. package/dist/types/llm.js.map +1 -0
  225. package/dist/types/metrics.d.ts +34 -0
  226. package/dist/types/metrics.d.ts.map +1 -0
  227. package/dist/types/metrics.js +10 -0
  228. package/dist/types/metrics.js.map +1 -0
  229. package/dist/types/observer.d.ts +41 -0
  230. package/dist/types/observer.d.ts.map +1 -0
  231. package/dist/types/observer.js +41 -0
  232. package/dist/types/observer.js.map +1 -0
  233. package/dist/types/project-context.d.ts +18 -0
  234. package/dist/types/project-context.d.ts.map +1 -0
  235. package/dist/types/project-context.js +11 -0
  236. package/dist/types/project-context.js.map +1 -0
  237. package/dist/types/runtime.d.ts +71 -0
  238. package/dist/types/runtime.d.ts.map +1 -0
  239. package/dist/types/runtime.js +21 -0
  240. package/dist/types/runtime.js.map +1 -0
  241. package/dist/types/session.d.ts +103 -0
  242. package/dist/types/session.d.ts.map +1 -0
  243. package/dist/types/session.js +11 -0
  244. package/dist/types/session.js.map +1 -0
  245. package/dist/types/storage.d.ts +20 -0
  246. package/dist/types/storage.d.ts.map +1 -0
  247. package/dist/types/storage.js +41 -0
  248. package/dist/types/storage.js.map +1 -0
  249. package/dist/types/strategy.d.ts +124 -0
  250. package/dist/types/strategy.d.ts.map +1 -0
  251. package/dist/types/strategy.js +10 -0
  252. package/dist/types/strategy.js.map +1 -0
  253. package/dist/types/tools.d.ts +154 -0
  254. package/dist/types/tools.d.ts.map +1 -0
  255. package/dist/types/tools.js +11 -0
  256. package/dist/types/tools.js.map +1 -0
  257. package/dist/types/trace.d.ts +175 -0
  258. package/dist/types/trace.d.ts.map +1 -0
  259. package/dist/types/trace.js +26 -0
  260. package/dist/types/trace.js.map +1 -0
  261. package/dist/types/workspace.d.ts +29 -0
  262. package/dist/types/workspace.d.ts.map +1 -0
  263. package/dist/types/workspace.js +18 -0
  264. package/dist/types/workspace.js.map +1 -0
  265. package/package.json +45 -14
  266. package/skills/agent-cli.md +218 -0
  267. package/index.js +0 -2
@@ -0,0 +1,341 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
2
+ /**
3
+ * Run view — OpenTUI/React renderer for `agent run` when stdout is a
4
+ * TTY. Subscribes to the `AgentSession` event stream and projects it
5
+ * into a four-section layout: header (run metadata) → thinking
6
+ * (scrollable trace) → output (markdown) → tool cards → footer
7
+ * (token/cost/elapsed).
8
+ *
9
+ * Wiring lives in `cli/commands/run.ts` — the runCommand picks this
10
+ * over the NDJSON emitter when `pickMode()` resolves to `text` AND
11
+ * stdout.isTTY. NDJSON / piped / `--output ndjson` keep the existing
12
+ * emitter behavior; agent integrations + tests rely on it.
13
+ *
14
+ * v0 scaffold (this file): state machine + placeholder layout. The
15
+ * scrollbox / markdown / code components plug in over the next two
16
+ * phases.
17
+ */
18
+ import { RGBA, SyntaxStyle } from '@opentui/core';
19
+ import { useKeyboard } from '@opentui/react';
20
+ import { useEffect, useReducer } from 'react';
21
+ /**
22
+ * Shared syntax-highlighting palette for the `<markdown>` and `<code>`
23
+ * components. Dark-on-default; close enough to GitHub-dark for
24
+ * markdown headings + code fences. Tree-sitter capture names follow
25
+ * the upstream highlight-queries convention (`markup.heading.1`,
26
+ * `keyword`, `string`, …) — fall back to `default` for unmapped
27
+ * captures.
28
+ */
29
+ const SYNTAX_STYLE = SyntaxStyle.fromStyles({
30
+ default: { fg: RGBA.fromHex('#e6edf3') },
31
+ 'markup.heading.1': { fg: RGBA.fromHex('#58a6ff'), bold: true },
32
+ 'markup.heading.2': { fg: RGBA.fromHex('#58a6ff'), bold: true },
33
+ 'markup.heading.3': { fg: RGBA.fromHex('#58a6ff'), bold: true },
34
+ 'markup.list': { fg: RGBA.fromHex('#ff7b72') },
35
+ 'markup.bold': { fg: RGBA.fromHex('#e6edf3'), bold: true },
36
+ 'markup.italic': { fg: RGBA.fromHex('#e6edf3'), italic: true },
37
+ 'markup.raw': { fg: RGBA.fromHex('#a5d6ff') },
38
+ 'markup.link': { fg: RGBA.fromHex('#79c0ff'), underline: true },
39
+ keyword: { fg: RGBA.fromHex('#ff7b72') },
40
+ string: { fg: RGBA.fromHex('#a5d6ff') },
41
+ number: { fg: RGBA.fromHex('#79c0ff') },
42
+ function: { fg: RGBA.fromHex('#d2a8ff') },
43
+ comment: { fg: RGBA.fromHex('#8b949e'), italic: true },
44
+ type: { fg: RGBA.fromHex('#ffa657') },
45
+ variable: { fg: RGBA.fromHex('#e6edf3') },
46
+ punctuation: { fg: RGBA.fromHex('#8b949e') },
47
+ });
48
+ export const initialState = {
49
+ sessionId: '',
50
+ scenario: '',
51
+ llmLabel: '',
52
+ promptPreview: '',
53
+ currentTurn: 0,
54
+ thinking: '',
55
+ output: '',
56
+ tools: [],
57
+ status: 'idle',
58
+ tokensIn: 0,
59
+ tokensOut: 0,
60
+ tokensCached: 0,
61
+ tokensReasoning: 0,
62
+ costUsd: 0,
63
+ startedAtMs: Date.now(),
64
+ elapsedMs: 0,
65
+ thinkingCollapsed: false,
66
+ };
67
+ export function reduce(s, a) {
68
+ switch (a.type) {
69
+ case 'session_start':
70
+ return {
71
+ ...s,
72
+ sessionId: a.sessionId,
73
+ scenario: a.scenario,
74
+ promptPreview: a.promptPreview,
75
+ status: 'thinking',
76
+ startedAtMs: Date.now(),
77
+ };
78
+ case 'llm_selected':
79
+ return {
80
+ ...s,
81
+ llmLabel: a.label,
82
+ ...(a.fallbackReason ? { llmFallbackReason: a.fallbackReason } : {}),
83
+ };
84
+ case 'turn_started':
85
+ return { ...s, currentTurn: a.turnNo, status: 'thinking' };
86
+ case 'thinking':
87
+ return { ...s, status: 'thinking', thinking: s.thinking + a.chunk };
88
+ case 'text':
89
+ return { ...s, status: 'streaming', output: s.output + a.chunk };
90
+ case 'tool_started':
91
+ return {
92
+ ...s,
93
+ status: 'tool',
94
+ tools: [...s.tools, { callId: a.callId, name: a.name, args: a.args }],
95
+ };
96
+ case 'tool_finished':
97
+ return {
98
+ ...s,
99
+ tools: s.tools.map((t) => t.callId === a.callId
100
+ ? { ...t, result: { ok: a.ok, ...(a.summary ? { summary: a.summary } : {}) } }
101
+ : t),
102
+ };
103
+ case 'turn_completed':
104
+ return {
105
+ ...s,
106
+ tokensIn: s.tokensIn + a.tokensIn,
107
+ tokensOut: s.tokensOut + a.tokensOut,
108
+ tokensCached: s.tokensCached + a.tokensCached,
109
+ tokensReasoning: s.tokensReasoning + a.tokensReasoning,
110
+ costUsd: s.costUsd + a.costUsd,
111
+ };
112
+ case 'session_end':
113
+ return { ...s, status: 'done' };
114
+ case 'error':
115
+ return { ...s, status: 'error', errorMessage: a.message };
116
+ case 'tick':
117
+ return { ...s, elapsedMs: a.nowMs - s.startedAtMs };
118
+ case 'toggle_thinking':
119
+ return { ...s, thinkingCollapsed: !s.thinkingCollapsed };
120
+ default:
121
+ return s;
122
+ }
123
+ }
124
+ // ─── Stream ↔ dispatch bridge ────────────────────────────────────────
125
+ /**
126
+ * Consume an async iterable of SessionEvents and dispatch reducer
127
+ * actions. Stops on `completed` or `error`. Caller is responsible for
128
+ * passing the cancellation `signal` through if the user aborts.
129
+ */
130
+ async function pumpEvents(stream, dispatch) {
131
+ let turnNo = 0;
132
+ for await (const ev of stream) {
133
+ switch (ev.kind) {
134
+ case 'turn_started':
135
+ turnNo += 1;
136
+ dispatch({ type: 'turn_started', turnNo });
137
+ break;
138
+ case 'thinking':
139
+ dispatch({ type: 'thinking', chunk: ev.chunk });
140
+ break;
141
+ case 'text':
142
+ dispatch({ type: 'text', chunk: ev.chunk });
143
+ break;
144
+ case 'tool_started':
145
+ dispatch({
146
+ type: 'tool_started',
147
+ callId: ev.callId,
148
+ name: ev.name,
149
+ args: ev.args,
150
+ });
151
+ break;
152
+ case 'tool_finished':
153
+ dispatch({
154
+ type: 'tool_finished',
155
+ callId: ev.callId,
156
+ ok: ev.result.ok,
157
+ ...(ev.result.summary ? { summary: ev.result.summary } : {}),
158
+ });
159
+ break;
160
+ case 'turn_completed':
161
+ dispatch({
162
+ type: 'turn_completed',
163
+ tokensIn: ev.metrics.tokensIn,
164
+ tokensOut: ev.metrics.tokensOut,
165
+ tokensCached: ev.metrics.tokensCached,
166
+ tokensReasoning: ev.metrics.tokensReasoning,
167
+ costUsd: ev.metrics.costUsd,
168
+ });
169
+ break;
170
+ case 'error':
171
+ dispatch({ type: 'error', message: ev.message });
172
+ break;
173
+ case 'completed':
174
+ dispatch({ type: 'session_end' });
175
+ return;
176
+ }
177
+ }
178
+ }
179
+ // ─── Component ───────────────────────────────────────────────────────
180
+ /**
181
+ * v0 stub. Phase 4 fills in the actual layout (header, scrollbox of
182
+ * thinking, markdown output, tool cards, footer). For now this just
183
+ * proves the pipe works — reducer dispatch, async-iterable pump, and
184
+ * a single `<box>` showing live status.
185
+ */
186
+ export function RunView({ events, bootstrap, onQuit }) {
187
+ const [state, dispatch] = useReducer(reduce, {
188
+ ...initialState,
189
+ sessionId: bootstrap.sessionId,
190
+ scenario: bootstrap.scenario,
191
+ llmLabel: bootstrap.llmLabel,
192
+ promptPreview: bootstrap.promptPreview,
193
+ ...(bootstrap.llmFallbackReason ? { llmFallbackReason: bootstrap.llmFallbackReason } : {}),
194
+ ...(bootstrap.logPath ? { logPath: bootstrap.logPath } : {}),
195
+ });
196
+ // Pump events into the reducer. Restarts only if the iterator
197
+ // identity changes (it won't, mid-session).
198
+ useEffect(() => {
199
+ let cancelled = false;
200
+ void (async () => {
201
+ try {
202
+ await pumpEvents(events, (a) => {
203
+ if (!cancelled)
204
+ dispatch(a);
205
+ });
206
+ }
207
+ catch (err) {
208
+ if (!cancelled) {
209
+ dispatch({
210
+ type: 'error',
211
+ message: err instanceof Error ? err.message : String(err),
212
+ });
213
+ }
214
+ }
215
+ // No onComplete fire here — the TUI stays up after stream end
216
+ // so the user can read the FinalSummary. They exit via `q` /
217
+ // `Escape` (handled below).
218
+ })();
219
+ return () => {
220
+ cancelled = true;
221
+ };
222
+ }, [events]);
223
+ // Elapsed-timer tick — once a second, dispatch a tick so the footer
224
+ // re-renders with a live elapsed counter even when no events fire.
225
+ useEffect(() => {
226
+ if (state.status === 'done' || state.status === 'error')
227
+ return;
228
+ const id = setInterval(() => dispatch({ type: 'tick', nowMs: Date.now() }), 1000);
229
+ return () => clearInterval(id);
230
+ }, [state.status]);
231
+ // Keyboard:
232
+ // `t` — toggle thinking-section visibility (works any time)
233
+ // `q` / Escape — exit, but only after the session has ended.
234
+ // Pressing q mid-stream is a no-op rather than
235
+ // aborting; aborting would need a cancellation
236
+ // handle we don't thread through the view today.
237
+ // Ctrl-C — handled by the renderer (`exitOnCtrlC: true`)
238
+ // in `runWithTui`. Hard exit; runs the post-
239
+ // teardown summary path.
240
+ useKeyboard((key) => {
241
+ if (key.name === 't') {
242
+ dispatch({ type: 'toggle_thinking' });
243
+ return;
244
+ }
245
+ if (key.name === 'q' || key.name === 'escape') {
246
+ if (state.status === 'done' || state.status === 'error')
247
+ onQuit?.();
248
+ }
249
+ });
250
+ const done = state.status === 'done' || state.status === 'error';
251
+ return (_jsxs("box", { style: { flexDirection: 'column', padding: 1, gap: 1 }, children: [_jsx(Header, { state: state }), _jsx(ThinkingSection, { state: state, dispatch: dispatch }), _jsx(OutputSection, { state: state }), _jsx(ToolsSection, { state: state }), done ? _jsx(FinalSummary, { state: state }) : _jsx(Footer, { state: state })] }));
252
+ }
253
+ // ─── Sections ────────────────────────────────────────────────────────
254
+ /**
255
+ * Header — session id, llm label, prompt preview. Rendered every tick
256
+ * (cheap) so a single component owns the chrome. The data is set once
257
+ * via bootstrap and `llm_selected` and doesn't change again.
258
+ */
259
+ function Header({ state }) {
260
+ return (_jsxs("box", { style: { border: true, padding: 1, flexDirection: 'column' }, children: [_jsxs("text", { children: [_jsx("text", { fg: "#888", children: "session " }), state.sessionId] }), _jsxs("text", { children: [_jsx("text", { fg: "#888", children: "llm " }), state.llmLabel] }), state.llmFallbackReason ? _jsxs("text", { fg: "#888", children: [" (", state.llmFallbackReason, ")"] }) : null, _jsxs("text", { children: [_jsx("text", { fg: "#888", children: "prompt " }), state.promptPreview] })] }));
261
+ }
262
+ /**
263
+ * Thinking — accumulates reasoning chunks into a scrollable trace.
264
+ * Hidden until the first chunk arrives. Auto-scrolls to bottom on new
265
+ * content via `stickyScroll`. A char counter in the heading gives a
266
+ * sense of magnitude even when the trace overflows.
267
+ */
268
+ function ThinkingSection({ state, dispatch, }) {
269
+ void dispatch; // dispatch isn't used here directly — the `t` keyboard
270
+ // handler in RunView owns toggling. Accepted as a prop
271
+ // for future affordances (clickable header, etc.).
272
+ if (state.thinking.length === 0)
273
+ return null;
274
+ const collapsed = state.thinkingCollapsed;
275
+ return (_jsxs("box", { style: { flexDirection: 'column' }, children: [_jsxs("text", { fg: "#888", children: [collapsed ? '▸' : '▾', " Thinking \u00B7 ", state.thinking.length, " chars", _jsxs("text", { fg: "#666", children: [" [t to ", collapsed ? 'expand' : 'collapse', "]"] })] }), collapsed ? null : (_jsx("scrollbox", { style: { height: 8, border: true, padding: 1 }, stickyScroll: true, children: _jsx("text", { fg: "#888", children: state.thinking }) }))] }));
276
+ }
277
+ /**
278
+ * Output — the model's answer rendered as markdown so headings, code
279
+ * fences, and lists land formatted instead of as raw prose. While
280
+ * streaming, partial markdown will re-render mid-construct (open code
281
+ * fence, half a header) — that's expected; the render settles when
282
+ * the chunk completes the syntax.
283
+ */
284
+ function OutputSection({ state }) {
285
+ if (state.output.length === 0) {
286
+ return _jsx("text", { fg: "#888", children: " \u2839 waiting for output\u2026" });
287
+ }
288
+ return (_jsxs("box", { style: { flexDirection: 'column' }, children: [_jsx("text", { fg: "#888", children: "Output" }), _jsx("markdown", { content: state.output, syntaxStyle: SYNTAX_STYLE })] }));
289
+ }
290
+ /**
291
+ * Tools — one card per tool call. While in flight, the card shows a
292
+ * spinner; on `tool_finished` it switches to ✓/✗ + summary. Args are
293
+ * rendered as JSON via the `<code>` component so they get
294
+ * syntax-highlighted (useful for big payloads).
295
+ */
296
+ function ToolsSection({ state }) {
297
+ if (state.tools.length === 0)
298
+ return null;
299
+ return (_jsxs("box", { style: { flexDirection: 'column' }, children: [_jsx("text", { fg: "#888", children: "Tools" }), state.tools.map((t) => (_jsxs("box", { style: { border: true, padding: 1, flexDirection: 'column' }, children: [_jsxs("text", { children: [t.result ? (t.result.ok ? '✓' : '✗') : '⠹', " ", t.name, t.result?.summary ? _jsxs("text", { fg: "#aaa", children: [" \u00B7 ", t.result.summary] }) : null] }), _jsx("code", { content: safeStringify(t.args), filetype: "json", syntaxStyle: SYNTAX_STYLE })] }, t.callId)))] }));
300
+ }
301
+ /**
302
+ * Footer — running totals + elapsed timer + status. Updates every
303
+ * 1s via the `tick` action AND on every event. Freezes on
304
+ * `session_end`; the bottom border + `done`/`error` status make the
305
+ * frozen state obvious so the user knows the run is over.
306
+ */
307
+ function Footer({ state }) {
308
+ const statusColor = state.status === 'error' ? '#f55' : state.status === 'done' ? '#5f5' : '#aaa';
309
+ return (_jsxs("box", { style: { border: true, padding: 1, flexDirection: 'column' }, children: [_jsxs("text", { children: [_jsx("text", { fg: statusColor, children: state.status }), _jsx("text", { fg: "#888", children: " \u00B7 turn " }), state.currentTurn || 0, _jsx("text", { fg: "#888", children: " \u00B7 " }), state.tokensIn, "+", state.tokensOut, " tok", _jsx("text", { fg: "#888", children: " \u00B7 $" }), state.costUsd.toFixed(6), _jsx("text", { fg: "#888", children: " \u00B7 " }), (state.elapsedMs / 1000).toFixed(1), "s"] }), state.errorMessage ? _jsxs("text", { fg: "#f55", children: ["error: ", state.errorMessage] }) : null] }));
310
+ }
311
+ /**
312
+ * Final summary — replaces the live Footer once status flips to
313
+ * `done` or `error`. Shows the full token breakdown (cached +
314
+ * reasoning surfaced separately so the user understands provider
315
+ * cost composition), elapsed time, log path, and exit status.
316
+ *
317
+ * Visible only briefly today — runWithTui awaits `onComplete` then
318
+ * immediately destroys the renderer. Phase 6 will keep the TUI alive
319
+ * until the user presses `q`, at which point this is what they read.
320
+ */
321
+ function FinalSummary({ state }) {
322
+ const statusColor = state.status === 'error' ? '#f55' : '#5f5';
323
+ const tokensTotal = state.tokensIn + state.tokensOut;
324
+ return (_jsxs("box", { style: { border: true, padding: 1, flexDirection: 'column' }, children: [_jsx("text", { children: _jsx("text", { fg: statusColor, children: state.status === 'error' ? '✗ Session failed' : '✓ Session complete' }) }), _jsx("text", { children: " " }), _jsxs("text", { children: [_jsx("text", { fg: "#888", children: "turns " }), state.currentTurn || 0] }), _jsxs("text", { children: [_jsx("text", { fg: "#888", children: "tokens " }), formatNum(tokensTotal), _jsxs("text", { fg: "#888", children: [' ', "(in ", formatNum(state.tokensIn), " \u00B7 out ", formatNum(state.tokensOut)] }), state.tokensCached > 0 ? (_jsxs("text", { fg: "#888", children: [" \u00B7 cached ", formatNum(state.tokensCached)] })) : null, state.tokensReasoning > 0 ? (_jsxs("text", { fg: "#888", children: [" \u00B7 reasoning ", formatNum(state.tokensReasoning)] })) : null, _jsx("text", { fg: "#888", children: ")" })] }), _jsxs("text", { children: [_jsx("text", { fg: "#888", children: "cost " }), "$", state.costUsd.toFixed(6)] }), _jsxs("text", { children: [_jsx("text", { fg: "#888", children: "elapsed " }), (state.elapsedMs / 1000).toFixed(1), "s"] }), state.logPath ? (_jsxs("text", { children: [_jsx("text", { fg: "#888", children: "log " }), state.logPath] })) : null, state.errorMessage ? _jsxs("text", { fg: "#f55", children: ["error: ", state.errorMessage] }) : null, _jsx("text", { children: " " }), _jsx("text", { fg: "#666", children: "Press q or Esc to exit \u00B7 t to toggle thinking" })] }));
325
+ }
326
+ // ─── Utilities ───────────────────────────────────────────────────────
327
+ /** US-style thousands separator. Cheap; no Intl. */
328
+ function formatNum(n) {
329
+ if (!Number.isFinite(n))
330
+ return String(n);
331
+ return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
332
+ }
333
+ function safeStringify(v) {
334
+ try {
335
+ return JSON.stringify(v, null, 2);
336
+ }
337
+ catch {
338
+ return String(v);
339
+ }
340
+ }
341
+ //# sourceMappingURL=RunView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunView.js","sourceRoot":"","sources":["../../../src/cli/ui/RunView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export type { TruthfulnessFlag, TruthfulnessFlagCategory, TruthfulnessReport, } from './truthfulness.js';
2
+ export { analyzeTruthfulness } from './truthfulness.js';
3
+ export type { TurnTimingRow } from './timing.js';
4
+ export { turnTimingTable } from './timing.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/diagnostics/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { analyzeTruthfulness } from './truthfulness.js';
2
+ export { turnTimingTable } from './timing.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/diagnostics/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Wall-clock split helper. Consumes a captured `TraceEvent[]` and
3
+ * returns one `TurnTimingRow` per ReAct iteration, with the
4
+ * iteration's language-model time and tool-dispatch time as
5
+ * separate columns.
6
+ *
7
+ * Pairing rule: events are matched by `requestId`. An iteration
8
+ * with only an `llm_request` (e.g. mid-stream error before
9
+ * `llm_response`) yields a row with `llmMs: undefined` and
10
+ * `dispatchMs: undefined`. An iteration with `llm_request` +
11
+ * `llm_response` but no `turn_dispatch_complete` (the final
12
+ * assistant turn that emits no tool calls) yields `llmMs` and
13
+ * `dispatchMs: undefined`. Missing endpoints never throw.
14
+ *
15
+ * `totalMs` is the iteration's full wall-clock from request
16
+ * dispatch through the tool-dispatch close — i.e. `dispatchEndMs -
17
+ * requestStartMs`. It is `undefined` whenever either endpoint is
18
+ * missing.
19
+ */
20
+ import type { TraceEvent } from '../types/trace.js';
21
+ export interface TurnTimingRow {
22
+ /** Session-scoped turn id. Multiple rows share a `turnId` when
23
+ * the turn ran multiple ReAct iterations. */
24
+ turnId: string;
25
+ /** 0-indexed ReAct iteration within the turn. Unique together
26
+ * with `turnId`; identical to the iteration index encoded in
27
+ * `requestId`. */
28
+ iteration: number;
29
+ /** Stable id for the row. Matches
30
+ * `LlmRequestTrace.requestId` / `LlmResponseTrace.requestId` /
31
+ * `TurnDispatchCompleteTrace.requestId`. */
32
+ requestId: string;
33
+ /** Wall-clock ms spent in the language model: response timestamp
34
+ * minus request timestamp. `undefined` if either endpoint is
35
+ * missing (e.g. mid-stream error). */
36
+ llmMs: number | undefined;
37
+ /** Wall-clock ms spent in tool dispatch: turn-dispatch-complete
38
+ * timestamp minus response timestamp. `undefined` for the final
39
+ * assistant turn (no tool calls → no dispatch event) or when
40
+ * the response endpoint is missing. */
41
+ dispatchMs: number | undefined;
42
+ /** Wall-clock ms across the full iteration: turn-dispatch-complete
43
+ * timestamp minus request timestamp. `undefined` when either
44
+ * endpoint is missing. */
45
+ totalMs: number | undefined;
46
+ }
47
+ export declare function turnTimingTable(events: readonly TraceEvent[]): TurnTimingRow[];
48
+ //# sourceMappingURL=timing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../../src/diagnostics/timing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B;kDAC8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf;;uBAEmB;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB;;iDAE6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB;;2CAEuC;IACvC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;;4CAGwC;IACxC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;+BAE2B;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAaD,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,aAAa,EAAE,CAsE9E"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Wall-clock split helper. Consumes a captured `TraceEvent[]` and
3
+ * returns one `TurnTimingRow` per ReAct iteration, with the
4
+ * iteration's language-model time and tool-dispatch time as
5
+ * separate columns.
6
+ *
7
+ * Pairing rule: events are matched by `requestId`. An iteration
8
+ * with only an `llm_request` (e.g. mid-stream error before
9
+ * `llm_response`) yields a row with `llmMs: undefined` and
10
+ * `dispatchMs: undefined`. An iteration with `llm_request` +
11
+ * `llm_response` but no `turn_dispatch_complete` (the final
12
+ * assistant turn that emits no tool calls) yields `llmMs` and
13
+ * `dispatchMs: undefined`. Missing endpoints never throw.
14
+ *
15
+ * `totalMs` is the iteration's full wall-clock from request
16
+ * dispatch through the tool-dispatch close — i.e. `dispatchEndMs -
17
+ * requestStartMs`. It is `undefined` whenever either endpoint is
18
+ * missing.
19
+ */
20
+ export function turnTimingTable(events) {
21
+ const byRequestId = new Map();
22
+ const touch = (requestId) => {
23
+ let acc = byRequestId.get(requestId);
24
+ if (!acc) {
25
+ acc = {
26
+ turnId: undefined,
27
+ iteration: undefined,
28
+ requestTs: undefined,
29
+ responseTs: undefined,
30
+ dispatchTs: undefined,
31
+ firstSeenAt: byRequestId.size,
32
+ };
33
+ byRequestId.set(requestId, acc);
34
+ }
35
+ return acc;
36
+ };
37
+ for (const ev of events) {
38
+ if (ev.kind === 'llm_request') {
39
+ const acc = touch(ev.data.requestId);
40
+ acc.turnId = ev.data.turnId;
41
+ acc.iteration = ev.data.iteration;
42
+ acc.requestTs = ev.data.ts;
43
+ }
44
+ else if (ev.kind === 'llm_response') {
45
+ const acc = touch(ev.data.requestId);
46
+ acc.responseTs = ev.data.ts;
47
+ }
48
+ else if (ev.kind === 'turn_dispatch_complete') {
49
+ const acc = touch(ev.data.requestId);
50
+ // `llm_request` is the canonical source for turnId/iteration,
51
+ // but fall through to the dispatch event so an out-of-order or
52
+ // truncated trace still produces a useful row.
53
+ acc.turnId = acc.turnId ?? ev.data.turnId;
54
+ acc.iteration = acc.iteration ?? ev.data.iteration;
55
+ acc.dispatchTs = ev.data.ts;
56
+ }
57
+ }
58
+ const rows = [];
59
+ for (const [requestId, acc] of byRequestId) {
60
+ const llmMs = acc.requestTs !== undefined && acc.responseTs !== undefined
61
+ ? acc.responseTs - acc.requestTs
62
+ : undefined;
63
+ const dispatchMs = acc.responseTs !== undefined && acc.dispatchTs !== undefined
64
+ ? acc.dispatchTs - acc.responseTs
65
+ : undefined;
66
+ const totalMs = acc.requestTs !== undefined && acc.dispatchTs !== undefined
67
+ ? acc.dispatchTs - acc.requestTs
68
+ : undefined;
69
+ rows.push({
70
+ turnId: acc.turnId ?? 'turn-anon',
71
+ iteration: acc.iteration ?? 0,
72
+ requestId,
73
+ llmMs,
74
+ dispatchMs,
75
+ totalMs,
76
+ });
77
+ }
78
+ rows.sort((a, b) => {
79
+ const accA = byRequestId.get(a.requestId);
80
+ const accB = byRequestId.get(b.requestId);
81
+ return accA.firstSeenAt - accB.firstSeenAt;
82
+ });
83
+ return rows;
84
+ }
85
+ //# sourceMappingURL=timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing.js","sourceRoot":"","sources":["../../src/diagnostics/timing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Post-hoc truthfulness detector for agent traces.
3
+ *
4
+ * Walks a list of `TraceEvent`s, pairs each `llm_request` with its
5
+ * matching `llm_response` (or derives the response text from the next
6
+ * request's appended assistant message), extracts candidate factual
7
+ * claims from the assistant text, and flags claims that do not appear
8
+ * in the grounding corpus visible to the model at that moment.
9
+ *
10
+ * The grounding corpus is the union of the system prompt, every
11
+ * message text in the request, and every tool result JSON in the
12
+ * request. Verification is literal substring match — case sensitive.
13
+ *
14
+ * The implementation plan's phase zero calls for an intentionally
15
+ * simple first version. False positives are acceptable. False
16
+ * negatives (missed fabrications) are the failure mode the eval
17
+ * harness will surface later via golden tasks.
18
+ */
19
+ import type { TraceEvent } from '../types/trace.js';
20
+ export type TruthfulnessFlagCategory = 'firestore-path' | 'quoted-identifier';
21
+ export interface TruthfulnessFlag {
22
+ requestId: string;
23
+ turnId: string;
24
+ iteration: number;
25
+ claim: string;
26
+ category: TruthfulnessFlagCategory;
27
+ context: string;
28
+ }
29
+ export interface TruthfulnessReport {
30
+ totalAssistantTurns: number;
31
+ totalFlags: number;
32
+ flags: TruthfulnessFlag[];
33
+ violationRate: number;
34
+ }
35
+ export declare function analyzeTruthfulness(events: readonly TraceEvent[]): TruthfulnessReport;
36
+ //# sourceMappingURL=truthfulness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truthfulness.d.ts","sourceRoot":"","sources":["../../src/diagnostics/truthfulness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAqC,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEvF,MAAM,MAAM,wBAAwB,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;AAE9E,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,wBAAwB,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACvB;AAqDD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,kBAAkB,CAgCrF"}