@dsh-cc/tui 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +144 -0
  3. package/lib/bash-history.d.ts +31 -0
  4. package/lib/bash-history.d.ts.map +1 -0
  5. package/lib/bash-history.js +94 -0
  6. package/lib/bash-history.js.map +1 -0
  7. package/lib/compact-fold.d.ts +35 -0
  8. package/lib/compact-fold.d.ts.map +1 -0
  9. package/lib/compact-fold.js +60 -0
  10. package/lib/compact-fold.js.map +1 -0
  11. package/lib/components/arg-completers.d.ts +22 -0
  12. package/lib/components/arg-completers.d.ts.map +1 -0
  13. package/lib/components/arg-completers.js +75 -0
  14. package/lib/components/arg-completers.js.map +1 -0
  15. package/lib/components/code-theme.d.ts +25 -0
  16. package/lib/components/code-theme.d.ts.map +1 -0
  17. package/lib/components/code-theme.js +137 -0
  18. package/lib/components/code-theme.js.map +1 -0
  19. package/lib/components/completion.d.ts +50 -0
  20. package/lib/components/completion.d.ts.map +1 -0
  21. package/lib/components/completion.js +279 -0
  22. package/lib/components/completion.js.map +1 -0
  23. package/lib/components/diff-card.d.ts +29 -0
  24. package/lib/components/diff-card.d.ts.map +1 -0
  25. package/lib/components/diff-card.js +175 -0
  26. package/lib/components/diff-card.js.map +1 -0
  27. package/lib/components/diff-hunks.d.ts +44 -0
  28. package/lib/components/diff-hunks.d.ts.map +1 -0
  29. package/lib/components/diff-hunks.js +188 -0
  30. package/lib/components/diff-hunks.js.map +1 -0
  31. package/lib/components/editor-history.d.ts +23 -0
  32. package/lib/components/editor-history.d.ts.map +1 -0
  33. package/lib/components/editor-history.js +29 -0
  34. package/lib/components/editor-history.js.map +1 -0
  35. package/lib/components/markdown-theme.d.ts +11 -0
  36. package/lib/components/markdown-theme.d.ts.map +1 -0
  37. package/lib/components/markdown-theme.js +29 -0
  38. package/lib/components/markdown-theme.js.map +1 -0
  39. package/lib/components/masked-input.d.ts +24 -0
  40. package/lib/components/masked-input.d.ts.map +1 -0
  41. package/lib/components/masked-input.js +168 -0
  42. package/lib/components/masked-input.js.map +1 -0
  43. package/lib/components/overlay-host.d.ts +31 -0
  44. package/lib/components/overlay-host.d.ts.map +1 -0
  45. package/lib/components/overlay-host.js +128 -0
  46. package/lib/components/overlay-host.js.map +1 -0
  47. package/lib/components/overlays.d.ts +94 -0
  48. package/lib/components/overlays.d.ts.map +1 -0
  49. package/lib/components/overlays.js +450 -0
  50. package/lib/components/overlays.js.map +1 -0
  51. package/lib/components/provider-box.d.ts +23 -0
  52. package/lib/components/provider-box.d.ts.map +1 -0
  53. package/lib/components/provider-box.js +164 -0
  54. package/lib/components/provider-box.js.map +1 -0
  55. package/lib/components/read-group.d.ts +51 -0
  56. package/lib/components/read-group.d.ts.map +1 -0
  57. package/lib/components/read-group.js +105 -0
  58. package/lib/components/read-group.js.map +1 -0
  59. package/lib/components/root-bash.d.ts +36 -0
  60. package/lib/components/root-bash.d.ts.map +1 -0
  61. package/lib/components/root-bash.js +112 -0
  62. package/lib/components/root-bash.js.map +1 -0
  63. package/lib/components/root-types.d.ts +42 -0
  64. package/lib/components/root-types.d.ts.map +1 -0
  65. package/lib/components/root-types.js +8 -0
  66. package/lib/components/root-types.js.map +1 -0
  67. package/lib/components/root-utils.d.ts +22 -0
  68. package/lib/components/root-utils.d.ts.map +1 -0
  69. package/lib/components/root-utils.js +45 -0
  70. package/lib/components/root-utils.js.map +1 -0
  71. package/lib/components/root.d.ts +25 -0
  72. package/lib/components/root.d.ts.map +1 -0
  73. package/lib/components/root.js +357 -0
  74. package/lib/components/root.js.map +1 -0
  75. package/lib/components/theme.d.ts +61 -0
  76. package/lib/components/theme.d.ts.map +1 -0
  77. package/lib/components/theme.js +99 -0
  78. package/lib/components/theme.js.map +1 -0
  79. package/lib/components/transcript.d.ts +43 -0
  80. package/lib/components/transcript.d.ts.map +1 -0
  81. package/lib/components/transcript.js +203 -0
  82. package/lib/components/transcript.js.map +1 -0
  83. package/lib/components/working-line.d.ts +35 -0
  84. package/lib/components/working-line.d.ts.map +1 -0
  85. package/lib/components/working-line.js +66 -0
  86. package/lib/components/working-line.js.map +1 -0
  87. package/lib/effort-catalog.d.ts +27 -0
  88. package/lib/effort-catalog.d.ts.map +1 -0
  89. package/lib/effort-catalog.js +36 -0
  90. package/lib/effort-catalog.js.map +1 -0
  91. package/lib/export-markdown.d.ts +18 -0
  92. package/lib/export-markdown.d.ts.map +1 -0
  93. package/lib/export-markdown.js +124 -0
  94. package/lib/export-markdown.js.map +1 -0
  95. package/lib/harness/approval-preview.d.ts +33 -0
  96. package/lib/harness/approval-preview.d.ts.map +1 -0
  97. package/lib/harness/approval-preview.js +179 -0
  98. package/lib/harness/approval-preview.js.map +1 -0
  99. package/lib/harness/boot-banner.d.ts +14 -0
  100. package/lib/harness/boot-banner.d.ts.map +1 -0
  101. package/lib/harness/boot-banner.js +89 -0
  102. package/lib/harness/boot-banner.js.map +1 -0
  103. package/lib/harness/driver-agent.d.ts +78 -0
  104. package/lib/harness/driver-agent.d.ts.map +1 -0
  105. package/lib/harness/driver-agent.js +314 -0
  106. package/lib/harness/driver-agent.js.map +1 -0
  107. package/lib/harness/driver-agents.d.ts +20 -0
  108. package/lib/harness/driver-agents.d.ts.map +1 -0
  109. package/lib/harness/driver-agents.js +123 -0
  110. package/lib/harness/driver-agents.js.map +1 -0
  111. package/lib/harness/driver-approvals.d.ts +38 -0
  112. package/lib/harness/driver-approvals.d.ts.map +1 -0
  113. package/lib/harness/driver-approvals.js +277 -0
  114. package/lib/harness/driver-approvals.js.map +1 -0
  115. package/lib/harness/driver-bash.d.ts +15 -0
  116. package/lib/harness/driver-bash.d.ts.map +1 -0
  117. package/lib/harness/driver-bash.js +73 -0
  118. package/lib/harness/driver-bash.js.map +1 -0
  119. package/lib/harness/driver-catalog.d.ts +84 -0
  120. package/lib/harness/driver-catalog.d.ts.map +1 -0
  121. package/lib/harness/driver-catalog.js +256 -0
  122. package/lib/harness/driver-catalog.js.map +1 -0
  123. package/lib/harness/driver-ctx.d.ts +462 -0
  124. package/lib/harness/driver-ctx.d.ts.map +1 -0
  125. package/lib/harness/driver-ctx.js +11 -0
  126. package/lib/harness/driver-ctx.js.map +1 -0
  127. package/lib/harness/driver-hud.d.ts +31 -0
  128. package/lib/harness/driver-hud.d.ts.map +1 -0
  129. package/lib/harness/driver-hud.js +204 -0
  130. package/lib/harness/driver-hud.js.map +1 -0
  131. package/lib/harness/driver-live.d.ts +36 -0
  132. package/lib/harness/driver-live.d.ts.map +1 -0
  133. package/lib/harness/driver-live.js +44 -0
  134. package/lib/harness/driver-live.js.map +1 -0
  135. package/lib/harness/driver-modal.d.ts +52 -0
  136. package/lib/harness/driver-modal.d.ts.map +1 -0
  137. package/lib/harness/driver-modal.js +78 -0
  138. package/lib/harness/driver-modal.js.map +1 -0
  139. package/lib/harness/driver-mode.d.ts +35 -0
  140. package/lib/harness/driver-mode.d.ts.map +1 -0
  141. package/lib/harness/driver-mode.js +84 -0
  142. package/lib/harness/driver-mode.js.map +1 -0
  143. package/lib/harness/driver-pickers.d.ts +48 -0
  144. package/lib/harness/driver-pickers.d.ts.map +1 -0
  145. package/lib/harness/driver-pickers.js +249 -0
  146. package/lib/harness/driver-pickers.js.map +1 -0
  147. package/lib/harness/driver-promote.d.ts +29 -0
  148. package/lib/harness/driver-promote.d.ts.map +1 -0
  149. package/lib/harness/driver-promote.js +36 -0
  150. package/lib/harness/driver-promote.js.map +1 -0
  151. package/lib/harness/driver-queue.d.ts +19 -0
  152. package/lib/harness/driver-queue.d.ts.map +1 -0
  153. package/lib/harness/driver-queue.js +281 -0
  154. package/lib/harness/driver-queue.js.map +1 -0
  155. package/lib/harness/driver-run-local.d.ts +32 -0
  156. package/lib/harness/driver-run-local.d.ts.map +1 -0
  157. package/lib/harness/driver-run-local.js +366 -0
  158. package/lib/harness/driver-run-local.js.map +1 -0
  159. package/lib/harness/driver-sessions.d.ts +28 -0
  160. package/lib/harness/driver-sessions.d.ts.map +1 -0
  161. package/lib/harness/driver-sessions.js +386 -0
  162. package/lib/harness/driver-sessions.js.map +1 -0
  163. package/lib/harness/driver.d.ts +22 -0
  164. package/lib/harness/driver.d.ts.map +1 -0
  165. package/lib/harness/driver.js +459 -0
  166. package/lib/harness/driver.js.map +1 -0
  167. package/lib/harness/preset.d.ts +32 -0
  168. package/lib/harness/preset.d.ts.map +1 -0
  169. package/lib/harness/preset.js +34 -0
  170. package/lib/harness/preset.js.map +1 -0
  171. package/lib/harness/session-list.d.ts +65 -0
  172. package/lib/harness/session-list.d.ts.map +1 -0
  173. package/lib/harness/session-list.js +91 -0
  174. package/lib/harness/session-list.js.map +1 -0
  175. package/lib/harness/shell-output.d.ts +44 -0
  176. package/lib/harness/shell-output.d.ts.map +1 -0
  177. package/lib/harness/shell-output.js +90 -0
  178. package/lib/harness/shell-output.js.map +1 -0
  179. package/lib/harness/statusline-cc-transcript.d.ts +51 -0
  180. package/lib/harness/statusline-cc-transcript.d.ts.map +1 -0
  181. package/lib/harness/statusline-cc-transcript.js +191 -0
  182. package/lib/harness/statusline-cc-transcript.js.map +1 -0
  183. package/lib/harness/statusline-command.d.ts +54 -0
  184. package/lib/harness/statusline-command.d.ts.map +1 -0
  185. package/lib/harness/statusline-command.js +161 -0
  186. package/lib/harness/statusline-command.js.map +1 -0
  187. package/lib/harness/statusline-payload.d.ts +79 -0
  188. package/lib/harness/statusline-payload.d.ts.map +1 -0
  189. package/lib/harness/statusline-payload.js +93 -0
  190. package/lib/harness/statusline-payload.js.map +1 -0
  191. package/lib/harness/statusline-settings.d.ts +47 -0
  192. package/lib/harness/statusline-settings.d.ts.map +1 -0
  193. package/lib/harness/statusline-settings.js +57 -0
  194. package/lib/harness/statusline-settings.js.map +1 -0
  195. package/lib/harness/statusline-wiring.d.ts +45 -0
  196. package/lib/harness/statusline-wiring.d.ts.map +1 -0
  197. package/lib/harness/statusline-wiring.js +247 -0
  198. package/lib/harness/statusline-wiring.js.map +1 -0
  199. package/lib/harness/usage-view.d.ts +84 -0
  200. package/lib/harness/usage-view.d.ts.map +1 -0
  201. package/lib/harness/usage-view.js +199 -0
  202. package/lib/harness/usage-view.js.map +1 -0
  203. package/lib/harness/worktree-exit.d.ts +105 -0
  204. package/lib/harness/worktree-exit.d.ts.map +1 -0
  205. package/lib/harness/worktree-exit.js +168 -0
  206. package/lib/harness/worktree-exit.js.map +1 -0
  207. package/lib/history.d.ts +50 -0
  208. package/lib/history.d.ts.map +1 -0
  209. package/lib/history.js +139 -0
  210. package/lib/history.js.map +1 -0
  211. package/lib/index.d.ts +63 -0
  212. package/lib/index.d.ts.map +1 -0
  213. package/lib/index.js +54 -0
  214. package/lib/index.js.map +1 -0
  215. package/lib/input.d.ts +158 -0
  216. package/lib/input.d.ts.map +1 -0
  217. package/lib/input.js +400 -0
  218. package/lib/input.js.map +1 -0
  219. package/lib/invariant.d.ts +14 -0
  220. package/lib/invariant.d.ts.map +1 -0
  221. package/lib/invariant.js +20 -0
  222. package/lib/invariant.js.map +1 -0
  223. package/lib/mode-cycle.d.ts +22 -0
  224. package/lib/mode-cycle.d.ts.map +1 -0
  225. package/lib/mode-cycle.js +32 -0
  226. package/lib/mode-cycle.js.map +1 -0
  227. package/lib/model-catalog.d.ts +22 -0
  228. package/lib/model-catalog.d.ts.map +1 -0
  229. package/lib/model-catalog.js +45 -0
  230. package/lib/model-catalog.js.map +1 -0
  231. package/lib/packaged-preset.d.ts +32 -0
  232. package/lib/packaged-preset.d.ts.map +1 -0
  233. package/lib/packaged-preset.js +94 -0
  234. package/lib/packaged-preset.js.map +1 -0
  235. package/lib/plugin.d.ts +11 -0
  236. package/lib/plugin.d.ts.map +1 -0
  237. package/lib/plugin.js +88 -0
  238. package/lib/plugin.js.map +1 -0
  239. package/lib/profile.d.ts +4 -0
  240. package/lib/profile.d.ts.map +1 -0
  241. package/lib/profile.js +7 -0
  242. package/lib/profile.js.map +1 -0
  243. package/lib/project-sessions.d.ts +29 -0
  244. package/lib/project-sessions.d.ts.map +1 -0
  245. package/lib/project-sessions.js +60 -0
  246. package/lib/project-sessions.js.map +1 -0
  247. package/lib/project.d.ts +75 -0
  248. package/lib/project.d.ts.map +1 -0
  249. package/lib/project.js +196 -0
  250. package/lib/project.js.map +1 -0
  251. package/lib/provider-actions.d.ts +37 -0
  252. package/lib/provider-actions.d.ts.map +1 -0
  253. package/lib/provider-actions.js +417 -0
  254. package/lib/provider-actions.js.map +1 -0
  255. package/lib/provider-command.d.ts +109 -0
  256. package/lib/provider-command.d.ts.map +1 -0
  257. package/lib/provider-command.js +220 -0
  258. package/lib/provider-command.js.map +1 -0
  259. package/lib/provider-detail.d.ts +15 -0
  260. package/lib/provider-detail.d.ts.map +1 -0
  261. package/lib/provider-detail.js +201 -0
  262. package/lib/provider-detail.js.map +1 -0
  263. package/lib/provider-flow.d.ts +191 -0
  264. package/lib/provider-flow.d.ts.map +1 -0
  265. package/lib/provider-flow.js +192 -0
  266. package/lib/provider-flow.js.map +1 -0
  267. package/lib/provider-presets.d.ts +32 -0
  268. package/lib/provider-presets.d.ts.map +1 -0
  269. package/lib/provider-presets.js +105 -0
  270. package/lib/provider-presets.js.map +1 -0
  271. package/lib/provider-read.d.ts +63 -0
  272. package/lib/provider-read.d.ts.map +1 -0
  273. package/lib/provider-read.js +115 -0
  274. package/lib/provider-read.js.map +1 -0
  275. package/lib/provider-settings.d.ts +30 -0
  276. package/lib/provider-settings.d.ts.map +1 -0
  277. package/lib/provider-settings.js +65 -0
  278. package/lib/provider-settings.js.map +1 -0
  279. package/lib/resume-target.d.ts +59 -0
  280. package/lib/resume-target.d.ts.map +1 -0
  281. package/lib/resume-target.js +143 -0
  282. package/lib/resume-target.js.map +1 -0
  283. package/lib/slash.d.ts +44 -0
  284. package/lib/slash.d.ts.map +1 -0
  285. package/lib/slash.js +81 -0
  286. package/lib/slash.js.map +1 -0
  287. package/lib/state/driver-types.d.ts +505 -0
  288. package/lib/state/driver-types.d.ts.map +1 -0
  289. package/lib/state/driver-types.js +8 -0
  290. package/lib/state/driver-types.js.map +1 -0
  291. package/lib/state/driver-usage-types.d.ts +59 -0
  292. package/lib/state/driver-usage-types.d.ts.map +1 -0
  293. package/lib/state/driver-usage-types.js +8 -0
  294. package/lib/state/driver-usage-types.js.map +1 -0
  295. package/lib/statusline.d.ts +63 -0
  296. package/lib/statusline.d.ts.map +1 -0
  297. package/lib/statusline.js +97 -0
  298. package/lib/statusline.js.map +1 -0
  299. package/lib/store/pickers.d.ts +34 -0
  300. package/lib/store/pickers.d.ts.map +1 -0
  301. package/lib/store/pickers.js +111 -0
  302. package/lib/store/pickers.js.map +1 -0
  303. package/lib/store/provider-panel.d.ts +107 -0
  304. package/lib/store/provider-panel.d.ts.map +1 -0
  305. package/lib/store/provider-panel.js +151 -0
  306. package/lib/store/provider-panel.js.map +1 -0
  307. package/lib/store/question.d.ts +21 -0
  308. package/lib/store/question.d.ts.map +1 -0
  309. package/lib/store/question.js +59 -0
  310. package/lib/store/question.js.map +1 -0
  311. package/lib/store/queue.d.ts +27 -0
  312. package/lib/store/queue.d.ts.map +1 -0
  313. package/lib/store/queue.js +34 -0
  314. package/lib/store/queue.js.map +1 -0
  315. package/lib/store/session.d.ts +73 -0
  316. package/lib/store/session.d.ts.map +1 -0
  317. package/lib/store/session.js +172 -0
  318. package/lib/store/session.js.map +1 -0
  319. package/lib/store/subagents.d.ts +16 -0
  320. package/lib/store/subagents.d.ts.map +1 -0
  321. package/lib/store/subagents.js +44 -0
  322. package/lib/store/subagents.js.map +1 -0
  323. package/lib/store/todos.d.ts +35 -0
  324. package/lib/store/todos.d.ts.map +1 -0
  325. package/lib/store/todos.js +68 -0
  326. package/lib/store/todos.js.map +1 -0
  327. package/lib/store/usage.d.ts +15 -0
  328. package/lib/store/usage.d.ts.map +1 -0
  329. package/lib/store/usage.js +27 -0
  330. package/lib/store/usage.js.map +1 -0
  331. package/lib/store/views.d.ts +419 -0
  332. package/lib/store/views.d.ts.map +1 -0
  333. package/lib/store/views.js +3 -0
  334. package/lib/store/views.js.map +1 -0
  335. package/lib/store.d.ts +19 -0
  336. package/lib/store.d.ts.map +1 -0
  337. package/lib/store.js +10 -0
  338. package/lib/store.js.map +1 -0
  339. package/lib/terminal/lease.d.ts +33 -0
  340. package/lib/terminal/lease.d.ts.map +1 -0
  341. package/lib/terminal/lease.js +99 -0
  342. package/lib/terminal/lease.js.map +1 -0
  343. package/lib/tool-card.d.ts +75 -0
  344. package/lib/tool-card.d.ts.map +1 -0
  345. package/lib/tool-card.js +109 -0
  346. package/lib/tool-card.js.map +1 -0
  347. package/lib/tool-verbs.d.ts +12 -0
  348. package/lib/tool-verbs.d.ts.map +1 -0
  349. package/lib/tool-verbs.js +29 -0
  350. package/lib/tool-verbs.js.map +1 -0
  351. package/lib/transcript.d.ts +40 -0
  352. package/lib/transcript.d.ts.map +1 -0
  353. package/lib/transcript.js +413 -0
  354. package/lib/transcript.js.map +1 -0
  355. package/lib/working-line.d.ts +44 -0
  356. package/lib/working-line.d.ts.map +1 -0
  357. package/lib/working-line.js +56 -0
  358. package/lib/working-line.js.map +1 -0
  359. package/package.json +72 -0
  360. package/presets/cc/.dsh-cc-managed.json +5 -0
  361. package/presets/cc/agent.cordis.yml +524 -0
  362. package/presets/cc/preset.yml +3 -0
  363. package/scripts/stage-preset.mjs +26 -0
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Masked single-line text input (dsh-cc-side, first-party): a drop-in
3
+ * companion to pi-tui's `Input` for secrets (API keys). Display shows one
4
+ * `•` per grapheme instead of the raw characters; `getValue()` and `onSubmit`
5
+ * still receive the raw value. Key handling mirrors `Input`'s behavior using
6
+ * pi-tui's own public helpers — the vendored package itself is untouched.
7
+ * @module @dsh-cc/tui/components/masked-input
8
+ */
9
+ import { CURSOR_MARKER, getKeybindings, sliceByColumn, visibleWidth, } from '@dsh-cc/pi-tui';
10
+ // pi-tui's segmenter/word-navigation helpers are not part of the package's
11
+ // public root surface, and deep `src/` imports are forbidden (check:deep-imports
12
+ // — they do not survive the lib emit). The grapheme segmenter is a one-liner,
13
+ // so it is instantiated locally; word-jump keys are deliberately not bound
14
+ // (secrets are single-token entries; the control-char filter below swallows
15
+ // those key sequences harmlessly instead).
16
+ const segmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
17
+ export class MaskedInput {
18
+ value = '';
19
+ cursor = 0;
20
+ pasteBuffer = '';
21
+ isInPaste = false;
22
+ onSubmit;
23
+ onEscape;
24
+ focused = false;
25
+ getValue() {
26
+ return this.value;
27
+ }
28
+ setValue(value) {
29
+ this.value = value;
30
+ this.cursor = Math.min(this.cursor, value.length);
31
+ }
32
+ handleInput(data) {
33
+ // Bracketed paste mode buffering (same protocol as Input).
34
+ if (data.includes('\x1b[200~')) {
35
+ this.isInPaste = true;
36
+ this.pasteBuffer = '';
37
+ data = data.replace('\x1b[200~', '');
38
+ }
39
+ if (this.isInPaste) {
40
+ this.pasteBuffer += data;
41
+ const endIndex = this.pasteBuffer.indexOf('\x1b[201~');
42
+ if (endIndex !== -1) {
43
+ const pasteContent = this.pasteBuffer.substring(0, endIndex);
44
+ this.isInPaste = false;
45
+ const remaining = this.pasteBuffer.substring(endIndex + 6);
46
+ this.pasteBuffer = '';
47
+ // Newlines are never part of a single-line secret.
48
+ this.value = this.value.slice(0, this.cursor) + pasteContent.replace(/[\r\n\t]/g, '') + this.value.slice(this.cursor);
49
+ this.cursor += pasteContent.replace(/[\r\n\t]/g, '').length;
50
+ if (remaining)
51
+ this.handleInput(remaining);
52
+ }
53
+ return;
54
+ }
55
+ const kb = getKeybindings();
56
+ if (kb.matches(data, 'tui.select.cancel')) {
57
+ if (this.onEscape)
58
+ this.onEscape();
59
+ return;
60
+ }
61
+ if (kb.matches(data, 'tui.input.submit') || data === '\n') {
62
+ if (this.onSubmit)
63
+ this.onSubmit(this.value);
64
+ return;
65
+ }
66
+ if (kb.matches(data, 'tui.editor.deleteCharBackward')) {
67
+ if (this.cursor > 0) {
68
+ const graphemes = [...segmenter.segment(this.value.slice(0, this.cursor))];
69
+ const len = graphemes[graphemes.length - 1]?.segment.length ?? 1;
70
+ this.value = this.value.slice(0, this.cursor - len) + this.value.slice(this.cursor);
71
+ this.cursor -= len;
72
+ }
73
+ return;
74
+ }
75
+ if (kb.matches(data, 'tui.editor.deleteCharForward')) {
76
+ if (this.cursor < this.value.length) {
77
+ const graphemes = [...segmenter.segment(this.value.slice(this.cursor))];
78
+ const len = graphemes[0]?.segment.length ?? 1;
79
+ this.value = this.value.slice(0, this.cursor) + this.value.slice(this.cursor + len);
80
+ }
81
+ return;
82
+ }
83
+ if (kb.matches(data, 'tui.editor.cursorLeft')) {
84
+ if (this.cursor > 0) {
85
+ const graphemes = [...segmenter.segment(this.value.slice(0, this.cursor))];
86
+ this.cursor -= graphemes[graphemes.length - 1]?.segment.length ?? 1;
87
+ }
88
+ return;
89
+ }
90
+ if (kb.matches(data, 'tui.editor.cursorRight')) {
91
+ if (this.cursor < this.value.length) {
92
+ const graphemes = [...segmenter.segment(this.value.slice(this.cursor))];
93
+ this.cursor += graphemes[0]?.segment.length ?? 1;
94
+ }
95
+ return;
96
+ }
97
+ if (kb.matches(data, 'tui.editor.cursorLineStart')) {
98
+ this.cursor = 0;
99
+ return;
100
+ }
101
+ if (kb.matches(data, 'tui.editor.cursorLineEnd')) {
102
+ this.cursor = this.value.length;
103
+ return;
104
+ }
105
+ // cursorWordLeft/Right intentionally unbound — see the header comment.
106
+ // Printable input only — never let control characters into a secret.
107
+ const hasControlChars = [...data].some((ch) => {
108
+ const code = ch.charCodeAt(0);
109
+ return code < 32 || code === 0x7f || (code >= 0x80 && code <= 0x9f);
110
+ });
111
+ if (!hasControlChars) {
112
+ this.value = this.value.slice(0, this.cursor) + data + this.value.slice(this.cursor);
113
+ this.cursor += data.length;
114
+ }
115
+ }
116
+ invalidate() {
117
+ // No cached state to invalidate currently
118
+ }
119
+ render(width) {
120
+ // Bullets are one column wide, so display text and cursor offsets derive
121
+ // from grapheme counts without ever exposing a raw substring.
122
+ const prompt = '> ';
123
+ const availableWidth = width - prompt.length;
124
+ if (availableWidth <= 0)
125
+ return [prompt];
126
+ const displayValue = '•'.repeat([...segmenter.segment(this.value)].length);
127
+ const graphemesBeforeCursor = [...segmenter.segment(this.value.slice(0, this.cursor))].length;
128
+ const totalWidth = displayValue.length;
129
+ let visibleText = '';
130
+ let cursorDisplay = graphemesBeforeCursor;
131
+ if (totalWidth < availableWidth) {
132
+ visibleText = displayValue;
133
+ }
134
+ else {
135
+ const scrollWidth = graphemesBeforeCursor === totalWidth ? availableWidth - 1 : availableWidth;
136
+ const cursorCol = graphemesBeforeCursor;
137
+ if (scrollWidth > 0) {
138
+ const halfWidth = Math.floor(scrollWidth / 2);
139
+ let startCol = 0;
140
+ if (cursorCol < halfWidth) {
141
+ startCol = 0;
142
+ }
143
+ else if (cursorCol > totalWidth - halfWidth) {
144
+ startCol = Math.max(0, totalWidth - scrollWidth);
145
+ }
146
+ else {
147
+ startCol = Math.max(0, cursorCol - halfWidth);
148
+ }
149
+ visibleText = sliceByColumn(displayValue, startCol, scrollWidth, true);
150
+ cursorDisplay = Math.max(0, cursorCol - startCol);
151
+ }
152
+ else {
153
+ visibleText = '';
154
+ cursorDisplay = 0;
155
+ }
156
+ }
157
+ const marker = this.focused ? CURSOR_MARKER : '';
158
+ const beforeCursor = visibleText.slice(0, cursorDisplay);
159
+ const atCursor = visibleText.slice(cursorDisplay, cursorDisplay + 1) || ' ';
160
+ const afterCursor = visibleText.slice(cursorDisplay + 1);
161
+ const cursorChar = `\x1b[7m${atCursor}\x1b[27m`;
162
+ const textWithCursor = beforeCursor + marker + cursorChar + afterCursor;
163
+ const visualLength = visibleWidth(textWithCursor);
164
+ const padding = ' '.repeat(Math.max(0, availableWidth - visualLength));
165
+ return [prompt + textWithCursor + padding];
166
+ }
167
+ }
168
+ //# sourceMappingURL=masked-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"masked-input.js","sourceRoot":"","sources":["../../src/components/masked-input.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared overlay host: single place that (a) routes one raw keypress into
3
+ * whichever modal overlay is parked in the live state, and (b) rebuilds the
4
+ * overlay slot's child boxes from the state on every driver emit. root.ts
5
+ * calls these two helpers so adding an overlay kind never touches the mount.
6
+ * @module @dsh-cc/tui/components/overlay-host
7
+ */
8
+ import { Container } from '@dsh-cc/pi-tui';
9
+ import type { Driver } from '../state/driver-types.ts';
10
+ import type { TuiState } from '../store.ts';
11
+ import type { Theme } from './theme.ts';
12
+ /**
13
+ * Whether any modal overlay is open. Used by root's Ctrl+C branch: while an
14
+ * overlay is open and the agent is idle, Ctrl+C falls through so the
15
+ * overlay's own key handling (esc to dismiss, etc.) owns it.
16
+ */
17
+ export declare function overlayOpen(state: TuiState): boolean;
18
+ /**
19
+ * Route one raw keypress into the open overlay. Order is fixed priority:
20
+ * the first overlay kind parked in state owns the key. Returns true when an
21
+ * overlay consumed the key (root must swallow it before the editor);
22
+ * false means no overlay is open and other handlers proceed.
23
+ */
24
+ export declare function routeOverlayInput(driver: Driver, live: TuiState, data: string): boolean;
25
+ /**
26
+ * Rebuild the overlay slot's children from the current state: one box for
27
+ * whichever overlay is parked, none when all are closed. Clears and
28
+ * invalidates the container so boxes appear and disappear with the state.
29
+ */
30
+ export declare function renderOverlayChildren(overlays: Container, state: TuiState, theme: Theme): void;
31
+ //# sourceMappingURL=overlay-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-host.d.ts","sourceRoot":"","sources":["../../src/components/overlay-host.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAEtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAa3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAKvC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAOpD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CA+DvF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAmC9F"}
@@ -0,0 +1,128 @@
1
+ import { routeApprovalInput, routeQuestionInput, routeEffortPickerInput, routeModelPickerInput, routePermissionPickerInput, routeSessionSwitcherInput, routeTodoPanelInput, routeUsagePanelInput, routeWorktreeExitInput, routeProviderPanelInput } from "../input.js";
2
+ import { createApprovalBox, createEffortPickerBox, createModelPickerBox, createPermissionPickerBox, createQuestionBox, createSessionSwitcherBox, createTodoPanelBox, createUsagePanelBox, createWorktreeExitBox, } from "./overlays.js";
3
+ import { createProviderPanelBox } from "./provider-box.js";
4
+ /**
5
+ * Whether any modal overlay is open. Used by root's Ctrl+C branch: while an
6
+ * overlay is open and the agent is idle, Ctrl+C falls through so the
7
+ * overlay's own key handling (esc to dismiss, etc.) owns it.
8
+ */
9
+ export function overlayOpen(state) {
10
+ return state.approval !== undefined || state.question !== undefined ||
11
+ state.modelPicker !== undefined || state.effortPicker !== undefined ||
12
+ state.permissionPicker !== undefined ||
13
+ state.sessionSwitcher !== undefined ||
14
+ state.todoPanel !== undefined || state.usagePanel !== undefined ||
15
+ state.worktreeExit !== undefined || state.providerPanel !== undefined;
16
+ }
17
+ /**
18
+ * Route one raw keypress into the open overlay. Order is fixed priority:
19
+ * the first overlay kind parked in state owns the key. Returns true when an
20
+ * overlay consumed the key (root must swallow it before the editor);
21
+ * false means no overlay is open and other handlers proceed.
22
+ */
23
+ export function routeOverlayInput(driver, live, data) {
24
+ if (live.approval !== undefined) {
25
+ // Approval keys route through the shared router in input.ts — the same
26
+ // single source of truth the headless composer path uses.
27
+ routeApprovalInput(driver, data);
28
+ return true;
29
+ }
30
+ if (live.question !== undefined) {
31
+ // While a question is open every key belongs to the overlay — routed and
32
+ // consumed here so the editor never sees typing, arrows, or enter.
33
+ routeQuestionInput(driver, data);
34
+ return true;
35
+ }
36
+ if (live.modelPicker !== undefined) {
37
+ // Modal model picker: arrows/enter/esc only, everything else consumed.
38
+ routeModelPickerInput(driver, data);
39
+ return true;
40
+ }
41
+ if (live.effortPicker !== undefined) {
42
+ // Modal effort picker: arrows/enter/esc only, everything else consumed.
43
+ routeEffortPickerInput(driver, data);
44
+ return true;
45
+ }
46
+ if (live.permissionPicker !== undefined) {
47
+ // Modal permission picker: arrows/enter/esc only, everything else consumed.
48
+ routePermissionPickerInput(driver, data);
49
+ return true;
50
+ }
51
+ if (live.sessionSwitcher !== undefined) {
52
+ // Modal session switcher: arrows/enter/esc only, everything else
53
+ // consumed. While `switching` is true, all keys are consumed without
54
+ // action.
55
+ routeSessionSwitcherInput(driver, data);
56
+ return true;
57
+ }
58
+ if (live.todoPanel !== undefined) {
59
+ // Modal todo panel: arrows/esc/ctrl+t (close) only, everything else
60
+ // consumed. The open path is the ctrl+t binding in root, which only
61
+ // fires while the panel is closed.
62
+ routeTodoPanelInput(driver, data);
63
+ return true;
64
+ }
65
+ if (live.usagePanel !== undefined) {
66
+ // Modal usage panel: pure display with no navigation — esc closes,
67
+ // everything else is consumed. The open path is the /usage command.
68
+ routeUsagePanelInput(driver, data);
69
+ return true;
70
+ }
71
+ if (live.worktreeExit !== undefined) {
72
+ // Modal /quit worktree-exit confirmation: arrows/enter/esc only,
73
+ // everything else consumed. While `busy` (a removal in flight) all
74
+ // keys are swallowed by the router.
75
+ routeWorktreeExitInput(driver, data);
76
+ return true;
77
+ }
78
+ if (live.providerPanel !== undefined) {
79
+ // Modal `/provider` panel (§4.2–§4.6): phase-dependent routing through
80
+ // the runtime seam the driver exposes (list j/k, wizard text entry,
81
+ // detail actions, remove confirm).
82
+ routeProviderPanelInput(driver.providerRuntime, data);
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+ /**
88
+ * Rebuild the overlay slot's children from the current state: one box for
89
+ * whichever overlay is parked, none when all are closed. Clears and
90
+ * invalidates the container so boxes appear and disappear with the state.
91
+ */
92
+ export function renderOverlayChildren(overlays, state, theme) {
93
+ overlays.clear();
94
+ if (state.approval !== undefined) {
95
+ overlays.addChild(createApprovalBox(state.approval, theme));
96
+ }
97
+ if (state.question !== undefined) {
98
+ overlays.addChild(createQuestionBox(state.question, theme));
99
+ }
100
+ if (state.modelPicker !== undefined) {
101
+ overlays.addChild(createModelPickerBox(state.modelPicker, theme));
102
+ }
103
+ if (state.effortPicker !== undefined) {
104
+ overlays.addChild(createEffortPickerBox(state.effortPicker, theme));
105
+ }
106
+ if (state.permissionPicker !== undefined) {
107
+ overlays.addChild(createPermissionPickerBox(state.permissionPicker, theme));
108
+ }
109
+ if (state.sessionSwitcher !== undefined) {
110
+ overlays.addChild(createSessionSwitcherBox(state.sessionSwitcher, theme));
111
+ }
112
+ if (state.todoPanel !== undefined) {
113
+ overlays.addChild(createTodoPanelBox(state.todos ?? [], state.todoPanel.focused, theme));
114
+ }
115
+ if (state.usagePanel !== undefined) {
116
+ // The panel rebuilds from the live snapshot on every emit, so
117
+ // projection changes refresh it in place while it is open.
118
+ overlays.addChild(createUsagePanelBox(state.usage, theme));
119
+ }
120
+ if (state.worktreeExit !== undefined) {
121
+ overlays.addChild(createWorktreeExitBox(state.worktreeExit, theme));
122
+ }
123
+ if (state.providerPanel !== undefined) {
124
+ overlays.addChild(createProviderPanelBox(state.providerPanel, theme));
125
+ }
126
+ overlays.invalidate();
127
+ }
128
+ //# sourceMappingURL=overlay-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-host.js","sourceRoot":"","sources":["../../src/components/overlay-host.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAEtQ,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EACzB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAM1D;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAe;IACzC,OAAO,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QACjE,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;QACnE,KAAK,CAAC,gBAAgB,KAAK,SAAS;QACpC,KAAK,CAAC,eAAe,KAAK,SAAS;QACnC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;QAC/D,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,CAAA;AACzE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,IAAc,EAAE,IAAY;IAC5E,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,uEAAuE;QACvE,0DAA0D;QAC1D,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,yEAAyE;QACzE,mEAAmE;QACnE,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAChC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACnC,uEAAuE;QACvE,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACnC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACpC,wEAAwE;QACxE,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACpC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACxC,4EAA4E;QAC5E,0BAA0B,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACxC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACvC,iEAAiE;QACjE,qEAAqE;QACrE,UAAU;QACV,yBAAyB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACvC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACjC,oEAAoE;QACpE,oEAAoE;QACpE,mCAAmC;QACnC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAClC,mEAAmE;QACnE,oEAAoE;QACpE,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAClC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACpC,iEAAiE;QACjE,mEAAmE;QACnE,oCAAoC;QACpC,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACpC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACrC,uEAAuE;QACvE,oEAAoE;QACpE,mCAAmC;QACnC,uBAAuB,CAAE,MAA6D,CAAC,eAAe,EAAE,IAAI,CAAC,CAAA;QAC7G,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAmB,EAAE,KAAe,EAAE,KAAY;IACtF,QAAQ,CAAC,KAAK,EAAE,CAAA;IAChB,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACjC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;IAC7D,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACjC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;IAC7D,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACpC,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAA;IACnE,CAAC;IACD,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACrC,QAAQ,CAAC,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAA;IACrE,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACzC,QAAQ,CAAC,QAAQ,CAAC,yBAAyB,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAA;IAC7E,CAAC;IACD,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACxC,QAAQ,CAAC,QAAQ,CAAC,wBAAwB,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAA;IAC3E,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAClC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;IAC1F,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,8DAA8D;QAC9D,2DAA2D;QAC3D,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;IAC5D,CAAC;IACD,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACrC,QAAQ,CAAC,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAA;IACrE,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACtC,QAAQ,CAAC,QAAQ,CAAC,sBAAsB,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAA;IACvE,CAAC;IACD,QAAQ,CAAC,UAAU,EAAE,CAAA;AACvB,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Approval and question overlay containers. Rendered inline (not as pi-tui
3
+ * overlays) so they participate in the main-screen scrollback flow, matching
4
+ * the previous Ink layout.
5
+ * @module @dsh-cc/tui/components/overlays
6
+ */
7
+ import { Container } from '@dsh-cc/pi-tui';
8
+ import type { ApprovalView, EffortPickerView, ModelPickerView, PermissionPickerView, QuestionView, SessionSwitcherView, TodoItemView, UsageTotalsView, UsageView, WorktreeExitView } from '../store.ts';
9
+ import { type Theme } from './theme.ts';
10
+ /**
11
+ * Approval box: the title ("Approve <tool>?", or "Approval (1 of N)" when
12
+ * other modals wait behind this one) + optional reason + the structured
13
+ * payload preview (command block, diff card, or raw-arguments JSON block) +
14
+ * an explicit key→outcome hint including the always-allow option.
15
+ */
16
+ export declare function createApprovalBox(approval: ApprovalView, theme?: Theme): Container;
17
+ /**
18
+ * Question box v2: title + question text, the plan markdown for plan-review
19
+ * intents, focusable option rows (multi-select checkboxes), the trailing
20
+ * free-text "Other" row, and a key hint footer.
21
+ */
22
+ export declare function createQuestionBox(question: QuestionView, theme?: Theme): Container;
23
+ /**
24
+ * Model picker box: a modal list of `provider/id — name` rows with a `❯`
25
+ * focus marker and a `*` on the active route, windowed to
26
+ * {@link MODEL_PICKER_VISIBLE_ROWS} rows around the focus.
27
+ *
28
+ * Hand-rolled (not the vendored `SelectList`) because SelectList owns its own
29
+ * `selectedIndex` and routes input through its own `handleInput`, which would
30
+ * fight the driver-owned `modelPicker` state and the emit/setter flow the rest
31
+ * of the overlays use. SelectList also renders a `→` prefix and a two-column
32
+ * layout that clash with the `❯` + Text-row convention shared by the approval
33
+ * and question boxes. A focused-list mirroring the question overlay keeps one
34
+ * state owner and one styling language.
35
+ */
36
+ export declare function createModelPickerBox(picker: ModelPickerView, theme?: Theme): Container;
37
+ /**
38
+ * Effort picker box: a modal list of the active model's reasoning-effort
39
+ * levels with a `❯` focus marker and a `*` on the live effort, windowed to
40
+ * {@link EFFORT_PICKER_VISIBLE_ROWS} rows around the focus. The trailing
41
+ * reserved `'default'` entry renders as `default (provider)` to make clear it
42
+ * restores the provider default rather than selecting a level named default.
43
+ */
44
+ export declare function createEffortPickerBox(picker: EffortPickerView, theme?: Theme): Container;
45
+ /**
46
+ * Permission picker box: a modal list of the five CC rule-engine modes with
47
+ * a `❯` focus marker and a `*` on the live mode. While `confirmingBypass`
48
+ * is set the list is replaced by the shared bypass risk-gate copy.
49
+ */
50
+ export declare function createPermissionPickerBox(picker: PermissionPickerView, theme?: Theme): Container;
51
+ /**
52
+ * Session switcher box: title `Resume session` (plus the live query while a
53
+ * filter is typed), rows of relative last-activity time + title (or short
54
+ * id) + short id via {@link formatSessionRow}, with the cwd basename added
55
+ * in all-projects scope, a `❯` focus marker, and a `●` on the current
56
+ * session, windowed to {@link SESSION_SWITCHER_VISIBLE_ROWS} rows. An empty
57
+ * visible list explains itself (cwd scope hints at Tab → all projects). A
58
+ * dim `Switching…` footer replaces the key hint while a switch is in flight
59
+ * (input blocked).
60
+ */
61
+ export declare function createSessionSwitcherBox(sw: SessionSwitcherView, theme?: Theme): Container;
62
+ /**
63
+ * Todo panel box: the session todo list with status icons, a `❯` focus
64
+ * marker, and a key hint footer, windowed to {@link TODO_PANEL_VISIBLE_ROWS}
65
+ * rows around the focus. An empty (or absent) todo list renders a dim
66
+ * placeholder instead of rows; the panel still opens so Ctrl+T is a stable
67
+ * toggle either way.
68
+ */
69
+ export declare function createTodoPanelBox(todos: readonly TodoItemView[], focused: number, theme?: Theme): Container;
70
+ /**
71
+ * Cache-hit rate as a rounded percent, `cacheRead / (input + cacheRead)` —
72
+ * `input` is the uncached bucket, so the denominator is all prompt input.
73
+ * Undefined when there is nothing to show: no `cacheRead` total at all, or a
74
+ * zero denominator (no input and no cache read). Ratios above 1 clamp at 100.
75
+ */
76
+ export declare function cacheHitPercent(totals: UsageTotalsView): number | undefined;
77
+ /**
78
+ * Usage panel box (`/usage`): the live context-occupancy bar, the cumulative
79
+ * token totals (cache rows only when non-zero, mirroring /cost), and the
80
+ * context breakdown by role. Pure display — no focus or navigation — and
81
+ * each section degrades independently to a dim `n/a` when its projection has
82
+ * no data. Quota and rate-limit figures have no projection at all, so the
83
+ * footer says so explicitly instead of implying the panel is exhaustive.
84
+ */
85
+ export declare function createUsagePanelBox(view: UsageView | undefined, theme?: Theme): Container;
86
+ /**
87
+ * `/quit` worktree-exit confirmation box: the session descriptor, the
88
+ * removal evidence next to the destructive option, and the three choices
89
+ * (keep / remove / cancel). Focused row carries a `❯` prefix. While a
90
+ * removal is in flight (`busy`) the footer reports progress and keys are
91
+ * swallowed upstream.
92
+ */
93
+ export declare function createWorktreeExitBox(view: WorktreeExitView, theme?: Theme): Container;
94
+ //# sourceMappingURL=overlays.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlays.d.ts","sourceRoot":"","sources":["../../src/components/overlays.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAA;AAE1D,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,SAAS,EACT,gBAAgB,EACjB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,YAAY,CAAA;AAerD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CAyBhG;AAYD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CAgChG;AASD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CAyBpG;AAQD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CAwBtG;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,oBAAoB,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CAmB9G;AAQD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,mBAAmB,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CAiDxG;AAmBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CA0B1H;AAqCD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAK3E;AAcD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CAqCvG;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,GAAE,KAAoB,GAAG,SAAS,CA+BpG"}