@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
@@ -4,41 +4,41 @@
4
4
  * The canonical evaluator is the SDK version exported from @/runtime/index.ts
5
5
  * (via operations.evaluateSessionMaintenance), which reads from configManager.
6
6
  * Import the evaluator from there, this module provides only the shared
7
- * Panel* type surface used across TUI panels and tests; it intentionally does
7
+ * View* type surface used across TUI views and tests; it intentionally does
8
8
  * not re-implement the evaluator.
9
9
  */
10
10
  import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config';
11
11
 
12
- export type PanelGuidanceMode = 'off' | 'minimal' | 'guided';
13
- export type PanelSessionMaintenanceLevel = 'stable' | 'watch' | 'suggest-compact' | 'compacting' | 'needs-repair' | 'unknown';
12
+ export type ViewGuidanceMode = 'off' | 'minimal' | 'guided';
13
+ export type ViewSessionMaintenanceLevel = 'stable' | 'watch' | 'suggest-compact' | 'compacting' | 'needs-repair' | 'unknown';
14
14
 
15
- export interface PanelSessionMaintenanceLineageEntry {
15
+ export interface ViewSessionMaintenanceLineageEntry {
16
16
  readonly branchReason?: string;
17
17
  }
18
18
 
19
- export interface PanelSessionMaintenanceSession {
20
- readonly lineage?: readonly PanelSessionMaintenanceLineageEntry[];
19
+ export interface ViewSessionMaintenanceSession {
20
+ readonly lineage?: readonly ViewSessionMaintenanceLineageEntry[];
21
21
  readonly lastCompactedAt?: number;
22
22
  readonly compactionMessageCount?: number;
23
23
  readonly compactionState?: string;
24
24
  }
25
25
 
26
- export interface PanelSessionMaintenanceInput {
26
+ export interface ViewSessionMaintenanceInput {
27
27
  /** ConfigManager used to read behavior.autoCompactThreshold and related keys. */
28
28
  readonly configManager: Pick<ConfigManager, 'get'>;
29
29
  readonly currentTokens: number;
30
30
  readonly contextWindow: number;
31
31
  readonly messageCount?: number;
32
32
  readonly sessionMemoryCount?: number;
33
- readonly session?: PanelSessionMaintenanceSession | null;
33
+ readonly session?: ViewSessionMaintenanceSession | null;
34
34
  }
35
35
 
36
- export interface PanelSessionMaintenanceStatus {
37
- readonly level: PanelSessionMaintenanceLevel;
36
+ export interface ViewSessionMaintenanceStatus {
37
+ readonly level: ViewSessionMaintenanceLevel;
38
38
  readonly summary: string;
39
39
  readonly reasons: readonly string[];
40
40
  readonly nextSteps: readonly string[];
41
- readonly guidanceMode: PanelGuidanceMode;
41
+ readonly guidanceMode: ViewGuidanceMode;
42
42
  readonly usagePct: number;
43
43
  readonly remainingTokens: number;
44
44
  /**
@@ -0,0 +1,159 @@
1
+ /**
2
+ * skills-discovery.ts, finding the skills on disk: project-local
3
+ * (.goodvibes/skills), global (~/.goodvibes/skills) and custom directories,
4
+ * each SKILL.md parsed for its frontmatter, marketplace-installed ones tagged
5
+ * with their provenance. Used by /skills, /local review and the Skills modal.
6
+ */
7
+
8
+ import { promises as fsPromises } from 'node:fs';
9
+ import { join, sep } from 'node:path';
10
+ import { listInstalledEcosystemEntries, type EcosystemCatalogPathOptions, type ShellPathService } from '@/runtime/index.ts';
11
+ import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
12
+
13
+ export type SkillOrigin = 'project-local' | 'global' | 'custom';
14
+
15
+ export interface SkillRecord {
16
+ name: string;
17
+ description: string;
18
+ path: string;
19
+ origin: SkillOrigin;
20
+ dependencies: string[];
21
+ includes: string[];
22
+ frontmatter: Record<string, string>;
23
+ /**
24
+ * Set when this skill's file lives under an installed ecosystem-marketplace
25
+ * receipt's targetPath, the receipt's provenance summary (e.g. curated
26
+ * source / signature info), so marketplace-installed skills read as such
27
+ * instead of looking identical to hand-authored ones.
28
+ */
29
+ marketplaceProvenance?: string;
30
+ }
31
+
32
+ function parseFrontmatter(content: string): Record<string, string> {
33
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
34
+ if (!match) return {};
35
+ const result: Record<string, string> = {};
36
+ for (const line of match[1].split('\n')) {
37
+ const [key, ...rest] = line.split(':');
38
+ if (key && rest.length > 0) {
39
+ result[key.trim()] = rest.join(':').trim();
40
+ }
41
+ }
42
+ return result;
43
+ }
44
+
45
+ function getSkillDirectories(cwd: string, homeDir: string): Array<{ root: string; origin: SkillOrigin }> {
46
+ return [
47
+ { root: join(cwd, '.goodvibes', 'skills'), origin: 'project-local' },
48
+ { root: join(cwd, '.goodvibes', 'tui', 'skills'), origin: 'project-local' },
49
+ { root: join(homeDir, '.goodvibes', 'skills'), origin: 'global' },
50
+ { root: join(homeDir, '.goodvibes', 'tui', 'skills'), origin: 'global' },
51
+ ];
52
+ }
53
+
54
+ async function readSkillFile(path: string, origin: SkillOrigin): Promise<SkillRecord | null> {
55
+ let content = '';
56
+ try {
57
+ content = await fsPromises.readFile(path, 'utf-8');
58
+ } catch {
59
+ return null;
60
+ }
61
+
62
+ const frontmatter = parseFrontmatter(content);
63
+ const body = content.replace(/^---\n[\s\S]*?\n---\n?/, '');
64
+ const name = frontmatter.name ?? path.split(/[\\/]/).pop()?.replace(/\.md$/, '') ?? 'skill';
65
+ const description = frontmatter.description ?? frontmatter.summary ?? '';
66
+ const dependencies = frontmatter.depends_on
67
+ ? frontmatter.depends_on.split(',').map((item) => item.trim()).filter(Boolean)
68
+ : [];
69
+ const includes: string[] = [];
70
+ const includeRegex = /^@([\w/-]+)/gm;
71
+ let match: RegExpExecArray | null;
72
+ while ((match = includeRegex.exec(body)) !== null) {
73
+ includes.push(match[1]);
74
+ }
75
+
76
+ return {
77
+ name,
78
+ description,
79
+ path,
80
+ origin,
81
+ dependencies,
82
+ includes,
83
+ frontmatter,
84
+ };
85
+ }
86
+
87
+ async function scanSkillDirectory(root: string, origin: SkillOrigin): Promise<SkillRecord[]> {
88
+ let entries: string[] = [];
89
+ try {
90
+ entries = await fsPromises.readdir(root);
91
+ } catch {
92
+ return [];
93
+ }
94
+
95
+ const records: SkillRecord[] = [];
96
+ for (const entry of entries.sort((a, b) => a.localeCompare(b))) {
97
+ if (entry.endsWith('.md')) {
98
+ const record = await readSkillFile(join(root, entry), origin);
99
+ if (record) records.push(record);
100
+ continue;
101
+ }
102
+
103
+ const markerPath = join(root, entry, 'SKILL.md');
104
+ const record = await readSkillFile(markerPath, origin);
105
+ if (record) records.push(record);
106
+ }
107
+
108
+ return records;
109
+ }
110
+
111
+ /**
112
+ * Tags records whose file lives under an installed ecosystem-marketplace
113
+ * receipt's targetPath with that receipt's provenance summary. Best-effort:
114
+ * a lookup failure (e.g. no ecosystem catalogs configured) leaves records
115
+ * untagged rather than failing skill discovery.
116
+ */
117
+ function applyMarketplaceProvenance(records: SkillRecord[], ecosystemPaths: EcosystemCatalogPathOptions): SkillRecord[] {
118
+ let receipts: ReturnType<typeof listInstalledEcosystemEntries>;
119
+ try {
120
+ receipts = listInstalledEcosystemEntries('skill', ecosystemPaths);
121
+ } catch {
122
+ return records;
123
+ }
124
+ if (receipts.length === 0) return records;
125
+ return records.map((record) => {
126
+ const receipt = receipts.find((candidate) => record.path === candidate.targetPath || record.path.startsWith(`${candidate.targetPath}${sep}`));
127
+ if (!receipt) return record;
128
+ return { ...record, marketplaceProvenance: receipt.provenanceSummary };
129
+ });
130
+ }
131
+
132
+ export async function discoverSkills(
133
+ shellPaths: Pick<ShellPathService, 'workingDirectory' | 'homeDirectory'>,
134
+ ecosystemPaths?: EcosystemCatalogPathOptions,
135
+ ): Promise<SkillRecord[]> {
136
+ const cwd = shellPaths.workingDirectory;
137
+ const homeDir = shellPaths.homeDirectory;
138
+ const seen = new Set<string>();
139
+ const records: SkillRecord[] = [];
140
+
141
+ for (const { root, origin } of getSkillDirectories(cwd, homeDir)) {
142
+ for (const record of await scanSkillDirectory(root, origin)) {
143
+ if (seen.has(record.name.toLowerCase())) continue;
144
+ seen.add(record.name.toLowerCase());
145
+ records.push(record);
146
+ }
147
+ }
148
+
149
+ const tagged = ecosystemPaths ? applyMarketplaceProvenance(records, ecosystemPaths) : records;
150
+
151
+ return tagged.sort((a, b) => {
152
+ const originRank = a.origin === b.origin
153
+ ? 0
154
+ : a.origin === 'project-local'
155
+ ? -1
156
+ : 1;
157
+ return originRank || a.name.localeCompare(b.name);
158
+ });
159
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * view-deps.ts, what the built-in modals and views are built from.
3
+ *
4
+ * Composed once at startup (runtime/bootstrap-shell.ts) and handed to
5
+ * createShellViews (builtin-views.ts), which builds the always-on read models
6
+ * (usage, fleet acts and spawn) and registers every config-modal surface.
7
+ */
8
+
9
+ import type { ConfigManager, ServiceRegistry, SubscriptionManager } from '@pellux/goodvibes-sdk/platform/config';
10
+ import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
11
+ import type { ProviderRegistry } from '@pellux/goodvibes-sdk/platform/providers';
12
+ import type { Orchestrator, SessionMemoryStore } from '@pellux/goodvibes-sdk/platform/core';
13
+ import type { MemoryAccess } from '@pellux/goodvibes-sdk/platform/runtime/memory-spine';
14
+ import type { HookActivityTracker, HookDispatcher, HookWorkbench } from '@pellux/goodvibes-sdk/platform/hooks';
15
+ import type { UserAuthManager } from '@pellux/goodvibes-sdk/platform/security';
16
+ import type { ProjectPlanningService, KnowledgeApi } from '@pellux/goodvibes-sdk/platform/knowledge';
17
+ import type { SessionChangeTracker } from '@pellux/goodvibes-sdk/platform/sessions';
18
+ import type { WorkPlanStore } from '@pellux/goodvibes-sdk/platform/workflow';
19
+ import type { PolicyRuntimeState, SandboxSessionRegistry } from '@/runtime/index.ts';
20
+ import type { UiRuntimeServices } from '../runtime/ui-services.ts';
21
+ import type { PluginsModalManager } from './modals/plugins-modal.ts';
22
+
23
+ export interface BuiltinViewDeps {
24
+ readonly providerRegistry: ProviderRegistry;
25
+ readonly uiServices: UiRuntimeServices;
26
+ readonly toolRegistry?: ToolRegistry;
27
+ /** The main orchestrator (session usage and context size). */
28
+ readonly orchestrator?: Orchestrator;
29
+ /** The current model's context window in tokens. */
30
+ readonly getCtxWindow?: () => number;
31
+ readonly requestRender?: () => void;
32
+ readonly sandboxSessionRegistry: SandboxSessionRegistry;
33
+ /** Memory access for the Memory modal (the spine client, which routes to an adopted daemon). */
34
+ readonly memoryRegistry?: MemoryAccess;
35
+ readonly pluginManager?: PluginsModalManager;
36
+ readonly hookDispatcher?: Pick<HookDispatcher, 'listHooks' | 'getChains'>;
37
+ readonly hookWorkbench?: HookWorkbench;
38
+ readonly hookActivityTracker?: Pick<HookActivityTracker, 'listRecent'>;
39
+ readonly knowledgeApi?: KnowledgeApi;
40
+ /** The files this session edited (the Changes modal's default view). */
41
+ readonly sessionChangeTracker?: Pick<SessionChangeTracker, 'getChangedFiles'>;
42
+ /** Report a fleet act's result (late-bound to the command context's print). */
43
+ readonly fleetActsNotify?: (message: string) => void;
44
+ /** Hand a spawned session id to the one-key jump affordance (late-bound). */
45
+ readonly armFixSessionAttach?: (sessionId: string) => void;
46
+ }
47
+
48
+ /** The deps with everything the modals require resolved from the UI services. */
49
+ export type ResolvedBuiltinViewDeps = BuiltinViewDeps & {
50
+ readonly configManager: ConfigManager;
51
+ readonly localUserAuthManager: UserAuthManager;
52
+ readonly subscriptionManager: SubscriptionManager;
53
+ readonly serviceRegistry: ServiceRegistry;
54
+ readonly sessionMemoryStore: SessionMemoryStore;
55
+ readonly projectPlanningService: ProjectPlanningService;
56
+ readonly projectPlanningProjectId: string;
57
+ readonly workPlanStore: WorkPlanStore;
58
+ readonly policyRuntimeState: PolicyRuntimeState;
59
+ };
60
+
61
+ function required<T>(value: T | undefined, what: string): T {
62
+ if (value === undefined) throw new Error(`${what} must be wired at bootstrap for the built-in modals.`);
63
+ return value;
64
+ }
65
+
66
+ export function resolveBuiltinViewDeps(deps: BuiltinViewDeps): ResolvedBuiltinViewDeps {
67
+ const ui = deps.uiServices;
68
+ return {
69
+ ...deps,
70
+ configManager: required(ui.platform.configManager, 'Config manager'),
71
+ localUserAuthManager: required(ui.platform.localUserAuthManager, 'Local auth manager'),
72
+ subscriptionManager: required(ui.platform.subscriptionManager, 'Subscription manager'),
73
+ serviceRegistry: required(ui.platform.serviceRegistry, 'Service registry'),
74
+ sessionMemoryStore: required(ui.sessions.sessionMemoryStore, 'Session memory store'),
75
+ projectPlanningService: required(ui.planning.projectPlanningService, 'Project planning service'),
76
+ projectPlanningProjectId: required(ui.planning.projectPlanningProjectId, 'Project planning project id'),
77
+ workPlanStore: required(ui.planning.workPlanStore, 'Work plan store'),
78
+ policyRuntimeState: required(ui.platform.policyRuntimeState, 'Policy runtime state'),
79
+ };
80
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * view-panel-adapter.ts, the operator API's panels.list / panels.open, answered
3
+ * by the modal views.
4
+ *
5
+ * THE ONLY PLACE PANE VOCABULARY IS KEPT IN THE TUI. The terminal has no panes:
6
+ * every view opens as a modal. The names here (ViewPanelAdapter, PanelManagerLike,
7
+ * getTopPane/getBottomPane, NO_PANES, the `panels` field) are kept on purpose
8
+ * because they are the SDK's contract, not TUI design:
9
+ * - the SDK's IntegrationHelperService serves the operator API verbs
10
+ * panels.list and panels.open (and the /api/panels/* HTTP routes) from the
11
+ * `panelManager` option, typed PanelManagerLike;
12
+ * - remote clients, the web UI and the daemon already speak those verb names.
13
+ * Renaming them is an SDK and wire change, so the TUI keeps one adapter that
14
+ * satisfies the contract and translates it: panels.list lists the views a
15
+ * remote client can open (Agents, Usage, Changes, Notifications, Sessions),
16
+ * panels.open opens one as its modal, and both pane lists are always empty
17
+ * because nothing is ever open in a pane. The opener is set by the shell once
18
+ * the modal host exists. See docs/architecture.md ("The operator API bridge").
19
+ */
20
+
21
+ import type { IntegrationHelperService } from '@/runtime/index.ts';
22
+
23
+ /** The SDK's panel-manager contract, as IntegrationHelperService takes it. */
24
+ type PanelManagerLike = ConstructorParameters<typeof IntegrationHelperService>[0]['panelManager'];
25
+ type PanelPaneLike = ReturnType<PanelManagerLike['getTopPane']>;
26
+ type PanelRegistrationLike = ReturnType<PanelManagerLike['getRegisteredTypes']>[number];
27
+
28
+ const VIEWS: readonly PanelRegistrationLike[] = [
29
+ { id: 'agents', name: 'Agents', category: 'views', description: 'Running and finished agents, chains, workflows and hosted sessions; steer, stop, open a transcript' },
30
+ { id: 'usage', name: 'Usage', category: 'views', description: 'Context pressure, session tokens and cost, per-turn history, per-agent costs, budget alert' },
31
+ { id: 'changes', name: 'Changes', category: 'views', description: 'Changed files with a tinted diff, semantic summary, hunk staging, review comments and recent commits' },
32
+ { id: 'notifications', name: 'Notifications', category: 'views', description: 'Everything the notification feed collected, newest first' },
33
+ { id: 'sessions', name: 'Sessions', category: 'views', description: 'Saved, hosted and cross-surface sessions' },
34
+ ];
35
+
36
+ const NO_PANES: PanelPaneLike = { panels: [], activeIndex: 0 };
37
+
38
+ export interface ViewPanelAdapter extends PanelManagerLike {
39
+ /** Set how a view name is opened (returns false when nothing holds it). */
40
+ setOpener(open: (id: string) => boolean): void;
41
+ }
42
+
43
+ export function createViewPanelAdapter(): ViewPanelAdapter {
44
+ let opener: ((id: string) => boolean) | null = null;
45
+ return {
46
+ getTopPane: () => NO_PANES,
47
+ getBottomPane: () => NO_PANES,
48
+ getRegisteredTypes: () => VIEWS,
49
+ open: (id: string) => opener?.(id) ?? false,
50
+ show: () => {},
51
+ setOpener: (open) => { opener = open; },
52
+ };
53
+ }
@@ -7,7 +7,7 @@
7
7
  // blockedReason, orphaned, stalled, agentId), edges (from → to dependency
8
8
  // links), and the elastic-pool state (ready/running/atCap/maxSize). This module
9
9
  // is a pure string renderer; every line is fit to the given width (no clipping,
10
- // no horizontal overflow), so the same output drives a panel or a command.
10
+ // no horizontal overflow), so the same output drives a view or a command.
11
11
  // ---------------------------------------------------------------------------
12
12
 
13
13
  import type { OperatorMethodOutput } from '@pellux/goodvibes-sdk';
@@ -1,101 +0,0 @@
1
- /**
2
- * conversation-fold.ts, which transcript rows render FOLDED, and what spacing
3
- * that earns them.
4
- *
5
- * A folded tool result is exactly ONE row: its header, with the preview riding
6
- * on the same line after the `▸ N lines` badge. It used to be four rows, a
7
- * `▄▄▄` cap, an interior preview line carrying a second `[▸ N hidden]` count, a
8
- * `▀▀▀` cap, and a blank after all of it, for one line of text the header had
9
- * already sized.
10
- *
11
- * These predicates live in their own leaf module because TWO callers must agree
12
- * on them and neither may depend on the other: the row renderer
13
- * (conversation-rendering.ts) decides how to draw the row, and the line cache
14
- * (conversation-line-cache.ts) decides the blank separator that follows it. If
15
- * those two ever disagreed about which rows are folded, a warm cache and a cold
16
- * rebuild would space the transcript differently, the exact class of bug the
17
- * cache's byte-identical contract exists to rule out.
18
- *
19
- * Everything here is PURE: collapse state is read, never written, so a row can
20
- * be asked about before it has rendered.
21
- */
22
-
23
- import { foldedToolResult, trailingBlankAfterRow } from '@pellux/goodvibes-terminal-shell';
24
- import { summarizeToolResult } from '../renderer/tool-result-summary.ts';
25
- import { isTurnCollapsed, type ConversationRenderContext } from './conversation-render-context.ts';
26
- import { collapseKeyForNode, type RenderNode } from './conversation-turn-structure.ts';
27
- import type { ConversationMessageSnapshot } from '@pellux/goodvibes-sdk/platform/core';
28
-
29
- /** The subset of a render context these predicates read. */
30
- type FoldContext = Pick<ConversationRenderContext, 'assistantTurns' | 'collapseState'>;
31
-
32
- /**
33
- * Does a tool-result row render FOLDED, one compact header row with its preview
34
- * on it, rather than header-plus-expanded-body?
35
- *
36
- * An unset collapse key answers the same as the default the row itself will
37
- * store (collapsed), so asking before and asking after the row renders give the
38
- * same answer.
39
- */
40
- export function isToolResultFolded(
41
- message: Extract<ConversationMessageSnapshot, { role: 'tool' }>,
42
- collapseState: ReadonlyMap<string, boolean>,
43
- collapseKey: string,
44
- ): boolean {
45
- // Threading only, the decision, the short-content threshold and the
46
- // unset-key default all belong to foldedToolResult(). summarizeToolResult is
47
- // this product's own renderer concern, so resolving it stays here: a
48
- // summarizable result stays folded even when short, because the one-line
49
- // summary is the better row and the raw payload belongs behind the toggle.
50
- return foldedToolResult({
51
- contentLength: message.content.length,
52
- hasSummary: summarizeToolResult(message.toolName, message.content) !== null,
53
- storedCollapsed: collapseState.get(collapseKey),
54
- });
55
- }
56
-
57
- /** A row that belongs to a tool run: the call itself, or the result under it. */
58
- function isToolRunNode(node: RenderNode): boolean {
59
- return node.kind === 'toolcall' || node.message.role === 'tool';
60
- }
61
-
62
- /**
63
- * Does this planned row emit exactly one folded tool-result line?
64
- *
65
- * A collapsed turn hides the row entirely, so there is no folded row to butt up
66
- * against the next one.
67
- */
68
- function rendersFoldedToolRow(node: RenderNode, context: FoldContext): boolean {
69
- if (node.kind === 'toolcall') return false;
70
- const message = node.message;
71
- if (message.role !== 'tool') return false;
72
- if (isTurnCollapsed(context.assistantTurns?.get(node.absIdx), context.collapseState)) return false;
73
- return isToolResultFolded(message, context.collapseState, collapseKeyForNode(node));
74
- }
75
-
76
- /**
77
- * The blank separator that follows a planned row.
78
- *
79
- * Branch rows sit tight under their parent, so the blank lands only after the
80
- * last row of a top-level unit, that is what keeps a turn's whole subtree
81
- * reading as one block. On top of that, a folded row followed by more tool
82
- * machinery gets NO blank at all: N consecutive folded results stack as N
83
- * adjacent single rows. A folded row followed by anything that is not tool
84
- * machinery keeps its blank, so the run still separates from the prose around
85
- * it.
86
- */
87
- export function trailingBlankAfter(
88
- node: RenderNode,
89
- next: RenderNode | undefined,
90
- context: FoldContext,
91
- ): boolean {
92
- // Adaptation only, RenderNode is this product's shape, so reading depth and
93
- // node kind off it stays here; the rule those facts feed belongs to
94
- // trailingBlankAfterRow(). No `next` at all means end of transcript: neither
95
- // a branch row nor tool machinery follows, which is the plain-blank case.
96
- return trailingBlankAfterRow({
97
- nextIsBranchRow: next !== undefined && next.depth !== 0,
98
- nextIsToolMachinery: next !== undefined && isToolRunNode(next),
99
- rowRendersFolded: rendersFoldedToolRow(node, context),
100
- });
101
- }