@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,86 @@
1
+ /**
2
+ * The one editable multi-line field in this feature (quick-prompt-library D-11).
3
+ *
4
+ * ASCII ONLY - `src/ui/**` is inside `glyphs.test.ts::inScope`.
5
+ *
6
+ * RENDER AND CARET COME FROM THE SAME FUNCTION. `layoutComposer` wraps the buffer and
7
+ * reports the caret's row and column from ONE `buildEditorVisualMap` pass, and the
8
+ * drawing below splits that same row at that same column. Every second authority
9
+ * here - a prose wrapper, a second width table, a "count the characters instead" -
10
+ * puts the caret on a cell that does not hold the character it points at, and the
11
+ * only symptom is that the user's edits land one column off in Chinese text.
12
+ *
13
+ * WHY `layout/wrap-rows.ts::wrapToRows` IS BANNED HERE (it is used one directory
14
+ * away, for the list's read-only preview): it splits on whitespace and rejoins with
15
+ * single spaces, so it eats indentation and destroys the character-index-to-cell
16
+ * mapping. `composer-rows.ts:16-20` says so in as many words, and that is the module
17
+ * this one borrows from.
18
+ *
19
+ * NO PASTE-COLLAPSE TOKENS, deliberately. The token machinery exists so a 218-line
20
+ * paste does not have to live in a one-line input; this IS a multi-line field, and a
21
+ * token inside a saved prompt body would be data corruption the user could not undo.
22
+ */
23
+ import React from 'react';
24
+ import type { Theme } from '../theme.js';
25
+ import type { TermCapabilities } from '../capabilities.js';
26
+ export interface PromptTextAreaState {
27
+ buffer: string;
28
+ cursor: number;
29
+ /** Kept across vertical moves, cleared by any horizontal one (composer parity). */
30
+ preferredVisualColumn?: number;
31
+ }
32
+ export declare const EMPTY_TEXT_AREA: PromptTextAreaState;
33
+ export type PromptTextAreaAction = {
34
+ type: 'insert';
35
+ text: string;
36
+ } | {
37
+ type: 'newline';
38
+ } | {
39
+ type: 'backspace';
40
+ } | {
41
+ type: 'delete';
42
+ } | {
43
+ type: 'left';
44
+ } | {
45
+ type: 'right';
46
+ } | {
47
+ type: 'home';
48
+ } | {
49
+ type: 'end';
50
+ }
51
+ /** Vertical moves need the wrap width; it is part of the ACTION, not of the state. */
52
+ | {
53
+ type: 'up';
54
+ cols: number;
55
+ } | {
56
+ type: 'down';
57
+ cols: number;
58
+ } | {
59
+ type: 'replace';
60
+ buffer: string;
61
+ cursor: number;
62
+ };
63
+ /**
64
+ * Pure. No React, no Ink, no filesystem - so the twelve editing cases are a table
65
+ * test rather than a rendered frame assertion.
66
+ */
67
+ export declare function promptTextAreaReducer(state: PromptTextAreaState, action: PromptTextAreaAction): PromptTextAreaState;
68
+ export interface PromptTextAreaProps {
69
+ state: PromptTextAreaState;
70
+ /** Wrap width, in cells, already net of the field's own chrome. */
71
+ cols: number;
72
+ /** Rows the field may occupy. `1` is the single-line case for title/description. */
73
+ rows: number;
74
+ focused: boolean;
75
+ theme: Theme;
76
+ caps: TermCapabilities;
77
+ reducedMotion?: boolean;
78
+ }
79
+ /**
80
+ * One field's worth of rows.
81
+ *
82
+ * The overflow chip is a plain `+N` on the LAST row rather than a row of its own:
83
+ * an extra row would make this component draw one more line than the caller budgeted
84
+ * for, and the frame it lives in has no way to find out.
85
+ */
86
+ export declare function PromptTextArea(props: PromptTextAreaProps): React.ReactElement;
@@ -0,0 +1,141 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * The one editable multi-line field in this feature (quick-prompt-library D-11).
4
+ *
5
+ * ASCII ONLY - `src/ui/**` is inside `glyphs.test.ts::inScope`.
6
+ *
7
+ * RENDER AND CARET COME FROM THE SAME FUNCTION. `layoutComposer` wraps the buffer and
8
+ * reports the caret's row and column from ONE `buildEditorVisualMap` pass, and the
9
+ * drawing below splits that same row at that same column. Every second authority
10
+ * here - a prose wrapper, a second width table, a "count the characters instead" -
11
+ * puts the caret on a cell that does not hold the character it points at, and the
12
+ * only symptom is that the user's edits land one column off in Chinese text.
13
+ *
14
+ * WHY `layout/wrap-rows.ts::wrapToRows` IS BANNED HERE (it is used one directory
15
+ * away, for the list's read-only preview): it splits on whitespace and rejoins with
16
+ * single spaces, so it eats indentation and destroys the character-index-to-cell
17
+ * mapping. `composer-rows.ts:16-20` says so in as many words, and that is the module
18
+ * this one borrows from.
19
+ *
20
+ * NO PASTE-COLLAPSE TOKENS, deliberately. The token machinery exists so a 218-line
21
+ * paste does not have to live in a one-line input; this IS a multi-line field, and a
22
+ * token inside a saved prompt body would be data corruption the user could not undo.
23
+ */
24
+ import React from 'react';
25
+ import { Box, Text } from 'ink';
26
+ import { pickGlyphs } from '../glyphs.js';
27
+ import { layoutComposer, splitRowAtColumn } from '../composer-rows.js';
28
+ import { moveVisualCursor, snapGrapheme, stepGrapheme } from '../editor-navigation.js';
29
+ import { PromptCaret } from '../PromptCaret.js';
30
+ export const EMPTY_TEXT_AREA = { buffer: '', cursor: 0 };
31
+ function withCursor(state, buffer, cursor) {
32
+ return { buffer, cursor: snapGrapheme(buffer, cursor, true) };
33
+ }
34
+ /**
35
+ * Pure. No React, no Ink, no filesystem - so the twelve editing cases are a table
36
+ * test rather than a rendered frame assertion.
37
+ */
38
+ export function promptTextAreaReducer(state, action) {
39
+ switch (action.type) {
40
+ case 'insert': {
41
+ const cursor = snapGrapheme(state.buffer, state.cursor);
42
+ const buffer = state.buffer.slice(0, cursor) + action.text + state.buffer.slice(cursor);
43
+ return {
44
+ buffer,
45
+ cursor: snapGrapheme(buffer, cursor + action.text.length, true),
46
+ };
47
+ }
48
+ case 'newline': {
49
+ const cursor = snapGrapheme(state.buffer, state.cursor);
50
+ const buffer = `${state.buffer.slice(0, cursor)}\n${state.buffer.slice(cursor)}`;
51
+ return { buffer, cursor: cursor + 1 };
52
+ }
53
+ case 'backspace':
54
+ case 'delete': {
55
+ const cursor = snapGrapheme(state.buffer, state.cursor);
56
+ if (action.type === 'backspace') {
57
+ if (cursor <= 0)
58
+ return state;
59
+ const from = stepGrapheme(state.buffer, cursor, 'left');
60
+ return withCursor(state, state.buffer.slice(0, from) + state.buffer.slice(cursor), from);
61
+ }
62
+ if (cursor >= state.buffer.length)
63
+ return state;
64
+ const to = stepGrapheme(state.buffer, cursor, 'right');
65
+ return withCursor(state, state.buffer.slice(0, cursor) + state.buffer.slice(to), cursor);
66
+ }
67
+ case 'left':
68
+ return {
69
+ buffer: state.buffer,
70
+ cursor: stepGrapheme(state.buffer, state.cursor, 'left'),
71
+ };
72
+ case 'right':
73
+ return {
74
+ buffer: state.buffer,
75
+ cursor: stepGrapheme(state.buffer, state.cursor, 'right'),
76
+ };
77
+ case 'home':
78
+ return { buffer: state.buffer, cursor: 0 };
79
+ case 'end':
80
+ return { buffer: state.buffer, cursor: snapGrapheme(state.buffer, state.buffer.length) };
81
+ case 'up':
82
+ case 'down': {
83
+ const moved = moveVisualCursor({
84
+ buffer: state.buffer,
85
+ cursor: state.cursor,
86
+ cols: action.cols,
87
+ direction: action.type,
88
+ ...(state.preferredVisualColumn === undefined
89
+ ? {}
90
+ : { preferredVisualColumn: state.preferredVisualColumn }),
91
+ });
92
+ // A vertical move at the first or last visual row stays put rather than
93
+ // jumping to the buffer's edge: the composer behaves the same way, and a jump
94
+ // here would silently relocate the caret in a field the user is editing.
95
+ return moved === null
96
+ ? state
97
+ : {
98
+ buffer: state.buffer,
99
+ cursor: moved.cursor,
100
+ preferredVisualColumn: moved.preferredVisualColumn,
101
+ };
102
+ }
103
+ case 'replace':
104
+ return withCursor(state, action.buffer, action.cursor);
105
+ }
106
+ }
107
+ function renderSegments(segments, keyPrefix) {
108
+ return segments.map((segment, at) => (_jsx(Text, { children: segment.text }, `${keyPrefix}${at}`)));
109
+ }
110
+ /**
111
+ * One field's worth of rows.
112
+ *
113
+ * The overflow chip is a plain `+N` on the LAST row rather than a row of its own:
114
+ * an extra row would make this component draw one more line than the caller budgeted
115
+ * for, and the frame it lives in has no way to find out.
116
+ */
117
+ export function PromptTextArea(props) {
118
+ const { state, cols, rows, focused } = props;
119
+ const glyphs = pickGlyphs(props.caps);
120
+ const layout = layoutComposer({
121
+ buffer: state.buffer,
122
+ cursor: state.cursor,
123
+ cols: Math.max(4, cols),
124
+ maxRows: Math.max(1, rows),
125
+ active: focused,
126
+ });
127
+ const hidden = layout.hiddenAbove + layout.hiddenBelow;
128
+ const resetKey = React.useMemo(() => ({}), [state.buffer, state.cursor, focused, props.cols, rows]);
129
+ if (state.buffer.length === 0) {
130
+ return (_jsxs(Text, { wrap: "truncate", color: props.theme.muted, children: [_jsx(PromptCaret, { text: " ", active: focused, reducedMotion: props.reducedMotion ?? false, colorLevel: props.caps.colorLevel, color: props.theme.muted, resetKey: resetKey }), glyphs.ellipsis] }));
131
+ }
132
+ return (_jsx(Box, { flexDirection: "column", children: layout.rows.map((row, at) => {
133
+ if (at !== layout.cursorRow) {
134
+ return _jsx(Text, { wrap: "truncate", children: renderSegments(row.segments, `r${at}.`) }, at);
135
+ }
136
+ const split = splitRowAtColumn(row, layout.cursorCol);
137
+ return (_jsxs(Text, { wrap: "truncate", children: [renderSegments(split.before, `b${at}.`), _jsx(PromptCaret, { text: split.at ? split.at.text : ' ', active: focused, reducedMotion: props.reducedMotion ?? false, colorLevel: props.caps.colorLevel, resetKey: resetKey }), renderSegments(split.after, `a${at}.`), at === layout.rows.length - 1 && hidden > 0
138
+ ? _jsx(Text, { color: props.theme.muted, children: ` +${hidden}` })
139
+ : null] }, at));
140
+ }) }));
141
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * QuestionOverlay — the keyboard-driven multiple-choice wizard `ask_user`
3
+ * renders (plan-mode §6.5).
4
+ *
5
+ * `OverlayFrame` MODE B (self-managed): the content is a small state machine,
6
+ * not a list of rows, and slicing it by element would be meaningless.
7
+ *
8
+ * THE SINGLE HIGHEST-VALUE DECISION HERE is that the recommended option is the
9
+ * initial highlight for every question, so `Enter Enter Enter` is a correct,
10
+ * deliberate "use your judgement" path rather than an accident.
11
+ *
12
+ * `Esc` IS NOT HANDLED HERE. `App` owns it, and the bridge's `settle()` is the
13
+ * only place a human request is ever answered. `ConfirmDialog` does the
14
+ * opposite — both it and `App` call `resolve` — which is harmless there only by
15
+ * accident of promise semantics, and is not a pattern to copy (R-P12).
16
+ */
17
+ import React from 'react';
18
+ import type { Theme } from '../theme.js';
19
+ import type { TermCapabilities } from '../capabilities.js';
20
+ import type { Answer, NormalizedQuestion } from '../../model/tools/human-input.js';
21
+ interface QuestionOverlayProps {
22
+ isActive?: boolean;
23
+ questions: NormalizedQuestion[];
24
+ maxRows: number;
25
+ cols: number;
26
+ theme: Theme;
27
+ caps: TermCapabilities;
28
+ onSubmit: (answers: Answer[]) => void;
29
+ /**
30
+ * PLAN+GOVERN interview progress (governance-mode 9 / 10.6). Present only in that
31
+ * posture; absent leaves the title byte-identical to the pre-governance overlay.
32
+ */
33
+ interview?: {
34
+ round: number;
35
+ required: number;
36
+ };
37
+ }
38
+ export declare function QuestionOverlay({ isActive, questions, maxRows, cols, theme, caps, onSubmit, interview, }: QuestionOverlayProps): React.ReactElement;
39
+ export {};
@@ -0,0 +1,258 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * QuestionOverlay — the keyboard-driven multiple-choice wizard `ask_user`
4
+ * renders (plan-mode §6.5).
5
+ *
6
+ * `OverlayFrame` MODE B (self-managed): the content is a small state machine,
7
+ * not a list of rows, and slicing it by element would be meaningless.
8
+ *
9
+ * THE SINGLE HIGHEST-VALUE DECISION HERE is that the recommended option is the
10
+ * initial highlight for every question, so `Enter Enter Enter` is a correct,
11
+ * deliberate "use your judgement" path rather than an accident.
12
+ *
13
+ * `Esc` IS NOT HANDLED HERE. `App` owns it, and the bridge's `settle()` is the
14
+ * only place a human request is ever answered. `ConfirmDialog` does the
15
+ * opposite — both it and `App` call `resolve` — which is harmless there only by
16
+ * accident of promise semantics, and is not a pattern to copy (R-P12).
17
+ */
18
+ import { useState, useLayoutEffect } from 'react';
19
+ import { Text, useInput } from 'ink';
20
+ import { pickGlyphs } from '../glyphs.js';
21
+ import { wrapToRows } from '../layout/wrap-rows.js';
22
+ import { OverlayFrame, overlayBodyRows } from '../layout/OverlayFrame.js';
23
+ import { stripPasteFrames } from '../paste-frames.js';
24
+ import { stripEnterFrames } from '../enter-frames.js';
25
+ import { interviewChipText } from '../governance-status.js';
26
+ /** Which option index each question starts on: the recommended one. */
27
+ function initialCursors(questions) {
28
+ return questions.map((q) => Math.max(0, q.options.findIndex((o) => o.recommended)));
29
+ }
30
+ function initialSelections(questions) {
31
+ return questions.map((q) => {
32
+ const recommended = q.options.findIndex((o) => o.recommended);
33
+ return new Set(recommended >= 0 ? [recommended] : [0]);
34
+ });
35
+ }
36
+ export function QuestionOverlay({ isActive = true, questions, maxRows, cols, theme, caps, onSubmit, interview, }) {
37
+ const glyphs = pickGlyphs(caps);
38
+ const [step, setStep] = useState(0);
39
+ const [phase, setPhase] = useState('choosing');
40
+ const [cursors, setCursors] = useState(() => initialCursors(questions));
41
+ const [selections, setSelections] = useState(() => initialSelections(questions));
42
+ /**
43
+ * THE PER-QUESTION EXPLICIT-MARK BIT (V-1 / D-8).
44
+ *
45
+ * `initialSelections` PRE-SELECTS the recommended option on EVERY question
46
+ * (or the first option when there is none), so "the selection set is empty"
47
+ * is unreachable and can never be the test for "did the user choose?". The
48
+ * only reliable discriminator is the fact itself: the user pressed SPACE on
49
+ * this question. Without it, a user who only MOVES the cursor and presses
50
+ * Enter would submit the RECOMMENDED option instead of the highlighted one -
51
+ * a silent regression of the wizard's most common path. The bit survives
52
+ * Left/Right navigation exactly like `selections` and `cursors` do, and a
53
+ * single-choice mark is idempotent (no un-mark; Enter always has at least
54
+ * the marked item to submit).
55
+ */
56
+ const [markedSteps, setMarkedSteps] = useState(() => questions.map(() => false));
57
+ const [customs, setCustoms] = useState(() => questions.map(() => ''));
58
+ const [draft, setDraft] = useState('');
59
+ const [offset, setOffset] = useState(0);
60
+ const question = questions[Math.min(step, questions.length - 1)];
61
+ const cursor = cursors[step] ?? 0;
62
+ const setCursorAt = (index, value) => setCursors((prev) => prev.map((c, i) => (i === index ? value : c)));
63
+ const setCustomAt = (index, value) => setCustoms((prev) => prev.map((c, i) => (i === index ? value : c)));
64
+ const toggleAt = (index, option) => setSelections((prev) => prev.map((set, i) => {
65
+ if (i !== index)
66
+ return set;
67
+ const next = new Set(set);
68
+ if (next.has(option))
69
+ next.delete(option);
70
+ else
71
+ next.add(option);
72
+ return next;
73
+ }));
74
+ const chooseAt = (index, option) => setSelections((prev) => prev.map((set, i) => (i === index ? new Set([option]) : set)));
75
+ const markAt = (index) => setMarkedSteps((prev) => prev.map((marked, i) => (i === index ? true : marked)));
76
+ const buildAnswers = () => questions.map((q, i) => {
77
+ const chosen = [...(selections[i] ?? new Set())].sort((a, b) => a - b);
78
+ const labels = chosen.map((index) => q.options[index]?.label ?? '').filter((l) => l.length > 0);
79
+ const pickedOther = chosen.some((index) => q.options[index]?.isOther);
80
+ return {
81
+ id: q.id,
82
+ question: q.question,
83
+ selected: labels,
84
+ custom: pickedOther && (customs[i] ?? '').length > 0 ? customs[i] : null,
85
+ };
86
+ });
87
+ const advance = () => {
88
+ if (step + 1 >= questions.length)
89
+ setPhase('review');
90
+ else {
91
+ setStep(step + 1);
92
+ setPhase('choosing');
93
+ }
94
+ };
95
+ const goBack = () => {
96
+ if (step === 0)
97
+ return; // No-op on the first question, by design.
98
+ setStep(step - 1);
99
+ setPhase('choosing');
100
+ };
101
+ useInput((input, key) => {
102
+ if (!isActive)
103
+ return;
104
+ if (key.pageUp) {
105
+ setOffset(n => Math.max(0, n - 1));
106
+ return;
107
+ }
108
+ if (key.pageDown) {
109
+ setOffset(n => n + 1);
110
+ return;
111
+ }
112
+ // App owns Esc for both new overlays (R-P12). Swallow it here so the
113
+ // free-text editor below cannot eat the raw escape byte as a character.
114
+ if (key.escape)
115
+ return;
116
+ if (phase === 'review') {
117
+ if (key.return) {
118
+ onSubmit(buildAnswers());
119
+ return;
120
+ }
121
+ if (key.leftArrow) {
122
+ setStep(questions.length - 1);
123
+ setPhase('choosing');
124
+ }
125
+ return;
126
+ }
127
+ if (phase === 'typingOther') {
128
+ if (key.return) {
129
+ // An empty commit falls back to the recommended option rather than
130
+ // recording a blank answer: the user pressed Enter, which everywhere
131
+ // else in this wizard means "accept the sensible default".
132
+ if (draft.trim().length === 0) {
133
+ const recommended = Math.max(0, question.options.findIndex((o) => o.recommended));
134
+ chooseAt(step, recommended);
135
+ setCursorAt(step, recommended);
136
+ setCustomAt(step, '');
137
+ }
138
+ else {
139
+ setCustomAt(step, draft.trim());
140
+ }
141
+ setDraft('');
142
+ setPhase('choosing');
143
+ advance();
144
+ return;
145
+ }
146
+ if (key.leftArrow) {
147
+ setDraft('');
148
+ setPhase('choosing');
149
+ return;
150
+ }
151
+ if (key.backspace || key.delete) {
152
+ setDraft(draft.slice(0, -1));
153
+ return;
154
+ }
155
+ // `stripPasteFrames`, NOT `input` (I-12 / P0-2) -- the same broadcast
156
+ // hazard `SettingsScreen` documents at length: a framed paste appended
157
+ // verbatim stores NULs that render as nothing.
158
+ // `stripEnterFrames` rides inside it for the newline frame a
159
+ // Shift+Enter broadcasts (tui-shift-enter-copy-queue 3.5): same hazard,
160
+ // same fix, and this order is the one that leaves no NUL in the draft.
161
+ if (input && !key.ctrl && !key.meta && !key.tab) {
162
+ setDraft(draft + stripPasteFrames(stripEnterFrames(input)));
163
+ }
164
+ return;
165
+ }
166
+ // phase === 'choosing'
167
+ if (key.upArrow) {
168
+ setCursorAt(step, (cursor - 1 + question.options.length) % question.options.length);
169
+ return;
170
+ }
171
+ if (key.downArrow) {
172
+ setCursorAt(step, (cursor + 1) % question.options.length);
173
+ return;
174
+ }
175
+ if (key.leftArrow) {
176
+ goBack();
177
+ return;
178
+ }
179
+ // SPACE, BY QUESTION SHAPE (D-8). The strict `input === ' '` keeps a
180
+ // multi-character paste frame from ever matching (R-8); the Other row is
181
+ // a no-op in both shapes because it needs TEXT, and Enter is its key.
182
+ if (input === ' ' && !question.options[cursor]?.isOther) {
183
+ if (question.allowMultiple) {
184
+ toggleAt(step, cursor);
185
+ return;
186
+ }
187
+ // SINGLE CHOICE: mark the highlighted item and STAY - the terminal
188
+ // convention of "space selects, enter confirms". The mark is recorded
189
+ // both in the selection set (so `[x]` renders) and in the explicit
190
+ // mark bit (so a later Enter submits THIS item even after the cursor
191
+ // has moved on).
192
+ chooseAt(step, cursor);
193
+ markAt(step);
194
+ return;
195
+ }
196
+ if (key.return) {
197
+ if (question.options[cursor]?.isOther) {
198
+ chooseAt(step, cursor);
199
+ setDraft(customs[step] ?? '');
200
+ setPhase('typingOther');
201
+ return;
202
+ }
203
+ // A single-choice Enter submits the CURSOR item unless the user has
204
+ // explicitly space-marked this question, in which case the marked item
205
+ // wins even if the cursor has since moved (V-1's regression guard:
206
+ // cursor + Enter alone keeps today's behavior, recommended preselect
207
+ // and all).
208
+ if (!question.allowMultiple) {
209
+ if (!markedSteps[step])
210
+ chooseAt(step, cursor);
211
+ }
212
+ else if (!(selections[step] ?? new Set()).has(cursor))
213
+ toggleAt(step, cursor);
214
+ advance();
215
+ }
216
+ });
217
+ const title = phase === 'review' ? 'Review your answers' : 'Clarify the request';
218
+ const position = phase === 'review' ? '' : ` ${step + 1}/${questions.length}`;
219
+ const interviewChip = interview ? ` ${interviewChipText(interview.round, interview.required)}` : '';
220
+ const hint = phase === 'typingOther'
221
+ ? `type your answer ${glyphs.midDot} ${glyphs.enterKey} commit ${glyphs.midDot} ${glyphs.arrowLeft} back ${glyphs.midDot} esc cancel`
222
+ : phase === 'review'
223
+ ? `${glyphs.enterKey} submit ${glyphs.midDot} ${glyphs.arrowLeft} back ${glyphs.midDot} esc cancel`
224
+ : question.options[cursor]?.isOther
225
+ ? `${glyphs.arrowUp}${glyphs.arrowDown} choose ${glyphs.midDot} ${glyphs.enterKey} to type ${glyphs.midDot} ${glyphs.arrowLeft} back ${glyphs.midDot} esc cancel`
226
+ : `${glyphs.arrowUp}${glyphs.arrowDown} choose ${glyphs.midDot} space select ${glyphs.midDot} ${glyphs.enterKey} next ${glyphs.midDot} ${glyphs.arrowLeft} back ${glyphs.midDot} esc cancel`;
227
+ const rowTexts = [];
228
+ const optionStarts = [];
229
+ const push = (text) => { rowTexts.push(...wrapToRows(text, Math.max(1, cols - 4))); };
230
+ if (phase === 'review') {
231
+ buildAnswers().forEach((answer, index) => push(`${questions[index].header}: ${answer.custom ?? answer.selected.join(', ')}`));
232
+ }
233
+ else {
234
+ push(question.header);
235
+ push(question.question);
236
+ question.options.forEach((option, index) => {
237
+ optionStarts.push(rowTexts.length);
238
+ const mark = (selections[step] ?? new Set()).has(index) ? '[x]' : '[ ]';
239
+ push(`${index === cursor ? glyphs.caret : ' '} ${mark} ${option.label}${option.recommended ? ' RECOMMENDED' : ''} ${option.description}`);
240
+ });
241
+ if (phase === 'typingOther')
242
+ push(`${glyphs.caret} ${draft || 'type your own answer'} `);
243
+ }
244
+ const focus = phase === 'review' ? 0 : phase === 'typingOther'
245
+ ? Math.max(0, rowTexts.length - 1) : optionStarts[cursor] ?? 0;
246
+ useLayoutEffect(() => {
247
+ const height = overlayBodyRows(maxRows, cols);
248
+ setOffset(previous => focus < previous ? focus : focus >= previous + height
249
+ ? focus - height + 1 : previous);
250
+ }, [focus, maxRows, cols, step, phase]);
251
+ // `space select` shows for BOTH shapes (AC-10) - 42 characters on the
252
+ // single-choice shape without `cancel`, a deliberate 5-column growth inside
253
+ // the `cols <= 48` budget this hint exists for (V-12).
254
+ const shortHint = phase === 'typingOther' ? 'Enter commit | Left back | Esc cancel'
255
+ : phase === 'review' ? 'Enter submit | Left back | Esc cancel'
256
+ : '^v choose Space select Enter next Esc';
257
+ return _jsx(OverlayFrame, { title: `${title}${position}${interviewChip}`, hint: cols <= 48 ? shortHint : hint, maxRows: maxRows, cols: cols, theme: theme, caps: caps, rows: rowTexts.map((line, index) => _jsx(Text, { wrap: "truncate", children: line || ' ' }, index)), scrollOffset: offset, onScrollClamp: setOffset });
258
+ }
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import type { PendingSteering } from '../../model/agent/queued-messages.js';
3
+ import type { Theme } from '../theme.js';
4
+ import type { TermCapabilities } from '../capabilities.js';
5
+ export interface QueueTextRow {
6
+ queueId: string;
7
+ offset: number;
8
+ text: string;
9
+ }
10
+ /** Preserve visible whitespace and display terminal controls as harmless escapes. */
11
+ export declare function projectQueueRows(pending: readonly PendingSteering[], columns: number): QueueTextRow[];
12
+ /** Anchor by stable message ID and source offset, including long soft-wrapped lines. */
13
+ export declare function restoreQueueAnchor(before: readonly QueueTextRow[], after: readonly QueueTextRow[], scroll: number): number;
14
+ export declare function QueueOverlay(props: {
15
+ pending: readonly PendingSteering[];
16
+ cols: number;
17
+ maxRows: number;
18
+ scrollOffset: number;
19
+ onScrollClamp: (offset: number) => void;
20
+ theme: Theme;
21
+ caps: TermCapabilities;
22
+ }): React.ReactElement;
@@ -0,0 +1,79 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef } from 'react';
3
+ import { Text } from 'ink';
4
+ import stringWidth from 'string-width';
5
+ import { OverlayFrame } from '../layout/OverlayFrame.js';
6
+ import { graphemes } from '../editor-navigation.js';
7
+ /** Preserve visible whitespace and display terminal controls as harmless escapes. */
8
+ export function projectQueueRows(pending, columns) {
9
+ const width = Math.max(1, columns);
10
+ const rows = [];
11
+ for (const [index, item] of pending.entries()) {
12
+ rows.push({ queueId: item.queueId, offset: -1, text: `Queue ${index + 1}` });
13
+ let text = '';
14
+ let cells = 0;
15
+ let offset = 0;
16
+ const flush = () => {
17
+ rows.push({ queueId: item.queueId, offset, text });
18
+ text = '';
19
+ cells = 0;
20
+ };
21
+ for (const part of graphemes(item.text)) {
22
+ if (part.text === '\n' || part.text === '\r\n') {
23
+ flush();
24
+ offset = part.end;
25
+ continue;
26
+ }
27
+ const safe = part.text === '\t' ? ' '.repeat(4 - cells % 4)
28
+ : part.text.replace(/[\x00-\x1f\x7f-\x9f]/g, (char) => `\\x${char.charCodeAt(0).toString(16).padStart(2, '0')}`);
29
+ const units = safe === part.text ? [safe] : Array.from(safe);
30
+ for (const unit of units) {
31
+ const size = stringWidth(unit);
32
+ if (cells + size > width && text) {
33
+ flush();
34
+ offset = part.index;
35
+ }
36
+ text += unit;
37
+ cells += size;
38
+ }
39
+ }
40
+ flush();
41
+ }
42
+ return rows;
43
+ }
44
+ /** Anchor by stable message ID and source offset, including long soft-wrapped lines. */
45
+ export function restoreQueueAnchor(before, after, scroll) {
46
+ const anchor = before[Math.min(scroll, before.length - 1)];
47
+ if (!anchor || !after.length)
48
+ return 0;
49
+ let target = -1;
50
+ for (let i = 0; i < after.length; i++) {
51
+ if (after[i].queueId === anchor.queueId && after[i].offset <= anchor.offset)
52
+ target = i;
53
+ }
54
+ if (target >= 0)
55
+ return target;
56
+ const next = before.slice(scroll).find((row) => after.some((item) => item.queueId === row.queueId));
57
+ if (next)
58
+ return after.findIndex((row) => row.queueId === next.queueId);
59
+ const previous = [...before.slice(0, scroll)].reverse()
60
+ .find((row) => after.some((item) => item.queueId === row.queueId));
61
+ return previous ? after.findIndex((row) => row.queueId === previous.queueId) : 0;
62
+ }
63
+ export function QueueOverlay(props) {
64
+ const { pending, cols, scrollOffset, onScrollClamp, theme } = props;
65
+ const projected = useMemo(() => projectQueueRows(pending, cols - (cols >= 48 ? 4 : 2)), [pending, cols]);
66
+ const previous = useRef({ rows: projected, scroll: scrollOffset });
67
+ const anchored = previous.current.rows === projected ? scrollOffset
68
+ : restoreQueueAnchor(previous.current.rows, projected, previous.current.scroll);
69
+ const bodyRows = Math.max(1, Math.floor(props.maxRows) - (cols >= 48 ? 5 : 3));
70
+ const offset = Math.max(0, Math.min(anchored, projected.length - bodyRows));
71
+ useEffect(() => {
72
+ previous.current = { rows: projected, scroll: offset };
73
+ if (offset !== scrollOffset)
74
+ onScrollClamp(offset);
75
+ }, [projected, offset, scrollOffset, onScrollClamp]);
76
+ const rows = useMemo(() => projected.length ? projected.map((row, index) => _jsx(Text, { wrap: "truncate", color: theme.primary, children: row.text || ' ' }, `${row.queueId}:${index}`))
77
+ : [_jsx(Text, { children: "Queue is empty" }, "empty")], [projected, theme]);
78
+ return _jsx(OverlayFrame, { ...props, title: `Queue: ${pending.length} pending`, hint: "PgUp/PgDn | Up/Down | Esc", rows: rows, scrollOffset: offset });
79
+ }