@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
@@ -1,371 +0,0 @@
1
- import type { Line } from '@pellux/goodvibes-sdk/platform/types';
2
- import { createEmptyLine } from '@pellux/goodvibes-sdk/platform/types';
3
- import { truncateDisplay } from '../utils/terminal-width.ts';
4
- import { ScrollableListPanel } from './scrollable-list-panel.ts';
5
- import type { PanelIntegrationContext } from './types.ts';
6
- import type { PluginManager, PluginManagerObserver, PluginStatus } from '@pellux/goodvibes-sdk/platform/plugins';
7
- import {
8
- type ConfirmState,
9
- handleConfirmInput,
10
- renderConfirmLines,
11
- } from './confirm-state.ts';
12
- import {
13
- buildDetailBlock,
14
- buildEmptyState,
15
- buildKeyValueLine,
16
- buildKeyboardHints,
17
- buildPanelLine,
18
- buildPanelWorkspace,
19
- DEFAULT_PANEL_PALETTE,
20
- type PanelPalette,
21
- } from './polish.ts';
22
-
23
- // Base chrome only, title band, state colors, and text tokens all come
24
- // straight from DEFAULT_PANEL_PALETTE.
25
- const C = DEFAULT_PANEL_PALETTE;
26
-
27
- /**
28
- * PluginsPanel drives real plugin-manager mutations (enable/disable/
29
- * verify/lift-quarantine) from the keyboard, not just read-only inspection.
30
- * `PluginManagerObserver` alone (the read-only surface most panels need) has
31
- * no mutation methods, so the constructor param is widened to also require
32
- * the handful of `PluginManager` methods this panel actually calls. The real
33
- * runtime object passed at bootstrap (`services.pluginManager`, a full
34
- * `PluginManager` instance, see src/runtime/services.ts) already satisfies
35
- * this widened shape.
36
- */
37
- export type PluginManagerControls = PluginManagerObserver
38
- & Pick<PluginManager, 'enable' | 'disable' | 'verify' | 'liftQuarantine'>;
39
-
40
- type PluginConfirmSubject = { readonly kind: 'disable' | 'lift-quarantine'; readonly name: string };
41
-
42
- function trustColor(tier: PluginStatus['trustTier']): string {
43
- switch (tier) {
44
- case 'trusted':
45
- return C.good;
46
- case 'limited':
47
- return C.warn;
48
- case 'untrusted':
49
- return C.bad;
50
- }
51
- }
52
-
53
- function statusColor(status: PluginStatus): string {
54
- if (status.quarantined) return C.bad;
55
- if (status.active) return C.good;
56
- if (status.enabled) return C.warn;
57
- return C.dim;
58
- }
59
-
60
- function statusLabel(status: PluginStatus): string {
61
- if (status.quarantined) return 'QUARANTINED';
62
- if (status.active) return 'ACTIVE';
63
- if (status.enabled) return 'ENABLED';
64
- return 'DISABLED';
65
- }
66
-
67
- export class PluginsPanel extends ScrollableListPanel<PluginStatus> {
68
- private readonly manager: PluginManagerControls;
69
- private readonly unsub: (() => void) | null;
70
- /** Pending destructive/state-changing confirm for 'd' disable and 'q' lift-quarantine. */
71
- private confirmAction: ConfirmState<PluginConfirmSubject> | null = null;
72
- /** Result of the last 'v' verify press, rendered in the detail block until the selection or a new verify changes it. */
73
- private _verifyResult: { name: string; valid: boolean; fingerprint?: string | undefined; reason?: string | undefined } | null = null;
74
-
75
- public constructor(manager: PluginManagerControls) {
76
- super('plugins', 'Plugins', '◐', 'automation-control');
77
- this.showSelectionGutter = true; // I5: non-color selection affordance
78
- this.filterEnabled = true;
79
- this.filterLabel = 'Filter plugins';
80
- this.manager = manager;
81
- this.unsub = manager.subscribe(() => this.markDirty());
82
- }
83
-
84
- protected override filterMatches(plugin: PluginStatus, q: string): boolean {
85
- return plugin.name.toLowerCase().includes(q)
86
- || plugin.trustTier.toLowerCase().includes(q)
87
- || plugin.version.toLowerCase().includes(q);
88
- }
89
-
90
- // selection is preserved across onActivate, BasePanel's default
91
- // (mark dirty, no index reset) is exactly what we want, so no override.
92
-
93
- public override onDestroy(): void {
94
- this.unsub?.();
95
- }
96
-
97
- // -------------------------------------------------------------------------
98
- // Input, e=enable, d=disable (confirm), v=verify, q=lift quarantine (confirm)
99
- // -------------------------------------------------------------------------
100
-
101
- public handleInput(key: string): boolean {
102
- if (this.lastError !== null) this.clearError();
103
-
104
- if (this.confirmAction) {
105
- const result = handleConfirmInput(this.confirmAction, key);
106
- if (result === 'confirmed') {
107
- this._executeConfirmed(this.confirmAction.subject);
108
- this.confirmAction = null;
109
- this.markDirty();
110
- return true;
111
- }
112
- if (result === 'cancelled') {
113
- this.confirmAction = null;
114
- this.markDirty();
115
- }
116
- return true;
117
- }
118
-
119
- if (!this.filterActive) {
120
- switch (key) {
121
- case 'e':
122
- this._enableSelected();
123
- return true;
124
- case 'd':
125
- this._requestDisable();
126
- return true;
127
- case 'v':
128
- this._verifySelected();
129
- return true;
130
- case 'q': {
131
- const plugin = this.getSelectedItem();
132
- if (!plugin?.quarantined) return false;
133
- this._requestLiftQuarantine();
134
- return true;
135
- }
136
- case 'm': {
137
- // Consumed here only when there is a quarantined plugin selected;
138
- // the actual /recall dispatch happens in handlePanelIntegrationAction
139
- // below, which needs the executeCommand bridge from the router.
140
- const plugin = this.getSelectedItem();
141
- return Boolean(plugin?.quarantined);
142
- }
143
- default:
144
- break;
145
- }
146
- }
147
-
148
- return super.handleInput(key);
149
- }
150
-
151
- /**
152
- * optional one-key capture-to-memory for a quarantined plugin, 'm'
153
- * dispatches `/recall capture plugin <name>` (recall-capture.ts:146 pattern)
154
- * instead of requiring the operator to type the command by hand.
155
- */
156
- public handlePanelIntegrationAction(key: string, ctx: PanelIntegrationContext): boolean {
157
- if (key !== 'm' || !ctx.executeCommand) return false;
158
- const plugin = this.getSelectedItem();
159
- if (!plugin?.quarantined) return false;
160
- void ctx.executeCommand('recall', ['capture', 'plugin', plugin.name]).catch(() => {});
161
- return true;
162
- }
163
-
164
- private _enableSelected(): void {
165
- const plugin = this.getSelectedItem();
166
- if (!plugin) return;
167
- void this.manager.enable(plugin.name).then((result) => {
168
- if (!result.ok) this.setError(`Enable failed: ${result.error ?? 'unknown error'}`);
169
- this.markDirty();
170
- }).catch((err) => {
171
- this.setError(`Enable failed: ${err instanceof Error ? err.message : String(err)}`);
172
- this.markDirty();
173
- });
174
- }
175
-
176
- private _requestDisable(): void {
177
- const plugin = this.getSelectedItem();
178
- if (!plugin) return;
179
- this.confirmAction = { subject: { kind: 'disable', name: plugin.name }, label: plugin.name, verb: 'Disable' };
180
- this.markDirty();
181
- }
182
-
183
- private _requestLiftQuarantine(): void {
184
- const plugin = this.getSelectedItem();
185
- if (!plugin?.quarantined) return;
186
- this.confirmAction = { subject: { kind: 'lift-quarantine', name: plugin.name }, label: plugin.name, verb: 'Lift quarantine on' };
187
- this.markDirty();
188
- }
189
-
190
- private _verifySelected(): void {
191
- const plugin = this.getSelectedItem();
192
- if (!plugin) return;
193
- const result = this.manager.verify(plugin.name);
194
- if (!result.ok && result.reason?.toLowerCase().includes('not found')) {
195
- this._verifyResult = null;
196
- this.setError(`Verify failed: ${result.reason}`);
197
- this.markDirty();
198
- return;
199
- }
200
- this._verifyResult = { name: plugin.name, valid: result.valid, fingerprint: result.fingerprint, reason: result.reason };
201
- this.markDirty();
202
- }
203
-
204
- private _executeConfirmed(subject: PluginConfirmSubject): void {
205
- if (subject.kind === 'disable') {
206
- void this.manager.disable(subject.name).then((result) => {
207
- if (!result.ok) this.setError(`Disable failed: ${result.error ?? 'unknown error'}`);
208
- this.markDirty();
209
- }).catch((err) => {
210
- this.setError(`Disable failed: ${err instanceof Error ? err.message : String(err)}`);
211
- this.markDirty();
212
- });
213
- return;
214
- }
215
- const result = this.manager.liftQuarantine(subject.name);
216
- if (!result.ok) this.setError(`Lift quarantine failed: ${result.error ?? 'unknown error'}`);
217
- this.markDirty();
218
- }
219
-
220
- protected override getPalette(): PanelPalette {
221
- return C;
222
- }
223
-
224
- protected getItems(): readonly PluginStatus[] {
225
- return this.manager.list();
226
- }
227
-
228
- protected renderItem(plugin: PluginStatus, _index: number, selected: boolean, width: number): Line {
229
- const bg = selected ? C.selectBg : undefined;
230
- return buildPanelLine(width, [
231
- [' ', C.label, bg],
232
- [plugin.name.padEnd(22), C.value, bg],
233
- [` ${statusLabel(plugin).padEnd(11)}`, statusColor(plugin), bg],
234
- [` ${plugin.trustTier.toUpperCase().padEnd(10)}`, trustColor(plugin.trustTier), bg],
235
- [` ${plugin.version}`, C.dim, bg],
236
- ]);
237
- }
238
-
239
- protected override getEmptyStateMessage(): string {
240
- return ' No plugins discovered.';
241
- }
242
-
243
- protected override getEmptyStateActions(): Array<{ command: string; summary: string }> {
244
- return [
245
- { command: '/plugin list', summary: 'inspect plugin discovery paths and current registry state' },
246
- { command: '/marketplace', summary: 'review curated ecosystem entries and provenance posture' },
247
- ];
248
- }
249
-
250
- public render(width: number, height: number): Line[] {
251
- const intro = 'Plugin trust, capabilities, signatures, and quarantine posture for the active ecosystem surface.';
252
- const plugins = this.getItems();
253
-
254
- if (plugins.length === 0) {
255
- const workspace = buildPanelWorkspace(width, height, {
256
- title: 'Plugin Control Room',
257
- intro,
258
- sections: [{
259
- lines: buildEmptyState(
260
- width,
261
- ' No plugins discovered.',
262
- 'Use /plugin list for search paths, install hints, and trust review before activating plugin-backed flows.',
263
- [
264
- { command: '/plugin list', summary: 'inspect plugin discovery paths and current registry state' },
265
- { command: '/marketplace', summary: 'review curated ecosystem entries and provenance posture' },
266
- ],
267
- C,
268
- ),
269
- }],
270
- palette: C,
271
- });
272
- while (workspace.length < height) workspace.push(createEmptyLine(width));
273
- return workspace;
274
- }
275
-
276
- // Provenance/error posture header, surface trust + quarantine pressure first.
277
- const quarantined = plugins.filter((p) => p.quarantined).length;
278
- const untrusted = plugins.filter((p) => p.trustTier === 'untrusted').length;
279
- const active = plugins.filter((p) => p.active).length;
280
- const headerLines: Line[] = [
281
- buildKeyValueLine(width, [
282
- { label: 'plugins', value: String(plugins.length), valueColor: C.info },
283
- { label: 'active', value: String(active), valueColor: active > 0 ? C.good : C.dim },
284
- { label: 'untrusted', value: String(untrusted), valueColor: untrusted > 0 ? C.warn : C.dim },
285
- { label: 'quarantined', value: String(quarantined), valueColor: quarantined > 0 ? C.bad : C.dim },
286
- ], C),
287
- ];
288
-
289
- this.clampSelection();
290
- const selected = this.getSelectedItem()!;
291
- const selectedCaps = this.manager.capabilities(selected.name);
292
- const trustRecord = this.manager.getTrustRecord(selected.name);
293
- const quarantineRecord = this.manager.getQuarantineRecord(selected.name);
294
- const detailRows: Line[] = [
295
- buildPanelLine(width, [
296
- [' Plugin: ', C.label],
297
- [selected.name, C.value],
298
- [' v', C.label],
299
- [selected.version, C.dim],
300
- [' State: ', C.label],
301
- [statusLabel(selected), statusColor(selected)],
302
- [' Trust: ', C.label],
303
- [selected.trustTier, trustColor(selected.trustTier)],
304
- ]),
305
- buildPanelLine(width, [
306
- [' Description: ', C.label],
307
- [truncateDisplay(selected.description, Math.max(0, width - 15)), C.dim],
308
- ]),
309
- ];
310
-
311
- if (selectedCaps) {
312
- detailRows.push(buildPanelLine(width, [
313
- [' Capabilities: ', C.label],
314
- [String(selectedCaps.requested.length), C.value],
315
- [' High-risk: ', C.label],
316
- [String(selectedCaps.highRisk.length), selectedCaps.highRisk.length > 0 ? C.warn : C.good],
317
- [' Blocked: ', C.label],
318
- [String(selectedCaps.blocked.length), selectedCaps.blocked.length > 0 ? C.bad : C.good],
319
- ]));
320
- }
321
-
322
- if (trustRecord?.signatureFingerprint) {
323
- detailRows.push(buildPanelLine(width, [
324
- [' Signature: ', C.label],
325
- [truncateDisplay(trustRecord.signatureFingerprint, Math.max(0, width - 14)), C.info],
326
- ]));
327
- } else {
328
- detailRows.push(buildPanelLine(width, [[' Signature: unsigned (no provenance fingerprint on record)', C.warn]]));
329
- }
330
-
331
- if (quarantineRecord) {
332
- detailRows.push(buildPanelLine(width, [
333
- [' Quarantine: ', C.label],
334
- [truncateDisplay(quarantineRecord.reason, Math.max(0, width - 14)), C.bad],
335
- ]));
336
- }
337
-
338
- if (this._verifyResult && this._verifyResult.name === selected.name) {
339
- const vr = this._verifyResult;
340
- const verifySegments: Array<[string, string, string?]> = [
341
- [' Verify: ', C.label],
342
- [vr.valid ? 'VALID' : 'INVALID', vr.valid ? C.good : C.bad],
343
- ];
344
- if (vr.fingerprint) verifySegments.push([` fp=${truncateDisplay(vr.fingerprint, 20)}`, C.info]);
345
- if (!vr.valid && vr.reason) verifySegments.push([` ${truncateDisplay(vr.reason, Math.max(0, width - 40))}`, C.warn]);
346
- detailRows.push(buildPanelLine(width, verifySegments));
347
- }
348
-
349
- if (this.confirmAction) detailRows.push(...renderConfirmLines(width, this.confirmAction));
350
-
351
- const hints = this.filterActive
352
- ? [{ keys: 'type', label: 'filter' }, { keys: 'Enter', label: 'apply' }, { keys: 'Esc', label: 'clear' }]
353
- : [
354
- { keys: 'Up/Down', label: 'move' },
355
- { keys: 'e', label: 'enable' },
356
- { keys: 'd', label: 'disable' },
357
- { keys: 'v', label: 'verify' },
358
- ...(selected.quarantined ? [{ keys: 'q', label: 'lift quarantine' }, { keys: 'm', label: 'capture to memory' }] : []),
359
- { keys: '/', label: 'filter' },
360
- ];
361
-
362
- return this.renderList(width, height, {
363
- title: 'Plugin Control Room',
364
- header: headerLines,
365
- footer: [
366
- ...buildDetailBlock(width, `Plugin · ${selected.name}`, detailRows, C),
367
- buildKeyboardHints(width, hints, C),
368
- ],
369
- });
370
- }
371
- }