@pellux/goodvibes-tui 2.0.21 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/CHANGELOG.md +65 -1
  2. package/README.md +30 -29
  3. package/docs/README.md +8 -5
  4. package/docs/foundation-artifacts/operator-contract.json +1 -1
  5. package/package.json +28 -19
  6. package/src/cli/management.ts +5 -2
  7. package/src/cli/tui-startup.ts +34 -39
  8. package/src/core/agent-view-render.ts +157 -0
  9. package/src/core/approval-alert.ts +49 -11
  10. package/src/core/bookmark-navigation.ts +7 -1
  11. package/src/core/budget-breach-notifier.ts +27 -8
  12. package/src/core/compaction-receipt.ts +1 -1
  13. package/src/core/context-usage.ts +1 -1
  14. package/src/core/conversation-compaction-render.ts +3 -3
  15. package/src/core/conversation-display-only.ts +86 -0
  16. package/src/core/conversation-event-navigation.ts +27 -0
  17. package/src/core/conversation-line-cache.ts +216 -447
  18. package/src/core/conversation-render-context.ts +20 -27
  19. package/src/core/conversation-rendering.ts +157 -575
  20. package/src/core/conversation-splash-state.ts +6 -1
  21. package/src/core/conversation-types.ts +35 -0
  22. package/src/core/conversation-usage.ts +12 -0
  23. package/src/core/conversation.ts +130 -131
  24. package/src/core/long-task-notifier.ts +100 -31
  25. package/src/core/notices.ts +75 -0
  26. package/src/core/pairing-tailscale-gateway.ts +1 -1
  27. package/src/core/process-output-log.ts +143 -0
  28. package/src/core/rewind-receipt.ts +1 -1
  29. package/src/core/session-focus.ts +190 -0
  30. package/src/core/session-resume-core.ts +23 -81
  31. package/src/core/stream-event-wiring.ts +31 -5
  32. package/src/core/system-message-noise.ts +2 -2
  33. package/src/core/system-message-router.ts +16 -18
  34. package/src/core/turn-event-wiring.ts +272 -33
  35. package/src/core/work-tree-focus.ts +290 -0
  36. package/src/core/work-tree-fold-store.ts +143 -0
  37. package/src/core/work-tree-model.ts +799 -0
  38. package/src/core/work-tree-render.ts +384 -0
  39. package/src/core/work-tree-sources.ts +184 -0
  40. package/src/core/work-tree-wiring.ts +176 -0
  41. package/src/core/workstream-notification.ts +36 -6
  42. package/src/core/wrfc-notice-titles.ts +37 -0
  43. package/src/input/agents-modal-text.ts +119 -0
  44. package/src/input/agents-modal.ts +699 -0
  45. package/src/input/bookmark-modal.ts +33 -9
  46. package/src/input/changes-git.ts +251 -0
  47. package/src/input/changes-modal.ts +629 -0
  48. package/src/input/changes-model.ts +125 -0
  49. package/src/input/command-palette-types.ts +41 -0
  50. package/src/input/command-palette.ts +272 -0
  51. package/src/input/command-reference.ts +2 -2
  52. package/src/input/command-registry.ts +77 -35
  53. package/src/input/commands/acp-runtime.ts +19 -9
  54. package/src/input/commands/channel-runtime.ts +2 -2
  55. package/src/input/commands/ci-runtime.ts +1 -1
  56. package/src/input/commands/codebase-runtime.ts +1 -1
  57. package/src/input/commands/config.ts +7 -1
  58. package/src/input/commands/context-window.ts +25 -19
  59. package/src/input/commands/control-room-runtime.ts +18 -18
  60. package/src/input/commands/conversation-runtime.ts +0 -1
  61. package/src/input/commands/cost-runtime.ts +29 -20
  62. package/src/input/commands/diff-runtime.ts +35 -181
  63. package/src/input/commands/eval.ts +1 -1
  64. package/src/input/commands/experience-runtime.ts +3 -7
  65. package/src/input/commands/fresh-conversation.ts +86 -0
  66. package/src/input/commands/git-runtime.ts +5 -22
  67. package/src/input/commands/graph-runtime.ts +1 -1
  68. package/src/input/commands/guidance-runtime.ts +1 -1
  69. package/src/input/commands/health-runtime.ts +8 -9
  70. package/src/input/commands/hooks-runtime.ts +2 -2
  71. package/src/input/commands/hosted-runtime.ts +3 -3
  72. package/src/input/commands/incident-runtime.ts +3 -3
  73. package/src/input/commands/intelligence-runtime.ts +6 -9
  74. package/src/input/commands/knowledge.ts +2 -2
  75. package/src/input/commands/legacy-panel-command.ts +57 -0
  76. package/src/input/commands/local-auth-runtime.ts +8 -9
  77. package/src/input/commands/local-provider-runtime.ts +7 -4
  78. package/src/input/commands/local-runtime.ts +12 -15
  79. package/src/input/commands/local-setup-review.ts +1 -1
  80. package/src/input/commands/local-setup.ts +13 -19
  81. package/src/input/commands/memory.ts +1 -1
  82. package/src/input/commands/notify-runtime.ts +9 -0
  83. package/src/input/commands/operator-runtime.ts +10 -12
  84. package/src/input/commands/permissions-provenance.ts +3 -3
  85. package/src/input/commands/planning-runtime.ts +7 -7
  86. package/src/input/commands/platform-sandbox-runtime.ts +2 -2
  87. package/src/input/commands/platform-services-runtime.ts +1 -1
  88. package/src/input/commands/policy-dispatch.ts +2 -2
  89. package/src/input/commands/policy.ts +3 -3
  90. package/src/input/commands/provider.ts +1 -1
  91. package/src/input/commands/remote-runtime.ts +1 -1
  92. package/src/input/commands/review-runtime.ts +39 -94
  93. package/src/input/commands/rewind-runtime.ts +81 -108
  94. package/src/input/commands/runtime-services.ts +15 -17
  95. package/src/input/commands/services-runtime.ts +2 -2
  96. package/src/input/commands/session-content.ts +21 -5
  97. package/src/input/commands/session-workflow.ts +13 -38
  98. package/src/input/commands/settings-sync-runtime.ts +2 -2
  99. package/src/input/commands/shell-core.ts +19 -4
  100. package/src/input/commands/skills-runtime.ts +2 -2
  101. package/src/input/commands/status-runtime.ts +13 -0
  102. package/src/input/commands/subscription-runtime.ts +1 -1
  103. package/src/input/commands/tasks-runtime.ts +2 -8
  104. package/src/input/commands/work-plan-runtime.ts +4 -4
  105. package/src/input/commands/workstream-attempts.ts +24 -47
  106. package/src/input/commands/workstream-runtime.ts +2 -2
  107. package/src/input/commands/worktree-runtime.ts +3 -3
  108. package/src/input/commands.ts +3 -1
  109. package/src/input/composer-editor.ts +44 -0
  110. package/src/input/concealed-input.ts +1 -1
  111. package/src/input/config-modal-types.ts +20 -8
  112. package/src/input/config-modal.ts +106 -105
  113. package/src/input/confirm-dialog-types.ts +28 -0
  114. package/src/input/confirm-dialog.ts +70 -0
  115. package/src/input/delete-key-policy.ts +3 -3
  116. package/src/input/feed-context-factory.ts +15 -16
  117. package/src/input/handler-command-route.ts +7 -42
  118. package/src/input/handler-content-actions.ts +16 -15
  119. package/src/input/handler-feed-routes.ts +26 -211
  120. package/src/input/handler-feed.ts +68 -95
  121. package/src/input/handler-interactions.ts +5 -3
  122. package/src/input/handler-modal-routes.ts +215 -216
  123. package/src/input/handler-modal-stack.ts +81 -11
  124. package/src/input/handler-modal-token-routes.ts +4 -0
  125. package/src/input/handler-onboarding.ts +0 -1
  126. package/src/input/handler-picker-routes.ts +65 -107
  127. package/src/input/handler-session-view-route.ts +149 -0
  128. package/src/input/handler-shortcuts.ts +16 -154
  129. package/src/input/handler-types.ts +4 -2
  130. package/src/input/handler-ui-state.ts +45 -15
  131. package/src/input/handler-work-tree-route.ts +123 -0
  132. package/src/input/handler.ts +25 -70
  133. package/src/input/keybindings.ts +16 -71
  134. package/src/input/masked-entry-modal.ts +117 -0
  135. package/src/input/mcp-workspace.ts +48 -17
  136. package/src/input/model-picker-filter.ts +8 -0
  137. package/src/input/model-picker-open.ts +99 -0
  138. package/src/input/model-picker-types.ts +1 -1
  139. package/src/input/model-picker.ts +92 -9
  140. package/src/input/notifications-modal.ts +123 -0
  141. package/src/input/overlay-filter.ts +26 -0
  142. package/src/input/profile-picker-modal.ts +37 -8
  143. package/src/input/search.ts +3 -3
  144. package/src/input/selection-modal-queue.ts +2 -0
  145. package/src/input/selection-modal.ts +28 -16
  146. package/src/input/session-picker-modal.ts +33 -8
  147. package/src/input/settings-modal-activation.ts +7 -2
  148. package/src/input/settings-modal-data.ts +11 -6
  149. package/src/input/settings-modal-types.ts +1 -1
  150. package/src/input/settings-modal.ts +20 -20
  151. package/src/input/submission-intent.ts +1 -1
  152. package/src/input/submission-router.ts +4 -9
  153. package/src/input/surface-modal-host.ts +110 -0
  154. package/src/input/theme-settings-actions.ts +82 -0
  155. package/src/input/usage-modal.ts +183 -0
  156. package/src/input/views.ts +97 -0
  157. package/src/main.ts +175 -165
  158. package/src/permissions/hunk-selection.ts +1 -1
  159. package/src/permissions/prompt-card.ts +511 -0
  160. package/src/permissions/prompt.ts +59 -622
  161. package/src/renderer/agents-modal.ts +310 -0
  162. package/src/renderer/autocomplete-overlay.ts +42 -220
  163. package/src/renderer/back-to-bottom.ts +80 -0
  164. package/src/renderer/block-actions-overlay.ts +30 -48
  165. package/src/renderer/bookmark-modal.ts +48 -79
  166. package/src/renderer/changes-modal.ts +325 -0
  167. package/src/renderer/code-block.ts +184 -106
  168. package/src/renderer/command-palette.ts +93 -0
  169. package/src/renderer/composer-fragments.ts +4 -4
  170. package/src/renderer/composer.ts +146 -0
  171. package/src/renderer/compositor.ts +26 -160
  172. package/src/renderer/config-modal.ts +185 -81
  173. package/src/renderer/confirm-dialog.ts +50 -0
  174. package/src/renderer/context-inspector.ts +116 -154
  175. package/src/renderer/context-status-hint.ts +4 -4
  176. package/src/renderer/conversation-layout.ts +20 -0
  177. package/src/renderer/conversation-overlays.ts +94 -84
  178. package/src/renderer/conversation-surface.ts +19 -38
  179. package/src/renderer/diff-tint.ts +98 -0
  180. package/src/renderer/file-picker-overlay.ts +63 -90
  181. package/src/renderer/footer-targets.ts +38 -0
  182. package/src/renderer/git-status.ts +3 -4
  183. package/src/renderer/header-line.ts +140 -117
  184. package/src/renderer/help-overlay.ts +133 -219
  185. package/src/renderer/history-search-overlay.ts +15 -12
  186. package/src/renderer/lane-graph/bead.ts +800 -0
  187. package/src/renderer/lane-graph/glyphs.ts +134 -0
  188. package/src/renderer/lane-graph/layout.ts +248 -0
  189. package/src/renderer/lane-graph/paint.ts +537 -0
  190. package/src/renderer/lane-graph/semantic-memo.ts +77 -0
  191. package/src/renderer/layout-engine.ts +2 -57
  192. package/src/renderer/layout.ts +7 -13
  193. package/src/renderer/markdown-inline.ts +2 -1
  194. package/src/renderer/markdown-table.ts +17 -12
  195. package/src/renderer/markdown.ts +92 -34
  196. package/src/renderer/masked-entry-modal.ts +78 -0
  197. package/src/renderer/mcp-workspace.ts +166 -203
  198. package/src/renderer/model-workspace.ts +381 -436
  199. package/src/renderer/notifications-modal.ts +116 -0
  200. package/src/renderer/onboarding/onboarding-wizard.ts +178 -588
  201. package/src/renderer/process-view.ts +192 -0
  202. package/src/renderer/profile-picker-modal.ts +58 -110
  203. package/src/renderer/search-overlay.ts +6 -3
  204. package/src/renderer/selection-modal-overlay.ts +87 -327
  205. package/src/renderer/semantic-diff.ts +2 -2
  206. package/src/renderer/session-chips.ts +102 -0
  207. package/src/renderer/session-picker-modal.ts +177 -297
  208. package/src/renderer/settings-modal-connections.ts +14 -23
  209. package/src/renderer/settings-modal-context.ts +367 -0
  210. package/src/renderer/settings-modal-helpers.ts +6 -11
  211. package/src/renderer/settings-modal.ts +322 -726
  212. package/src/renderer/shell-surface.ts +277 -175
  213. package/src/renderer/shortcuts-overlay.ts +217 -0
  214. package/src/renderer/status-line.ts +475 -0
  215. package/src/renderer/surface-compose.ts +174 -0
  216. package/src/renderer/surface-kit-extra.ts +303 -0
  217. package/src/renderer/surface-kit-list.ts +366 -0
  218. package/src/renderer/surface-kit-parts.ts +360 -0
  219. package/src/renderer/surface-kit.ts +568 -0
  220. package/src/renderer/syntax-highlighter.ts +280 -197
  221. package/src/renderer/syntax-theme.ts +51 -0
  222. package/src/renderer/system-message.ts +0 -1
  223. package/src/renderer/term-caps.ts +42 -1
  224. package/src/renderer/terminal-bg-probe.ts +116 -19
  225. package/src/renderer/terminal-palette-probe.ts +322 -0
  226. package/src/renderer/terminal-palette-reader.ts +183 -0
  227. package/src/renderer/terminal-palette.ts +58 -0
  228. package/src/renderer/theme-mode-config.ts +16 -1
  229. package/src/renderer/theme.ts +234 -207
  230. package/src/renderer/thinking.ts +0 -1
  231. package/src/renderer/throbber.ts +188 -0
  232. package/src/renderer/toast-center.ts +119 -0
  233. package/src/renderer/ui-factory.ts +39 -602
  234. package/src/renderer/ui-primitives.ts +8 -25
  235. package/src/renderer/usage-modal.ts +353 -0
  236. package/src/renderer/user-message.ts +58 -0
  237. package/src/renderer/voice-capture-chip.ts +53 -0
  238. package/src/runtime/bootstrap-command-context.ts +0 -5
  239. package/src/runtime/bootstrap-command-parts.ts +38 -89
  240. package/src/runtime/bootstrap-core.ts +13 -15
  241. package/src/runtime/bootstrap-hook-bridge.ts +12 -21
  242. package/src/runtime/bootstrap-notifier-sync.ts +17 -1
  243. package/src/runtime/bootstrap-shell.ts +16 -50
  244. package/src/runtime/bootstrap.ts +14 -14
  245. package/src/runtime/client/fleet-union.ts +5 -5
  246. package/src/runtime/client/hosted-exit.ts +2 -2
  247. package/src/runtime/client/hosted-sessions.ts +1 -1
  248. package/src/runtime/client/spine-adoption.ts +1 -1
  249. package/src/runtime/context-accounting-source.ts +5 -4
  250. package/src/runtime/index.ts +1 -0
  251. package/src/runtime/notification-dispatch.ts +102 -29
  252. package/src/runtime/recovery-offer-wiring.ts +4 -1
  253. package/src/runtime/recovery-prompt.ts +31 -15
  254. package/src/runtime/runtime-services-types.ts +10 -6
  255. package/src/runtime/services.ts +17 -12
  256. package/src/runtime/session-continuity-hints.ts +2 -5
  257. package/src/runtime/session-inbound-inputs.ts +1 -1
  258. package/src/runtime/session-resume-liveness-confirm.ts +14 -2
  259. package/src/runtime/startup-typeahead-gate.ts +103 -0
  260. package/src/runtime/store/domains/domain-read-matrix.ts +0 -1
  261. package/src/runtime/store/domains/index.ts +0 -8
  262. package/src/runtime/store/selectors/index.ts +0 -28
  263. package/src/runtime/store/state.ts +0 -8
  264. package/src/runtime/ui-services.ts +4 -6
  265. package/src/runtime/usage-tracker.ts +348 -0
  266. package/src/runtime/wrfc-persistence.ts +4 -4
  267. package/src/shell/blocking-input.ts +92 -2
  268. package/src/shell/recovery-input-helpers.ts +1 -1
  269. package/src/shell/session-views.ts +539 -0
  270. package/src/shell/status-report.ts +86 -0
  271. package/src/shell/transcript-scroll.ts +68 -0
  272. package/src/shell/ui-openers.ts +84 -172
  273. package/src/shell/view-openers.ts +205 -0
  274. package/src/tools/wrfc-agent-guard.ts +22 -2
  275. package/src/utils/format-duration.ts +4 -8
  276. package/src/utils/splash-lines.ts +9 -1
  277. package/src/utils/terminal-width.ts +56 -0
  278. package/src/verification/live-verifier.ts +0 -10
  279. package/src/version.ts +1 -1
  280. package/src/{panels → views}/agent-inspector-shared.ts +2 -2
  281. package/src/{panels → views}/builtin-modals.ts +22 -21
  282. package/src/views/builtin-views.ts +135 -0
  283. package/src/{panels → views}/confirm-state.ts +9 -9
  284. package/src/{panels → views}/diff-review-model.ts +10 -3
  285. package/src/{panels → views}/eval-registry.ts +1 -1
  286. package/src/{panels → views}/fleet-acts.ts +49 -85
  287. package/src/{panels/fleet-panel-format.ts → views/fleet-format.ts} +40 -40
  288. package/src/{panels → views}/fleet-gateway.ts +5 -5
  289. package/src/{panels → views}/fleet-observed-render.ts +16 -16
  290. package/src/{panels → views}/fleet-read-model.ts +9 -9
  291. package/src/{panels/fleet-tabs.ts → views/fleet-session-tabs.ts} +13 -13
  292. package/src/{panels → views}/fleet-spawn.ts +33 -49
  293. package/src/{panels → views}/fleet-steer.ts +12 -12
  294. package/src/{panels → views}/fleet-stop.ts +4 -4
  295. package/src/{panels → views}/fleet-transcript.ts +26 -27
  296. package/src/{panels/fleet-panel-worktree-detail.ts → views/fleet-worktree-detail.ts} +7 -7
  297. package/src/{panels → views}/hosted-session-feed.ts +6 -6
  298. package/src/views/modal-surface-registry.ts +41 -0
  299. package/src/{panels → views}/modals/devices-modal.ts +2 -2
  300. package/src/{panels → views}/modals/hooks-modal.ts +13 -13
  301. package/src/{panels → views}/modals/keybindings-modal.ts +19 -27
  302. package/src/{panels → views}/modals/knowledge-modal.ts +6 -5
  303. package/src/{panels → views}/modals/local-auth-modal.ts +22 -21
  304. package/src/{panels → views}/modals/marketplace-modal.ts +11 -11
  305. package/src/{panels → views}/modals/memory-modal.ts +8 -8
  306. package/src/{panels → views}/modals/modal-surface-helpers.ts +15 -5
  307. package/src/{panels → views}/modals/pairing-modal.ts +9 -9
  308. package/src/{panels → views}/modals/planning-modal.ts +15 -20
  309. package/src/{panels → views}/modals/plugins-modal.ts +6 -6
  310. package/src/{panels → views}/modals/policy-modal.ts +13 -5
  311. package/src/{panels → views}/modals/provider-health-modal.ts +4 -4
  312. package/src/{panels → views}/modals/remote-modal.ts +3 -3
  313. package/src/{panels → views}/modals/sandbox-modal.ts +4 -4
  314. package/src/{panels → views}/modals/security-modal.ts +22 -16
  315. package/src/{panels → views}/modals/services-modal.ts +3 -3
  316. package/src/{panels → views}/modals/settings-sync-modal.ts +4 -4
  317. package/src/{panels → views}/modals/skills-modal.ts +9 -9
  318. package/src/{panels → views}/modals/subscription-modal.ts +3 -3
  319. package/src/{panels → views}/modals/work-plan-modal.ts +10 -13
  320. package/src/views/notifications-feed.ts +314 -0
  321. package/src/{panels → views}/polish-core.ts +38 -36
  322. package/src/{panels → views}/polish-tables.ts +35 -26
  323. package/src/{panels → views}/polish.ts +101 -95
  324. package/src/{panels → views}/project-planning-answer-actions.ts +3 -3
  325. package/src/{panels → views}/provider-health-routes.ts +14 -14
  326. package/src/{panels → views}/search-focus.ts +8 -8
  327. package/src/{panels → views}/session-maintenance.ts +11 -11
  328. package/src/views/skills-discovery.ts +159 -0
  329. package/src/views/view-deps.ts +80 -0
  330. package/src/views/view-panel-adapter.ts +53 -0
  331. package/src/{panels → views}/workstream-graph-render.ts +1 -1
  332. package/src/core/conversation-fold.ts +0 -101
  333. package/src/core/conversation-turn-structure.ts +0 -464
  334. package/src/core/conversation-user-receipts.ts +0 -42
  335. package/src/input/commands/operator-panel-runtime.ts +0 -186
  336. package/src/input/panel-integration-actions.ts +0 -33
  337. package/src/input/panel-mouse-geometry.ts +0 -97
  338. package/src/input/panel-paste-flood-guard.ts +0 -86
  339. package/src/panels/base-panel.ts +0 -301
  340. package/src/panels/builtin/agent.ts +0 -27
  341. package/src/panels/builtin/development.ts +0 -92
  342. package/src/panels/builtin/knowledge.ts +0 -12
  343. package/src/panels/builtin/operations.ts +0 -177
  344. package/src/panels/builtin/session.ts +0 -81
  345. package/src/panels/builtin/shared.ts +0 -357
  346. package/src/panels/builtin-panels.ts +0 -28
  347. package/src/panels/cost-tracker-panel.ts +0 -746
  348. package/src/panels/diff-panel.ts +0 -797
  349. package/src/panels/diff-review-panel.ts +0 -395
  350. package/src/panels/expandable-list-panel.ts +0 -189
  351. package/src/panels/fleet-deep-link.ts +0 -31
  352. package/src/panels/fleet-panel.ts +0 -799
  353. package/src/panels/git-panel.ts +0 -800
  354. package/src/panels/hosted-session-panel.ts +0 -221
  355. package/src/panels/index.ts +0 -21
  356. package/src/panels/local-auth-panel.ts +0 -478
  357. package/src/panels/notifications-feed.ts +0 -127
  358. package/src/panels/notifications-panel.ts +0 -160
  359. package/src/panels/panel-confirm-overlay.ts +0 -72
  360. package/src/panels/panel-manager.ts +0 -791
  361. package/src/panels/plugins-panel.ts +0 -371
  362. package/src/panels/scrollable-list-panel.ts +0 -498
  363. package/src/panels/skills-panel.ts +0 -454
  364. package/src/panels/token-budget-panel.ts +0 -688
  365. package/src/panels/types.ts +0 -191
  366. package/src/panels/wrfc-panel-format.ts +0 -133
  367. package/src/renderer/diff-view.ts +0 -134
  368. package/src/renderer/fleet-tab-strip.ts +0 -56
  369. package/src/renderer/footer-tips.ts +0 -53
  370. package/src/renderer/fullscreen-primitives.ts +0 -146
  371. package/src/renderer/fullscreen-workspace.ts +0 -194
  372. package/src/renderer/hint-grammar.ts +0 -52
  373. package/src/renderer/modal-factory.ts +0 -480
  374. package/src/renderer/overlay-box.ts +0 -154
  375. package/src/renderer/overlay-viewport.ts +0 -104
  376. package/src/renderer/panel-composite.ts +0 -145
  377. package/src/renderer/panel-workspace-bar.ts +0 -54
  378. package/src/renderer/process-indicator.ts +0 -163
  379. package/src/renderer/tab-strip.ts +0 -222
  380. package/src/renderer/text-layout.ts +0 -31
  381. package/src/renderer/tool-call.ts +0 -276
  382. package/src/renderer/tool-result-expanded-lines.ts +0 -48
  383. package/src/renderer/tool-result-summary.ts +0 -219
  384. package/src/runtime/diagnostics/panels/index.ts +0 -21
  385. package/src/runtime/diagnostics/panels/ops.ts +0 -156
  386. package/src/runtime/perf/panel-contracts.ts +0 -32
  387. package/src/runtime/store/domains/panels.ts +0 -117
  388. package/src/verification/verification-ledger.ts +0 -707
  389. /package/src/{panels → views}/memory-consolidation-gateway.ts +0 -0
  390. /package/src/{panels → views}/modals/modal-theme.ts +0 -0
  391. /package/src/{panels → views}/provider-health-domains.ts +0 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * lane-graph/glyphs.ts, the characters the conversation work tree draws with.
3
+ *
4
+ * The layout (layout.ts) speaks in ROLES ("a vertical lane line", "the corner
5
+ * where a lane merges back"); this module turns a role into a character for
6
+ * the chosen set, so the same layout draws rounded, square or ascii without a
7
+ * second code path.
8
+ *
9
+ * `display.treeGlyphs` picks the set. A terminal the capability probe reports
10
+ * as limited (TERM=dumb, NO_COLOR, or a locale without UTF-8) draws ascii no
11
+ * matter what the setting says, because box drawing on such a terminal prints
12
+ * as garbage.
13
+ */
14
+
15
+ export type TreeGlyphSetName = 'rounded' | 'square' | 'ascii';
16
+
17
+ const TREE_GLYPH_SET_NAMES: readonly TreeGlyphSetName[] = ['rounded', 'square', 'ascii'];
18
+
19
+ /** Every drawing role the lane layout emits. */
20
+ export type LaneGlyphRole =
21
+ | 'vert' // │ a lane running down
22
+ | 'horiz' // ─ a horizontal run between lanes
23
+ | 'branch' // ├ where a lane leaves its parent, or merges back into it
24
+ | 'cross' // ┼ a horizontal run crossing a live lane
25
+ | 'open' // ╮ where a new lane starts
26
+ | 'merge' // ╯ where a lane ends into its parent
27
+ | 'head' // ╭ the top of a turn's spine
28
+ | 'close' // ╰ the end of a turn's spine (the answer row)
29
+ | 'folded' // ◉ a finished lane folded to one bead
30
+ | 'turn'; // ◆ a folded turn's header
31
+
32
+ export interface LaneGlyphs {
33
+ readonly name: TreeGlyphSetName;
34
+ readonly role: Readonly<Record<LaneGlyphRole, string>>;
35
+ /** Bead marks, one per status. `run` is the spinner's frames. */
36
+ readonly ok: string;
37
+ readonly warn: string;
38
+ readonly err: string;
39
+ readonly run: readonly string[];
40
+ readonly wait: string;
41
+ readonly cancel: string;
42
+ readonly background: string;
43
+ /** Body triangles: closed (has a body) and open. */
44
+ readonly closed: string;
45
+ readonly opened: string;
46
+ /** The focused row's edge mark. */
47
+ readonly focus: string;
48
+ /** "↳" linking a WRFC fix to its finding. */
49
+ readonly answers: string;
50
+ /** "…" in "… N more". */
51
+ readonly ellipsis: string;
52
+ /** "·" between summary pieces. */
53
+ readonly dot: string;
54
+ }
55
+
56
+ const ROUNDED: LaneGlyphs = {
57
+ name: 'rounded',
58
+ role: { vert: '│', horiz: '─', branch: '├', cross: '┼', open: '╮', merge: '╯', head: '╭', close: '╰', folded: '◉', turn: '◆' },
59
+ ok: '✓',
60
+ warn: '!',
61
+ err: '✕',
62
+ run: ['◐', '◓', '◑', '◒'],
63
+ wait: '●',
64
+ cancel: '○',
65
+ background: '▶',
66
+ closed: '▸',
67
+ opened: '▾',
68
+ focus: '┃',
69
+ answers: '↳',
70
+ ellipsis: '…',
71
+ dot: '·',
72
+ };
73
+
74
+ const SQUARE: LaneGlyphs = {
75
+ ...ROUNDED,
76
+ name: 'square',
77
+ role: { ...ROUNDED.role, open: '┐', merge: '┘', head: '┌', close: '└', folded: '●' },
78
+ };
79
+
80
+ /**
81
+ * Plain ASCII: | for lanes, + for every junction and corner except the
82
+ * spine's end (`), - for horizontal runs. Beads: * done, ! look at this,
83
+ * x failed, o running, ? waiting on you, . cancelled, > background,
84
+ * @ a folded lane, # a folded turn.
85
+ */
86
+ const ASCII: LaneGlyphs = {
87
+ name: 'ascii',
88
+ role: { vert: '|', horiz: '-', branch: '+', cross: '+', open: '+', merge: '+', head: '+', close: '`', folded: '@', turn: '#' },
89
+ ok: '*',
90
+ warn: '!',
91
+ err: 'x',
92
+ run: ['o', 'O'],
93
+ wait: '?',
94
+ cancel: '.',
95
+ background: '>',
96
+ closed: '>',
97
+ opened: 'v',
98
+ focus: '|',
99
+ answers: '->',
100
+ ellipsis: '...',
101
+ dot: '-',
102
+ };
103
+
104
+ const SETS: Readonly<Record<TreeGlyphSetName, LaneGlyphs>> = { rounded: ROUNDED, square: SQUARE, ascii: ASCII };
105
+
106
+ function isTreeGlyphSetName(value: unknown): value is TreeGlyphSetName {
107
+ return typeof value === 'string' && (TREE_GLYPH_SET_NAMES as readonly string[]).includes(value);
108
+ }
109
+
110
+ /** The glyph set for a name; anything unrecognised draws rounded. */
111
+ export function laneGlyphs(name: TreeGlyphSetName): LaneGlyphs {
112
+ return SETS[name];
113
+ }
114
+
115
+ /**
116
+ * The set to draw with: the configured name, unless the terminal cannot draw
117
+ * unicode, in which case ascii.
118
+ */
119
+ export function resolveTreeGlyphSet(configured: unknown, unicodeCapable: boolean): TreeGlyphSetName {
120
+ if (!unicodeCapable) return 'ascii';
121
+ return isTreeGlyphSetName(configured) ? configured : 'rounded';
122
+ }
123
+
124
+ const ASCII_TEXT: ReadonlyArray<readonly [RegExp, string]> = [
125
+ [/·/g, '-'], [/[−–—]/g, '-'], [/…/g, '...'], [/↳/g, '->'], [/[✓✔]/g, '*'], [/[✕✗]/g, 'x'], [/◈/g, '*'], [/[▸▶]/g, '>'], [/▾/g, 'v'], [/⋯/g, '...'],
126
+ ];
127
+
128
+ /** Row text as the glyph set draws it: plain ASCII for the ascii set, unchanged otherwise. */
129
+ export function glyphText(text: string, glyphs: Pick<LaneGlyphs, 'name'>): string {
130
+ if (glyphs.name !== 'ascii') return text;
131
+ let out = text;
132
+ for (const [pattern, replacement] of ASCII_TEXT) out = out.replace(pattern, replacement);
133
+ return out;
134
+ }
@@ -0,0 +1,248 @@
1
+ /**
2
+ * lane-graph/layout.ts, where every lane of a turn's work tree sits, row by
3
+ * row.
4
+ *
5
+ * A turn is drawn the way `git log --graph` draws history: the turn's own
6
+ * work is a vertical SPINE, a subagent (or a WRFC chain, or a hosted agent)
7
+ * BRANCHES off the lane that started it into a lane of its own, its tool
8
+ * calls are beads on that lane, and it MERGES back into exactly the lane it
9
+ * came from. Lanes that run at the same time sit side by side.
10
+ *
11
+ * Input: the turn's rows in display order, each described only by what it
12
+ * does to the lanes (see LaneEvent). Output: one gutter row per event, made
13
+ * of drawing ROLES (glyphs.ts turns a role into a character), plus the
14
+ * continuation gutter that runs beside anything drawn under that row (wrapped
15
+ * text, an opened bead's body).
16
+ *
17
+ * Geometry: every lane is 2 columns wide, the lane line on the even column,
18
+ * the odd column free for horizontal runs. A new lane takes the lowest free
19
+ * slot to the right of its parent, so a child is always right of its parent
20
+ * and lanes never move sideways once placed. The text column is fixed for the
21
+ * whole turn (see gutterWidthFor) so text never shifts with depth.
22
+ *
23
+ * Everything here is pure: no theme, no width, no glyph set.
24
+ */
25
+
26
+ import type { LaneGlyphRole } from './glyphs.ts';
27
+
28
+ export type LaneId = string;
29
+
30
+ /** The turn's own lane. */
31
+ export const SPINE: LaneId = 'spine';
32
+
33
+ export type LaneEvent =
34
+ /** The turn header: the spine opens with ╭─. */
35
+ | { readonly kind: 'head' }
36
+ /** A folded turn's header: a single ◆, no lane opens. */
37
+ | { readonly kind: 'turn' }
38
+ /** A row with no mark of its own (text): every live lane runs past it. */
39
+ | { readonly kind: 'row' }
40
+ /** A tool call on `lane`: its bead sits on the lane. */
41
+ | { readonly kind: 'bead'; readonly lane: LaneId }
42
+ /** A finished lane folded to one ◉ bead on its parent's lane, in its own color. */
43
+ | { readonly kind: 'folded'; readonly lane: LaneId; readonly child: LaneId }
44
+ /** `lane` branches off `parent` (├─╮). */
45
+ | { readonly kind: 'spawn'; readonly parent: LaneId; readonly lane: LaneId }
46
+ /** `lane` merges back into the lane it came from (├─╯). */
47
+ | { readonly kind: 'merge'; readonly lane: LaneId }
48
+ /** The answer's first row: the spine closes with ╰─. */
49
+ | { readonly kind: 'answer' };
50
+
51
+ /** One drawn cell of a gutter row. `color` is the lane's color index (creation order). */
52
+ export interface GutterCell {
53
+ readonly role: LaneGlyphRole | 'bead';
54
+ readonly color: number;
55
+ }
56
+
57
+ export type GutterRow = ReadonlyArray<GutterCell | null>;
58
+
59
+ export interface LaneLayout {
60
+ /** One gutter row per input event. */
61
+ readonly rows: readonly GutterRow[];
62
+ /** The gutter under each event's row: every lane still live after it, as │. */
63
+ readonly cont: readonly GutterRow[];
64
+ /** Column (within the gutter) of the row's bead, ◉, ◆ or the lane end the row is about. */
65
+ readonly markCol: ReadonlyArray<number | undefined>;
66
+ /** Most lanes live at once anywhere in the turn. */
67
+ readonly maxLive: number;
68
+ /** Highest slot used + 1. */
69
+ readonly slots: number;
70
+ /** Columns from the gutter's first column to the turn's text column. */
71
+ readonly gutterWidth: number;
72
+ /** Color index of every lane that appeared. */
73
+ readonly laneColor: ReadonlyMap<LaneId, number>;
74
+ }
75
+
76
+ /**
77
+ * Columns from the gutter's first column to the text column: 6 while one lane
78
+ * is live, 10 for up to four, and two more per lane past that. Fixed per turn
79
+ * so a turn's text starts in one column however deep its lanes go.
80
+ */
81
+ function gutterWidthFor(slots: number): number {
82
+ if (slots <= 1) return 6;
83
+ if (slots <= 4) return 10;
84
+ return slots * 2 + 2;
85
+ }
86
+
87
+ interface LaneState {
88
+ readonly id: LaneId;
89
+ readonly parent: LaneId | undefined;
90
+ readonly slot: number;
91
+ readonly color: number;
92
+ live: boolean;
93
+ }
94
+
95
+ export function layoutLaneGraph(events: readonly LaneEvent[]): LaneLayout {
96
+ const lanes = new Map<LaneId, LaneState>();
97
+ const bySlot: Array<LaneState | undefined> = [];
98
+ let nextColor = 0;
99
+ let maxLive = 0;
100
+ let maxSlot = -1;
101
+
102
+ const colorOf = (id: LaneId): number => {
103
+ const known = lanes.get(id);
104
+ if (known) return known.color;
105
+ return nextColor++;
106
+ };
107
+
108
+ const liveCount = (): number => bySlot.filter((l) => l?.live).length;
109
+
110
+ const openLane = (id: LaneId, parent: LaneId | undefined, minSlot: number): LaneState => {
111
+ let slot = Math.max(0, minSlot);
112
+ while (bySlot[slot]?.live) slot++;
113
+ const state: LaneState = { id, parent, slot, color: colorOf(id), live: true };
114
+ lanes.set(id, state);
115
+ bySlot[slot] = state;
116
+ maxSlot = Math.max(maxSlot, slot);
117
+ maxLive = Math.max(maxLive, liveCount());
118
+ return state;
119
+ };
120
+
121
+ /** A lane an event names but that never opened (defensive): open it off the spine. */
122
+ const ensureLane = (id: LaneId): LaneState => {
123
+ const known = lanes.get(id);
124
+ if (known && known.live) return known;
125
+ if (id === SPINE) return openLane(SPINE, undefined, 0);
126
+ const parent = lanes.get(SPINE);
127
+ return openLane(id, SPINE, (parent?.live ? parent.slot : -1) + 1);
128
+ };
129
+
130
+ /** The nearest ancestor of `lane` that is still live. */
131
+ const openAncestor = (lane: LaneState): LaneState | undefined => {
132
+ let cursor = lane.parent !== undefined ? lanes.get(lane.parent) : undefined;
133
+ while (cursor && !cursor.live) cursor = cursor.parent !== undefined ? lanes.get(cursor.parent) : undefined;
134
+ return cursor;
135
+ };
136
+
137
+ /** A row of │ for every live lane. */
138
+ const baseRow = (): Array<GutterCell | null> => {
139
+ const row: Array<GutterCell | null> = [];
140
+ bySlot.forEach((lane, slot) => {
141
+ if (lane?.live) row[slot * 2] = { role: 'vert', color: lane.color };
142
+ });
143
+ return row;
144
+ };
145
+
146
+ /** Draw a horizontal run from slot `from` (exclusive) to slot `to` (exclusive), in `color`. */
147
+ const run = (row: Array<GutterCell | null>, from: number, to: number, color: number): void => {
148
+ for (let col = from * 2 + 1; col < to * 2; col++) {
149
+ const lane = col % 2 === 0 ? bySlot[col / 2] : undefined;
150
+ row[col] = lane?.live ? { role: 'cross', color: lane.color } : { role: 'horiz', color };
151
+ }
152
+ };
153
+
154
+ const rows: GutterRow[] = [];
155
+ const cont: GutterRow[] = [];
156
+ const markCol: Array<number | undefined> = [];
157
+
158
+ for (const event of events) {
159
+ let row: Array<GutterCell | null>;
160
+ let mark: number | undefined;
161
+ switch (event.kind) {
162
+ case 'head': {
163
+ const spine = lanes.get(SPINE)?.live ? lanes.get(SPINE)! : openLane(SPINE, undefined, 0);
164
+ row = baseRow();
165
+ row[spine.slot * 2] = { role: 'head', color: spine.color };
166
+ row[spine.slot * 2 + 1] = { role: 'horiz', color: spine.color };
167
+ mark = spine.slot * 2;
168
+ break;
169
+ }
170
+ case 'turn': {
171
+ const color = colorOf(SPINE);
172
+ if (!lanes.has(SPINE)) lanes.set(SPINE, { id: SPINE, parent: undefined, slot: 0, color, live: false });
173
+ row = baseRow();
174
+ row[0] = { role: 'turn', color };
175
+ maxSlot = Math.max(maxSlot, 0);
176
+ maxLive = Math.max(maxLive, 1);
177
+ mark = 0;
178
+ break;
179
+ }
180
+ case 'row': {
181
+ row = baseRow();
182
+ break;
183
+ }
184
+ case 'bead': {
185
+ const lane = ensureLane(event.lane);
186
+ row = baseRow();
187
+ row[lane.slot * 2] = { role: 'bead', color: lane.color };
188
+ mark = lane.slot * 2;
189
+ break;
190
+ }
191
+ case 'folded': {
192
+ const parent = ensureLane(event.lane);
193
+ const color = colorOf(event.child);
194
+ if (!lanes.has(event.child)) lanes.set(event.child, { id: event.child, parent: event.lane, slot: parent.slot, color, live: false });
195
+ row = baseRow();
196
+ row[parent.slot * 2] = { role: 'folded', color };
197
+ mark = parent.slot * 2;
198
+ break;
199
+ }
200
+ case 'spawn': {
201
+ const parent = ensureLane(event.parent);
202
+ row = baseRow();
203
+ const child = openLane(event.lane, event.parent, parent.slot + 1);
204
+ row[parent.slot * 2] = { role: 'branch', color: parent.color };
205
+ run(row, parent.slot, child.slot, child.color);
206
+ row[child.slot * 2] = { role: 'open', color: child.color };
207
+ mark = child.slot * 2;
208
+ break;
209
+ }
210
+ case 'merge': {
211
+ const lane = lanes.get(event.lane);
212
+ row = baseRow();
213
+ if (!lane || !lane.live) break;
214
+ const target = openAncestor(lane);
215
+ if (target) {
216
+ row[target.slot * 2] = { role: 'branch', color: target.color };
217
+ run(row, target.slot, lane.slot, lane.color);
218
+ row[lane.slot * 2] = { role: 'merge', color: lane.color };
219
+ } else {
220
+ // Nothing left to merge into (its parents already ended): the lane just ends.
221
+ row[lane.slot * 2] = { role: 'close', color: lane.color };
222
+ }
223
+ mark = lane.slot * 2;
224
+ lane.live = false;
225
+ break;
226
+ }
227
+ case 'answer': {
228
+ const spine = lanes.get(SPINE);
229
+ row = baseRow();
230
+ const slot = spine?.slot ?? 0;
231
+ const color = spine?.color ?? colorOf(SPINE);
232
+ row[slot * 2] = { role: 'close', color };
233
+ row[slot * 2 + 1] = { role: 'horiz', color };
234
+ if (spine) spine.live = false;
235
+ mark = slot * 2;
236
+ break;
237
+ }
238
+ }
239
+ rows.push(row);
240
+ cont.push(baseRow());
241
+ markCol.push(mark);
242
+ }
243
+
244
+ const slots = maxSlot + 1;
245
+ const laneColor = new Map<LaneId, number>();
246
+ for (const [id, lane] of lanes) laneColor.set(id, lane.color);
247
+ return { rows, cont, markCol, maxLive, slots, gutterWidth: gutterWidthFor(slots), laneColor };
248
+ }