@pellux/goodvibes-tui 2.0.20 → 2.1.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 (388) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +16 -16
  3. package/docs/README.md +4 -4
  4. package/docs/foundation-artifacts/operator-contract.json +59 -4
  5. package/package.json +16 -6
  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-registry.ts +77 -35
  52. package/src/input/commands/acp-runtime.ts +19 -9
  53. package/src/input/commands/channel-runtime.ts +2 -2
  54. package/src/input/commands/ci-runtime.ts +1 -1
  55. package/src/input/commands/codebase-runtime.ts +1 -1
  56. package/src/input/commands/config.ts +7 -1
  57. package/src/input/commands/context-window.ts +25 -19
  58. package/src/input/commands/control-room-runtime.ts +18 -18
  59. package/src/input/commands/conversation-runtime.ts +0 -1
  60. package/src/input/commands/cost-runtime.ts +29 -20
  61. package/src/input/commands/diff-runtime.ts +35 -181
  62. package/src/input/commands/eval.ts +1 -1
  63. package/src/input/commands/experience-runtime.ts +3 -7
  64. package/src/input/commands/fresh-conversation.ts +86 -0
  65. package/src/input/commands/git-runtime.ts +5 -22
  66. package/src/input/commands/graph-runtime.ts +1 -1
  67. package/src/input/commands/guidance-runtime.ts +1 -1
  68. package/src/input/commands/health-runtime.ts +8 -9
  69. package/src/input/commands/hooks-runtime.ts +2 -2
  70. package/src/input/commands/hosted-runtime.ts +3 -3
  71. package/src/input/commands/incident-runtime.ts +3 -3
  72. package/src/input/commands/intelligence-runtime.ts +6 -9
  73. package/src/input/commands/knowledge.ts +2 -2
  74. package/src/input/commands/legacy-panel-command.ts +57 -0
  75. package/src/input/commands/local-auth-runtime.ts +8 -9
  76. package/src/input/commands/local-provider-runtime.ts +7 -4
  77. package/src/input/commands/local-runtime.ts +12 -15
  78. package/src/input/commands/local-setup-review.ts +1 -1
  79. package/src/input/commands/local-setup.ts +13 -19
  80. package/src/input/commands/memory.ts +1 -1
  81. package/src/input/commands/notify-runtime.ts +9 -0
  82. package/src/input/commands/operator-runtime.ts +10 -12
  83. package/src/input/commands/permissions-provenance.ts +3 -3
  84. package/src/input/commands/planning-runtime.ts +7 -7
  85. package/src/input/commands/platform-sandbox-runtime.ts +2 -2
  86. package/src/input/commands/platform-services-runtime.ts +1 -1
  87. package/src/input/commands/policy-dispatch.ts +2 -2
  88. package/src/input/commands/policy.ts +3 -3
  89. package/src/input/commands/provider.ts +1 -1
  90. package/src/input/commands/remote-runtime.ts +1 -1
  91. package/src/input/commands/review-runtime.ts +39 -94
  92. package/src/input/commands/rewind-runtime.ts +81 -108
  93. package/src/input/commands/runtime-services.ts +15 -17
  94. package/src/input/commands/services-runtime.ts +2 -2
  95. package/src/input/commands/session-content.ts +21 -5
  96. package/src/input/commands/session-workflow.ts +13 -38
  97. package/src/input/commands/settings-sync-runtime.ts +2 -2
  98. package/src/input/commands/shell-core.ts +19 -4
  99. package/src/input/commands/skills-runtime.ts +2 -2
  100. package/src/input/commands/status-runtime.ts +13 -0
  101. package/src/input/commands/subscription-runtime.ts +1 -1
  102. package/src/input/commands/tasks-runtime.ts +2 -8
  103. package/src/input/commands/work-plan-runtime.ts +4 -4
  104. package/src/input/commands/workstream-attempts.ts +24 -47
  105. package/src/input/commands/workstream-runtime.ts +2 -2
  106. package/src/input/commands/worktree-runtime.ts +3 -3
  107. package/src/input/commands.ts +3 -1
  108. package/src/input/composer-editor.ts +44 -0
  109. package/src/input/concealed-input.ts +1 -1
  110. package/src/input/config-modal-types.ts +20 -8
  111. package/src/input/config-modal.ts +106 -105
  112. package/src/input/confirm-dialog-types.ts +28 -0
  113. package/src/input/confirm-dialog.ts +70 -0
  114. package/src/input/delete-key-policy.ts +3 -3
  115. package/src/input/feed-context-factory.ts +15 -16
  116. package/src/input/handler-command-route.ts +7 -42
  117. package/src/input/handler-content-actions.ts +16 -15
  118. package/src/input/handler-feed-routes.ts +26 -211
  119. package/src/input/handler-feed.ts +68 -95
  120. package/src/input/handler-interactions.ts +5 -3
  121. package/src/input/handler-modal-routes.ts +215 -216
  122. package/src/input/handler-modal-stack.ts +81 -11
  123. package/src/input/handler-modal-token-routes.ts +4 -0
  124. package/src/input/handler-onboarding.ts +0 -1
  125. package/src/input/handler-picker-routes.ts +65 -107
  126. package/src/input/handler-session-view-route.ts +149 -0
  127. package/src/input/handler-shortcuts.ts +16 -154
  128. package/src/input/handler-types.ts +4 -2
  129. package/src/input/handler-ui-state.ts +45 -15
  130. package/src/input/handler-work-tree-route.ts +123 -0
  131. package/src/input/handler.ts +25 -70
  132. package/src/input/keybindings.ts +16 -71
  133. package/src/input/masked-entry-modal.ts +117 -0
  134. package/src/input/mcp-workspace.ts +48 -17
  135. package/src/input/model-picker-filter.ts +8 -0
  136. package/src/input/model-picker-open.ts +99 -0
  137. package/src/input/model-picker-types.ts +1 -1
  138. package/src/input/model-picker.ts +92 -9
  139. package/src/input/notifications-modal.ts +123 -0
  140. package/src/input/overlay-filter.ts +26 -0
  141. package/src/input/profile-picker-modal.ts +37 -8
  142. package/src/input/search.ts +3 -3
  143. package/src/input/selection-modal-queue.ts +2 -0
  144. package/src/input/selection-modal.ts +28 -16
  145. package/src/input/session-picker-modal.ts +33 -8
  146. package/src/input/settings-modal-activation.ts +7 -2
  147. package/src/input/settings-modal-data.ts +11 -6
  148. package/src/input/settings-modal-types.ts +1 -1
  149. package/src/input/settings-modal.ts +20 -20
  150. package/src/input/submission-intent.ts +1 -1
  151. package/src/input/submission-router.ts +4 -9
  152. package/src/input/surface-modal-host.ts +110 -0
  153. package/src/input/theme-settings-actions.ts +82 -0
  154. package/src/input/usage-modal.ts +183 -0
  155. package/src/input/views.ts +97 -0
  156. package/src/main.ts +175 -165
  157. package/src/permissions/hunk-selection.ts +1 -1
  158. package/src/permissions/prompt-card.ts +511 -0
  159. package/src/permissions/prompt.ts +59 -622
  160. package/src/renderer/agents-modal.ts +310 -0
  161. package/src/renderer/autocomplete-overlay.ts +42 -220
  162. package/src/renderer/back-to-bottom.ts +80 -0
  163. package/src/renderer/block-actions-overlay.ts +30 -48
  164. package/src/renderer/bookmark-modal.ts +48 -79
  165. package/src/renderer/changes-modal.ts +325 -0
  166. package/src/renderer/code-block.ts +184 -106
  167. package/src/renderer/command-palette.ts +93 -0
  168. package/src/renderer/composer-fragments.ts +4 -4
  169. package/src/renderer/composer.ts +146 -0
  170. package/src/renderer/compositor.ts +26 -160
  171. package/src/renderer/config-modal.ts +185 -81
  172. package/src/renderer/confirm-dialog.ts +50 -0
  173. package/src/renderer/context-inspector.ts +116 -154
  174. package/src/renderer/context-status-hint.ts +4 -4
  175. package/src/renderer/conversation-layout.ts +20 -0
  176. package/src/renderer/conversation-overlays.ts +94 -84
  177. package/src/renderer/conversation-surface.ts +19 -38
  178. package/src/renderer/diff-tint.ts +98 -0
  179. package/src/renderer/file-picker-overlay.ts +63 -90
  180. package/src/renderer/footer-targets.ts +38 -0
  181. package/src/renderer/git-status.ts +3 -4
  182. package/src/renderer/header-line.ts +140 -117
  183. package/src/renderer/help-overlay.ts +133 -219
  184. package/src/renderer/history-search-overlay.ts +15 -12
  185. package/src/renderer/lane-graph/bead.ts +800 -0
  186. package/src/renderer/lane-graph/glyphs.ts +134 -0
  187. package/src/renderer/lane-graph/layout.ts +248 -0
  188. package/src/renderer/lane-graph/paint.ts +537 -0
  189. package/src/renderer/lane-graph/semantic-memo.ts +77 -0
  190. package/src/renderer/layout-engine.ts +2 -57
  191. package/src/renderer/layout.ts +7 -13
  192. package/src/renderer/markdown-inline.ts +2 -1
  193. package/src/renderer/markdown-table.ts +17 -12
  194. package/src/renderer/markdown.ts +92 -34
  195. package/src/renderer/masked-entry-modal.ts +78 -0
  196. package/src/renderer/mcp-workspace.ts +166 -203
  197. package/src/renderer/model-workspace.ts +381 -436
  198. package/src/renderer/notifications-modal.ts +116 -0
  199. package/src/renderer/onboarding/onboarding-wizard.ts +178 -588
  200. package/src/renderer/process-view.ts +192 -0
  201. package/src/renderer/profile-picker-modal.ts +58 -110
  202. package/src/renderer/search-overlay.ts +6 -3
  203. package/src/renderer/selection-modal-overlay.ts +87 -327
  204. package/src/renderer/semantic-diff.ts +2 -2
  205. package/src/renderer/session-chips.ts +102 -0
  206. package/src/renderer/session-picker-modal.ts +177 -297
  207. package/src/renderer/settings-modal-connections.ts +14 -23
  208. package/src/renderer/settings-modal-context.ts +367 -0
  209. package/src/renderer/settings-modal-helpers.ts +6 -11
  210. package/src/renderer/settings-modal.ts +322 -726
  211. package/src/renderer/shell-surface.ts +277 -175
  212. package/src/renderer/shortcuts-overlay.ts +217 -0
  213. package/src/renderer/status-line.ts +475 -0
  214. package/src/renderer/surface-compose.ts +174 -0
  215. package/src/renderer/surface-kit-extra.ts +303 -0
  216. package/src/renderer/surface-kit-list.ts +366 -0
  217. package/src/renderer/surface-kit-parts.ts +360 -0
  218. package/src/renderer/surface-kit.ts +568 -0
  219. package/src/renderer/syntax-highlighter.ts +280 -197
  220. package/src/renderer/syntax-theme.ts +51 -0
  221. package/src/renderer/system-message.ts +0 -1
  222. package/src/renderer/term-caps.ts +42 -1
  223. package/src/renderer/terminal-bg-probe.ts +116 -19
  224. package/src/renderer/terminal-palette-probe.ts +322 -0
  225. package/src/renderer/terminal-palette-reader.ts +183 -0
  226. package/src/renderer/terminal-palette.ts +58 -0
  227. package/src/renderer/theme-mode-config.ts +16 -1
  228. package/src/renderer/theme.ts +234 -207
  229. package/src/renderer/thinking.ts +0 -1
  230. package/src/renderer/throbber.ts +188 -0
  231. package/src/renderer/toast-center.ts +119 -0
  232. package/src/renderer/ui-factory.ts +39 -602
  233. package/src/renderer/ui-primitives.ts +8 -25
  234. package/src/renderer/usage-modal.ts +353 -0
  235. package/src/renderer/user-message.ts +58 -0
  236. package/src/renderer/voice-capture-chip.ts +53 -0
  237. package/src/runtime/bootstrap-command-context.ts +0 -5
  238. package/src/runtime/bootstrap-command-parts.ts +38 -89
  239. package/src/runtime/bootstrap-core.ts +13 -15
  240. package/src/runtime/bootstrap-hook-bridge.ts +12 -21
  241. package/src/runtime/bootstrap-notifier-sync.ts +17 -1
  242. package/src/runtime/bootstrap-shell.ts +16 -50
  243. package/src/runtime/bootstrap.ts +14 -14
  244. package/src/runtime/client/fleet-union.ts +5 -5
  245. package/src/runtime/client/hosted-exit.ts +2 -2
  246. package/src/runtime/client/hosted-sessions.ts +1 -1
  247. package/src/runtime/client/spine-adoption.ts +1 -1
  248. package/src/runtime/context-accounting-source.ts +5 -4
  249. package/src/runtime/index.ts +1 -0
  250. package/src/runtime/notification-dispatch.ts +102 -29
  251. package/src/runtime/recovery-offer-wiring.ts +4 -1
  252. package/src/runtime/recovery-prompt.ts +31 -15
  253. package/src/runtime/runtime-services-types.ts +10 -6
  254. package/src/runtime/services.ts +17 -12
  255. package/src/runtime/session-continuity-hints.ts +2 -5
  256. package/src/runtime/session-inbound-inputs.ts +1 -1
  257. package/src/runtime/session-resume-liveness-confirm.ts +14 -2
  258. package/src/runtime/startup-typeahead-gate.ts +103 -0
  259. package/src/runtime/store/domains/domain-read-matrix.ts +0 -1
  260. package/src/runtime/store/domains/index.ts +0 -8
  261. package/src/runtime/store/selectors/index.ts +0 -28
  262. package/src/runtime/store/state.ts +0 -8
  263. package/src/runtime/ui-services.ts +4 -6
  264. package/src/runtime/usage-tracker.ts +348 -0
  265. package/src/runtime/wrfc-persistence.ts +4 -4
  266. package/src/shell/blocking-input.ts +92 -2
  267. package/src/shell/recovery-input-helpers.ts +1 -1
  268. package/src/shell/session-views.ts +539 -0
  269. package/src/shell/status-report.ts +86 -0
  270. package/src/shell/transcript-scroll.ts +68 -0
  271. package/src/shell/ui-openers.ts +84 -172
  272. package/src/shell/view-openers.ts +205 -0
  273. package/src/tools/wrfc-agent-guard.ts +22 -2
  274. package/src/utils/format-duration.ts +4 -8
  275. package/src/utils/splash-lines.ts +9 -1
  276. package/src/utils/terminal-width.ts +56 -0
  277. package/src/verification/verification-ledger.ts +18 -16
  278. package/src/{panels → views}/agent-inspector-shared.ts +2 -2
  279. package/src/{panels → views}/builtin-modals.ts +22 -21
  280. package/src/views/builtin-views.ts +135 -0
  281. package/src/{panels → views}/confirm-state.ts +9 -9
  282. package/src/{panels → views}/diff-review-model.ts +10 -3
  283. package/src/{panels → views}/eval-registry.ts +1 -1
  284. package/src/{panels → views}/fleet-acts.ts +49 -85
  285. package/src/{panels/fleet-panel-format.ts → views/fleet-format.ts} +40 -40
  286. package/src/{panels → views}/fleet-gateway.ts +5 -5
  287. package/src/{panels → views}/fleet-observed-render.ts +16 -16
  288. package/src/{panels → views}/fleet-read-model.ts +9 -9
  289. package/src/{panels/fleet-tabs.ts → views/fleet-session-tabs.ts} +13 -13
  290. package/src/{panels → views}/fleet-spawn.ts +33 -49
  291. package/src/{panels → views}/fleet-steer.ts +12 -12
  292. package/src/{panels → views}/fleet-stop.ts +4 -4
  293. package/src/{panels → views}/fleet-transcript.ts +26 -27
  294. package/src/{panels/fleet-panel-worktree-detail.ts → views/fleet-worktree-detail.ts} +7 -7
  295. package/src/{panels → views}/hosted-session-feed.ts +6 -6
  296. package/src/views/modal-surface-registry.ts +41 -0
  297. package/src/{panels → views}/modals/devices-modal.ts +2 -2
  298. package/src/{panels → views}/modals/hooks-modal.ts +13 -13
  299. package/src/{panels → views}/modals/keybindings-modal.ts +19 -27
  300. package/src/{panels → views}/modals/knowledge-modal.ts +6 -5
  301. package/src/{panels → views}/modals/local-auth-modal.ts +22 -21
  302. package/src/{panels → views}/modals/marketplace-modal.ts +11 -11
  303. package/src/{panels → views}/modals/memory-modal.ts +8 -8
  304. package/src/{panels → views}/modals/modal-surface-helpers.ts +15 -5
  305. package/src/{panels → views}/modals/pairing-modal.ts +9 -9
  306. package/src/{panels → views}/modals/planning-modal.ts +15 -20
  307. package/src/{panels → views}/modals/plugins-modal.ts +6 -6
  308. package/src/{panels → views}/modals/policy-modal.ts +13 -5
  309. package/src/{panels → views}/modals/provider-health-modal.ts +4 -4
  310. package/src/{panels → views}/modals/remote-modal.ts +3 -3
  311. package/src/{panels → views}/modals/sandbox-modal.ts +4 -4
  312. package/src/{panels → views}/modals/security-modal.ts +22 -16
  313. package/src/{panels → views}/modals/services-modal.ts +3 -3
  314. package/src/{panels → views}/modals/settings-sync-modal.ts +4 -4
  315. package/src/{panels → views}/modals/skills-modal.ts +9 -9
  316. package/src/{panels → views}/modals/subscription-modal.ts +3 -3
  317. package/src/{panels → views}/modals/work-plan-modal.ts +10 -13
  318. package/src/views/notifications-feed.ts +314 -0
  319. package/src/{panels → views}/polish-core.ts +38 -36
  320. package/src/{panels → views}/polish-tables.ts +35 -26
  321. package/src/{panels → views}/polish.ts +101 -95
  322. package/src/{panels → views}/project-planning-answer-actions.ts +3 -3
  323. package/src/{panels → views}/provider-health-routes.ts +14 -14
  324. package/src/{panels → views}/search-focus.ts +8 -8
  325. package/src/{panels → views}/session-maintenance.ts +11 -11
  326. package/src/views/skills-discovery.ts +159 -0
  327. package/src/views/view-deps.ts +80 -0
  328. package/src/views/view-panel-adapter.ts +53 -0
  329. package/src/{panels → views}/workstream-graph-render.ts +1 -1
  330. package/src/core/conversation-fold.ts +0 -101
  331. package/src/core/conversation-turn-structure.ts +0 -464
  332. package/src/core/conversation-user-receipts.ts +0 -42
  333. package/src/input/commands/operator-panel-runtime.ts +0 -186
  334. package/src/input/panel-integration-actions.ts +0 -33
  335. package/src/input/panel-mouse-geometry.ts +0 -97
  336. package/src/input/panel-paste-flood-guard.ts +0 -86
  337. package/src/panels/base-panel.ts +0 -301
  338. package/src/panels/builtin/agent.ts +0 -27
  339. package/src/panels/builtin/development.ts +0 -92
  340. package/src/panels/builtin/knowledge.ts +0 -12
  341. package/src/panels/builtin/operations.ts +0 -177
  342. package/src/panels/builtin/session.ts +0 -81
  343. package/src/panels/builtin/shared.ts +0 -357
  344. package/src/panels/builtin-panels.ts +0 -28
  345. package/src/panels/cost-tracker-panel.ts +0 -746
  346. package/src/panels/diff-panel.ts +0 -797
  347. package/src/panels/diff-review-panel.ts +0 -395
  348. package/src/panels/expandable-list-panel.ts +0 -189
  349. package/src/panels/fleet-deep-link.ts +0 -31
  350. package/src/panels/fleet-panel.ts +0 -799
  351. package/src/panels/git-panel.ts +0 -800
  352. package/src/panels/hosted-session-panel.ts +0 -221
  353. package/src/panels/index.ts +0 -21
  354. package/src/panels/local-auth-panel.ts +0 -478
  355. package/src/panels/notifications-feed.ts +0 -127
  356. package/src/panels/notifications-panel.ts +0 -160
  357. package/src/panels/panel-confirm-overlay.ts +0 -72
  358. package/src/panels/panel-manager.ts +0 -791
  359. package/src/panels/plugins-panel.ts +0 -371
  360. package/src/panels/scrollable-list-panel.ts +0 -498
  361. package/src/panels/skills-panel.ts +0 -454
  362. package/src/panels/token-budget-panel.ts +0 -688
  363. package/src/panels/types.ts +0 -191
  364. package/src/panels/wrfc-panel-format.ts +0 -133
  365. package/src/renderer/diff-view.ts +0 -134
  366. package/src/renderer/fleet-tab-strip.ts +0 -56
  367. package/src/renderer/footer-tips.ts +0 -53
  368. package/src/renderer/fullscreen-primitives.ts +0 -146
  369. package/src/renderer/fullscreen-workspace.ts +0 -194
  370. package/src/renderer/hint-grammar.ts +0 -52
  371. package/src/renderer/modal-factory.ts +0 -480
  372. package/src/renderer/overlay-box.ts +0 -154
  373. package/src/renderer/overlay-viewport.ts +0 -104
  374. package/src/renderer/panel-composite.ts +0 -145
  375. package/src/renderer/panel-workspace-bar.ts +0 -54
  376. package/src/renderer/process-indicator.ts +0 -163
  377. package/src/renderer/tab-strip.ts +0 -222
  378. package/src/renderer/text-layout.ts +0 -31
  379. package/src/renderer/tool-call.ts +0 -276
  380. package/src/renderer/tool-result-expanded-lines.ts +0 -48
  381. package/src/renderer/tool-result-summary.ts +0 -219
  382. package/src/runtime/diagnostics/panels/index.ts +0 -21
  383. package/src/runtime/diagnostics/panels/ops.ts +0 -156
  384. package/src/runtime/perf/panel-contracts.ts +0 -32
  385. package/src/runtime/store/domains/panels.ts +0 -117
  386. /package/src/{panels → views}/memory-consolidation-gateway.ts +0 -0
  387. /package/src/{panels → views}/modals/modal-theme.ts +0 -0
  388. /package/src/{panels → views}/provider-health-domains.ts +0 -0
@@ -0,0 +1,217 @@
1
+ /**
2
+ * renderShortcutsOverlay, the keyboard shortcuts modal (/shortcuts), drawn
3
+ * like the concept's "keys" screen: columns of key / action pairs, keys bold,
4
+ * actions muted, grouped under ✦ headers, with the always-live search row
5
+ * filtering by key or action. Reflects the live keybindings table (user
6
+ * overrides included).
7
+ *
8
+ * Two columns below a 170-column screen, three from 170 up (one on a narrow
9
+ * modal). The modal takes 86% of the screen without the usual 124-column cap,
10
+ * so each description gets room to stay on one line; the key column is as wide
11
+ * as the longest key (up to 18). Keys and actions that still do not fit wrap
12
+ * inside their column; the grid scrolls when it is taller than the modal.
13
+ */
14
+
15
+ import type { KeybindingsManager } from '../input/keybindings.ts';
16
+ import type { OverlayFilter } from '../input/overlay-filter.ts';
17
+ import { getDisplayWidth } from '../utils/terminal-width.ts';
18
+ import { activeTokens } from './theme.ts';
19
+ import {
20
+ NARROW_MODAL_BREAKPOINT,
21
+ beginModal,
22
+ finishModal,
23
+ searchRow,
24
+ scrollCountText,
25
+ standardModalWidth,
26
+ wrapLines,
27
+ MODAL_MARK_INSET,
28
+ type KitHint,
29
+ type SurfaceCanvas,
30
+ type SurfaceLayer,
31
+ } from './surface-kit.ts';
32
+ import { drawTextBlock } from './surface-kit-extra.ts';
33
+
34
+ interface ShortcutGroup {
35
+ readonly title: string;
36
+ readonly items: ReadonlyArray<readonly [key: string, action: string]>;
37
+ }
38
+
39
+ /** Keys that are real but are not KeyAction entries (context chords, literal characters). */
40
+ const HARDCODED_ROWS: ReadonlyArray<readonly [string, string]> = [
41
+ ['Up / Down', 'Recall input history; Down at bottom focuses the process indicator'],
42
+ ['PageUp / PageDn', 'Scroll by full page'],
43
+ ['Home / End', 'Jump to start / end of line'],
44
+ ['n / N (search)', 'Next / previous match'],
45
+ ['Mouse wheel', 'Scroll the conversation (or the open modal)'],
46
+ ['Enter', 'Submit message (composer empty: open the block-actions menu)'],
47
+ ['Shift+Enter', 'Insert newline'],
48
+ ['@', 'Open file picker'],
49
+ ['/', 'Slash command mode'],
50
+ ['Esc', 'Close overlay / clear prompt / leave an agent or process view / interrupt main'],
51
+ ['Shift+Tab', 'Cycle permission mode; with session chips showing and an empty composer, the previous session'],
52
+ ['F2', 'Open Agents'],
53
+ ['? or /help', 'Open the command browser (search & run any command)'],
54
+ // Precedence: a partial path under the cursor claims Tab for completion,
55
+ // otherwise it collapses or expands the nearest block.
56
+ ['Tab', 'Path-complete, else collapse/expand block; with session chips showing and an empty composer, the next session'],
57
+ ];
58
+
59
+ /** Where the views live now (they open as modals over the conversation). */
60
+ const VIEW_ROWS: ReadonlyArray<readonly [string, string]> = [
61
+ ['/usage', 'Usage: context, tokens and cost'],
62
+ ['/changes', 'Changes: files, diff, review'],
63
+ ['/notifications', 'Notification history'],
64
+ ['Esc', 'Close the top modal (one level)'],
65
+ ['Enter on lane', 'Open that agent full screen; typing there steers it'],
66
+ ['Enter on ▶ bead', 'Open that background process\'s live output'],
67
+ ['ctrl+x in view', 'Stop the agent or process shown (press twice)'],
68
+ ];
69
+
70
+ /** Every shortcut group, generated from the live keybindings table where it can be. */
71
+ function shortcutGroups(keybindingsManager: KeybindingsManager): ShortcutGroup[] {
72
+ const all = keybindingsManager.getAll();
73
+ const combos = (entry: (typeof all)[number]): string => entry.combos.map((c) => keybindingsManager.formatCombo(c)).join(', ');
74
+ return [
75
+ { title: 'Navigation & editing', items: HARDCODED_ROWS },
76
+ { title: 'Actions', items: all.map((e) => [combos(e), e.description] as const) },
77
+ { title: 'Views', items: VIEW_ROWS },
78
+ ];
79
+ }
80
+
81
+ function filterGroups(groups: readonly ShortcutGroup[], query: string): ShortcutGroup[] {
82
+ const q = query.trim().toLowerCase();
83
+ if (!q) return groups.filter((g) => g.items.length > 0);
84
+ return groups
85
+ .map((g) => ({
86
+ title: g.title,
87
+ items: g.title.toLowerCase().includes(q)
88
+ ? g.items
89
+ : g.items.filter(([key, action]) => key.toLowerCase().includes(q) || action.toLowerCase().includes(q)),
90
+ }))
91
+ .filter((g) => g.items.length > 0);
92
+ }
93
+
94
+ /** One drawn row of one column. */
95
+ type GridCell =
96
+ | { readonly kind: 'blank' }
97
+ | { readonly kind: 'header'; readonly text: string }
98
+ | { readonly kind: 'pair'; readonly key: string; readonly action: string };
99
+
100
+ interface Block { readonly cells: GridCell[]; readonly group: string; readonly header: boolean }
101
+
102
+ function blocksFor(groups: readonly ShortcutGroup[], keyW: number, actionW: number): Block[] {
103
+ const blocks: Block[] = [];
104
+ groups.forEach((g, gi) => {
105
+ blocks.push({ cells: [...(gi > 0 ? [{ kind: 'blank' as const }] : []), { kind: 'header', text: g.title }], group: g.title, header: true });
106
+ for (const [key, action] of g.items) {
107
+ const keys = wrapLines(key, keyW);
108
+ const actions = wrapLines(action, actionW);
109
+ const cells: GridCell[] = [];
110
+ for (let k = 0; k < Math.max(keys.length, actions.length); k++) cells.push({ kind: 'pair', key: keys[k] ?? '', action: actions[k] ?? '' });
111
+ blocks.push({ cells, group: g.title, header: false });
112
+ }
113
+ });
114
+ return blocks;
115
+ }
116
+
117
+ /** Split blocks into `n` balanced columns; a header never ends a column, a continued group repeats its header. */
118
+ function columnsFor(blocks: readonly Block[], n: number): GridCell[][] {
119
+ const total = blocks.reduce((sum, b) => sum + b.cells.length, 0);
120
+ const target = Math.ceil(total / n);
121
+ const cols: GridCell[][] = [[]];
122
+ blocks.forEach((block, i) => {
123
+ let col = cols[cols.length - 1]!;
124
+ const next = blocks[i + 1];
125
+ const need = block.cells.length + (block.header && next && !next.header ? next.cells.length : 0);
126
+ if (col.length > 0 && col.length + need > target && cols.length < n) {
127
+ col = [];
128
+ cols.push(col);
129
+ if (!block.header) col.push({ kind: 'header', text: block.group });
130
+ }
131
+ const cells = col.length === 0 ? block.cells.filter((c) => c.kind !== 'blank') : block.cells;
132
+ col.push(...cells);
133
+ });
134
+ return cols;
135
+ }
136
+
137
+ function drawCell(canvas: SurfaceCanvas, x: number, y: number, keyW: number, cell: GridCell): void {
138
+ const t = activeTokens();
139
+ if (cell.kind === 'header') {
140
+ canvas.put(x - MODAL_MARK_INSET, y, '✦', { fg: t.brandEnd });
141
+ canvas.put(x, y, cell.text.toLowerCase(), { fg: t.accent, bold: true });
142
+ } else if (cell.kind === 'pair') {
143
+ canvas.put(x, y, cell.key, { fg: t.text, bold: true });
144
+ canvas.put(x + keyW + 2, y, cell.action, { fg: t.textMuted });
145
+ }
146
+ }
147
+
148
+ const HINTS: readonly KitHint[] = [['↑↓', 'scroll'], ['type', 'to filter']];
149
+ const COLUMN_GAP = 4;
150
+ /** Screen width from which the grid has three columns instead of two. */
151
+ const SHORTCUTS_THREE_COLUMN_SCREEN = 170;
152
+ /** Widest key column; longer key lists wrap inside it. */
153
+ const MAX_KEY_WIDTH = 18;
154
+ /** Below this inner width the grid is one column. */
155
+ const ONE_COLUMN_INNER = 60;
156
+
157
+ /** The shortcuts modal's width: the standard 86% rule without the 124-column cap. */
158
+ function shortcutsModalWidth(screenW: number): number {
159
+ if (screenW < NARROW_MODAL_BREAKPOINT) return standardModalWidth(screenW);
160
+ return Math.max(standardModalWidth(screenW), Math.min(screenW - 2, Math.round(screenW * 0.86)));
161
+ }
162
+
163
+ /** Columns in the grid for a screen width and the modal's inner width. */
164
+ function shortcutsColumnCount(screenW: number, inner: number): number {
165
+ if (inner < ONE_COLUMN_INNER) return 1;
166
+ return screenW >= SHORTCUTS_THREE_COLUMN_SCREEN ? 3 : 2;
167
+ }
168
+
169
+ /**
170
+ * Render the keyboard shortcuts modal as a SurfaceLayer in screen coordinates.
171
+ * `filter` holds the search row's query; the renderer records how far the
172
+ * grid can scroll in it.
173
+ */
174
+ export function renderShortcutsOverlay(
175
+ screenWidth: number,
176
+ screenHeight: number,
177
+ keybindingsManager: KeybindingsManager,
178
+ scrollOffset = 0,
179
+ filter?: OverlayFilter,
180
+ ): SurfaceLayer {
181
+ const t = activeTokens();
182
+ const query = filter?.query ?? '';
183
+ const f = beginModal(screenWidth, screenHeight, { title: 'Keyboard shortcuts', sub: 'customize with /keybindings', hints: HINTS, width: shortcutsModalWidth(screenWidth) });
184
+ const all = shortcutGroups(keybindingsManager);
185
+ const groups = filterGroups(all, query);
186
+ const totalPairs = all.reduce((n, g) => n + g.items.length, 0);
187
+ const shown = groups.reduce((n, g) => n + g.items.length, 0);
188
+ searchRow(f, f.top, query, 'Filter shortcuts', query ? `${shown} of ${totalPairs}` : `${totalPairs} shortcuts`);
189
+
190
+ const top = f.top + 2;
191
+ const inner = f.r - f.l + 1;
192
+ if (groups.length === 0) {
193
+ if (filter) filter.maxScroll = 0;
194
+ drawTextBlock(f.canvas, f.l, top, inner, [{ text: `No shortcuts match "${query}".`, style: { fg: t.textMuted } }], f.bottom);
195
+ return finishModal(f);
196
+ }
197
+
198
+ const n = shortcutsColumnCount(screenWidth, inner);
199
+ const colW = Math.max(8, Math.floor((inner - COLUMN_GAP * (n - 1)) / n));
200
+ // Measured over every shortcut, not just the filtered ones, so filtering never shifts the columns.
201
+ const longestKey = all.reduce((w, g) => g.items.reduce((m, [key]) => Math.max(m, getDisplayWidth(key)), w), 0);
202
+ const keyW = Math.max(4, Math.min(MAX_KEY_WIDTH, longestKey, Math.floor(colW * 0.45)));
203
+ const actionW = Math.max(4, colW - keyW - 2);
204
+ const cols = columnsFor(blocksFor(groups, keyW, actionW), n);
205
+ const gridH = Math.max(...cols.map((c) => c.length));
206
+ const capacity = Math.max(1, f.bottom - top + 1);
207
+ const maxScroll = Math.max(0, gridH - capacity);
208
+ if (filter) filter.maxScroll = maxScroll;
209
+ const offset = Math.max(0, Math.min(scrollOffset, maxScroll));
210
+
211
+ cols.forEach((col, c) => {
212
+ const x = f.l + c * (colW + COLUMN_GAP);
213
+ for (let k = 0; k < capacity && offset + k < col.length; k++) drawCell(f.canvas, x, top + k, keyW, col[offset + k]!);
214
+ });
215
+ f.hintRight = scrollCountText(offset, Math.max(0, gridH - offset - capacity));
216
+ return finishModal(f);
217
+ }