@plune-ai/cairn 0.2.1

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 (323) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +181 -0
  3. package/dist/agent/graph.d.ts +538 -0
  4. package/dist/agent/graph.d.ts.map +1 -0
  5. package/dist/agent/graph.js +0 -0
  6. package/dist/agent/graph.js.map +1 -0
  7. package/dist/agent/index.d.ts +83 -0
  8. package/dist/agent/index.d.ts.map +1 -0
  9. package/dist/agent/index.js +407 -0
  10. package/dist/agent/index.js.map +1 -0
  11. package/dist/analyze/index.d.ts +22 -0
  12. package/dist/analyze/index.d.ts.map +1 -0
  13. package/dist/analyze/index.js +39 -0
  14. package/dist/analyze/index.js.map +1 -0
  15. package/dist/artifacts/index.d.ts +29 -0
  16. package/dist/artifacts/index.d.ts.map +1 -0
  17. package/dist/artifacts/index.js +68 -0
  18. package/dist/artifacts/index.js.map +1 -0
  19. package/dist/artifacts/report.d.ts +21 -0
  20. package/dist/artifacts/report.d.ts.map +1 -0
  21. package/dist/artifacts/report.js +56 -0
  22. package/dist/artifacts/report.js.map +1 -0
  23. package/dist/artifacts/testcase-md.d.ts +37 -0
  24. package/dist/artifacts/testcase-md.d.ts.map +1 -0
  25. package/dist/artifacts/testcase-md.js +91 -0
  26. package/dist/artifacts/testcase-md.js.map +1 -0
  27. package/dist/browser/backends/playwright-cli.d.ts +23 -0
  28. package/dist/browser/backends/playwright-cli.d.ts.map +1 -0
  29. package/dist/browser/backends/playwright-cli.js +85 -0
  30. package/dist/browser/backends/playwright-cli.js.map +1 -0
  31. package/dist/browser/backends/playwright-lib.d.ts +32 -0
  32. package/dist/browser/backends/playwright-lib.d.ts.map +1 -0
  33. package/dist/browser/backends/playwright-lib.js +157 -0
  34. package/dist/browser/backends/playwright-lib.js.map +1 -0
  35. package/dist/browser/gateway.d.ts +33 -0
  36. package/dist/browser/gateway.d.ts.map +1 -0
  37. package/dist/browser/gateway.js +2 -0
  38. package/dist/browser/gateway.js.map +1 -0
  39. package/dist/browser/index.d.ts +15 -0
  40. package/dist/browser/index.d.ts.map +1 -0
  41. package/dist/browser/index.js +59 -0
  42. package/dist/browser/index.js.map +1 -0
  43. package/dist/browser/types.d.ts +99 -0
  44. package/dist/browser/types.d.ts.map +1 -0
  45. package/dist/browser/types.js +6 -0
  46. package/dist/browser/types.js.map +1 -0
  47. package/dist/checklist/index.d.ts +24 -0
  48. package/dist/checklist/index.d.ts.map +1 -0
  49. package/dist/checklist/index.js +65 -0
  50. package/dist/checklist/index.js.map +1 -0
  51. package/dist/cli/branding.d.ts +14 -0
  52. package/dist/cli/branding.d.ts.map +1 -0
  53. package/dist/cli/branding.js +14 -0
  54. package/dist/cli/branding.js.map +1 -0
  55. package/dist/cli/index.d.ts +12 -0
  56. package/dist/cli/index.d.ts.map +1 -0
  57. package/dist/cli/index.js +322 -0
  58. package/dist/cli/index.js.map +1 -0
  59. package/dist/cli/lex-bot.d.ts +3 -0
  60. package/dist/cli/lex-bot.d.ts.map +1 -0
  61. package/dist/cli/lex-bot.js +11 -0
  62. package/dist/cli/lex-bot.js.map +1 -0
  63. package/dist/codegen/index.d.ts +36 -0
  64. package/dist/codegen/index.d.ts.map +1 -0
  65. package/dist/codegen/index.js +63 -0
  66. package/dist/codegen/index.js.map +1 -0
  67. package/dist/codegen/schema.d.ts +14 -0
  68. package/dist/codegen/schema.d.ts.map +1 -0
  69. package/dist/codegen/schema.js +9 -0
  70. package/dist/codegen/schema.js.map +1 -0
  71. package/dist/config/env.d.ts +18 -0
  72. package/dist/config/env.d.ts.map +1 -0
  73. package/dist/config/env.js +42 -0
  74. package/dist/config/env.js.map +1 -0
  75. package/dist/config/index.d.ts +11 -0
  76. package/dist/config/index.d.ts.map +1 -0
  77. package/dist/config/index.js +74 -0
  78. package/dist/config/index.js.map +1 -0
  79. package/dist/config/profiles.d.ts +7 -0
  80. package/dist/config/profiles.d.ts.map +1 -0
  81. package/dist/config/profiles.js +28 -0
  82. package/dist/config/profiles.js.map +1 -0
  83. package/dist/config/schema.d.ts +91 -0
  84. package/dist/config/schema.d.ts.map +1 -0
  85. package/dist/config/schema.js +20 -0
  86. package/dist/config/schema.js.map +1 -0
  87. package/dist/design/index.d.ts +36 -0
  88. package/dist/design/index.d.ts.map +1 -0
  89. package/dist/design/index.js +35 -0
  90. package/dist/design/index.js.map +1 -0
  91. package/dist/design/schema.d.ts +109 -0
  92. package/dist/design/schema.d.ts.map +1 -0
  93. package/dist/design/schema.js +35 -0
  94. package/dist/design/schema.js.map +1 -0
  95. package/dist/eval/collect.d.ts +18 -0
  96. package/dist/eval/collect.d.ts.map +1 -0
  97. package/dist/eval/collect.js +53 -0
  98. package/dist/eval/collect.js.map +1 -0
  99. package/dist/eval/experiment.d.ts +49 -0
  100. package/dist/eval/experiment.d.ts.map +1 -0
  101. package/dist/eval/experiment.js +66 -0
  102. package/dist/eval/experiment.js.map +1 -0
  103. package/dist/eval/judge.d.ts +30 -0
  104. package/dist/eval/judge.d.ts.map +1 -0
  105. package/dist/eval/judge.js +47 -0
  106. package/dist/eval/judge.js.map +1 -0
  107. package/dist/eval/pilot.d.ts +21 -0
  108. package/dist/eval/pilot.d.ts.map +1 -0
  109. package/dist/eval/pilot.js +24 -0
  110. package/dist/eval/pilot.js.map +1 -0
  111. package/dist/eval/scorers.d.ts +23 -0
  112. package/dist/eval/scorers.d.ts.map +1 -0
  113. package/dist/eval/scorers.js +38 -0
  114. package/dist/eval/scorers.js.map +1 -0
  115. package/dist/index.d.ts +21 -0
  116. package/dist/index.d.ts.map +1 -0
  117. package/dist/index.js +13 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/knowledge/index.d.ts +7 -0
  120. package/dist/knowledge/index.d.ts.map +1 -0
  121. package/dist/knowledge/index.js +39 -0
  122. package/dist/knowledge/index.js.map +1 -0
  123. package/dist/llm/factory.d.ts +31 -0
  124. package/dist/llm/factory.d.ts.map +1 -0
  125. package/dist/llm/factory.js +48 -0
  126. package/dist/llm/factory.js.map +1 -0
  127. package/dist/llm/index.d.ts +5 -0
  128. package/dist/llm/index.d.ts.map +1 -0
  129. package/dist/llm/index.js +3 -0
  130. package/dist/llm/index.js.map +1 -0
  131. package/dist/llm/structured.d.ts +30 -0
  132. package/dist/llm/structured.d.ts.map +1 -0
  133. package/dist/llm/structured.js +58 -0
  134. package/dist/llm/structured.js.map +1 -0
  135. package/dist/llm/vision.d.ts +16 -0
  136. package/dist/llm/vision.d.ts.map +1 -0
  137. package/dist/llm/vision.js +4 -0
  138. package/dist/llm/vision.js.map +1 -0
  139. package/dist/observe/index.d.ts +21 -0
  140. package/dist/observe/index.d.ts.map +1 -0
  141. package/dist/observe/index.js +18 -0
  142. package/dist/observe/index.js.map +1 -0
  143. package/dist/observe/parse-aria.d.ts +8 -0
  144. package/dist/observe/parse-aria.d.ts.map +1 -0
  145. package/dist/observe/parse-aria.js +71 -0
  146. package/dist/observe/parse-aria.js.map +1 -0
  147. package/dist/probe/index.d.ts +19 -0
  148. package/dist/probe/index.d.ts.map +1 -0
  149. package/dist/probe/index.js +38 -0
  150. package/dist/probe/index.js.map +1 -0
  151. package/dist/promote/index.d.ts +6 -0
  152. package/dist/promote/index.d.ts.map +1 -0
  153. package/dist/promote/index.js +4 -0
  154. package/dist/promote/index.js.map +1 -0
  155. package/dist/promote/promote-case.d.ts +12 -0
  156. package/dist/promote/promote-case.d.ts.map +1 -0
  157. package/dist/promote/promote-case.js +103 -0
  158. package/dist/promote/promote-case.js.map +1 -0
  159. package/dist/promote/selectors.d.ts +29 -0
  160. package/dist/promote/selectors.d.ts.map +1 -0
  161. package/dist/promote/selectors.js +58 -0
  162. package/dist/promote/selectors.js.map +1 -0
  163. package/dist/prompts/index.d.ts +32 -0
  164. package/dist/prompts/index.d.ts.map +1 -0
  165. package/dist/prompts/index.js +55 -0
  166. package/dist/prompts/index.js.map +1 -0
  167. package/dist/prompts/local/identify-elements.d.ts +6 -0
  168. package/dist/prompts/local/identify-elements.d.ts.map +1 -0
  169. package/dist/prompts/local/identify-elements.js +21 -0
  170. package/dist/prompts/local/identify-elements.js.map +1 -0
  171. package/dist/prompts/local/index.d.ts +3 -0
  172. package/dist/prompts/local/index.d.ts.map +1 -0
  173. package/dist/prompts/local/index.js +18 -0
  174. package/dist/prompts/local/index.js.map +1 -0
  175. package/dist/prompts/local/judge-checklist-coverage.d.ts +3 -0
  176. package/dist/prompts/local/judge-checklist-coverage.d.ts.map +1 -0
  177. package/dist/prompts/local/judge-checklist-coverage.js +11 -0
  178. package/dist/prompts/local/judge-checklist-coverage.js.map +1 -0
  179. package/dist/prompts/local/judge-test-cases.d.ts +3 -0
  180. package/dist/prompts/local/judge-test-cases.d.ts.map +1 -0
  181. package/dist/prompts/local/judge-test-cases.js +11 -0
  182. package/dist/prompts/local/judge-test-cases.js.map +1 -0
  183. package/dist/prompts/local/pilot-review.d.ts +3 -0
  184. package/dist/prompts/local/pilot-review.d.ts.map +1 -0
  185. package/dist/prompts/local/pilot-review.js +13 -0
  186. package/dist/prompts/local/pilot-review.js.map +1 -0
  187. package/dist/prompts/local/qa-manual-test-designer.d.ts +7 -0
  188. package/dist/prompts/local/qa-manual-test-designer.d.ts.map +1 -0
  189. package/dist/prompts/local/qa-manual-test-designer.js +13 -0
  190. package/dist/prompts/local/qa-manual-test-designer.js.map +1 -0
  191. package/dist/prompts/local/qa-playwright-ts-writer.d.ts +6 -0
  192. package/dist/prompts/local/qa-playwright-ts-writer.d.ts.map +1 -0
  193. package/dist/prompts/local/qa-playwright-ts-writer.js +40 -0
  194. package/dist/prompts/local/qa-playwright-ts-writer.js.map +1 -0
  195. package/dist/prompts/local/qa-testcase-from-ui.d.ts +6 -0
  196. package/dist/prompts/local/qa-testcase-from-ui.d.ts.map +1 -0
  197. package/dist/prompts/local/qa-testcase-from-ui.js +52 -0
  198. package/dist/prompts/local/qa-testcase-from-ui.js.map +1 -0
  199. package/dist/session/index.d.ts +27 -0
  200. package/dist/session/index.d.ts.map +1 -0
  201. package/dist/session/index.js +74 -0
  202. package/dist/session/index.js.map +1 -0
  203. package/dist/telemetry/index.d.ts +21 -0
  204. package/dist/telemetry/index.d.ts.map +1 -0
  205. package/dist/telemetry/index.js +26 -0
  206. package/dist/telemetry/index.js.map +1 -0
  207. package/dist/tui/App.d.ts +6 -0
  208. package/dist/tui/App.d.ts.map +1 -0
  209. package/dist/tui/App.js +61 -0
  210. package/dist/tui/App.js.map +1 -0
  211. package/dist/tui/components/error-boundary.d.ts +17 -0
  212. package/dist/tui/components/error-boundary.d.ts.map +1 -0
  213. package/dist/tui/components/error-boundary.js +20 -0
  214. package/dist/tui/components/error-boundary.js.map +1 -0
  215. package/dist/tui/components/field.d.ts +10 -0
  216. package/dist/tui/components/field.d.ts.map +1 -0
  217. package/dist/tui/components/field.js +8 -0
  218. package/dist/tui/components/field.js.map +1 -0
  219. package/dist/tui/components/help.d.ts +5 -0
  220. package/dist/tui/components/help.d.ts.map +1 -0
  221. package/dist/tui/components/help.js +7 -0
  222. package/dist/tui/components/help.js.map +1 -0
  223. package/dist/tui/components/log-pane.d.ts +6 -0
  224. package/dist/tui/components/log-pane.d.ts.map +1 -0
  225. package/dist/tui/components/log-pane.js +10 -0
  226. package/dist/tui/components/log-pane.js.map +1 -0
  227. package/dist/tui/components/node-checklist.d.ts +6 -0
  228. package/dist/tui/components/node-checklist.d.ts.map +1 -0
  229. package/dist/tui/components/node-checklist.js +9 -0
  230. package/dist/tui/components/node-checklist.js.map +1 -0
  231. package/dist/tui/components/pilot-badge.d.ts +6 -0
  232. package/dist/tui/components/pilot-badge.d.ts.map +1 -0
  233. package/dist/tui/components/pilot-badge.js +12 -0
  234. package/dist/tui/components/pilot-badge.js.map +1 -0
  235. package/dist/tui/components/scores-table.d.ts +6 -0
  236. package/dist/tui/components/scores-table.d.ts.map +1 -0
  237. package/dist/tui/components/scores-table.js +9 -0
  238. package/dist/tui/components/scores-table.js.map +1 -0
  239. package/dist/tui/components/scrollable-text.d.ts +6 -0
  240. package/dist/tui/components/scrollable-text.d.ts.map +1 -0
  241. package/dist/tui/components/scrollable-text.js +22 -0
  242. package/dist/tui/components/scrollable-text.js.map +1 -0
  243. package/dist/tui/components/session-picker.d.ts +5 -0
  244. package/dist/tui/components/session-picker.d.ts.map +1 -0
  245. package/dist/tui/components/session-picker.js +16 -0
  246. package/dist/tui/components/session-picker.js.map +1 -0
  247. package/dist/tui/components/test-case-list.d.ts +7 -0
  248. package/dist/tui/components/test-case-list.d.ts.map +1 -0
  249. package/dist/tui/components/test-case-list.js +10 -0
  250. package/dist/tui/components/test-case-list.js.map +1 -0
  251. package/dist/tui/hooks/use-run-artifacts.d.ts +14 -0
  252. package/dist/tui/hooks/use-run-artifacts.d.ts.map +1 -0
  253. package/dist/tui/hooks/use-run-artifacts.js +37 -0
  254. package/dist/tui/hooks/use-run-artifacts.js.map +1 -0
  255. package/dist/tui/hooks/use-runner.d.ts +25 -0
  256. package/dist/tui/hooks/use-runner.d.ts.map +1 -0
  257. package/dist/tui/hooks/use-runner.js +116 -0
  258. package/dist/tui/hooks/use-runner.js.map +1 -0
  259. package/dist/tui/hooks/use-runs.d.ts +14 -0
  260. package/dist/tui/hooks/use-runs.d.ts.map +1 -0
  261. package/dist/tui/hooks/use-runs.js +57 -0
  262. package/dist/tui/hooks/use-runs.js.map +1 -0
  263. package/dist/tui/hooks/use-sessions.d.ts +10 -0
  264. package/dist/tui/hooks/use-sessions.d.ts.map +1 -0
  265. package/dist/tui/hooks/use-sessions.js +32 -0
  266. package/dist/tui/hooks/use-sessions.js.map +1 -0
  267. package/dist/tui/hooks/use-stdout-dimensions.d.ts +3 -0
  268. package/dist/tui/hooks/use-stdout-dimensions.d.ts.map +1 -0
  269. package/dist/tui/hooks/use-stdout-dimensions.js +18 -0
  270. package/dist/tui/hooks/use-stdout-dimensions.js.map +1 -0
  271. package/dist/tui/index.d.ts +7 -0
  272. package/dist/tui/index.d.ts.map +1 -0
  273. package/dist/tui/index.js +13 -0
  274. package/dist/tui/index.js.map +1 -0
  275. package/dist/tui/router-context.d.ts +12 -0
  276. package/dist/tui/router-context.d.ts.map +1 -0
  277. package/dist/tui/router-context.js +14 -0
  278. package/dist/tui/router-context.js.map +1 -0
  279. package/dist/tui/router.d.ts +44 -0
  280. package/dist/tui/router.d.ts.map +1 -0
  281. package/dist/tui/router.js +22 -0
  282. package/dist/tui/router.js.map +1 -0
  283. package/dist/tui/screens/form-screen.d.ts +7 -0
  284. package/dist/tui/screens/form-screen.d.ts.map +1 -0
  285. package/dist/tui/screens/form-screen.js +104 -0
  286. package/dist/tui/screens/form-screen.js.map +1 -0
  287. package/dist/tui/screens/launcher-screen.d.ts +2 -0
  288. package/dist/tui/screens/launcher-screen.d.ts.map +1 -0
  289. package/dist/tui/screens/launcher-screen.js +28 -0
  290. package/dist/tui/screens/launcher-screen.js.map +1 -0
  291. package/dist/tui/screens/run-dashboard-screen.d.ts +7 -0
  292. package/dist/tui/screens/run-dashboard-screen.d.ts.map +1 -0
  293. package/dist/tui/screens/run-dashboard-screen.js +32 -0
  294. package/dist/tui/screens/run-dashboard-screen.js.map +1 -0
  295. package/dist/tui/screens/run-detail-screen.d.ts +5 -0
  296. package/dist/tui/screens/run-detail-screen.d.ts.map +1 -0
  297. package/dist/tui/screens/run-detail-screen.js +67 -0
  298. package/dist/tui/screens/run-detail-screen.js.map +1 -0
  299. package/dist/tui/screens/runs-list-screen.d.ts +2 -0
  300. package/dist/tui/screens/runs-list-screen.d.ts.map +1 -0
  301. package/dist/tui/screens/runs-list-screen.js +22 -0
  302. package/dist/tui/screens/runs-list-screen.js.map +1 -0
  303. package/dist/tui/screens/summary-screen.d.ts +6 -0
  304. package/dist/tui/screens/summary-screen.d.ts.map +1 -0
  305. package/dist/tui/screens/summary-screen.js +53 -0
  306. package/dist/tui/screens/summary-screen.js.map +1 -0
  307. package/dist/tui/theme.d.ts +31 -0
  308. package/dist/tui/theme.d.ts.map +1 -0
  309. package/dist/tui/theme.js +70 -0
  310. package/dist/tui/theme.js.map +1 -0
  311. package/dist/tui/types.d.ts +38 -0
  312. package/dist/tui/types.d.ts.map +1 -0
  313. package/dist/tui/types.js +2 -0
  314. package/dist/tui/types.js.map +1 -0
  315. package/dist/validate/index.d.ts +30 -0
  316. package/dist/validate/index.d.ts.map +1 -0
  317. package/dist/validate/index.js +39 -0
  318. package/dist/validate/index.js.map +1 -0
  319. package/dist/validate/runner.d.ts +15 -0
  320. package/dist/validate/runner.d.ts.map +1 -0
  321. package/dist/validate/runner.js +74 -0
  322. package/dist/validate/runner.js.map +1 -0
  323. package/package.json +97 -0
@@ -0,0 +1,18 @@
1
+ import { useStdout } from "ink";
2
+ import { useEffect, useState } from "react";
3
+ /** Current terminal [columns, rows], updated on resize — used to size scroll viewports. */
4
+ export function useStdoutDimensions() {
5
+ const { stdout } = useStdout();
6
+ const [size, setSize] = useState([stdout.columns ?? 80, stdout.rows ?? 24]);
7
+ useEffect(() => {
8
+ if (typeof stdout?.on !== "function")
9
+ return; // headless/test stdout has no resize events
10
+ const onResize = () => setSize([stdout.columns ?? 80, stdout.rows ?? 24]);
11
+ stdout.on("resize", onResize);
12
+ return () => {
13
+ stdout.off?.("resize", onResize);
14
+ };
15
+ }, [stdout]);
16
+ return size;
17
+ }
18
+ //# sourceMappingURL=use-stdout-dimensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-stdout-dimensions.js","sourceRoot":"","sources":["../../../src/tui/hooks/use-stdout-dimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,2FAA2F;AAC3F,MAAM,UAAU,mBAAmB;IACjC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAmB,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IAE9F,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,EAAE,EAAE,KAAK,UAAU;YAAE,OAAO,CAAC,4CAA4C;QAC1F,MAAM,QAAQ,GAAG,GAAS,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QAChF,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * TUI entry point. Lazily imported by the CLI dispatch when `cairn` runs with
3
+ * no arguments in a TTY — this keeps React/Ink out of every non-TUI code path
4
+ * (other CLI commands and library embedders never load them).
5
+ */
6
+ export declare function mountTui(): Promise<void>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9C"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * TUI entry point. Lazily imported by the CLI dispatch when `cairn` runs with
3
+ * no arguments in a TTY — this keeps React/Ink out of every non-TUI code path
4
+ * (other CLI commands and library embedders never load them).
5
+ */
6
+ export async function mountTui() {
7
+ const React = (await import("react")).default;
8
+ const { render } = await import("ink");
9
+ const { App } = await import("./App.js");
10
+ const { waitUntilExit } = render(React.createElement(App), { exitOnCtrlC: true });
11
+ await waitUntilExit();
12
+ }
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Screen } from "./router.js";
2
+ export interface RouterApi {
3
+ navigate: (screen: Screen) => void;
4
+ back: () => void;
5
+ replace: (screen: Screen) => void;
6
+ canGoBack: boolean;
7
+ /** Screens with a focused text input set this true so global `q`/esc don't steal keys. */
8
+ setInTextField: (v: boolean) => void;
9
+ }
10
+ export declare const RouterProvider: import("react").Provider<RouterApi | null>;
11
+ export declare function useRouter(): RouterApi;
12
+ //# sourceMappingURL=router-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-context.d.ts","sourceRoot":"","sources":["../../src/tui/router-context.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,0FAA0F;IAC1F,cAAc,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACtC;AAID,eAAO,MAAM,cAAc,4CAAyB,CAAC;AAErD,wBAAgB,SAAS,IAAI,SAAS,CAIrC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * React context exposing navigation to any screen without prop-drilling.
3
+ * The reducer itself lives in router.ts (pure); this only wires it into React.
4
+ */
5
+ import { createContext, useContext } from "react";
6
+ const RouterContext = createContext(null);
7
+ export const RouterProvider = RouterContext.Provider;
8
+ export function useRouter() {
9
+ const ctx = useContext(RouterContext);
10
+ if (!ctx)
11
+ throw new Error("useRouter must be used within a RouterProvider");
12
+ return ctx;
13
+ }
14
+ //# sourceMappingURL=router-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-context.js","sourceRoot":"","sources":["../../src/tui/router-context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAYlD,MAAM,aAAa,GAAG,aAAa,CAAmB,IAAI,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC;AAErD,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAC5E,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Pure screen router for the TUI: a stack of screens with go/back/replace.
3
+ * Kept free of React so it is trivially unit-testable (router.test.ts).
4
+ */
5
+ import type { Command, FormValues, AnyResult } from "./types.js";
6
+ export type Screen = {
7
+ name: "launcher";
8
+ } | {
9
+ name: "form";
10
+ command: Command;
11
+ initial?: Partial<FormValues>;
12
+ } | {
13
+ name: "dashboard";
14
+ command: Command;
15
+ values: FormValues;
16
+ } | {
17
+ name: "summary";
18
+ command: Command;
19
+ result: AnyResult;
20
+ } | {
21
+ name: "runsList";
22
+ } | {
23
+ name: "runDetail";
24
+ runDir: string;
25
+ };
26
+ export interface RouterState {
27
+ stack: Screen[];
28
+ }
29
+ export type RouterAction = {
30
+ type: "go";
31
+ screen: Screen;
32
+ } | {
33
+ type: "back";
34
+ } | {
35
+ type: "replace";
36
+ screen: Screen;
37
+ };
38
+ export declare const initialRouter: RouterState;
39
+ export declare function routerReducer(state: RouterState, action: RouterAction): RouterState;
40
+ /** The visible (top-of-stack) screen. The stack is never empty (seeded with launcher). */
41
+ export declare function currentScreen(state: RouterState): Screen;
42
+ /** Whether back navigation is possible (i.e. not at the root). */
43
+ export declare function canGoBack(state: RouterState): boolean;
44
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/tui/router.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,MAAM,GACd;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,eAAO,MAAM,aAAa,EAAE,WAA+C,CAAC;AAE5E,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,WAAW,CAUnF;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAGxD;AAED,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAErD"}
@@ -0,0 +1,22 @@
1
+ export const initialRouter = { stack: [{ name: "launcher" }] };
2
+ export function routerReducer(state, action) {
3
+ switch (action.type) {
4
+ case "go":
5
+ return { stack: [...state.stack, action.screen] };
6
+ case "back":
7
+ // Never pop the root screen.
8
+ return state.stack.length > 1 ? { stack: state.stack.slice(0, -1) } : state;
9
+ case "replace":
10
+ return { stack: [...state.stack.slice(0, -1), action.screen] };
11
+ }
12
+ }
13
+ /** The visible (top-of-stack) screen. The stack is never empty (seeded with launcher). */
14
+ export function currentScreen(state) {
15
+ const top = state.stack[state.stack.length - 1];
16
+ return top ?? { name: "launcher" };
17
+ }
18
+ /** Whether back navigation is possible (i.e. not at the root). */
19
+ export function canGoBack(state) {
20
+ return state.stack.length > 1;
21
+ }
22
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/tui/router.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,MAAM,aAAa,GAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;AAE5E,MAAM,UAAU,aAAa,CAAC,KAAkB,EAAE,MAAoB;IACpE,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,IAAI;YACP,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,KAAK,MAAM;YACT,6BAA6B;YAC7B,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC9E,KAAK,SAAS;YACZ,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IACnE,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,aAAa,CAAC,KAAkB;IAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,OAAO,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AACrC,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Command, FormValues } from "../types.js";
2
+ /** Sequential wizard: one field per step, ⏎ advances, last step runs the command. */
3
+ export declare function FormScreen({ command, initial }: {
4
+ command: Command;
5
+ initial?: Partial<FormValues>;
6
+ }): import("react").JSX.Element;
7
+ //# sourceMappingURL=form-screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/form-screen.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAiB,MAAM,aAAa,CAAC;AA6BtE,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,+BAsHnG"}
@@ -0,0 +1,104 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import SelectInput from "ink-select-input";
5
+ import { useRouter } from "../router-context.js";
6
+ import { Field } from "../components/field.js";
7
+ import { SessionPicker } from "../components/session-picker.js";
8
+ function stepsFor(command) {
9
+ if (command === "automate")
10
+ return ["runDir", "session", "validate", "submit"];
11
+ if (command === "observe")
12
+ return ["url", "session", "headed", "submit"];
13
+ return ["url", "session", "checklist", "style", "headed", "submit"]; // explore / design
14
+ }
15
+ const STYLE_ITEMS = [
16
+ { label: "all — full coverage", value: "all" },
17
+ { label: "happy — positive paths", value: "happy" },
18
+ { label: "negative — error cases", value: "negative" },
19
+ { label: "coverage — breadth", value: "coverage" },
20
+ ];
21
+ const YESNO = [
22
+ { label: "no", value: "no" },
23
+ { label: "yes", value: "yes" },
24
+ ];
25
+ /** Sequential wizard: one field per step, ⏎ advances, last step runs the command. */
26
+ export function FormScreen({ command, initial }) {
27
+ const { navigate, setInTextField } = useRouter();
28
+ const [values, setValues] = useState({ url: "", style: "all", headed: false, ...initial });
29
+ const [stepIndex, setStepIndex] = useState(0);
30
+ const steps = stepsFor(command);
31
+ const step = steps[stepIndex] ?? "submit";
32
+ const isText = step === "url" || step === "runDir" || step === "checklist";
33
+ // Suppress global q/esc only while a text field owns the keyboard.
34
+ useEffect(() => {
35
+ setInTextField(isText);
36
+ return () => setInTextField(false);
37
+ }, [isText, setInTextField]);
38
+ const advance = () => setStepIndex((i) => Math.min(i + 1, steps.length - 1));
39
+ const set = (k, v) => setValues((s) => ({ ...s, [k]: v }));
40
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: command }), _jsx(FormSummary, { values: values, command: command }), _jsx(Box, { marginTop: 1, children: renderStep() })] }));
41
+ function renderStep() {
42
+ switch (step) {
43
+ case "url":
44
+ return (_jsx(Field, { label: "URL", value: values.url, onChange: (v) => set("url", v), onSubmit: () => values.url.trim() && advance(), placeholder: "https://app.example.com/page (required)" }));
45
+ case "runDir":
46
+ return (_jsx(Field, { label: "Run dir", value: values.runDir ?? "", onChange: (v) => set("runDir", v), onSubmit: () => (values.runDir ?? "").trim() && advance(), placeholder: "runs/<id> (required)" }));
47
+ case "checklist":
48
+ return (_jsx(Field, { label: "Checklist", value: values.checklist ?? "", onChange: (v) => set("checklist", v), onSubmit: advance, placeholder: "(optional) path to a .md file" }));
49
+ case "session":
50
+ return (_jsx(SessionPicker, { onSelect: (s) => {
51
+ set("session", s);
52
+ advance();
53
+ } }));
54
+ case "style":
55
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Planning style:" }), _jsx(SelectInput, { items: STYLE_ITEMS, onSelect: (it) => {
56
+ set("style", it.value);
57
+ advance();
58
+ } })] }));
59
+ case "headed":
60
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Headed (visible) browser?" }), _jsx(SelectInput, { items: YESNO, onSelect: (it) => {
61
+ set("headed", it.value === "yes");
62
+ advance();
63
+ } })] }));
64
+ case "validate":
65
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Validate (run the generated tests)?" }), _jsx(SelectInput, { items: YESNO, onSelect: (it) => {
66
+ set("validate", it.value === "yes");
67
+ advance();
68
+ } })] }));
69
+ case "submit":
70
+ return (_jsx(SubmitStep, { command: command, onRun: () => navigate({ name: "dashboard", command, values }) }));
71
+ }
72
+ }
73
+ }
74
+ function SubmitStep({ command, onRun }) {
75
+ useInput((_, key) => {
76
+ if (key.return)
77
+ onRun();
78
+ });
79
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "green", children: ["Ready to run ", command, "."] }), _jsx(Text, { dimColor: true, children: "Press \u23CE to start \u00B7 esc to go back" })] }));
80
+ }
81
+ function FormSummary({ values, command }) {
82
+ const rows = [];
83
+ if (command === "automate") {
84
+ if (values.runDir)
85
+ rows.push(`run dir: ${values.runDir}`);
86
+ if (values.validate !== undefined)
87
+ rows.push(`validate: ${values.validate ? "yes" : "no"}`);
88
+ }
89
+ else {
90
+ if (values.url)
91
+ rows.push(`url: ${values.url}`);
92
+ if (command !== "observe") {
93
+ if (values.checklist)
94
+ rows.push(`checklist: ${values.checklist}`);
95
+ rows.push(`style: ${values.style}`);
96
+ }
97
+ }
98
+ if (values.session)
99
+ rows.push(`session: ${values.session}`);
100
+ if (rows.length === 0)
101
+ return null;
102
+ return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: rows.map((r) => (_jsxs(Text, { dimColor: true, children: ["\u00B7 ", r] }, r))) }));
103
+ }
104
+ //# sourceMappingURL=form-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/form-screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAahE,SAAS,QAAQ,CAAC,OAAgB;IAChC,IAAI,OAAO,KAAK,UAAU;QAAE,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/E,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,mBAAmB;AAC1F,CAAC;AAED,MAAM,WAAW,GAAG;IAClB,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE;IAC9C,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE;IACnD,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,UAAU,EAAE;IACtD,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE;CACnD,CAAC;AACF,MAAM,KAAK,GAAG;IACZ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IAC5B,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;CAC/B,CAAC;AAEF,qFAAqF;AACrF,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,EAAuD;IAClG,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,SAAS,EAAE,CAAC;IACjD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAa,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACvG,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE9C,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,IAAI,GAAY,KAAK,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,WAAW,CAAC;IAE3E,mEAAmE;IACnE,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAE7B,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,GAAG,GAAG,CAA6B,CAAI,EAAE,CAAgB,EAAE,EAAE,CACjE,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAEvC,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,kBACpB,OAAO,GACH,EACP,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAI,EACjD,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YAAG,UAAU,EAAE,GAAO,IACnC,CACP,CAAC;IAEF,SAAS,UAAU;QACjB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,KAAK;gBACR,OAAO,CACL,KAAC,KAAK,IACJ,KAAK,EAAC,KAAK,EACX,KAAK,EAAE,MAAM,CAAC,GAAG,EACjB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAC9B,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,OAAO,EAAE,EAC9C,WAAW,EAAC,0CAA0C,GACtD,CACH,CAAC;YACJ,KAAK,QAAQ;gBACX,OAAO,CACL,KAAC,KAAK,IACJ,KAAK,EAAC,SAAS,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAC1B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EACjC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,OAAO,EAAE,EACzD,WAAW,EAAC,uBAAuB,GACnC,CACH,CAAC;YACJ,KAAK,WAAW;gBACd,OAAO,CACL,KAAC,KAAK,IACJ,KAAK,EAAC,WAAW,EACjB,KAAK,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,EAC7B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,EACpC,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAC,+BAA+B,GAC3C,CACH,CAAC;YACJ,KAAK,SAAS;gBACZ,OAAO,CACL,KAAC,aAAa,IACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;wBACd,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;wBAClB,OAAO,EAAE,CAAC;oBACZ,CAAC,GACD,CACH,CAAC;YACJ,KAAK,OAAO;gBACV,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,kCAAuB,EAC5B,KAAC,WAAW,IACV,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE;gCACf,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,KAAsB,CAAC,CAAC;gCACxC,OAAO,EAAE,CAAC;4BACZ,CAAC,GACD,IACE,CACP,CAAC;YACJ,KAAK,QAAQ;gBACX,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,4CAAiC,EACtC,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE;gCACf,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;gCAClC,OAAO,EAAE,CAAC;4BACZ,CAAC,GACD,IACE,CACP,CAAC;YACJ,KAAK,UAAU;gBACb,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,sDAA2C,EAChD,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE;gCACf,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;gCACpC,OAAO,EAAE,CAAC;4BACZ,CAAC,GACD,IACE,CACP,CAAC;YACJ,KAAK,QAAQ;gBACX,OAAO,CACL,KAAC,UAAU,IACT,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAC7D,CACH,CAAC;QACN,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,EAA2C;IAC7E,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;QAClB,IAAI,GAAG,CAAC,MAAM;YAAE,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IACH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,8BAAe,OAAO,SAAS,EAClD,KAAC,IAAI,IAAC,QAAQ,kEAAyC,IACnD,CACP,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,EAA4C;IAChF,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9F,CAAC;SAAM,CAAC;QACN,IAAI,MAAM,CAAC,GAAG;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QAChD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,MAAM,CAAC,SAAS;gBAAE,IAAI,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YAClE,IAAI,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,YACrC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACf,MAAC,IAAI,IAAS,QAAQ,8BACjB,CAAC,KADK,CAAC,CAEL,CACR,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function LauncherScreen(): import("react").JSX.Element;
2
+ //# sourceMappingURL=launcher-screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/launcher-screen.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,cAAc,gCA2B7B"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useApp } from "ink";
3
+ import SelectInput from "ink-select-input";
4
+ import { useRouter } from "../router-context.js";
5
+ const ITEMS = [
6
+ { label: "Explore — full pipeline (cases → code → validate → repair)", value: "explore" },
7
+ { label: "Design — test cases only (.md, no code)", value: "design" },
8
+ { label: "Automate — generate @playwright/test from existing cases", value: "automate" },
9
+ { label: "Browse past runs", value: "runs" },
10
+ { label: "Quit", value: "quit" },
11
+ ];
12
+ export function LauncherScreen() {
13
+ const { navigate } = useRouter();
14
+ const { exit } = useApp();
15
+ const onSelect = (item) => {
16
+ if (item.value === "quit") {
17
+ exit();
18
+ return;
19
+ }
20
+ if (item.value === "runs") {
21
+ navigate({ name: "runsList" });
22
+ return;
23
+ }
24
+ navigate({ name: "form", command: item.value });
25
+ };
26
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Cairn" }), _jsx(Text, { dimColor: true, children: "Interactive UI-test generation \u2014 pick a command" }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: ITEMS, onSelect: onSelect }) })] }));
27
+ }
28
+ //# sourceMappingURL=launcher-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/launcher-screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AACxC,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAQjD,MAAM,KAAK,GAAe;IACxB,EAAE,KAAK,EAAE,4DAA4D,EAAE,KAAK,EAAE,SAAS,EAAE;IACzF,EAAE,KAAK,EAAE,yCAAyC,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrE,EAAE,KAAK,EAAE,0DAA0D,EAAE,KAAK,EAAE,UAAU,EAAE;IACxF,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE;IAC5C,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;CACjC,CAAC;AAEF,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;IACjC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;IAE1B,MAAM,QAAQ,GAAG,CAAC,IAAc,EAAE,EAAE;QAClC,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAgB,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,4BAEhB,EACP,KAAC,IAAI,IAAC,QAAQ,2EAAuD,EACrE,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,GAC7C,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Command, FormValues } from "../types.js";
2
+ /** Runs the command and shows a live node checklist + log; routes to summary on success. */
3
+ export declare function RunDashboardScreen({ command, values }: {
4
+ command: Command;
5
+ values: FormValues;
6
+ }): import("react").JSX.Element;
7
+ //# sourceMappingURL=run-dashboard-screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-dashboard-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/run-dashboard-screen.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAUvD,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,+BA6C/F"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { useRouter } from "../router-context.js";
5
+ import { useRunner } from "../hooks/use-runner.js";
6
+ import { NodeChecklist } from "../components/node-checklist.js";
7
+ import { LogPane } from "../components/log-pane.js";
8
+ const ERROR_HINTS = {
9
+ session: "Session looks expired/missing — recapture it (npm run session:save).",
10
+ "rate-limit": "Rate-limited (429). The SDK retried; try again shortly.",
11
+ budget: "Call budget exceeded — the run hit the cost guardrail.",
12
+ config: "Check your API key env (ANTHROPIC_API_KEY / OPENROUTER_API_KEY).",
13
+ unknown: "Unexpected error — see the message above.",
14
+ };
15
+ /** Runs the command and shows a live node checklist + log; routes to summary on success. */
16
+ export function RunDashboardScreen({ command, values }) {
17
+ const { replace, setInTextField } = useRouter();
18
+ const { state, start, dispose } = useRunner();
19
+ useEffect(() => {
20
+ setInTextField(false);
21
+ start(command, values);
22
+ return dispose;
23
+ // run once on mount
24
+ }, []);
25
+ useEffect(() => {
26
+ if (state.phase === "done" && state.result) {
27
+ replace({ name: "summary", command, result: state.result });
28
+ }
29
+ }, [state.phase]);
30
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: command }), _jsx(Text, { dimColor: true, children: state.phase === "running" ? " running…" : ` ${state.phase}` }), state.liveGreen !== undefined && _jsx(Text, { color: "green", children: ` · ${String(state.liveGreen)}% green` })] }), _jsx(Box, { marginTop: 1, children: _jsx(NodeChecklist, { nodes: state.nodes }) }), _jsx(LogPane, { log: state.log }), state.phase === "error" && state.error && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { color: "red", bold: true, children: ["Failed: ", state.error.kind] }), _jsx(Text, { children: state.error.message }), _jsx(Text, { dimColor: true, children: ERROR_HINTS[state.error.kind] ?? "" }), _jsx(Text, { dimColor: true, children: "esc \u2014 back to the form" })] }))] }));
31
+ }
32
+ //# sourceMappingURL=run-dashboard-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-dashboard-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/run-dashboard-screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAGpD,MAAM,WAAW,GAA2B;IAC1C,OAAO,EAAE,sEAAsE;IAC/E,YAAY,EAAE,yDAAyD;IACvE,MAAM,EAAE,wDAAwD;IAChE,MAAM,EAAE,kEAAkE;IAC1E,OAAO,EAAE,2CAA2C;CACrD,CAAC;AAEF,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,EAA4C;IAC9F,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,SAAS,EAAE,CAAC;IAChD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;IAE9C,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvB,OAAO,OAAO,CAAC;QACf,oBAAoB;IACtB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3C,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,kBACpB,OAAO,GACH,EACP,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,EAAE,GAAQ,EACpF,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,GAAQ,IAClG,EAEN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAI,GACjC,EAEN,KAAC,OAAO,IAAC,GAAG,EAAE,KAAK,CAAC,GAAG,GAAI,EAE1B,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,IAAI,CACzC,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aACtC,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,EAAC,IAAI,+BACX,KAAK,CAAC,KAAK,CAAC,IAAI,IACpB,EACP,KAAC,IAAI,cAAE,KAAK,CAAC,KAAK,CAAC,OAAO,GAAQ,EAClC,KAAC,IAAI,IAAC,QAAQ,kBAAE,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAQ,EAC3D,KAAC,IAAI,IAAC,QAAQ,kDAA8B,IACxC,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** Tabbed artifact viewer. Tabs: 1/2/3 or ←→ · scroll: ↑↓ · cases: n/p · back: esc. */
2
+ export declare function RunDetailScreen({ runDir }: {
3
+ runDir: string;
4
+ }): import("react").JSX.Element;
5
+ //# sourceMappingURL=run-detail-screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-detail-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/run-detail-screen.tsx"],"names":[],"mappings":"AAWA,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,+BA2F7D"}
@@ -0,0 +1,67 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import { useRunArtifacts } from "../hooks/use-run-artifacts.js";
5
+ import { useStdoutDimensions } from "../hooks/use-stdout-dimensions.js";
6
+ import { ScrollableText } from "../components/scrollable-text.js";
7
+ import { promoteCase } from "../../promote/index.js";
8
+ const TABS = ["cases", "report", "logs"];
9
+ const TAB_LABELS = { cases: "Cases", report: "Report", logs: "Logs" };
10
+ /** Tabbed artifact viewer. Tabs: 1/2/3 or ←→ · scroll: ↑↓ · cases: n/p · back: esc. */
11
+ export function RunDetailScreen({ runDir }) {
12
+ const arts = useRunArtifacts(runDir);
13
+ const [, rows] = useStdoutDimensions();
14
+ const [tab, setTab] = useState("cases");
15
+ const [caseIdx, setCaseIdx] = useState(0);
16
+ const [note, setNote] = useState("");
17
+ const [promoted, setPromoted] = useState(false);
18
+ // Derive current case here (before useInput) so the key handler can reference it.
19
+ const current = arts.cases[caseIdx];
20
+ useInput((input, key) => {
21
+ if (input === "1")
22
+ setTab("cases");
23
+ else if (input === "2")
24
+ setTab("report");
25
+ else if (input === "3")
26
+ setTab("logs");
27
+ else if (key.leftArrow)
28
+ setTab((t) => TABS[(TABS.indexOf(t) + TABS.length - 1) % TABS.length] ?? "cases");
29
+ else if (key.rightArrow || key.tab)
30
+ setTab((t) => TABS[(TABS.indexOf(t) + 1) % TABS.length] ?? "cases");
31
+ else if (tab === "cases" && input === "n") {
32
+ setCaseIdx((i) => Math.min(i + 1, Math.max(0, arts.cases.length - 1)));
33
+ }
34
+ else if (tab === "cases" && input === "p") {
35
+ setCaseIdx((i) => Math.max(i - 1, 0));
36
+ }
37
+ else if (tab === "cases" && input === "a" && !promoted && current?.name.startsWith("MTC")) {
38
+ const id = current.name.replace(/\.md$/, "");
39
+ void promoteCase(runDir, id, {})
40
+ .then((r) => {
41
+ setPromoted(true);
42
+ setNote(`Promoted ${r.oldId} → ${r.newId}${r.warning ? ` (⚠ ${r.warning})` : ""}`);
43
+ arts.reload();
44
+ })
45
+ .catch((e) => setNote(`Promote failed: ${e instanceof Error ? e.message : String(e)}`));
46
+ }
47
+ });
48
+ if (arts.loading)
49
+ return _jsx(Text, { dimColor: true, children: "loading artifacts\u2026" });
50
+ const viewHeight = Math.max(6, rows - 10);
51
+ let body;
52
+ if (tab === "cases") {
53
+ body = current ? (_jsx(ScrollableText, { text: current.text, height: viewHeight }, caseIdx)) : (_jsx(Text, { dimColor: true, children: "No test cases in this run." }));
54
+ }
55
+ else if (tab === "report") {
56
+ body = _jsx(ScrollableText, { text: arts.report, height: viewHeight });
57
+ }
58
+ else {
59
+ body = _jsx(ScrollableText, { text: arts.log, height: viewHeight });
60
+ }
61
+ const isMtc = tab === "cases" && (current?.name.startsWith("MTC") ?? false);
62
+ const hint = tab === "cases" && arts.cases.length > 1
63
+ ? `↑↓ scroll · n/p next·prev case${isMtc ? " · a promote→ATC" : ""} · 1/2/3 or ←→ tab · esc back`
64
+ : `↑↓ scroll${isMtc ? " · a promote→ATC" : ""} · 1/2/3 or ←→ tab · esc back`;
65
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: TABS.map((t, i) => (_jsx(Box, { marginRight: 1, children: _jsx(Text, { color: t === tab ? "black" : "cyan", backgroundColor: t === tab ? "cyan" : undefined, bold: t === tab, children: ` ${String(i + 1)} ${TAB_LABELS[t]} ` }) }, t))) }), _jsxs(Box, { borderStyle: "round", borderColor: "gray", flexDirection: "column", paddingX: 1, marginTop: 1, children: [tab === "cases" && current ? (_jsxs(Text, { children: [_jsxs(Text, { color: "cyan", children: ["case ", caseIdx + 1, "/", arts.cases.length] }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", current.name] }), arts.cases.length > 1 ? (_jsx(Text, { color: "yellow", children: " \u00B7 press n/p for next/prev" })) : null] })) : null, body] }), note ? _jsx(Text, { color: "green", children: note }) : null, _jsx(Text, { dimColor: true, children: hint })] }));
66
+ }
67
+ //# sourceMappingURL=run-detail-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-detail-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/run-detail-screen.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function RunsListScreen(): import("react").JSX.Element;
2
+ //# sourceMappingURL=runs-list-screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs-list-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/runs-list-screen.tsx"],"names":[],"mappings":"AAUA,wBAAgB,cAAc,gCAkC7B"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import SelectInput from "ink-select-input";
4
+ import { useRouter } from "../router-context.js";
5
+ import { useRuns } from "../hooks/use-runs.js";
6
+ export function RunsListScreen() {
7
+ const { navigate } = useRouter();
8
+ const { runs, loading } = useRuns();
9
+ if (loading)
10
+ return _jsx(Text, { dimColor: true, children: "scanning ./runs\u2026" });
11
+ if (runs.length === 0) {
12
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "No runs found in ./runs" }), _jsx(Text, { dimColor: true, children: "esc \u2014 back" })] }));
13
+ }
14
+ const items = runs.map((r) => {
15
+ const date = r.date.toISOString().slice(0, 16).replace("T", " ");
16
+ const green = r.greenRatio !== undefined ? `${String(Math.round(r.greenRatio * 100))}% ` : "";
17
+ const pilot = r.pilot ? `${r.pilot} ` : "";
18
+ return { label: `${date} ${r.mode} ${green}${pilot} ${r.url}`, value: r.dir };
19
+ });
20
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "cyan", bold: true, children: ["Past runs (", runs.length, ")"] }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: items, onSelect: (it) => navigate({ name: "runDetail", runDir: it.value }) }) })] }));
21
+ }
22
+ //# sourceMappingURL=runs-list-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs-list-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/runs-list-screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAO/C,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;IACjC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,IAAI,OAAO;QAAE,OAAO,KAAC,IAAI,IAAC,QAAQ,4CAAwB,CAAC;IAC3D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,0CAA+B,EACpC,KAAC,IAAI,IAAC,QAAQ,sCAAkB,IAC5B,CACP,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,kCACT,IAAI,CAAC,MAAM,SAClB,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,EAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,GACzE,GACE,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { Command, AnyResult } from "../types.js";
2
+ export declare function SummaryScreen({ command, result }: {
3
+ command: Command;
4
+ result: AnyResult;
5
+ }): import("react").JSX.Element;
6
+ //# sourceMappingURL=summary-screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/summary-screen.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAc,MAAM,aAAa,CAAC;AAgClE,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,+BAmDzF"}
@@ -0,0 +1,53 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import SelectInput from "ink-select-input";
4
+ import { useRouter } from "../router-context.js";
5
+ import { ScoresTable } from "../components/scores-table.js";
6
+ import { PilotBadge } from "../components/pilot-badge.js";
7
+ import { TestCaseList } from "../components/test-case-list.js";
8
+ /** Rebuild form prefill from a finished run so re-run starts with the same target. */
9
+ function rerunInitial(command, result) {
10
+ if (command === "automate")
11
+ return { runDir: result.runDir };
12
+ const url = "study" in result ? result.study.url : undefined;
13
+ return url ? { url } : {};
14
+ }
15
+ // All numbers come from the typed result — never parsed from progress text.
16
+ function validationOf(r) {
17
+ return "validation" in r ? r.validation : undefined;
18
+ }
19
+ function pilotOf(r) {
20
+ return "pilot" in r ? r.pilot : undefined;
21
+ }
22
+ function testCasesOf(r) {
23
+ return "testCases" in r ? r.testCases : [];
24
+ }
25
+ function scoresOf(r) {
26
+ return "scores" in r ? r.scores : [];
27
+ }
28
+ function specCountOf(r) {
29
+ return "specFiles" in r ? r.specFiles.length : undefined;
30
+ }
31
+ export function SummaryScreen({ command, result }) {
32
+ const { navigate } = useRouter();
33
+ const validation = validationOf(result);
34
+ const pilot = pilotOf(result);
35
+ const cases = testCasesOf(result);
36
+ const scores = scoresOf(result);
37
+ const specs = specCountOf(result);
38
+ const actions = [
39
+ { label: "View artifacts (cases · report · logs)", value: "artifacts" },
40
+ { label: "Re-run this command", value: "rerun" },
41
+ { label: "Back to menu", value: "menu" },
42
+ ];
43
+ const onAction = (item) => {
44
+ if (item.value === "artifacts")
45
+ navigate({ name: "runDetail", runDir: result.runDir });
46
+ else if (item.value === "rerun")
47
+ navigate({ name: "form", command, initial: rerunInitial(command, result) });
48
+ else
49
+ navigate({ name: "launcher" });
50
+ };
51
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "cyan", bold: true, children: [command, " \u2014 done"] }), _jsx(Text, { dimColor: true, children: result.runDir }), validation ? (_jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: validation.greenRatio >= 0.8 ? "green" : "yellow", children: [Math.round(validation.greenRatio * 100), "% green"] }), _jsxs(Text, { dimColor: true, children: [" \u00B7 flaky: ", validation.flakyCount] })] })) : null, specs !== undefined ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: [specs, " spec file(s) generated"] }) })) : null, pilot ? _jsx(PilotBadge, { pilot: pilot }) : null, _jsx(ScoresTable, { scores: scores }), _jsx(TestCaseList, { cases: cases }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: actions, onSelect: onAction }) })] }));
52
+ }
53
+ //# sourceMappingURL=summary-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/summary-screen.tsx"],"names":[],"mappings":"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"}