@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,204 @@
1
+ /**
2
+ * Statusline HUD + sessionProjections feed for the TUI driver.
3
+ *
4
+ * Migrated out of createDriver (harness/driver.ts) as a free-function
5
+ * collaborator so the factory stays under the line budget. Receives a
6
+ * structural {@link DriverHudCtx} instead of importing the factory (no cycle).
7
+ *
8
+ * Owned state: the git-branch probe result, the sessionProjections handle, and
9
+ * the derived HUD patch path. Exposes back to createDriver the pieces the
10
+ * factory (runLocal usage panel) and switchSession still need: applyUsage,
11
+ * projections, statusLineOf, seedHud, seedTodos, refreshBranch.
12
+ * @module @dsh-cc/tui/harness/driver-hud
13
+ */
14
+ import { setHud, setTodos, setTurnActive, setUsage, } from "../store.js";
15
+ import { breakdownOf, occupancyOf, percentOf, sameTodos, sameUsage, todosOf, tokensOf, totalsOf, usageViewOf, } from "./usage-view.js";
16
+ import { formatModeLine, formatStatusLine } from "../statusline.js";
17
+ import { truncateToWidth } from '@dsh-cc/pi-tui';
18
+ /**
19
+ * Build the statusline HUD section. Runs the boot sequence on construction —
20
+ * in original order: branch probe, seed HUD/todos from live projections, anchor
21
+ * the working line if busy, then subscribe to the change feed — so createDriver
22
+ * needs no extra call.
23
+ */
24
+ export function createHudSection(rt) {
25
+ const { state, emit, ctx, cwd, current, selection, branchProbe, statusline } = rt;
26
+ // --- Branch: one best-effort probe at boot and after each switchSession (the
27
+ // cwd may differ per session). Async is fine — a late landing re-emits so
28
+ // the footer picks it up; a probe superseded by a switch is dropped by the
29
+ // sequence check. The probe never throws; failures just omit the segment.
30
+ // No timer, one probe per (re)bind — zero polling.
31
+ let branch;
32
+ let branchSeq = 0;
33
+ const refreshBranch = () => {
34
+ const seq = ++branchSeq;
35
+ const dir = current.agent.session.header.cwd ?? cwd;
36
+ void Promise.resolve(branchProbe(dir))
37
+ .catch(() => undefined)
38
+ .then(next => {
39
+ if (seq !== branchSeq || next === branch)
40
+ return;
41
+ branch = next;
42
+ // Same-reference emit: re-notifies subscribers so root re-reads the
43
+ // statusline getter with the fresh branch.
44
+ emit(state());
45
+ });
46
+ };
47
+ refreshBranch();
48
+ // Projections: seed once from stateOf (a resumed session may already be
49
+ // populated), then keep the hud fresh from the change feed — event-driven,
50
+ // filtered to the live session so late events from a disposed session are
51
+ // dropped by the id mismatch.
52
+ const projections = ctx.get('sessionProjections');
53
+ const applyHud = (patch) => {
54
+ const hud = state().hud;
55
+ const percentSame = patch.contextPercent === undefined || hud?.contextPercent === patch.contextPercent;
56
+ const tokens = patch.tokens;
57
+ const tokensSame = tokens === undefined
58
+ || (hud?.tokens !== undefined && hud.tokens.input === tokens.input && hud.tokens.output === tokens.output);
59
+ const detail = patch.contextTokens;
60
+ const detailSame = detail === undefined
61
+ || (hud?.contextTokens !== undefined
62
+ && hud.contextTokens.used === detail.used
63
+ && hud.contextTokens.window === detail.window);
64
+ if (percentSame && tokensSame && detailSame)
65
+ return; // emit only on an actual change
66
+ emit(setHud(state(), patch));
67
+ };
68
+ const applyUsage = (patch) => {
69
+ if (patch === undefined)
70
+ return;
71
+ const s = state();
72
+ const merged = { ...s.usage, ...patch };
73
+ if (sameUsage(s.usage, merged))
74
+ return;
75
+ emit(setUsage(s, merged));
76
+ };
77
+ const seedHud = () => {
78
+ statusline?.onRebind();
79
+ const s = state();
80
+ const patch = {};
81
+ if (projections !== undefined) {
82
+ const tokens = tokensOf(projections.stateOf(current.agent.session, 'tokenUsage'));
83
+ if (tokens !== undefined)
84
+ patch.tokens = tokens;
85
+ const pressure = projections.stateOf(current.agent.session, 'contextPressure');
86
+ const percent = percentOf(pressure);
87
+ if (percent !== undefined)
88
+ patch.contextPercent = percent;
89
+ const occupancy = occupancyOf(pressure);
90
+ if (occupancy !== undefined)
91
+ patch.contextTokens = occupancy;
92
+ }
93
+ // Replace wholesale: clear first so stale fields from a previous session
94
+ // never leak, then apply whatever the new session actually has.
95
+ let next = setHud(s, undefined);
96
+ if (patch.contextPercent !== undefined || patch.tokens !== undefined || patch.contextTokens !== undefined) {
97
+ next = setHud(next, patch);
98
+ }
99
+ if (next !== s)
100
+ emit(next);
101
+ };
102
+ // Todos: same seeding contract as the HUD — stateOf at (re)bind, then the
103
+ // change feed. Absent (`null` before the first write) clears the strip so
104
+ // no cross-session leak survives a switch.
105
+ const seedTodos = () => {
106
+ const s = state();
107
+ const value = projections === undefined
108
+ ? undefined
109
+ : projections.stateOf(current.agent.session, 'todos');
110
+ const todos = todosOf(value);
111
+ if (sameTodos(s.todos, todos))
112
+ return;
113
+ emit(setTodos(s, todos));
114
+ };
115
+ seedHud();
116
+ seedTodos();
117
+ // Boot may resume a log that ended mid-turn (crashed process): the setBusy
118
+ // sync above flipped busy from the ground-truth agent status, so anchor the
119
+ // working line here — deliberately after seedHud, so outputBase reads the
120
+ // seeded token totals instead of pinning an unseeded baseline.
121
+ if (state().busy) {
122
+ emit(setTurnActive(state(), { startedAt: Date.now(), outputBase: state().hud?.tokens?.output }));
123
+ }
124
+ if (projections !== undefined) {
125
+ projections.onChanged((session, key, value) => {
126
+ if (session.id !== current.agent.session.id)
127
+ return;
128
+ statusline?.onProjection(key);
129
+ if (key === 'tokenUsage') {
130
+ const usage = value;
131
+ const tokens = tokensOf(usage);
132
+ if (tokens !== undefined)
133
+ applyHud({ tokens });
134
+ applyUsage(usageViewOf(totalsOf(usage), undefined, undefined));
135
+ // Working-line rebase guard: an anchor created before the HUD was
136
+ // seeded carries outputBase === undefined; the first tokenUsage
137
+ // change pins it. Strictly turn-MODIFYING (turn must already exist) —
138
+ // a tokenUsage emit while idle must never conjure a phantom anchor.
139
+ // setTurnActive re-derives verbIndex deterministically from the
140
+ // unchanged startedAt, so this is a pure baseline pin; the live
141
+ // stepStartedAt passes through so pinning never resets a mid-step
142
+ // clock.
143
+ const turn = state().turn;
144
+ if (turn !== undefined && turn.outputBase === undefined && tokens !== undefined) {
145
+ emit(setTurnActive(state(), { startedAt: turn.startedAt, outputBase: tokens.output, stepStartedAt: turn.stepStartedAt }));
146
+ }
147
+ }
148
+ else if (key === 'contextPressure') {
149
+ const pressure = value;
150
+ const percent = percentOf(pressure);
151
+ const occupancy = occupancyOf(pressure);
152
+ if (percent === undefined && occupancy === undefined)
153
+ return;
154
+ applyHud({
155
+ ...percent === undefined ? {} : { contextPercent: percent },
156
+ ...occupancy === undefined ? {} : { contextTokens: occupancy },
157
+ });
158
+ applyUsage(usageViewOf(undefined, occupancy, undefined));
159
+ }
160
+ else if (key === 'todos') {
161
+ const todos = todosOf(value);
162
+ if (sameTodos(state().todos, todos))
163
+ return;
164
+ emit(setTodos(state(), todos));
165
+ }
166
+ else if (key === 'contextBreakdown') {
167
+ applyUsage(usageViewOf(undefined, undefined, breakdownOf(value)));
168
+ }
169
+ });
170
+ }
171
+ const statusLineOf = (width) => {
172
+ // Custom statusLine (plan §3.2/D3/D4): active → the command's rows with
173
+ // padding plus a client-drawn mode row below; inactive → today's built-in
174
+ // line, byte-identical.
175
+ const custom = statusline?.override();
176
+ if (custom !== undefined) {
177
+ // Blank detection must trim: with padding > 0 an all-blank settle is
178
+ // whitespace, not ''. Blank → the mode row alone.
179
+ if (custom.trim().length === 0)
180
+ return formatModeLine(state().permissionMode);
181
+ const rows = custom.split('\n');
182
+ const clipped = width === undefined
183
+ ? rows
184
+ : rows.map(row => truncateToWidth(row, width));
185
+ return `${clipped.join('\n')}\n${formatModeLine(state().permissionMode)}`;
186
+ }
187
+ const effort = selection.current?.reasoningEffort;
188
+ const s = state();
189
+ return formatStatusLine({
190
+ cwd: current.agent.session.header.cwd ?? cwd,
191
+ sessionId: String(current.agent.session.id),
192
+ permissionMode: s.permissionMode,
193
+ ...selection.current === undefined ? {} : { model: selection.current.model },
194
+ ...effort === undefined ? {} : { effort },
195
+ ...branch === undefined ? {} : { branch },
196
+ ...s.hud?.contextPercent === undefined ? {} : { contextPercent: s.hud.contextPercent },
197
+ ...s.hud?.contextTokens === undefined ? {} : { contextTokens: s.hud.contextTokens },
198
+ ...s.hud?.tokens === undefined ? {} : { tokens: s.hud.tokens },
199
+ busy: s.busy,
200
+ }, width === undefined ? {} : { width });
201
+ };
202
+ return { refreshBranch, seedHud, seedTodos, applyUsage, projections, statusLineOf };
203
+ }
204
+ //# sourceMappingURL=driver-hud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-hud.js","sourceRoot":"","sources":["../../src/harness/driver-hud.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Live session folds shared by the driver factory and its sections: the
3
+ * effective permission mode (plan overlay, else the durable override) and the
4
+ * LIVE session working directory (the session-cwd plugin's durable
5
+ * `worktree/entered` fold, then the boot-time header cwd).
6
+ *
7
+ * @module @dsh-cc/tui/harness/driver-live
8
+ */
9
+ import type { Agent } from '@deepseek-ai/dsh-agent';
10
+ export declare function liveMode(agent: Agent, fallback: string): string;
11
+ /** Duck-typed face of the host context carrying the permission-rules engine. */
12
+ type RulesHostCtx = {
13
+ get(key: string): unknown;
14
+ };
15
+ /**
16
+ * The LIVE merged settings `permissions.defaultMode` (the engine rebuilds it
17
+ * on settings reload), falling back to the literal `'default'` when the
18
+ * permission-rules engine is not mounted. Structural on purpose: the driver
19
+ * must not depend on the engine's class shape.
20
+ */
21
+ export declare function liveDefaultMode(ctx: RulesHostCtx): string;
22
+ /**
23
+ * `liveMode` with the F1 fallback bound to the host context: sections call
24
+ * `liveMode(agent)` and the fallback resolves to the permission-rules
25
+ * engine's LIVE merged settings defaultMode (literal `'default'` when the
26
+ * engine is not mounted). An explicit `fallback` still wins.
27
+ */
28
+ export declare function liveModeWithDefault(ctx: RulesHostCtx): (agent: Agent, fallback?: string) => string;
29
+ /**
30
+ * The LIVE session working directory: the session-cwd plugin's durable
31
+ * `worktree/entered` fold first (authoritative across EnterWorktree/
32
+ * ExitWorktree moves), then the boot-time header cwd.
33
+ */
34
+ export declare function liveSessionCwd(agent: Agent, fallback: string): string;
35
+ export {};
36
+ //# sourceMappingURL=driver-live.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-live.d.ts","sourceRoot":"","sources":["../../src/harness/driver-live.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAKnD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED,gFAAgF;AAChF,KAAK,YAAY,GAAG;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAA;AAEjD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAGzD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,YAAY,GAChB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErE"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Live session folds shared by the driver factory and its sections: the
3
+ * effective permission mode (plan overlay, else the durable override) and the
4
+ * LIVE session working directory (the session-cwd plugin's durable
5
+ * `worktree/entered` fold, then the boot-time header cwd).
6
+ *
7
+ * @module @dsh-cc/tui/harness/driver-live
8
+ */
9
+ import { foldPlanMode } from '@deepseek-ai/dsh-plan-mode';
10
+ import { foldPermissionMode } from '@dsh-cc/permission-rules';
11
+ import { foldSessionCwd } from '@dsh-cc/session-cwd';
12
+ export function liveMode(agent, fallback) {
13
+ if (foldPlanMode(agent.session.events))
14
+ return 'plan';
15
+ return foldPermissionMode(agent.session.events) ?? fallback;
16
+ }
17
+ /**
18
+ * The LIVE merged settings `permissions.defaultMode` (the engine rebuilds it
19
+ * on settings reload), falling back to the literal `'default'` when the
20
+ * permission-rules engine is not mounted. Structural on purpose: the driver
21
+ * must not depend on the engine's class shape.
22
+ */
23
+ export function liveDefaultMode(ctx) {
24
+ const rules = ctx.get('permissionRules');
25
+ return rules?.defaultMode ?? 'default';
26
+ }
27
+ /**
28
+ * `liveMode` with the F1 fallback bound to the host context: sections call
29
+ * `liveMode(agent)` and the fallback resolves to the permission-rules
30
+ * engine's LIVE merged settings defaultMode (literal `'default'` when the
31
+ * engine is not mounted). An explicit `fallback` still wins.
32
+ */
33
+ export function liveModeWithDefault(ctx) {
34
+ return (agent, fallback) => liveMode(agent, fallback ?? liveDefaultMode(ctx));
35
+ }
36
+ /**
37
+ * The LIVE session working directory: the session-cwd plugin's durable
38
+ * `worktree/entered` fold first (authoritative across EnterWorktree/
39
+ * ExitWorktree moves), then the boot-time header cwd.
40
+ */
41
+ export function liveSessionCwd(agent, fallback) {
42
+ return foldSessionCwd(agent.session.events) ?? agent.session.header.cwd ?? fallback;
43
+ }
44
+ //# sourceMappingURL=driver-live.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-live.js","sourceRoot":"","sources":["../../src/harness/driver-live.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,MAAM,UAAU,QAAQ,CAAC,KAAY,EAAE,QAAgB;IACrD,IAAI,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAA;IACrD,OAAO,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAA;AAC7D,CAAC;AAKD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAiB;IAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAyC,CAAA;IAChF,OAAO,KAAK,EAAE,WAAW,IAAI,SAAS,CAAA;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAiB;IAEjB,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC,CAAA;AAC/E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,QAAgB;IAC3D,OAAO,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAA;AACrF,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Modal pipeline (approvals + questions sharing one FIFO) extracted from
3
+ * harness/driver.ts. Free-function collaborator: `createModalQueue` takes a
4
+ * {@link DriverModalCtx} instead of closing over createDriver's locals, so the
5
+ * harness factory stays out of this leaf. Emits re-read the current view-model
6
+ * via `rt.state()` after every emit (createDriver rebinds `state` on emit).
7
+ * @module @dsh-cc/tui/harness/driver-modal
8
+ */
9
+ import { type ApprovalPreview, type ApprovalView, type QuestionView } from '../store.ts';
10
+ import type { ApprovalOutcome } from '@deepseek-ai/dsh-user-approval';
11
+ import type { AskUserQuestionAnswer } from '@deepseek-ai/dsh-user-questions';
12
+ import type { DriverModalCtx } from './driver-ctx.ts';
13
+ export type ApprovalEntry = {
14
+ kind: 'approval';
15
+ view: ApprovalView;
16
+ resolve: (outcome: ApprovalOutcome) => void;
17
+ /** The requesting agent — carries the session a 'session' grant scopes to. */
18
+ agent?: unknown;
19
+ signal?: AbortSignal;
20
+ };
21
+ export type QuestionEntry = {
22
+ kind: 'question';
23
+ id: string;
24
+ view: QuestionView;
25
+ resolve: (answer: AskUserQuestionAnswer) => void;
26
+ reject: (error: unknown) => void;
27
+ signal?: AbortSignal;
28
+ };
29
+ export type ModalEntry = ApprovalEntry | QuestionEntry;
30
+ /** Deps `answerApproval` threads through to createDriver's persistence layer. */
31
+ export interface ModalAnswerDeps {
32
+ writeAllowRule(toolName: string, preview: ApprovalPreview | undefined): Promise<void>;
33
+ /** Grant the derived rule to the requesting session's allowlist (WS4-PR-B). */
34
+ addSessionRule(agent: unknown, toolName: string, preview: ApprovalPreview | undefined): void;
35
+ showNotice(text: string): void;
36
+ }
37
+ /**
38
+ * Build the modal FIFO. Only the head renders (exactly one of the approval and
39
+ * question slots is set); answering or aborting the head promotes the next
40
+ * entry, and `ask()` during an active modal queues behind it instead of
41
+ * stacking a second box.
42
+ */
43
+ export declare function createModalQueue(rt: DriverModalCtx): {
44
+ push(entry: ModalEntry): void;
45
+ dequeue(entry: ModalEntry): void;
46
+ publishHead(): void;
47
+ shiftHead(): ModalEntry | undefined;
48
+ peekHead(): ModalEntry | undefined;
49
+ spliceAll(): ModalEntry[];
50
+ answerApproval(kind: 'once' | 'always' | 'session' | 'reject', deps: ModalAnswerDeps): void;
51
+ };
52
+ //# sourceMappingURL=driver-modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-modal.d.ts","sourceRoot":"","sources":["../../src/harness/driver-modal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AACrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAA;IAC3C,8EAA8E;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AACD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAChD,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AACD,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,aAAa,CAAA;AAEtD,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrF,+EAA+E;IAC/E,cAAc,CACZ,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,GAAG,SAAS,GACnC,IAAI,CAAA;IACP,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,cAAc,GAAG;IACpD,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IAC7B,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IAChC,WAAW,IAAI,IAAI,CAAA;IACnB,SAAS,IAAI,UAAU,GAAG,SAAS,CAAA;IACnC,QAAQ,IAAI,UAAU,GAAG,SAAS,CAAA;IAClC,SAAS,IAAI,UAAU,EAAE,CAAA;IACzB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAAA;CAC5F,CA6DA"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Modal pipeline (approvals + questions sharing one FIFO) extracted from
3
+ * harness/driver.ts. Free-function collaborator: `createModalQueue` takes a
4
+ * {@link DriverModalCtx} instead of closing over createDriver's locals, so the
5
+ * harness factory stays out of this leaf. Emits re-read the current view-model
6
+ * via `rt.state()` after every emit (createDriver rebinds `state` on emit).
7
+ * @module @dsh-cc/tui/harness/driver-modal
8
+ */
9
+ import { setApproval, setQuestion, } from "../store.js";
10
+ /**
11
+ * Build the modal FIFO. Only the head renders (exactly one of the approval and
12
+ * question slots is set); answering or aborting the head promotes the next
13
+ * entry, and `ask()` during an active modal queues behind it instead of
14
+ * stacking a second box.
15
+ */
16
+ export function createModalQueue(rt) {
17
+ const modalQueue = [];
18
+ /** Publish the queue head into exactly one of the two modal slots. */
19
+ const publishHead = () => {
20
+ const head = modalQueue[0];
21
+ const behind = modalQueue.length - 1;
22
+ if (head === undefined || head.kind !== 'approval')
23
+ rt.emit(setApproval(rt.state(), undefined));
24
+ if (head === undefined || head.kind !== 'question')
25
+ rt.emit(setQuestion(rt.state(), undefined));
26
+ if (head === undefined)
27
+ return;
28
+ if (head.kind === 'approval') {
29
+ rt.emit(setApproval(rt.state(), { ...head.view, ...(behind === 0 ? {} : { pendingCount: behind }) }));
30
+ }
31
+ else {
32
+ rt.emit(setQuestion(rt.state(), head.view));
33
+ }
34
+ };
35
+ /** Remove an entry from the queue (no-op if already gone) and republish. */
36
+ const dequeue = (entry) => {
37
+ const index = modalQueue.indexOf(entry);
38
+ if (index < 0)
39
+ return;
40
+ modalQueue.splice(index, 1);
41
+ publishHead();
42
+ };
43
+ const peekHead = () => modalQueue[0];
44
+ const shiftHead = () => modalQueue.shift();
45
+ const spliceAll = () => modalQueue.splice(0);
46
+ const answerApproval = (kind, deps) => {
47
+ const head = modalQueue[0];
48
+ if (head === undefined || head.kind !== 'approval')
49
+ return;
50
+ // Advance the queue BEFORE resolving: a resolution can immediately fire
51
+ // the next approval/request, which must enqueue behind the survivors.
52
+ modalQueue.shift();
53
+ publishHead();
54
+ head.resolve(kind === 'reject' ? 'rejected' : 'allowed-once');
55
+ if (kind === 'always') {
56
+ // Fire-and-forget: the call proceeds while the rule persists; a write
57
+ // failure surfaces as a notice, never as an answer error.
58
+ void deps.writeAllowRule(head.view.toolName, head.view.preview).catch((error) => {
59
+ const message = error instanceof Error ? error.message : String(error);
60
+ deps.showNotice(`Allowed once only — saving the allow rule failed: ${message}`);
61
+ });
62
+ }
63
+ if (kind === 'session') {
64
+ // Fire-and-forget like 'always': the call proceeds while the derived
65
+ // rule is granted to the requesting session's allowlist (WS4-PR-B,
66
+ // never global settings); a failure surfaces as a notice.
67
+ try {
68
+ deps.addSessionRule(head.agent, head.view.toolName, head.view.preview);
69
+ }
70
+ catch (error) {
71
+ const message = error instanceof Error ? error.message : String(error);
72
+ deps.showNotice(`Allowed once only — adding the session rule failed: ${message}`);
73
+ }
74
+ }
75
+ };
76
+ return { push: (e) => modalQueue.push(e), dequeue, publishHead, shiftHead, peekHead, spliceAll, answerApproval };
77
+ }
78
+ //# sourceMappingURL=driver-modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-modal.js","sourceRoot":"","sources":["../../src/harness/driver-modal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Plan/mode switching cluster for the in-process driver: the `/plan` channel
3
+ * seam and permission-mode cycling. Verbatim extraction from harness/driver.ts
4
+ * (applyMode / applyModeInner / cyclePermissionMode), reading shared state
5
+ * through a DriverModeCtx instead of createDriver's closures.
6
+ *
7
+ * Plan is owned by plan-mode inside the preset's isolate realm; the ONLY
8
+ * cross-plane write seam is the `/plan` command channel — dispatched bare,
9
+ * never '/plan on' (the upstream handler steers any non-'off' argument into
10
+ * the conversation as a user message).
11
+ * @module @dsh-cc/tui/harness/driver-mode
12
+ */
13
+ import type { Agent } from '@deepseek-ai/dsh-agent';
14
+ import { type PermissionCommandMode } from '../mode-cycle.ts';
15
+ import type { TuiState } from '../store.ts';
16
+ import type { DriverModeCtx } from './driver-ctx.ts';
17
+ /** Returns the current permission-rules engine's setMode seam (duck-typed). */
18
+ type PermissionRulesSeam = {
19
+ setMode(agent: Agent, mode: string): void;
20
+ };
21
+ /**
22
+ * Free-function collaborator implementing the plan/mode writepath. Reads all
23
+ * shared state/functions off `rt` (DriverModeCtx) so it never imports the
24
+ * createDriver factory. `modeWrites` is a serialization gate held here; each
25
+ * call chains onto the previous write so concurrent mode switches cannot
26
+ * interleave.
27
+ */
28
+ export declare function createModeSection(rt: DriverModeCtx): {
29
+ applyMode(mode: PermissionCommandMode): void;
30
+ cyclePermissionMode(): Promise<void>;
31
+ get modeWrites(): Promise<void>;
32
+ };
33
+ export type { PermissionRulesSeam };
34
+ export type { TuiState };
35
+ //# sourceMappingURL=driver-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-mode.d.ts","sourceRoot":"","sources":["../../src/harness/driver-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAwC,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAGnG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,+EAA+E;AAC/E,KAAK,mBAAmB,GAAG;IAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAExE;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,aAAa,GAAG;IACpD,SAAS,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,CAAA;IAC5C,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,IAAI,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAChC,CA8DA;AAED,YAAY,EAAE,mBAAmB,EAAE,CAAA;AACnC,YAAY,EAAE,QAAQ,EAAE,CAAA"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Plan/mode switching cluster for the in-process driver: the `/plan` channel
3
+ * seam and permission-mode cycling. Verbatim extraction from harness/driver.ts
4
+ * (applyMode / applyModeInner / cyclePermissionMode), reading shared state
5
+ * through a DriverModeCtx instead of createDriver's closures.
6
+ *
7
+ * Plan is owned by plan-mode inside the preset's isolate realm; the ONLY
8
+ * cross-plane write seam is the `/plan` command channel — dispatched bare,
9
+ * never '/plan on' (the upstream handler steers any non-'off' argument into
10
+ * the conversation as a user message).
11
+ * @module @dsh-cc/tui/harness/driver-mode
12
+ */
13
+ import { isPermissionMode, nextPermissionMode } from "../mode-cycle.js";
14
+ import { PERMISSION_COMMAND_MODES, planPhaseOf } from '@dsh-cc/command-permissions';
15
+ import { setPermissionMode } from "../store.js";
16
+ /**
17
+ * Free-function collaborator implementing the plan/mode writepath. Reads all
18
+ * shared state/functions off `rt` (DriverModeCtx) so it never imports the
19
+ * createDriver factory. `modeWrites` is a serialization gate held here; each
20
+ * call chains onto the previous write so concurrent mode switches cannot
21
+ * interleave.
22
+ */
23
+ export function createModeSection(rt) {
24
+ let modeWrites = Promise.resolve();
25
+ const applyMode = (mode) => {
26
+ modeWrites = modeWrites.then(() => applyModeInner(mode)).catch((error) => {
27
+ rt.showNotice(error instanceof Error ? error.message : String(error));
28
+ });
29
+ };
30
+ const applyModeInner = async (mode) => {
31
+ if (mode === 'plan') {
32
+ const result = await rt.runHarness('/plan');
33
+ if (result === undefined)
34
+ rt.showNotice('plan mode is not mounted in this composition');
35
+ // No optimistic emit: the display re-folds from the committed plan/mode
36
+ // event (see the session/event listener), so a queued mid-turn entry
37
+ // stays truthful until it applies.
38
+ return;
39
+ }
40
+ const phase = planPhaseOf(rt.current.agent.session.events, rt.projections?.stateOf(rt.current.agent.session, 'plan'));
41
+ if (phase !== 'off') {
42
+ const exit = await rt.runHarness('/plan off');
43
+ if (exit === null)
44
+ return; // no command registry — runHarness already noticed
45
+ if (exit === undefined) {
46
+ rt.showNotice('plan mode is not mounted in this composition');
47
+ return;
48
+ }
49
+ // A failed exit must not strand the switch half-done.
50
+ if (exit.kind === 'error')
51
+ return;
52
+ }
53
+ const rules = rt.getRules();
54
+ if (rules === undefined) {
55
+ rt.showNotice('The permission-rules engine is not mounted in this composition.');
56
+ return;
57
+ }
58
+ rules.setMode(rt.current.agent, mode);
59
+ // rebind-proof: emit reassigns createDriver's `state`, so read through the
60
+ // getter for a fresh snapshot to drive setPermissionMode.
61
+ const live = rt.state();
62
+ rt.emit(setPermissionMode(live, mode));
63
+ };
64
+ return {
65
+ applyMode,
66
+ cyclePermissionMode() {
67
+ // F1: the cycle start follows the live settings default when no fold
68
+ // exists — but a settings defaultMode outside PERMISSION_COMMAND_MODES
69
+ // must not become the start (one Tab press would never reach it and the
70
+ // shown mode would be "lost"), so clamp non-members to 'default' first.
71
+ const live = rt.liveMode(rt.current.agent);
72
+ const start = isPermissionMode(live) ? live : 'default';
73
+ const next = nextPermissionMode(start);
74
+ if (!PERMISSION_COMMAND_MODES.includes(next))
75
+ return modeWrites;
76
+ applyMode(next);
77
+ return modeWrites;
78
+ },
79
+ get modeWrites() {
80
+ return modeWrites;
81
+ },
82
+ };
83
+ }
84
+ //# sourceMappingURL=driver-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-mode.js","sourceRoot":"","sources":["../../src/harness/driver-mode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Model / effort / permission pickers for the in-process driver. Verbatim
3
+ * extraction from harness/driver.ts (openModelPicker / applyModelSwitch /
4
+ * openEffortPicker / openPermissionPicker plus the return-literal picker
5
+ * bodies), reading shared state through a DriverPickersCtx instead of
6
+ * createDriver's closures.
7
+ *
8
+ * The pickers are stateless overlays: each open parks picker state and each
9
+ * submit reads-then-closes before validating. The bare model switch writes
10
+ * synchronously; a carried effort validates detached via resolveEfforts /
11
+ * stalePair, kept in createDriver and passed in.
12
+ * @module @dsh-cc/tui/harness/driver-pickers
13
+ */
14
+ import { type TuiState } from '../store.ts';
15
+ import { type CatalogEntry } from '../model-catalog.ts';
16
+ import type { DriverPickersCtx } from './driver-ctx.ts';
17
+ /** A single selection route, matching what selection.current holds. */
18
+ type SelectionRoute = {
19
+ provider: string;
20
+ model: string;
21
+ reasoningEffort?: string;
22
+ };
23
+ /**
24
+ * Free-function collaborator implementing the three pickers. Reads all shared
25
+ * state/functions off `rt` (DriverPickersCtx) so it never imports the
26
+ * createDriver factory. `selection` is passed by reference so writes land on
27
+ * createDriver's live ref across switchSession; resolveEfforts / stalePair /
28
+ * loadCatalog stay in createDriver and arrive on the ctx.
29
+ */
30
+ export declare function createPickersSection(rt: DriverPickersCtx): {
31
+ openModelPicker(): Promise<void>;
32
+ applyModelSwitch(provider: string, model: string): Promise<void>;
33
+ openEffortPicker(): Promise<void>;
34
+ openPermissionPicker(): void;
35
+ modelPickerMove(delta: -1 | 1): void;
36
+ modelPickerSubmit(): Promise<void>;
37
+ modelPickerCancel(): void;
38
+ effortPickerMove(delta: -1 | 1): void;
39
+ effortPickerSubmit(): Promise<void>;
40
+ effortPickerCancel(): void;
41
+ permissionPickerMove(delta: -1 | 1): void;
42
+ permissionPickerSubmit(): Promise<void>;
43
+ permissionPickerCancel(): void;
44
+ loadModelCatalog(): Promise<CatalogEntry[]>;
45
+ loadModelEfforts(): Promise<string[]>;
46
+ };
47
+ export type { SelectionRoute, CatalogEntry, TuiState };
48
+ //# sourceMappingURL=driver-pickers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver-pickers.d.ts","sourceRoot":"","sources":["../../src/harness/driver-pickers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EASL,KAAK,QAAQ,EACd,MAAM,aAAa,CAAA;AACpB,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAEvD,uEAAuE;AACvE,KAAK,cAAc,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,gBAAgB,GAAG;IAC1D,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAChC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,oBAAoB,IAAI,IAAI,CAAA;IAC5B,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACpC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,iBAAiB,IAAI,IAAI,CAAA;IACzB,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACrC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC,kBAAkB,IAAI,IAAI,CAAA;IAC1B,oBAAoB,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACzC,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,sBAAsB,IAAI,IAAI,CAAA;IAC9B,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;IAC3C,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CACtC,CAyNA;AAED,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAA"}