@aragon-agent/tui 0.0.0-stage → 0.0.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 (528) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +21 -0
  3. package/README.md +81 -2
  4. package/dist/index.d.ts +11 -0
  5. package/dist/index.js +11 -0
  6. package/dist/input/control-sequences.d.ts +71 -0
  7. package/dist/input/control-sequences.js +222 -0
  8. package/dist/input/csiu-keys.d.ts +66 -0
  9. package/dist/input/csiu-keys.js +181 -0
  10. package/dist/input/cursor-report.d.ts +61 -0
  11. package/dist/input/cursor-report.js +97 -0
  12. package/dist/input/enter-sequences.d.ts +64 -0
  13. package/dist/input/enter-sequences.js +153 -0
  14. package/dist/input/interrupt-gesture.d.ts +18 -0
  15. package/dist/input/interrupt-gesture.js +19 -0
  16. package/dist/input/keyboard-enhancement.d.ts +42 -0
  17. package/dist/input/keyboard-enhancement.js +65 -0
  18. package/dist/input/keymap.d.ts +20 -0
  19. package/dist/input/keymap.js +99 -0
  20. package/dist/input/limits.d.ts +118 -0
  21. package/dist/input/limits.js +109 -0
  22. package/dist/input/mouse-events.d.ts +87 -0
  23. package/dist/input/mouse-events.js +212 -0
  24. package/dist/input/paste-parse.d.ts +83 -0
  25. package/dist/input/paste-parse.js +107 -0
  26. package/dist/input/pointer-router.d.ts +11 -0
  27. package/dist/input/pointer-router.js +14 -0
  28. package/dist/input/stdin-filter.d.ts +112 -0
  29. package/dist/input/stdin-filter.js +657 -0
  30. package/dist/input/win32-input-mode.d.ts +61 -0
  31. package/dist/input/win32-input-mode.js +269 -0
  32. package/dist/model/agent/agent-mode.d.ts +108 -0
  33. package/dist/model/agent/agent-mode.js +121 -0
  34. package/dist/model/agent/entry-limits.d.ts +65 -0
  35. package/dist/model/agent/entry-limits.js +133 -0
  36. package/dist/model/agent/governance-view.d.ts +40 -0
  37. package/dist/model/agent/governance-view.js +40 -0
  38. package/dist/model/agent/invocation-card.d.ts +77 -0
  39. package/dist/model/agent/invocation-card.js +169 -0
  40. package/dist/model/agent/model-probe-limits.d.ts +39 -0
  41. package/dist/model/agent/model-probe-limits.js +25 -0
  42. package/dist/model/agent/model-probe.d.ts +104 -0
  43. package/dist/model/agent/model-probe.js +391 -0
  44. package/dist/model/agent/queued-messages.d.ts +23 -0
  45. package/dist/model/agent/queued-messages.js +49 -0
  46. package/dist/model/agent/reducer.d.ts +857 -0
  47. package/dist/model/agent/reducer.js +1646 -0
  48. package/dist/model/agent/retry-view.d.ts +68 -0
  49. package/dist/model/agent/retry-view.js +95 -0
  50. package/dist/model/agent/usage.d.ts +47 -0
  51. package/dist/model/agent/usage.js +84 -0
  52. package/dist/model/compaction/limits.d.ts +61 -0
  53. package/dist/model/compaction/limits.js +64 -0
  54. package/dist/model/compaction/meter.d.ts +276 -0
  55. package/dist/model/compaction/meter.js +512 -0
  56. package/dist/model/compaction/pressure.d.ts +163 -0
  57. package/dist/model/compaction/pressure.js +199 -0
  58. package/dist/model/compaction/reason-text.d.ts +36 -0
  59. package/dist/model/compaction/reason-text.js +78 -0
  60. package/dist/model/compaction/types.d.ts +360 -0
  61. package/dist/model/compaction/types.js +22 -0
  62. package/dist/model/config/governance-config.d.ts +125 -0
  63. package/dist/model/config/governance-config.js +164 -0
  64. package/dist/model/config/kit-resolution.d.ts +93 -0
  65. package/dist/model/config/kit-resolution.js +226 -0
  66. package/dist/model/config/model-kits.d.ts +225 -0
  67. package/dist/model/config/model-kits.js +302 -0
  68. package/dist/model/config/model-profile-resolution.d.ts +28 -0
  69. package/dist/model/config/model-profile-resolution.js +88 -0
  70. package/dist/model/config/model-profiles.d.ts +103 -0
  71. package/dist/model/config/model-profiles.js +188 -0
  72. package/dist/model/config/model-settings-types.d.ts +71 -0
  73. package/dist/model/config/model-settings-types.js +18 -0
  74. package/dist/model/config/schema.d.ts +1645 -0
  75. package/dist/model/config/schema.js +1383 -0
  76. package/dist/model/fast/limits.d.ts +152 -0
  77. package/dist/model/fast/limits.js +152 -0
  78. package/dist/model/fast/resolve.d.ts +44 -0
  79. package/dist/model/fast/resolve.js +107 -0
  80. package/dist/model/fast/task-summary-types.d.ts +66 -0
  81. package/dist/model/fast/task-summary-types.js +17 -0
  82. package/dist/model/fast/types.d.ts +141 -0
  83. package/dist/model/fast/types.js +14 -0
  84. package/dist/model/governance/governed-dispatch.d.ts +19 -0
  85. package/dist/model/governance/governed-dispatch.js +17 -0
  86. package/dist/model/governance/limits.d.ts +107 -0
  87. package/dist/model/governance/limits.js +131 -0
  88. package/dist/model/governance/posture.d.ts +35 -0
  89. package/dist/model/governance/posture.js +59 -0
  90. package/dist/model/governance/rules/events-table.d.ts +46 -0
  91. package/dist/model/governance/rules/events-table.js +94 -0
  92. package/dist/model/governance/types.d.ts +661 -0
  93. package/dist/model/governance/types.js +27 -0
  94. package/dist/model/logging/levels.d.ts +40 -0
  95. package/dist/model/logging/levels.js +59 -0
  96. package/dist/model/logging/log-port.d.ts +38 -0
  97. package/dist/model/logging/log-port.js +41 -0
  98. package/dist/model/logging/secret-registry.d.ts +32 -0
  99. package/dist/model/logging/secret-registry.js +73 -0
  100. package/dist/model/proc/limits.d.ts +214 -0
  101. package/dist/model/proc/limits.js +221 -0
  102. package/dist/model/proc/progress.d.ts +47 -0
  103. package/dist/model/proc/progress.js +163 -0
  104. package/dist/model/proc/types.d.ts +269 -0
  105. package/dist/model/proc/types.js +15 -0
  106. package/dist/model/proc/wait-view.d.ts +65 -0
  107. package/dist/model/proc/wait-view.js +66 -0
  108. package/dist/model/prompts/copy.d.ts +89 -0
  109. package/dist/model/prompts/copy.js +131 -0
  110. package/dist/model/prompts/fill.d.ts +51 -0
  111. package/dist/model/prompts/fill.js +46 -0
  112. package/dist/model/prompts/limits.d.ts +53 -0
  113. package/dist/model/prompts/limits.js +53 -0
  114. package/dist/model/prompts/search.d.ts +58 -0
  115. package/dist/model/prompts/search.js +146 -0
  116. package/dist/model/prompts/types.d.ts +204 -0
  117. package/dist/model/prompts/types.js +13 -0
  118. package/dist/model/prompts/validate.d.ts +22 -0
  119. package/dist/model/prompts/validate.js +69 -0
  120. package/dist/model/team/activity.d.ts +67 -0
  121. package/dist/model/team/activity.js +130 -0
  122. package/dist/model/team/limits.d.ts +308 -0
  123. package/dist/model/team/limits.js +330 -0
  124. package/dist/model/team/model.d.ts +104 -0
  125. package/dist/model/team/model.js +150 -0
  126. package/dist/model/team/panel-rows.d.ts +48 -0
  127. package/dist/model/team/panel-rows.js +75 -0
  128. package/dist/model/team/timeline.d.ts +74 -0
  129. package/dist/model/team/timeline.js +101 -0
  130. package/dist/model/team/types.d.ts +354 -0
  131. package/dist/model/team/types.js +13 -0
  132. package/dist/model/todo/acceptance.d.ts +120 -0
  133. package/dist/model/todo/acceptance.js +399 -0
  134. package/dist/model/todo/follow-through.d.ts +138 -0
  135. package/dist/model/todo/follow-through.js +248 -0
  136. package/dist/model/todo/limits.d.ts +152 -0
  137. package/dist/model/todo/limits.js +152 -0
  138. package/dist/model/todo/panel-rows.d.ts +45 -0
  139. package/dist/model/todo/panel-rows.js +70 -0
  140. package/dist/model/todo/plan-sections.d.ts +60 -0
  141. package/dist/model/todo/plan-sections.js +108 -0
  142. package/dist/model/todo/row-window.d.ts +51 -0
  143. package/dist/model/todo/row-window.js +107 -0
  144. package/dist/model/todo/types.d.ts +124 -0
  145. package/dist/model/todo/types.js +12 -0
  146. package/dist/model/tools/human-input.d.ts +212 -0
  147. package/dist/model/tools/human-input.js +265 -0
  148. package/dist/model/tools/patch.d.ts +115 -0
  149. package/dist/model/tools/patch.js +453 -0
  150. package/dist/model/tools/terminal-output.d.ts +115 -0
  151. package/dist/model/tools/terminal-output.js +201 -0
  152. package/dist/model/tools/tool-output-store.d.ts +68 -0
  153. package/dist/model/tools/tool-output-store.js +102 -0
  154. package/dist/model/update/limits.d.ts +111 -0
  155. package/dist/model/update/limits.js +111 -0
  156. package/dist/model/update/semver.d.ts +89 -0
  157. package/dist/model/update/semver.js +295 -0
  158. package/dist/model/update/types.d.ts +169 -0
  159. package/dist/model/update/types.js +68 -0
  160. package/dist/testing/governance-fixtures.d.ts +13 -0
  161. package/dist/testing/governance-fixtures.js +98 -0
  162. package/dist/testing/mini-vt.d.ts +28 -0
  163. package/dist/testing/mini-vt.js +158 -0
  164. package/dist/testing/render-at-width.d.ts +16 -0
  165. package/dist/testing/render-at-width.js +57 -0
  166. package/dist/testing/terminal-harness.d.ts +15 -0
  167. package/dist/testing/terminal-harness.js +40 -0
  168. package/dist/testing/vt-screen.d.ts +28 -0
  169. package/dist/testing/vt-screen.js +139 -0
  170. package/dist/ui/ActivityLine.d.ts +26 -0
  171. package/dist/ui/ActivityLine.js +51 -0
  172. package/dist/ui/AutocompletePopup.d.ts +23 -0
  173. package/dist/ui/AutocompletePopup.js +17 -0
  174. package/dist/ui/BottomStatusRow.d.ts +10 -0
  175. package/dist/ui/BottomStatusRow.js +9 -0
  176. package/dist/ui/Composer.d.ts +115 -0
  177. package/dist/ui/Composer.js +64 -0
  178. package/dist/ui/GovernancePanel.d.ts +50 -0
  179. package/dist/ui/GovernancePanel.js +77 -0
  180. package/dist/ui/GovernanceRun.d.ts +18 -0
  181. package/dist/ui/GovernanceRun.js +11 -0
  182. package/dist/ui/Header.d.ts +48 -0
  183. package/dist/ui/Header.js +27 -0
  184. package/dist/ui/Logo.d.ts +32 -0
  185. package/dist/ui/Logo.js +65 -0
  186. package/dist/ui/Markdown.d.ts +29 -0
  187. package/dist/ui/Markdown.js +116 -0
  188. package/dist/ui/PromptCaret.d.ts +11 -0
  189. package/dist/ui/PromptCaret.js +31 -0
  190. package/dist/ui/PromptInput.d.ts +192 -0
  191. package/dist/ui/PromptInput.js +689 -0
  192. package/dist/ui/QueuePanel.d.ts +8 -0
  193. package/dist/ui/QueuePanel.js +9 -0
  194. package/dist/ui/QueueStatusRow.d.ts +24 -0
  195. package/dist/ui/QueueStatusRow.js +51 -0
  196. package/dist/ui/ScrollbackShell.d.ts +132 -0
  197. package/dist/ui/ScrollbackShell.js +26 -0
  198. package/dist/ui/SessionOpener.d.ts +30 -0
  199. package/dist/ui/SessionOpener.js +12 -0
  200. package/dist/ui/StatusBar.d.ts +130 -0
  201. package/dist/ui/StatusBar.js +61 -0
  202. package/dist/ui/TeamPanel.d.ts +76 -0
  203. package/dist/ui/TeamPanel.js +103 -0
  204. package/dist/ui/ToastStack.d.ts +8 -0
  205. package/dist/ui/ToastStack.js +31 -0
  206. package/dist/ui/TodoPanel.d.ts +52 -0
  207. package/dist/ui/TodoPanel.js +214 -0
  208. package/dist/ui/Transcript.d.ts +105 -0
  209. package/dist/ui/Transcript.js +258 -0
  210. package/dist/ui/UpdateLine.d.ts +44 -0
  211. package/dist/ui/UpdateLine.js +129 -0
  212. package/dist/ui/activity-phrases.d.ts +33 -0
  213. package/dist/ui/activity-phrases.js +50 -0
  214. package/dist/ui/capabilities.d.ts +27 -0
  215. package/dist/ui/capabilities.js +65 -0
  216. package/dist/ui/clipboard-task.d.ts +29 -0
  217. package/dist/ui/clipboard-task.js +66 -0
  218. package/dist/ui/clipboard.d.ts +31 -0
  219. package/dist/ui/clipboard.js +157 -0
  220. package/dist/ui/color-runtime.d.ts +5 -0
  221. package/dist/ui/color-runtime.js +29 -0
  222. package/dist/ui/composer-input.d.ts +38 -0
  223. package/dist/ui/composer-input.js +79 -0
  224. package/dist/ui/composer-limits.d.ts +30 -0
  225. package/dist/ui/composer-limits.js +45 -0
  226. package/dist/ui/composer-rows.d.ts +73 -0
  227. package/dist/ui/composer-rows.js +129 -0
  228. package/dist/ui/console-bridge.d.ts +19 -0
  229. package/dist/ui/console-bridge.js +52 -0
  230. package/dist/ui/density.d.ts +26 -0
  231. package/dist/ui/density.js +34 -0
  232. package/dist/ui/display-tab.d.ts +51 -0
  233. package/dist/ui/display-tab.js +82 -0
  234. package/dist/ui/editor-navigation.d.ts +55 -0
  235. package/dist/ui/editor-navigation.js +96 -0
  236. package/dist/ui/editor-reducer.d.ts +108 -0
  237. package/dist/ui/editor-reducer.js +187 -0
  238. package/dist/ui/enter-frames.d.ts +47 -0
  239. package/dist/ui/enter-frames.js +117 -0
  240. package/dist/ui/entries/AssistantEntry.d.ts +37 -0
  241. package/dist/ui/entries/AssistantEntry.js +43 -0
  242. package/dist/ui/entries/CompactionCard.d.ts +88 -0
  243. package/dist/ui/entries/CompactionCard.js +222 -0
  244. package/dist/ui/entries/DiffView.d.ts +61 -0
  245. package/dist/ui/entries/DiffView.js +103 -0
  246. package/dist/ui/entries/EntryFrame.d.ts +23 -0
  247. package/dist/ui/entries/EntryFrame.js +6 -0
  248. package/dist/ui/entries/FastCard.d.ts +53 -0
  249. package/dist/ui/entries/FastCard.js +105 -0
  250. package/dist/ui/entries/GovernanceCard.d.ts +30 -0
  251. package/dist/ui/entries/GovernanceCard.js +32 -0
  252. package/dist/ui/entries/InvocationCard.d.ts +20 -0
  253. package/dist/ui/entries/InvocationCard.js +32 -0
  254. package/dist/ui/entries/QueuedEntry.d.ts +27 -0
  255. package/dist/ui/entries/QueuedEntry.js +33 -0
  256. package/dist/ui/entries/RetryCard.d.ts +56 -0
  257. package/dist/ui/entries/RetryCard.js +60 -0
  258. package/dist/ui/entries/ServiceCard.d.ts +82 -0
  259. package/dist/ui/entries/ServiceCard.js +151 -0
  260. package/dist/ui/entries/TeamCard.d.ts +55 -0
  261. package/dist/ui/entries/TeamCard.js +94 -0
  262. package/dist/ui/entries/TodoCard.d.ts +54 -0
  263. package/dist/ui/entries/TodoCard.js +98 -0
  264. package/dist/ui/entries/ToolCard.d.ts +81 -0
  265. package/dist/ui/entries/ToolCard.js +169 -0
  266. package/dist/ui/entries/ToolPreview.d.ts +59 -0
  267. package/dist/ui/entries/ToolPreview.js +208 -0
  268. package/dist/ui/entries/UserEntry.d.ts +36 -0
  269. package/dist/ui/entries/UserEntry.js +57 -0
  270. package/dist/ui/entries/WaitCard.d.ts +37 -0
  271. package/dist/ui/entries/WaitCard.js +92 -0
  272. package/dist/ui/exit-snapshot.d.ts +43 -0
  273. package/dist/ui/exit-snapshot.js +26 -0
  274. package/dist/ui/frame-differ.d.ts +166 -0
  275. package/dist/ui/frame-differ.js +354 -0
  276. package/dist/ui/frame-observer.d.ts +17 -0
  277. package/dist/ui/frame-observer.js +94 -0
  278. package/dist/ui/frame-parser.d.ts +7 -0
  279. package/dist/ui/frame-parser.js +18 -0
  280. package/dist/ui/gauge.d.ts +39 -0
  281. package/dist/ui/gauge.js +55 -0
  282. package/dist/ui/glyphs.d.ts +178 -0
  283. package/dist/ui/glyphs.js +165 -0
  284. package/dist/ui/governance-copy.d.ts +69 -0
  285. package/dist/ui/governance-copy.js +104 -0
  286. package/dist/ui/governance-status.d.ts +145 -0
  287. package/dist/ui/governance-status.js +326 -0
  288. package/dist/ui/gradient.d.ts +11 -0
  289. package/dist/ui/gradient.js +50 -0
  290. package/dist/ui/ink-runtime.d.ts +4 -0
  291. package/dist/ui/ink-runtime.js +51 -0
  292. package/dist/ui/interaction-copy.d.ts +84 -0
  293. package/dist/ui/interaction-copy.js +41 -0
  294. package/dist/ui/interaction-hints.d.ts +44 -0
  295. package/dist/ui/interaction-hints.js +97 -0
  296. package/dist/ui/layout/AppShell.d.ts +17 -0
  297. package/dist/ui/layout/AppShell.js +6 -0
  298. package/dist/ui/layout/Gutter.d.ts +67 -0
  299. package/dist/ui/layout/Gutter.js +42 -0
  300. package/dist/ui/layout/MeasuredEntry.d.ts +21 -0
  301. package/dist/ui/layout/MeasuredEntry.js +30 -0
  302. package/dist/ui/layout/OverlayFrame.d.ts +73 -0
  303. package/dist/ui/layout/OverlayFrame.js +110 -0
  304. package/dist/ui/layout/ScrollIndicator.d.ts +32 -0
  305. package/dist/ui/layout/ScrollIndicator.js +22 -0
  306. package/dist/ui/layout/ScrollViewport.d.ts +40 -0
  307. package/dist/ui/layout/ScrollViewport.js +222 -0
  308. package/dist/ui/layout/agents-board.d.ts +102 -0
  309. package/dist/ui/layout/agents-board.js +389 -0
  310. package/dist/ui/layout/autocomplete.d.ts +18 -0
  311. package/dist/ui/layout/autocomplete.js +26 -0
  312. package/dist/ui/layout/budget.d.ts +43 -0
  313. package/dist/ui/layout/budget.js +52 -0
  314. package/dist/ui/layout/cells.d.ts +61 -0
  315. package/dist/ui/layout/cells.js +156 -0
  316. package/dist/ui/layout/document-layout.d.ts +13 -0
  317. package/dist/ui/layout/document-layout.js +10 -0
  318. package/dist/ui/layout/follow-state.d.ts +138 -0
  319. package/dist/ui/layout/follow-state.js +148 -0
  320. package/dist/ui/layout/frame.d.ts +36 -0
  321. package/dist/ui/layout/frame.js +39 -0
  322. package/dist/ui/layout/governance-board.d.ts +121 -0
  323. package/dist/ui/layout/governance-board.js +382 -0
  324. package/dist/ui/layout/governance-card.d.ts +53 -0
  325. package/dist/ui/layout/governance-card.js +134 -0
  326. package/dist/ui/layout/governance-chip.d.ts +38 -0
  327. package/dist/ui/layout/governance-chip.js +64 -0
  328. package/dist/ui/layout/governance-panel.d.ts +85 -0
  329. package/dist/ui/layout/governance-panel.js +358 -0
  330. package/dist/ui/layout/governance-roster.d.ts +65 -0
  331. package/dist/ui/layout/governance-roster.js +275 -0
  332. package/dist/ui/layout/header-hints.d.ts +90 -0
  333. package/dist/ui/layout/header-hints.js +110 -0
  334. package/dist/ui/layout/header-left.d.ts +115 -0
  335. package/dist/ui/layout/header-left.js +206 -0
  336. package/dist/ui/layout/invocation-card.d.ts +41 -0
  337. package/dist/ui/layout/invocation-card.js +91 -0
  338. package/dist/ui/layout/kit-chip.d.ts +50 -0
  339. package/dist/ui/layout/kit-chip.js +81 -0
  340. package/dist/ui/layout/overlay-window.d.ts +43 -0
  341. package/dist/ui/layout/overlay-window.js +51 -0
  342. package/dist/ui/layout/queue-layout.d.ts +19 -0
  343. package/dist/ui/layout/queue-layout.js +26 -0
  344. package/dist/ui/layout/rail.d.ts +7 -0
  345. package/dist/ui/layout/rail.js +16 -0
  346. package/dist/ui/layout/scroll-indicator.d.ts +27 -0
  347. package/dist/ui/layout/scroll-indicator.js +36 -0
  348. package/dist/ui/layout/scroll.d.ts +37 -0
  349. package/dist/ui/layout/scroll.js +99 -0
  350. package/dist/ui/layout/scrollbar-geometry.d.ts +17 -0
  351. package/dist/ui/layout/scrollbar-geometry.js +13 -0
  352. package/dist/ui/layout/session-chip.d.ts +52 -0
  353. package/dist/ui/layout/session-chip.js +64 -0
  354. package/dist/ui/layout/shortcut-panel-layout.d.ts +191 -0
  355. package/dist/ui/layout/shortcut-panel-layout.js +321 -0
  356. package/dist/ui/layout/status-detail-layout.d.ts +9 -0
  357. package/dist/ui/layout/status-detail-layout.js +79 -0
  358. package/dist/ui/layout/status-layout.d.ts +140 -0
  359. package/dist/ui/layout/status-layout.js +262 -0
  360. package/dist/ui/layout/task-summary-cell.d.ts +61 -0
  361. package/dist/ui/layout/task-summary-cell.js +65 -0
  362. package/dist/ui/layout/team-panel.d.ts +18 -0
  363. package/dist/ui/layout/team-panel.js +25 -0
  364. package/dist/ui/layout/team-row.d.ts +139 -0
  365. package/dist/ui/layout/team-row.js +246 -0
  366. package/dist/ui/layout/todo-layout.d.ts +62 -0
  367. package/dist/ui/layout/todo-layout.js +102 -0
  368. package/dist/ui/layout/useTerminalSize.d.ts +13 -0
  369. package/dist/ui/layout/useTerminalSize.js +50 -0
  370. package/dist/ui/layout/viewport-geometry.d.ts +29 -0
  371. package/dist/ui/layout/viewport-geometry.js +28 -0
  372. package/dist/ui/layout/virtual-window.d.ts +112 -0
  373. package/dist/ui/layout/virtual-window.js +494 -0
  374. package/dist/ui/layout/wait-bar.d.ts +34 -0
  375. package/dist/ui/layout/wait-bar.js +48 -0
  376. package/dist/ui/layout/wrap-rows.d.ts +26 -0
  377. package/dist/ui/layout/wrap-rows.js +88 -0
  378. package/dist/ui/live-clamp.d.ts +14 -0
  379. package/dist/ui/live-clamp.js +46 -0
  380. package/dist/ui/markdown-blocks.d.ts +107 -0
  381. package/dist/ui/markdown-blocks.js +240 -0
  382. package/dist/ui/overlays/AgentsBoardOverlay.d.ts +57 -0
  383. package/dist/ui/overlays/AgentsBoardOverlay.js +183 -0
  384. package/dist/ui/overlays/ConfirmDialog.d.ts +31 -0
  385. package/dist/ui/overlays/ConfirmDialog.js +44 -0
  386. package/dist/ui/overlays/GovernanceBoardOverlay.d.ts +41 -0
  387. package/dist/ui/overlays/GovernanceBoardOverlay.js +76 -0
  388. package/dist/ui/overlays/GovernanceSettingsPage.d.ts +48 -0
  389. package/dist/ui/overlays/GovernanceSettingsPage.js +93 -0
  390. package/dist/ui/overlays/HelpOverlay.d.ts +29 -0
  391. package/dist/ui/overlays/HelpOverlay.js +232 -0
  392. package/dist/ui/overlays/KitEditor.d.ts +23 -0
  393. package/dist/ui/overlays/KitEditor.js +101 -0
  394. package/dist/ui/overlays/KitManager.d.ts +23 -0
  395. package/dist/ui/overlays/KitManager.js +104 -0
  396. package/dist/ui/overlays/KitPicker.d.ts +49 -0
  397. package/dist/ui/overlays/KitPicker.js +58 -0
  398. package/dist/ui/overlays/ModelDiscoveryList.d.ts +23 -0
  399. package/dist/ui/overlays/ModelDiscoveryList.js +161 -0
  400. package/dist/ui/overlays/ModelPicker.d.ts +26 -0
  401. package/dist/ui/overlays/ModelPicker.js +63 -0
  402. package/dist/ui/overlays/ModelProfileEditor.d.ts +29 -0
  403. package/dist/ui/overlays/ModelProfileEditor.js +168 -0
  404. package/dist/ui/overlays/ModelProfilePicker.d.ts +48 -0
  405. package/dist/ui/overlays/ModelProfilePicker.js +231 -0
  406. package/dist/ui/overlays/PlanReviewOverlay.d.ts +51 -0
  407. package/dist/ui/overlays/PlanReviewOverlay.js +132 -0
  408. package/dist/ui/overlays/PromptEditorPage.d.ts +48 -0
  409. package/dist/ui/overlays/PromptEditorPage.js +227 -0
  410. package/dist/ui/overlays/PromptLibraryOverlay.d.ts +37 -0
  411. package/dist/ui/overlays/PromptLibraryOverlay.js +191 -0
  412. package/dist/ui/overlays/PromptPicker.d.ts +36 -0
  413. package/dist/ui/overlays/PromptPicker.js +129 -0
  414. package/dist/ui/overlays/PromptTextArea.d.ts +86 -0
  415. package/dist/ui/overlays/PromptTextArea.js +141 -0
  416. package/dist/ui/overlays/QuestionOverlay.d.ts +39 -0
  417. package/dist/ui/overlays/QuestionOverlay.js +258 -0
  418. package/dist/ui/overlays/QueueOverlay.d.ts +22 -0
  419. package/dist/ui/overlays/QueueOverlay.js +79 -0
  420. package/dist/ui/overlays/SettingsScreen.d.ts +228 -0
  421. package/dist/ui/overlays/SettingsScreen.js +1037 -0
  422. package/dist/ui/overlays/ShortcutPanel.d.ts +39 -0
  423. package/dist/ui/overlays/ShortcutPanel.js +106 -0
  424. package/dist/ui/overlays/TeamFanoutPage.d.ts +51 -0
  425. package/dist/ui/overlays/TeamFanoutPage.js +90 -0
  426. package/dist/ui/overlays/governance-settings.d.ts +79 -0
  427. package/dist/ui/overlays/governance-settings.js +140 -0
  428. package/dist/ui/overlays/kit-picker-state.d.ts +87 -0
  429. package/dist/ui/overlays/kit-picker-state.js +136 -0
  430. package/dist/ui/overlays/kit-settings-state.d.ts +129 -0
  431. package/dist/ui/overlays/kit-settings-state.js +268 -0
  432. package/dist/ui/overlays/model-probe-view.d.ts +128 -0
  433. package/dist/ui/overlays/model-probe-view.js +225 -0
  434. package/dist/ui/overlays/model-profile-state.d.ts +177 -0
  435. package/dist/ui/overlays/model-profile-state.js +301 -0
  436. package/dist/ui/overlays/prompt-library-state.d.ts +162 -0
  437. package/dist/ui/overlays/prompt-library-state.js +335 -0
  438. package/dist/ui/overlays/prompt-picker-state.d.ts +71 -0
  439. package/dist/ui/overlays/prompt-picker-state.js +98 -0
  440. package/dist/ui/overlays/team-fanout-state.d.ts +106 -0
  441. package/dist/ui/overlays/team-fanout-state.js +155 -0
  442. package/dist/ui/overlays/use-model-probe.d.ts +30 -0
  443. package/dist/ui/overlays/use-model-probe.js +109 -0
  444. package/dist/ui/palettes.d.ts +112 -0
  445. package/dist/ui/palettes.js +130 -0
  446. package/dist/ui/paste-frames.d.ts +91 -0
  447. package/dist/ui/paste-frames.js +117 -0
  448. package/dist/ui/paste-tokens.d.ts +90 -0
  449. package/dist/ui/paste-tokens.js +147 -0
  450. package/dist/ui/render-cache.d.ts +81 -0
  451. package/dist/ui/render-cache.js +196 -0
  452. package/dist/ui/render-governor.d.ts +54 -0
  453. package/dist/ui/render-governor.js +78 -0
  454. package/dist/ui/run-metrics.d.ts +23 -0
  455. package/dist/ui/run-metrics.js +27 -0
  456. package/dist/ui/run-status-row.d.ts +63 -0
  457. package/dist/ui/run-status-row.js +54 -0
  458. package/dist/ui/screen.d.ts +107 -0
  459. package/dist/ui/screen.js +234 -0
  460. package/dist/ui/scrollback/LiveTail.d.ts +115 -0
  461. package/dist/ui/scrollback/LiveTail.js +48 -0
  462. package/dist/ui/scrollback/band.d.ts +114 -0
  463. package/dist/ui/scrollback/band.js +143 -0
  464. package/dist/ui/scrollback/budget.d.ts +90 -0
  465. package/dist/ui/scrollback/budget.js +100 -0
  466. package/dist/ui/scrollback/canvas.d.ts +100 -0
  467. package/dist/ui/scrollback/canvas.js +114 -0
  468. package/dist/ui/scrollback/cursor-probe.d.ts +71 -0
  469. package/dist/ui/scrollback/cursor-probe.js +133 -0
  470. package/dist/ui/scrollback/drain.d.ts +32 -0
  471. package/dist/ui/scrollback/drain.js +64 -0
  472. package/dist/ui/scrollback/exit-summary.d.ts +23 -0
  473. package/dist/ui/scrollback/exit-summary.js +25 -0
  474. package/dist/ui/scrollback/limits.d.ts +98 -0
  475. package/dist/ui/scrollback/limits.js +98 -0
  476. package/dist/ui/scrollback/live-preview.d.ts +34 -0
  477. package/dist/ui/scrollback/live-preview.js +130 -0
  478. package/dist/ui/scrollback/overflow-print.d.ts +108 -0
  479. package/dist/ui/scrollback/overflow-print.js +120 -0
  480. package/dist/ui/scrollback/renderer.d.ts +48 -0
  481. package/dist/ui/scrollback/renderer.js +186 -0
  482. package/dist/ui/scrollback/scrollback-writer.d.ts +174 -0
  483. package/dist/ui/scrollback/scrollback-writer.js +648 -0
  484. package/dist/ui/scrollback/settled-boundary.d.ts +42 -0
  485. package/dist/ui/scrollback/settled-boundary.js +109 -0
  486. package/dist/ui/scrollback/tail-anchor.d.ts +71 -0
  487. package/dist/ui/scrollback/tail-anchor.js +79 -0
  488. package/dist/ui/scrollback/tail-window.d.ts +73 -0
  489. package/dist/ui/scrollback/tail-window.js +89 -0
  490. package/dist/ui/scrollback/use-scrollback-view.d.ts +139 -0
  491. package/dist/ui/scrollback/use-scrollback-view.js +601 -0
  492. package/dist/ui/scrollback/writer-shapes.d.ts +127 -0
  493. package/dist/ui/scrollback/writer-shapes.js +159 -0
  494. package/dist/ui/scrollbar-controller.d.ts +30 -0
  495. package/dist/ui/scrollbar-controller.js +124 -0
  496. package/dist/ui/selection/highlight.d.ts +39 -0
  497. package/dist/ui/selection/highlight.js +64 -0
  498. package/dist/ui/selection/screen-mirror.d.ts +24 -0
  499. package/dist/ui/selection/screen-mirror.js +35 -0
  500. package/dist/ui/selection/selection-controller.d.ts +104 -0
  501. package/dist/ui/selection/selection-controller.js +372 -0
  502. package/dist/ui/selection/selection.d.ts +90 -0
  503. package/dist/ui/selection/selection.js +223 -0
  504. package/dist/ui/shortcuts.d.ts +81 -0
  505. package/dist/ui/shortcuts.js +221 -0
  506. package/dist/ui/status-feedback.d.ts +35 -0
  507. package/dist/ui/status-feedback.js +38 -0
  508. package/dist/ui/stdout-frame-writer.d.ts +74 -0
  509. package/dist/ui/stdout-frame-writer.js +155 -0
  510. package/dist/ui/team-status.d.ts +166 -0
  511. package/dist/ui/team-status.js +252 -0
  512. package/dist/ui/terminal-plan.d.ts +52 -0
  513. package/dist/ui/terminal-plan.js +49 -0
  514. package/dist/ui/theme.d.ts +96 -0
  515. package/dist/ui/theme.js +130 -0
  516. package/dist/ui/transcript-text.d.ts +41 -0
  517. package/dist/ui/transcript-text.js +282 -0
  518. package/dist/ui/use-height-store.d.ts +31 -0
  519. package/dist/ui/use-height-store.js +76 -0
  520. package/dist/ui/use-render-governor.d.ts +39 -0
  521. package/dist/ui/use-render-governor.js +57 -0
  522. package/dist/ui/use-wheel-routing.d.ts +57 -0
  523. package/dist/ui/use-wheel-routing.js +152 -0
  524. package/dist/ui/win-vt-force.d.ts +136 -0
  525. package/dist/ui/win-vt-force.js +237 -0
  526. package/dist/ui/win-vt-input.d.ts +57 -0
  527. package/dist/ui/win-vt-input.js +62 -0
  528. package/package.json +86 -4
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Snapshot / card fixtures for the governance TUI tests. The engine is built by another
3
+ * agent, so every UI test runs against these hand-built shapes.
4
+ */
5
+ export const NOW = 1_000_000;
6
+ export function rosterRow(over = {}) {
7
+ return {
8
+ id: 'dev1',
9
+ role: 'DEV',
10
+ generation: 0,
11
+ state: 'working',
12
+ wpId: 'auth-api',
13
+ activity: 'login endpoint + session',
14
+ confirmed: 100,
15
+ provisional: 0,
16
+ label: 'NORMAL',
17
+ lastDelta: null,
18
+ replacedBy: null,
19
+ ...over,
20
+ };
21
+ }
22
+ export function pipeline(active = 'review') {
23
+ const keys = ['intake', 'dev', 'review', 'test', 'settle', 'integrate'];
24
+ const at = keys.indexOf(active);
25
+ return keys.map((key, index) => ({
26
+ key,
27
+ state: index < at ? 'done' : index === at ? 'active' : 'pending',
28
+ }));
29
+ }
30
+ /** The six-member roster of the spec's 10.3 sketch. */
31
+ export function sketchRoster() {
32
+ return [
33
+ rosterRow({ id: 'dev1', state: 'submitted', confirmed: 100, provisional: 15, activity: '' }),
34
+ rosterRow({
35
+ id: 'dev2', wpId: 'ui-form', state: 'submitted', confirmed: 80, label: 'WARNING',
36
+ activity: 'rework 1/3',
37
+ }),
38
+ rosterRow({
39
+ id: 'rev1', role: 'REV', state: 'working', wpId: 'auth-api',
40
+ activity: 'grep "sanitize" src/auth',
41
+ }),
42
+ rosterRow({
43
+ id: 'rev2', role: 'REV', state: 'working', wpId: 'ui-form',
44
+ activity: 'read_file ui/Form.tsx',
45
+ }),
46
+ rosterRow({ id: 'tst1', role: 'TEST', state: 'queued', wpId: null, activity: '' }),
47
+ rosterRow({
48
+ id: 'insp', role: 'INSP', state: 'idle', wpId: null, activity: '', confirmed: null,
49
+ label: 'NOT_SCORED',
50
+ }),
51
+ ];
52
+ }
53
+ export function snapshot(over = {}) {
54
+ return {
55
+ runId: 'gmh3k7f3a',
56
+ goal: 'ship the login flow',
57
+ status: 'executing',
58
+ phase: 2,
59
+ phaseCount: 3,
60
+ stage: 'review',
61
+ stageRunning: true,
62
+ startedAt: NOW - 842_000,
63
+ pipeline: pipeline('review'),
64
+ roster: sketchRoster(),
65
+ health: 88,
66
+ recent: [
67
+ { at: NOW - 3000, agentId: 'rev2', code: 'R2', delta: 10, provisional: false, reason: 'valid finding' },
68
+ { at: NOW - 2000, agentId: 'dev2', code: 'D5', delta: -20, provisional: false, reason: 'rework' },
69
+ { at: NOW - 1000, agentId: 'dev1', code: 'D1', delta: 15, provisional: true, reason: 'review pass' },
70
+ ],
71
+ usage: { inputTokens: 300_000, outputTokens: 112_000, costUsd: 0.42 },
72
+ budgetTokens: 0,
73
+ alerts: [],
74
+ reworkNote: 'rework 1/3 (ui-form)',
75
+ rev: 1,
76
+ ...over,
77
+ };
78
+ }
79
+ export function manyAgents(count) {
80
+ return Array.from({ length: count }, (_, i) => rosterRow({ id: `dev${i + 1}`, wpId: `wp-${i + 1}` }));
81
+ }
82
+ export function card(over = {}) {
83
+ return {
84
+ variant: 'phase',
85
+ runId: 'gmh3k7f3a',
86
+ title: 'phase 2 integrated',
87
+ headline: 'integration passed (attempt 1) 3 contracts checked npm test: 214 ok',
88
+ tone: 'ok',
89
+ rows: [
90
+ { id: 'dev1', role: 'DEV', confirmed: 115, deltaText: '+15P->C D1 +10 D12 +5 C1' },
91
+ { id: 'dev2', role: 'DEV', confirmed: 90, deltaText: '-20 D5 +10 D12 +5 C1' },
92
+ { id: 'rev1', role: 'REV', confirmed: 110, deltaText: '+10P->C R1 +10 R10' },
93
+ { id: 'tst1', role: 'TEST', confirmed: 105, deltaText: '+10P->C T1 +5 C1' },
94
+ ],
95
+ notes: ['dev2 reworked once', 'no eliminations', 'health 96'],
96
+ ...over,
97
+ };
98
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A minimal VT screen with a SCROLLBACK, for native-scroll tests
3
+ * (tui-native-terminal-scroll §9.1).
4
+ *
5
+ * `vt-screen.ts` models only a fixed alternate screen. Native mode is about what
6
+ * the host terminal does when output runs past the bottom: the top row moves into
7
+ * scrollback. This model supports exactly the whitelist the writer may emit (SGR,
8
+ * CUU, CUD, CHA, CR, LF, ED0, EL0, DEC private modes) and RECORDS every sequence on
9
+ * the blacklist instead of acting on it, so a test can assert both the resulting
10
+ * screen and that nothing forbidden was ever written (I-S5 / I-S6).
11
+ */
12
+ export type MiniVtWrapModel = 'at-last-column' | 'virtual-column';
13
+ export interface MiniVt {
14
+ write(data: string): void;
15
+ /** Visible rows, right-trimmed. */
16
+ screen(): string[];
17
+ /** Rows that scrolled off the top, oldest first, right-trimmed. */
18
+ readonly scrollback: string[];
19
+ /** scrollback + screen, with trailing blank screen rows removed. */
20
+ history(): string[];
21
+ cursor(): {
22
+ row: number;
23
+ col: number;
24
+ };
25
+ /** Blacklisted sequences seen (`ESC[?1049h`, `ESC[3J`, a CUP, ...). */
26
+ readonly forbidden: string[];
27
+ }
28
+ export declare function createMiniVt(rows: number, cols: number, model?: MiniVtWrapModel): MiniVt;
@@ -0,0 +1,158 @@
1
+ /**
2
+ * A minimal VT screen with a SCROLLBACK, for native-scroll tests
3
+ * (tui-native-terminal-scroll §9.1).
4
+ *
5
+ * `vt-screen.ts` models only a fixed alternate screen. Native mode is about what
6
+ * the host terminal does when output runs past the bottom: the top row moves into
7
+ * scrollback. This model supports exactly the whitelist the writer may emit (SGR,
8
+ * CUU, CUD, CHA, CR, LF, ED0, EL0, DEC private modes) and RECORDS every sequence on
9
+ * the blacklist instead of acting on it, so a test can assert both the resulting
10
+ * screen and that nothing forbidden was ever written (I-S5 / I-S6).
11
+ */
12
+ import stringWidth from 'string-width';
13
+ const FORBIDDEN_PRIVATE = new Set([1049, 1047, 47, 1000, 1002, 1003, 1006, 1007]);
14
+ export function createMiniVt(rows, cols, model = 'virtual-column') {
15
+ const blank = () => new Array(cols).fill(' ');
16
+ const grid = Array.from({ length: rows }, blank);
17
+ const scrollback = [];
18
+ const forbidden = [];
19
+ let r = 0;
20
+ let c = 0;
21
+ let pending = false;
22
+ const text = (cells) => cells.join('').replace(/\s+$/, '');
23
+ const clamp = (v, max) => Math.max(0, Math.min(max, v));
24
+ const lineFeed = () => {
25
+ if (r === rows - 1) {
26
+ scrollback.push(text(grid.shift()));
27
+ grid.push(blank());
28
+ }
29
+ else
30
+ r += 1;
31
+ };
32
+ const print = (glyph) => {
33
+ const width = Math.max(1, stringWidth(glyph));
34
+ if (pending) {
35
+ c = 0;
36
+ pending = false;
37
+ lineFeed();
38
+ }
39
+ if (c + width > cols) {
40
+ c = 0;
41
+ lineFeed();
42
+ }
43
+ grid[r][c] = glyph;
44
+ for (let k = 1; k < width; k += 1)
45
+ grid[r][c + k] = '';
46
+ c += width;
47
+ if (c >= cols) {
48
+ pending = true;
49
+ c = model === 'at-last-column' ? cols - 1 : cols;
50
+ }
51
+ };
52
+ const eraseToEol = () => {
53
+ const from = model === 'virtual-column' && pending ? cols : c;
54
+ for (let k = from; k < cols; k += 1)
55
+ grid[r][k] = ' ';
56
+ };
57
+ const csi = (params, final, raw) => {
58
+ if (params.startsWith('?')) {
59
+ const modes = params.slice(1).split(';').map(Number);
60
+ if (modes.some((mode) => FORBIDDEN_PRIVATE.has(mode)))
61
+ forbidden.push(raw);
62
+ return; // 2026 / 25 / 2004: no visible effect
63
+ }
64
+ const first = params === '' ? undefined : Number(params.split(';')[0]);
65
+ switch (final) {
66
+ case 'A':
67
+ r = clamp(r - (first ?? 1), rows - 1);
68
+ break;
69
+ case 'B':
70
+ r = clamp(r + (first ?? 1), rows - 1);
71
+ break;
72
+ case 'G':
73
+ c = clamp((first ?? 1) - 1, cols - 1);
74
+ pending = false;
75
+ break;
76
+ case 'K':
77
+ if (first === 2)
78
+ grid[r].fill(' ');
79
+ else
80
+ eraseToEol();
81
+ break;
82
+ case 'J':
83
+ if (first === 2 || first === 3) {
84
+ forbidden.push(raw);
85
+ break;
86
+ }
87
+ eraseToEol();
88
+ for (let row = r + 1; row < rows; row += 1)
89
+ grid[row].fill(' ');
90
+ break;
91
+ case 'H':
92
+ case 'f':
93
+ case 'r':
94
+ case 'S':
95
+ case 'T':
96
+ forbidden.push(raw);
97
+ break;
98
+ default: break; // SGR and the rest: no cell effect
99
+ }
100
+ };
101
+ const write = (data) => {
102
+ const chars = Array.from(data);
103
+ for (let i = 0; i < chars.length; i += 1) {
104
+ const ch = chars[i];
105
+ if (ch === '\x1b') {
106
+ const next = chars[i + 1];
107
+ if (next === '[') {
108
+ let j = i + 2;
109
+ let params = '';
110
+ while (j < chars.length && /[0-?]/.test(chars[j]))
111
+ params += chars[j++];
112
+ while (j < chars.length && /[ -/]/.test(chars[j]))
113
+ j += 1;
114
+ const final = chars[j] ?? '';
115
+ csi(params, final, chars.slice(i, j + 1).join(''));
116
+ i = j;
117
+ }
118
+ else if (next === ']') {
119
+ let j = i + 2;
120
+ while (j < chars.length && chars[j] !== '\x07' && !(chars[j] === '\x1b' && chars[j + 1] === '\\'))
121
+ j += 1;
122
+ i = chars[j] === '\x07' ? j : j + 1;
123
+ }
124
+ else if (next === 'c') {
125
+ forbidden.push('\x1bc');
126
+ i += 1;
127
+ }
128
+ else
129
+ i += 1;
130
+ }
131
+ else if (ch === '\r') {
132
+ c = 0;
133
+ pending = false;
134
+ }
135
+ else if (ch === '\n') {
136
+ c = 0; // ONLCR, like a real tty
137
+ pending = false;
138
+ lineFeed();
139
+ }
140
+ else if (ch >= ' ')
141
+ print(ch);
142
+ }
143
+ };
144
+ const screen = () => grid.map(text);
145
+ return {
146
+ write,
147
+ screen,
148
+ scrollback,
149
+ history: () => {
150
+ const rowsOut = screen();
151
+ while (rowsOut.length > 0 && rowsOut[rowsOut.length - 1] === '')
152
+ rowsOut.pop();
153
+ return [...scrollback, ...rowsOut];
154
+ },
155
+ cursor: () => ({ row: r, col: c }),
156
+ forbidden,
157
+ };
158
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Render an Ink tree at a CHOSEN terminal width.
3
+ *
4
+ * `ink-testing-library`'s `render` takes the tree and nothing else, and its
5
+ * stdout stub hard-codes `get columns() { return 100 }` — so a second argument
6
+ * spelling `{ columns: 40 }` is silently ignored and any assertion built on it
7
+ * is VACUOUS while looking exactly like a real one. (`budget.test.ts` records the
8
+ * same stub's missing `rows` for the same reason.)
9
+ *
10
+ * This is that library's `render`, verbatim, with the one number made a
11
+ * parameter. Nothing else about the harness changes: `debug: true` is what makes
12
+ * every frame arrive whole rather than as cursor movements.
13
+ */
14
+ import type { ReactElement } from 'react';
15
+ /** The stripped rows of one frame rendered at `columns`, then unmounted. */
16
+ export declare function renderRowsAtWidth(tree: ReactElement, columns: number): string[];
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Render an Ink tree at a CHOSEN terminal width.
3
+ *
4
+ * `ink-testing-library`'s `render` takes the tree and nothing else, and its
5
+ * stdout stub hard-codes `get columns() { return 100 }` — so a second argument
6
+ * spelling `{ columns: 40 }` is silently ignored and any assertion built on it
7
+ * is VACUOUS while looking exactly like a real one. (`budget.test.ts` records the
8
+ * same stub's missing `rows` for the same reason.)
9
+ *
10
+ * This is that library's `render`, verbatim, with the one number made a
11
+ * parameter. Nothing else about the harness changes: `debug: true` is what makes
12
+ * every frame arrive whole rather than as cursor movements.
13
+ */
14
+ import { EventEmitter } from 'node:events';
15
+ import { render as inkRender } from 'ink';
16
+ import stripAnsi from 'strip-ansi';
17
+ class WidthStdout extends EventEmitter {
18
+ columns;
19
+ frames = [];
20
+ last;
21
+ constructor(columns) {
22
+ super();
23
+ this.columns = columns;
24
+ }
25
+ write = (frame) => {
26
+ this.frames.push(frame);
27
+ this.last = frame;
28
+ };
29
+ lastFrame = () => this.last;
30
+ }
31
+ class NullStream extends EventEmitter {
32
+ write = () => { };
33
+ isTTY = true;
34
+ setEncoding() { }
35
+ setRawMode() { }
36
+ resume() { }
37
+ pause() { }
38
+ ref() { }
39
+ unref() { }
40
+ read = () => null;
41
+ }
42
+ /** The stripped rows of one frame rendered at `columns`, then unmounted. */
43
+ export function renderRowsAtWidth(tree, columns) {
44
+ const stdout = new WidthStdout(columns);
45
+ const instance = inkRender(tree, {
46
+ stdout: stdout,
47
+ stderr: new NullStream(),
48
+ stdin: new NullStream(),
49
+ debug: true,
50
+ exitOnCtrlC: false,
51
+ patchConsole: false,
52
+ });
53
+ const frame = stripAnsi(stdout.lastFrame() ?? '');
54
+ instance.unmount();
55
+ instance.cleanup();
56
+ return frame.split('\n');
57
+ }
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ /** Real Yoga sizing and input streams, independent of the host terminal dimensions. */
3
+ export declare function createTerminalHarness(columns?: number, rows?: number, debug?: boolean): {
4
+ stdout: NodeJS.WriteStream;
5
+ stdin: NodeJS.ReadStream;
6
+ frames: string[];
7
+ layoutFrames: string[];
8
+ mount(node: React.ReactElement): void;
9
+ rerender(node: React.ReactElement): void;
10
+ resize(nextCols: number, nextRows: number): void;
11
+ lastFrame: () => string;
12
+ input(text: string): void;
13
+ dispose(): void;
14
+ };
15
+ export declare const settleTerminal: () => Promise<void>;
@@ -0,0 +1,40 @@
1
+ import { PassThrough } from 'node:stream';
2
+ import { render } from 'ink';
3
+ import stripAnsi from 'strip-ansi';
4
+ /** Real Yoga sizing and input streams, independent of the host terminal dimensions. */
5
+ export function createTerminalHarness(columns = 80, rows = 24, debug = true) {
6
+ const output = new PassThrough();
7
+ const stdout = Object.assign(output, { columns, rows, isTTY: true,
8
+ getColorDepth: () => 1 });
9
+ const stdin = Object.assign(new PassThrough(), {
10
+ isTTY: true, setRawMode: () => stdin, ref: () => stdin, unref: () => stdin,
11
+ });
12
+ const frames = [];
13
+ const layoutFrames = [];
14
+ output.on('data', (chunk) => {
15
+ const raw = chunk.toString();
16
+ frames.push(raw);
17
+ // Ink debug emits each complete layout in one write. PassThrough preserves
18
+ // these writes; cursor-only control writes are not layout boundaries.
19
+ // Never filter by height: an undersized layout is a regression to expose.
20
+ const text = stripAnsi(raw);
21
+ if (debug && text.trim().length > 0)
22
+ layoutFrames.push(text);
23
+ });
24
+ let instance;
25
+ return { stdout, stdin, frames, layoutFrames,
26
+ mount(node) {
27
+ instance = render(node, { stdout, stdin, stderr: stdout, debug,
28
+ exitOnCtrlC: false, patchConsole: false });
29
+ },
30
+ rerender(node) { instance.rerender(node); },
31
+ resize(nextCols, nextRows) {
32
+ stdout.columns = nextCols;
33
+ stdout.rows = nextRows;
34
+ stdout.emit('resize');
35
+ },
36
+ lastFrame: () => stripAnsi(frames.at(-1) ?? ''),
37
+ input(text) { stdin.write(text); },
38
+ dispose() { instance?.unmount(); instance?.cleanup(); output.destroy(); stdin.destroy(); }, };
39
+ }
40
+ export const settleTerminal = () => new Promise((resolve) => setTimeout(resolve, 70));
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A minimal VT screen model — just the subset the frame differ and Ink emit.
3
+ *
4
+ * It exists to turn one belief about real terminals into a regression guard
5
+ * (tui-scrollbar-edge-and-run-row §3.1.4). Writing the LAST column leaves the
6
+ * cursor in a "pending wrap" state, and terminals disagree on what a following
7
+ * `CSI K` (erase cursor → end of line) does there:
8
+ *
9
+ * - `virtual-column`: the cursor is logically at column N+1, so EL erases an
10
+ * empty range (xterm.js and friends);
11
+ * - `at-last-column`: the cursor still sits on column N with a wrap flag, so EL
12
+ * erases the cell that was JUST written (Windows console hosts).
13
+ *
14
+ * The differ must leave the last column intact under BOTH.
15
+ */
16
+ export type PendingWrapModel = 'at-last-column' | 'virtual-column';
17
+ export interface VtScreen {
18
+ /** The visible text of row `row` (0-based), cells joined, wide-char tails dropped. */
19
+ line(row: number): string;
20
+ /** The cell at (`row`, `col`), 0-based; `' '` when blank. */
21
+ cell(row: number, col: number): string;
22
+ /** 0-based cursor row. */
23
+ cursorRow(): number;
24
+ write(data: string): void;
25
+ touchedRows(): number[];
26
+ resetTouchedRows(): void;
27
+ }
28
+ export declare function createVtScreen(rows: number, cols: number, model: PendingWrapModel): VtScreen;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * A minimal VT screen model — just the subset the frame differ and Ink emit.
3
+ *
4
+ * It exists to turn one belief about real terminals into a regression guard
5
+ * (tui-scrollbar-edge-and-run-row §3.1.4). Writing the LAST column leaves the
6
+ * cursor in a "pending wrap" state, and terminals disagree on what a following
7
+ * `CSI K` (erase cursor → end of line) does there:
8
+ *
9
+ * - `virtual-column`: the cursor is logically at column N+1, so EL erases an
10
+ * empty range (xterm.js and friends);
11
+ * - `at-last-column`: the cursor still sits on column N with a wrap flag, so EL
12
+ * erases the cell that was JUST written (Windows console hosts).
13
+ *
14
+ * The differ must leave the last column intact under BOTH.
15
+ */
16
+ import stringWidth from 'string-width';
17
+ export function createVtScreen(rows, cols, model) {
18
+ const grid = Array.from({ length: rows }, () => new Array(cols).fill(' '));
19
+ let r = 0;
20
+ let c = 0;
21
+ let pending = false;
22
+ const touched = new Set();
23
+ const scrollUp = () => {
24
+ for (let row = 0; row < rows; row++)
25
+ touched.add(row);
26
+ grid.shift();
27
+ grid.push(new Array(cols).fill(' '));
28
+ };
29
+ const lineFeed = () => {
30
+ if (r === rows - 1)
31
+ scrollUp();
32
+ else
33
+ r += 1;
34
+ };
35
+ const clamp = (value, max) => Math.max(0, Math.min(max, value));
36
+ const print = (glyph) => {
37
+ const width = Math.max(1, stringWidth(glyph));
38
+ if (pending) {
39
+ c = 0;
40
+ pending = false;
41
+ lineFeed();
42
+ }
43
+ if (c + width > cols) {
44
+ c = 0;
45
+ lineFeed();
46
+ }
47
+ touched.add(r);
48
+ grid[r][c] = glyph;
49
+ for (let k = 1; k < width; k += 1)
50
+ grid[r][c + k] = '';
51
+ c += width;
52
+ if (c >= cols) {
53
+ pending = true;
54
+ // The two models differ ONLY here and in `eraseToEol`.
55
+ c = model === 'at-last-column' ? cols - 1 : cols;
56
+ }
57
+ };
58
+ const eraseToEol = () => {
59
+ const from = model === 'virtual-column' && pending ? cols : c;
60
+ if (from < cols)
61
+ touched.add(r);
62
+ for (let k = from; k < cols; k += 1)
63
+ grid[r][k] = ' ';
64
+ };
65
+ const csi = (params, final) => {
66
+ if (params.startsWith('?'))
67
+ return; // DEC private modes (2026, 25, ...) — no visible effect
68
+ const nums = params.split(';').map((part) => (part === '' ? NaN : Number(part)));
69
+ const first = Number.isNaN(nums[0]) ? undefined : nums[0];
70
+ switch (final) {
71
+ case 'H':
72
+ case 'f':
73
+ r = clamp((first ?? 1) - 1, rows - 1);
74
+ c = clamp((Number.isNaN(nums[1] ?? NaN) ? 1 : nums[1]) - 1, cols - 1);
75
+ pending = false;
76
+ break;
77
+ case 'G':
78
+ c = clamp((first ?? 1) - 1, cols - 1);
79
+ pending = false;
80
+ break;
81
+ case 'A':
82
+ r = clamp(r - (first ?? 1), rows - 1);
83
+ break;
84
+ case 'K':
85
+ if (first === 2) {
86
+ touched.add(r);
87
+ grid[r].fill(' ');
88
+ }
89
+ else
90
+ eraseToEol();
91
+ break;
92
+ case 'J':
93
+ eraseToEol();
94
+ for (let row = r + 1; row < rows; row += 1) {
95
+ touched.add(row);
96
+ grid[row].fill(' ');
97
+ }
98
+ break;
99
+ default:
100
+ break; // SGR ('m') and anything else: no cell effect
101
+ }
102
+ };
103
+ const write = (data) => {
104
+ const chars = Array.from(data);
105
+ for (let i = 0; i < chars.length; i += 1) {
106
+ const ch = chars[i];
107
+ if (ch === '\x1b' && chars[i + 1] === '[') {
108
+ let j = i + 2;
109
+ let params = '';
110
+ while (j < chars.length && /[0-?]/.test(chars[j]))
111
+ params += chars[j++];
112
+ const final = chars[j] ?? '';
113
+ csi(params, final);
114
+ i = j;
115
+ }
116
+ else if (ch === '\r') {
117
+ c = 0;
118
+ pending = false;
119
+ }
120
+ else if (ch === '\n') {
121
+ // TTY output translates LF to CRLF (ONLCR), including Ink's first full frame.
122
+ c = 0;
123
+ lineFeed();
124
+ pending = false;
125
+ }
126
+ else if (ch >= ' ') {
127
+ print(ch);
128
+ }
129
+ }
130
+ };
131
+ return {
132
+ line: (row) => grid[row].join(''),
133
+ cell: (row, col) => grid[row][col] ?? ' ',
134
+ cursorRow: () => r,
135
+ write,
136
+ touchedRows: () => [...touched].sort((a, b) => a - b),
137
+ resetTouchedRows: () => touched.clear(),
138
+ };
139
+ }
@@ -0,0 +1,26 @@
1
+ /** Legacy activity presentation. Explicit facts share the global status label mapping.
2
+ * StatusBar owns the application's sole live spinner via the factory below.
3
+ */
4
+ import React from 'react';
5
+ import type { Theme } from './theme.js';
6
+ import type { TermCapabilities } from './capabilities.js';
7
+ import { pickGlyphs } from './glyphs.js';
8
+ import type { RunActivity } from './run-status-row.js';
9
+ /** Shared animation factory; returns null for ASCII or reduced-motion terminals. */
10
+ export declare function liveSpinner(reducedMotion: boolean, caps: TermCapabilities): React.ReactElement | null;
11
+ /** Explicit execution facts outrank compatibility tool names and rotating phrases. */
12
+ export declare function resolveActivityLabel(activity: RunActivity, glyphs: ReturnType<typeof pickGlyphs>): string;
13
+ export interface ActivityLabelProps extends RunActivity {
14
+ /**
15
+ * False forces a static glyph. Compatibility phrases still follow reducedMotion.
16
+ */
17
+ spinnerLive?: boolean;
18
+ /** Prefix one space for compatibility line consumers. */
19
+ leadingSpace?: boolean;
20
+ theme: Theme;
21
+ caps: TermCapabilities;
22
+ }
23
+ /** `<spinner> <label>` as ONE truncating `<Text>`; the only place that composes them. */
24
+ export declare function ActivityLabel({ spinnerLive, leadingSpace, theme, caps, ...activity }: ActivityLabelProps): React.ReactElement;
25
+ export type ActivityLineProps = Omit<ActivityLabelProps, 'spinnerLive' | 'leadingSpace'>;
26
+ export declare function ActivityLine(props: ActivityLineProps): React.ReactElement;
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import Spinner from 'ink-spinner';
4
+ import { pickGlyphs } from './glyphs.js';
5
+ import { pickActivityPhrase } from './activity-phrases.js';
6
+ import { phaseLabels, shortDuration } from './layout/status-layout.js';
7
+ /** Shared animation factory; returns null for ASCII or reduced-motion terminals. */
8
+ export function liveSpinner(reducedMotion, caps) {
9
+ return caps.unicode && !reducedMotion ? _jsx(Spinner, { type: "dots" }) : null;
10
+ }
11
+ /** Explicit execution facts outrank compatibility tool names and rotating phrases. */
12
+ export function resolveActivityLabel(activity, glyphs) {
13
+ // A WAIT OUTRANKS EVERYTHING BELOW IT, and sits ABOVE `runningTool` on purpose:
14
+ // "Running job_wait" names the tool, "Waiting on t3 (up to 30s)" names the
15
+ // situation. It is placed after the phase/outcome branch because a settled run
16
+ // must never claim to be waiting for anything.
17
+ if (activity.phase === undefined && activity.outcome === undefined && activity.wait) {
18
+ const { jobId, upToSeconds, elapsedSeconds } = activity.wait;
19
+ return elapsedSeconds !== undefined
20
+ ? `Waiting on ${jobId} ${shortDuration(elapsedSeconds * 1000)}/${shortDuration(upToSeconds * 1000)}`
21
+ : `Waiting on ${jobId} (up to ${upToSeconds}s)`;
22
+ }
23
+ if (activity.phase !== undefined || activity.activeTool !== undefined || activity.outcome !== undefined) {
24
+ return phaseLabels({
25
+ phase: activity.phase ?? (activity.activeTool ? 'tool' : 'idle'),
26
+ activeTool: activity.activeTool, runOutcome: activity.outcome, compacting: activity.compacting,
27
+ })[1];
28
+ }
29
+ if (activity.compacting)
30
+ return `Compacting context${glyphs.ellipsis}`;
31
+ if (activity.runningTool)
32
+ return `Running ${activity.runningTool}`;
33
+ // PURE AND DERIVED FROM `(startedAt, now)`, so the sequence does not need to
34
+ // keep rotating underneath the tool label: when the tool settles the phrase
35
+ // resumes at the position the clock implies, with no state anywhere.
36
+ const phrase = pickActivityPhrase(activity.startedAt, activity.startedAt + activity.elapsedMs, !activity.reducedMotion);
37
+ return `${phrase}${glyphs.ellipsis}`;
38
+ }
39
+ /** `<spinner> <label>` as ONE truncating `<Text>`; the only place that composes them. */
40
+ export function ActivityLabel({ spinnerLive = true, leadingSpace = false, theme, caps, ...activity }) {
41
+ const glyphs = pickGlyphs(caps);
42
+ const label = resolveActivityLabel(activity, glyphs);
43
+ const settled = activity.phase === 'idle' || (activity.phase === undefined
44
+ && activity.outcome !== undefined && activity.outcome !== 'none' && !activity.activeTool);
45
+ const spinner = (spinnerLive && (!settled || activity.compacting) ? liveSpinner(activity.reducedMotion, caps) : null) ??
46
+ glyphs.spinnerStill;
47
+ return (_jsxs(Text, { wrap: "truncate", color: theme.thinking, children: [leadingSpace ? ' ' : '', spinner, " ", label] }));
48
+ }
49
+ export function ActivityLine(props) {
50
+ return (_jsx(Box, { flexShrink: 0, children: _jsx(ActivityLabel, { ...props, leadingSpace: true }) }));
51
+ }