@pellux/goodvibes-tui 1.27.1 → 2.0.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 (405) hide show
  1. package/CHANGELOG.md +116 -2
  2. package/README.md +7 -9
  3. package/bin/goodvibes +2 -2
  4. package/bin/launcher-support.js +8 -4
  5. package/docs/README.md +11 -2
  6. package/docs/foundation-artifacts/operator-contract.json +6403 -2347
  7. package/package.json +14 -25
  8. package/scripts/postinstall.js +35 -35
  9. package/src/audio/spoken-turn-model-routing.ts +1 -1
  10. package/src/cli/bundle-command.ts +5 -5
  11. package/src/cli/completions/generate.ts +1 -1
  12. package/src/cli/doctor.ts +3 -3
  13. package/src/cli/entrypoint.ts +12 -7
  14. package/src/cli/help.ts +4 -5
  15. package/src/cli/hooks-command.ts +1 -1
  16. package/src/cli/index.ts +1 -4
  17. package/src/cli/launch-auto-update.ts +59 -7
  18. package/src/cli/management-commands.ts +6 -6
  19. package/src/cli/management-utils.ts +5 -5
  20. package/src/cli/management.ts +7 -7
  21. package/src/cli/network-posture.ts +1 -1
  22. package/src/cli/package-verification.ts +7 -6
  23. package/src/cli/plugin-bundles-command.ts +1 -1
  24. package/src/cli/plugin-command.ts +2 -2
  25. package/src/cli/service-command.ts +2 -2
  26. package/src/cli/service-posture.ts +4 -4
  27. package/src/cli/status.ts +9 -8
  28. package/src/cli/surface-command.ts +4 -4
  29. package/src/cli/tui-startup.ts +3 -3
  30. package/src/cli-flags.ts +3 -3
  31. package/src/config/goodvibes-home-audit.ts +0 -2
  32. package/src/config/secret-config.ts +37 -5
  33. package/src/config/tui-extension-settings.ts +1 -1
  34. package/src/core/approval-alert.ts +2 -2
  35. package/src/core/budget-breach-notifier.ts +3 -3
  36. package/src/core/conversation-compaction-render.ts +1 -1
  37. package/src/core/conversation-line-cache.ts +1 -1
  38. package/src/core/conversation-render-context.ts +1 -1
  39. package/src/core/conversation-rendering.ts +2 -2
  40. package/src/core/conversation.ts +10 -10
  41. package/src/core/long-task-notifier.ts +2 -2
  42. package/src/core/memory-diagnostics-gateway.ts +1 -1
  43. package/src/core/scriptable-statusline.ts +1 -1
  44. package/src/core/session-auto-titler.ts +1 -1
  45. package/src/core/session-resume-core.ts +2 -2
  46. package/src/core/stream-event-wiring.ts +24 -44
  47. package/src/core/terminal-notifier.ts +3 -3
  48. package/src/core/turn-cancellation.ts +1 -1
  49. package/src/core/turn-event-wiring.ts +5 -5
  50. package/src/input/command-registry.ts +6 -6
  51. package/src/input/commands/channel-pairing.ts +1 -1
  52. package/src/input/commands/cluster-runtime.ts +1 -1
  53. package/src/input/commands/codebase-runtime.ts +1 -1
  54. package/src/input/commands/devices-runtime.ts +1 -1
  55. package/src/input/commands/hosted-runtime.ts +330 -0
  56. package/src/input/commands/local-setup-review.ts +1 -1
  57. package/src/input/commands/local-setup-transfer.ts +2 -2
  58. package/src/input/commands/local-setup.ts +3 -3
  59. package/src/input/commands/managed-runtime.ts +2 -2
  60. package/src/input/commands/operator-rpc.ts +24 -110
  61. package/src/input/commands/payment-card-intake.ts +1 -1
  62. package/src/input/commands/permissions-provenance.ts +2 -2
  63. package/src/input/commands/plugin-runtime.ts +1 -1
  64. package/src/input/commands/provider.ts +1 -1
  65. package/src/input/commands/relay-runtime.ts +18 -9
  66. package/src/input/commands/rewind-runtime.ts +1 -1
  67. package/src/input/commands/runtime-services.ts +1 -1
  68. package/src/input/commands/services-runtime.ts +1 -1
  69. package/src/input/commands/session-workflow.ts +1 -1
  70. package/src/input/commands/settings-sync-runtime.ts +2 -2
  71. package/src/input/commands/share-runtime.ts +1 -1
  72. package/src/input/commands/tasks-runtime.ts +145 -55
  73. package/src/input/commands/update-runtime.ts +31 -28
  74. package/src/input/commands/work-plan-runtime.ts +2 -2
  75. package/src/input/commands/workstream-attempts.ts +1 -1
  76. package/src/input/commands/workstream-runtime.ts +2 -2
  77. package/src/input/commands.ts +2 -0
  78. package/src/input/feature-unit-layout.ts +1 -1
  79. package/src/input/feed-context-factory.ts +3 -3
  80. package/src/input/handler-content-actions.ts +2 -2
  81. package/src/input/handler-feed-routes.ts +1 -1
  82. package/src/input/handler-feed.ts +3 -3
  83. package/src/input/handler-modal-token-routes.ts +1 -1
  84. package/src/input/handler-onboarding-daemon-adopt.ts +3 -2
  85. package/src/input/handler-onboarding.ts +1 -1
  86. package/src/input/handler-types.ts +2 -2
  87. package/src/input/handler-ui-state.ts +1 -1
  88. package/src/input/handler.ts +4 -4
  89. package/src/input/input-history.ts +1 -1
  90. package/src/input/onboarding/onboarding-feature-units.ts +2 -2
  91. package/src/input/onboarding/onboarding-runtime-status.ts +15 -1
  92. package/src/input/onboarding/onboarding-wizard-apply.ts +17 -8
  93. package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +5 -3
  94. package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +1 -1
  95. package/src/input/onboarding/onboarding-wizard-types.ts +1 -1
  96. package/src/input/payments-config.ts +6 -6
  97. package/src/input/search.ts +1 -1
  98. package/src/input/session-picker-modal.ts +46 -0
  99. package/src/input/settings-modal-activation.ts +1 -1
  100. package/src/input/settings-modal-behavior.ts +4 -4
  101. package/src/input/settings-modal-commit.ts +11 -0
  102. package/src/input/settings-modal-data.ts +13 -80
  103. package/src/input/settings-modal-mutations.ts +33 -0
  104. package/src/input/settings-modal-secrets.ts +34 -0
  105. package/src/input/settings-modal-subscriptions.ts +1 -1
  106. package/src/input/settings-modal-types.ts +15 -1
  107. package/src/input/settings-modal.ts +28 -3
  108. package/src/input/worktree-setup-config.ts +1 -1
  109. package/src/main.ts +11 -9
  110. package/src/panels/agent-inspector-shared.ts +2 -2
  111. package/src/panels/base-panel.ts +2 -2
  112. package/src/panels/builtin/operations.ts +6 -8
  113. package/src/panels/builtin/session.ts +17 -0
  114. package/src/panels/builtin/shared.ts +5 -5
  115. package/src/panels/builtin-modals.ts +3 -3
  116. package/src/panels/confirm-state.ts +1 -1
  117. package/src/panels/cost-tracker-panel.ts +4 -4
  118. package/src/panels/diff-panel.ts +2 -2
  119. package/src/panels/diff-review-panel.ts +2 -2
  120. package/src/panels/expandable-list-panel.ts +2 -2
  121. package/src/panels/fleet-acts.ts +1 -1
  122. package/src/panels/fleet-observed-render.ts +1 -1
  123. package/src/panels/fleet-panel-format.ts +1 -1
  124. package/src/panels/fleet-panel.ts +1 -1
  125. package/src/panels/fleet-spawn.ts +1 -1
  126. package/src/panels/fleet-steer.ts +1 -1
  127. package/src/panels/fleet-transcript.ts +1 -1
  128. package/src/panels/git-panel.ts +1 -1
  129. package/src/panels/hosted-session-feed.ts +352 -0
  130. package/src/panels/hosted-session-panel.ts +221 -0
  131. package/src/panels/local-auth-panel.ts +3 -3
  132. package/src/panels/modals/devices-modal.ts +1 -1
  133. package/src/panels/modals/local-auth-modal.ts +1 -1
  134. package/src/panels/modals/pairing-modal.ts +1 -1
  135. package/src/panels/modals/services-modal.ts +1 -1
  136. package/src/panels/modals/settings-sync-modal.ts +1 -1
  137. package/src/panels/modals/subscription-modal.ts +1 -1
  138. package/src/panels/modals/work-plan-modal.ts +1 -1
  139. package/src/panels/notifications-panel.ts +1 -1
  140. package/src/panels/panel-confirm-overlay.ts +1 -1
  141. package/src/panels/plugins-panel.ts +2 -2
  142. package/src/panels/polish-core.ts +2 -2
  143. package/src/panels/polish-tables.ts +1 -1
  144. package/src/panels/polish.ts +2 -2
  145. package/src/panels/scrollable-list-panel.ts +3 -3
  146. package/src/panels/skills-panel.ts +3 -3
  147. package/src/panels/token-budget-panel.ts +5 -5
  148. package/src/panels/types.ts +1 -2
  149. package/src/permissions/prompt.ts +1 -1
  150. package/src/renderer/autocomplete-overlay.ts +1 -1
  151. package/src/renderer/block-actions-overlay.ts +1 -1
  152. package/src/renderer/bookmark-modal.ts +1 -1
  153. package/src/renderer/buffer.ts +1 -1
  154. package/src/renderer/code-block.ts +1 -1
  155. package/src/renderer/composer-fragments.ts +1 -1
  156. package/src/renderer/compositor.ts +2 -2
  157. package/src/renderer/config-modal.ts +1 -1
  158. package/src/renderer/context-inspector.ts +1 -1
  159. package/src/renderer/conversation-layout.ts +2 -2
  160. package/src/renderer/conversation-overlays.ts +1 -1
  161. package/src/renderer/conversation-surface.ts +2 -2
  162. package/src/renderer/diff-view.ts +1 -1
  163. package/src/renderer/diff.ts +1 -1
  164. package/src/renderer/file-picker-overlay.ts +1 -1
  165. package/src/renderer/fleet-tab-strip.ts +1 -1
  166. package/src/renderer/fullscreen-primitives.ts +2 -2
  167. package/src/renderer/fullscreen-workspace.ts +1 -1
  168. package/src/renderer/header-line.ts +1 -1
  169. package/src/renderer/help-overlay.ts +1 -1
  170. package/src/renderer/history-search-overlay.ts +2 -2
  171. package/src/renderer/layout.ts +5 -8
  172. package/src/renderer/markdown-inline.ts +1 -1
  173. package/src/renderer/markdown-table.ts +1 -1
  174. package/src/renderer/markdown.ts +1 -1
  175. package/src/renderer/mcp-workspace.ts +1 -1
  176. package/src/renderer/modal-factory.ts +2 -2
  177. package/src/renderer/model-workspace.ts +2 -2
  178. package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
  179. package/src/renderer/overlay-box.ts +1 -1
  180. package/src/renderer/panel-composite.ts +1 -1
  181. package/src/renderer/panel-workspace-bar.ts +1 -1
  182. package/src/renderer/process-indicator.ts +1 -1
  183. package/src/renderer/profile-picker-modal.ts +1 -1
  184. package/src/renderer/search-overlay.ts +2 -2
  185. package/src/renderer/selection-modal-overlay.ts +1 -1
  186. package/src/renderer/session-picker-modal.ts +124 -3
  187. package/src/renderer/settings-modal-helpers.ts +2 -0
  188. package/src/renderer/settings-modal.ts +2 -2
  189. package/src/renderer/shell-surface.ts +2 -2
  190. package/src/renderer/system-message.ts +1 -1
  191. package/src/renderer/tab-strip.ts +1 -1
  192. package/src/renderer/theme-mode-config.ts +1 -1
  193. package/src/renderer/theme.ts +11 -12
  194. package/src/renderer/thinking.ts +1 -1
  195. package/src/renderer/tool-call.ts +2 -2
  196. package/src/renderer/tool-result-expanded-lines.ts +1 -1
  197. package/src/renderer/turn-injection.ts +7 -8
  198. package/src/renderer/ui-factory.ts +3 -3
  199. package/src/runtime/bootstrap-command-context.ts +4 -4
  200. package/src/runtime/bootstrap-command-parts.ts +5 -5
  201. package/src/runtime/bootstrap-core.ts +30 -30
  202. package/src/runtime/bootstrap-shell.ts +4 -4
  203. package/src/runtime/bootstrap.ts +128 -157
  204. package/src/runtime/client/approval-updates.ts +82 -0
  205. package/src/runtime/client/build-floors.ts +167 -0
  206. package/src/runtime/client/daemon-attach-handshake.ts +115 -0
  207. package/src/runtime/client/fleet-union.ts +147 -0
  208. package/src/runtime/client/host-service-status.ts +71 -0
  209. package/src/runtime/client/hosted-exit.ts +86 -0
  210. package/src/runtime/client/hosted-roster.ts +110 -0
  211. package/src/runtime/client/hosted-session-stream.ts +178 -0
  212. package/src/runtime/client/hosted-sessions.ts +187 -0
  213. package/src/runtime/client/operator-endpoint.ts +213 -0
  214. package/src/runtime/client/spine-adoption.ts +99 -0
  215. package/src/runtime/cloudflare-control-plane.ts +1 -1
  216. package/src/runtime/context-accounting-source.ts +1 -1
  217. package/src/runtime/context.ts +2 -2
  218. package/src/runtime/conversation-rewind-port.ts +42 -14
  219. package/src/runtime/daemon-attach-notices.ts +55 -19
  220. package/src/runtime/diagnostics/panels/ops.ts +1 -1
  221. package/src/runtime/disposal-wiring.ts +4 -24
  222. package/src/runtime/index.ts +119 -105
  223. package/src/runtime/install-self-check-startup.ts +2 -2
  224. package/src/runtime/interaction-seams.ts +1 -1
  225. package/src/runtime/knowledge-services.ts +8 -2
  226. package/src/runtime/legacy-daemon-migration.ts +4 -3
  227. package/src/runtime/legacy-daemon-reconcile.ts +3 -2
  228. package/src/runtime/memory-spine-transport.ts +37 -267
  229. package/src/runtime/notification-dispatch.ts +2 -2
  230. package/src/runtime/onboarding/apply.ts +2 -2
  231. package/src/runtime/onboarding/derivation.ts +2 -2
  232. package/src/runtime/onboarding/markers.ts +2 -2
  233. package/src/runtime/onboarding/progress.ts +2 -2
  234. package/src/runtime/onboarding/snapshot.ts +1 -1
  235. package/src/runtime/onboarding/state.ts +2 -2
  236. package/src/runtime/onboarding/types.ts +2 -2
  237. package/src/runtime/orchestrator-core-services.ts +1 -1
  238. package/src/runtime/path-shadow-startup.ts +28 -221
  239. package/src/runtime/power-keepawake-remote.ts +3 -2
  240. package/src/runtime/process-lifecycle.ts +2 -2
  241. package/src/runtime/provider-fallback.ts +10 -66
  242. package/src/runtime/recovery-autosave.ts +1 -1
  243. package/src/runtime/recovery-offer-wiring.ts +39 -23
  244. package/src/runtime/recovery-prompt.ts +31 -17
  245. package/src/runtime/relay-reachability-bridge.ts +53 -42
  246. package/src/runtime/release-artifacts.ts +2 -1
  247. package/src/runtime/runtime-services-types.ts +82 -35
  248. package/src/runtime/services.ts +305 -300
  249. package/src/runtime/session-resume-liveness-confirm.ts +1 -1
  250. package/src/runtime/ui-services.ts +7 -6
  251. package/src/runtime/update-check.ts +23 -43
  252. package/src/runtime/workspace-checkpointing.ts +1 -1
  253. package/src/runtime/wrfc-persistence.ts +2 -2
  254. package/src/shell/ui-openers.ts +30 -7
  255. package/src/utils/clipboard.ts +1 -1
  256. package/src/verification/verification-ledger.ts +10 -8
  257. package/src/version.ts +1 -1
  258. package/bin/goodvibes-daemon +0 -90
  259. package/src/cli/config-overrides.ts +0 -267
  260. package/src/cli/endpoints.ts +0 -109
  261. package/src/cli/parser.ts +0 -395
  262. package/src/cli/redaction.ts +0 -170
  263. package/src/cli/types.ts +0 -84
  264. package/src/cluster/commands.ts +0 -382
  265. package/src/cluster/remote-daemon-target.ts +0 -225
  266. package/src/cluster/render.ts +0 -268
  267. package/src/config/atomic-write.ts +0 -70
  268. package/src/config/credential-availability.ts +0 -122
  269. package/src/config/goodvibes-home.ts +0 -149
  270. package/src/config/index.ts +0 -88
  271. package/src/config/provider-model.ts +0 -23
  272. package/src/config/read-versioned.ts +0 -228
  273. package/src/core/alert-gating.ts +0 -67
  274. package/src/core/consolidation-receipt.ts +0 -41
  275. package/src/core/focus-tracker.ts +0 -41
  276. package/src/core/history.ts +0 -45
  277. package/src/core/memory-status.ts +0 -118
  278. package/src/core/orchestrator.ts +0 -7
  279. package/src/core/pairing-devices.ts +0 -49
  280. package/src/core/pairing-handoff.ts +0 -101
  281. package/src/core/pairing-offers.ts +0 -83
  282. package/src/core/pairing-origin.ts +0 -78
  283. package/src/core/rewind-turn-anchors.ts +0 -311
  284. package/src/core/session-recovery.ts +0 -210
  285. package/src/core/stable-host.ts +0 -171
  286. package/src/core/transcript-journal.ts +0 -503
  287. package/src/daemon/cli.ts +0 -693
  288. package/src/daemon/fatal-boot-report.ts +0 -111
  289. package/src/daemon/handlers/context.ts +0 -29
  290. package/src/daemon/handlers/contracts.ts +0 -77
  291. package/src/daemon/handlers/credentials.ts +0 -139
  292. package/src/daemon/handlers/drafts/draft-store.ts +0 -427
  293. package/src/daemon/handlers/drafts/index.ts +0 -17
  294. package/src/daemon/handlers/drafts/register.ts +0 -331
  295. package/src/daemon/handlers/errors.ts +0 -18
  296. package/src/daemon/handlers/inbox/cursor-store.ts +0 -457
  297. package/src/daemon/handlers/inbox/index.ts +0 -284
  298. package/src/daemon/handlers/inbox/mapping.ts +0 -192
  299. package/src/daemon/handlers/inbox/poller.ts +0 -212
  300. package/src/daemon/handlers/inbox/provider-adapter.ts +0 -156
  301. package/src/daemon/handlers/inbox/providers/discord.ts +0 -252
  302. package/src/daemon/handlers/inbox/providers/email.ts +0 -152
  303. package/src/daemon/handlers/inbox/providers/imap-client.ts +0 -300
  304. package/src/daemon/handlers/inbox/providers/route-util.ts +0 -24
  305. package/src/daemon/handlers/inbox/providers/slack.ts +0 -263
  306. package/src/daemon/handlers/index.ts +0 -117
  307. package/src/daemon/handlers/register.ts +0 -168
  308. package/src/daemon/handlers/remote/backends/cloud-terminal.ts +0 -142
  309. package/src/daemon/handlers/remote/backends/docker.ts +0 -79
  310. package/src/daemon/handlers/remote/backends/index.ts +0 -40
  311. package/src/daemon/handlers/remote/backends/local-process.ts +0 -113
  312. package/src/daemon/handlers/remote/backends/process-runner.ts +0 -127
  313. package/src/daemon/handlers/remote/backends/ssh.ts +0 -125
  314. package/src/daemon/handlers/remote/backends/types.ts +0 -97
  315. package/src/daemon/handlers/remote/dispatcher.ts +0 -181
  316. package/src/daemon/handlers/remote/index.ts +0 -119
  317. package/src/daemon/handlers/remote/peer-registry.ts +0 -357
  318. package/src/daemon/handlers/remote/service.ts +0 -191
  319. package/src/daemon/handlers/routing/inbox-bridge.ts +0 -71
  320. package/src/daemon/handlers/routing/index.ts +0 -261
  321. package/src/daemon/handlers/routing/route-store.ts +0 -319
  322. package/src/daemon/handlers/routing/routing-resolver.ts +0 -75
  323. package/src/daemon/handlers/sqlite-store.ts +0 -278
  324. package/src/daemon/handlers/triage/index.ts +0 -57
  325. package/src/daemon/handlers/triage/integration.ts +0 -213
  326. package/src/daemon/handlers/triage/pipeline.ts +0 -274
  327. package/src/daemon/handlers/triage/scorer.ts +0 -287
  328. package/src/daemon/handlers/triage/tagger/discord.ts +0 -187
  329. package/src/daemon/handlers/triage/tagger/imap.ts +0 -384
  330. package/src/daemon/handlers/triage/tagger/index.ts +0 -184
  331. package/src/daemon/handlers/triage/tagger/shared.ts +0 -70
  332. package/src/daemon/handlers/triage/tagger/slack.ts +0 -69
  333. package/src/daemon/handlers/triage/types.ts +0 -50
  334. package/src/daemon/lifecycle.ts +0 -41
  335. package/src/daemon/provision-wake-model.ts +0 -81
  336. package/src/daemon/safe-serve.ts +0 -61
  337. package/src/daemon/send/channels.ts +0 -200
  338. package/src/daemon/send/command.ts +0 -332
  339. package/src/daemon/send/composition.ts +0 -99
  340. package/src/daemon/send/failure-text.ts +0 -93
  341. package/src/daemon/send/inert-text.ts +0 -225
  342. package/src/daemon/send/stdin.ts +0 -24
  343. package/src/daemon/service-commands.ts +0 -329
  344. package/src/export/cost-utils.ts +0 -319
  345. package/src/input/selection.ts +0 -135
  346. package/src/plugins/loader.ts +0 -15
  347. package/src/renderer/bottom-bar.ts +0 -58
  348. package/src/renderer/conversation-tree.ts +0 -228
  349. package/src/runtime/agent-graph-composition.ts +0 -78
  350. package/src/runtime/channel-composition.ts +0 -46
  351. package/src/runtime/cluster-composition.ts +0 -124
  352. package/src/runtime/cluster-group-composition.ts +0 -284
  353. package/src/runtime/code-index-services.ts +0 -167
  354. package/src/runtime/daemon-handler-composition.ts +0 -76
  355. package/src/runtime/device-posture-composition.ts +0 -110
  356. package/src/runtime/durability-housekeeping.ts +0 -183
  357. package/src/runtime/durability-services.ts +0 -155
  358. package/src/runtime/embedded-service-factories.ts +0 -74
  359. package/src/runtime/feature-settings.ts +0 -154
  360. package/src/runtime/fleet-needs-input-push.ts +0 -70
  361. package/src/runtime/fleet-services.ts +0 -41
  362. package/src/runtime/idle-power-services.ts +0 -85
  363. package/src/runtime/mail-composition.ts +0 -65
  364. package/src/runtime/memory-fold.ts +0 -55
  365. package/src/runtime/operator-token-cleanup.ts +0 -109
  366. package/src/runtime/path-shadow.ts +0 -418
  367. package/src/runtime/perf/panel-health-monitor.ts +0 -18
  368. package/src/runtime/provider-optimizer-wiring.ts +0 -55
  369. package/src/runtime/reachability-notice.ts +0 -100
  370. package/src/runtime/remote-execution-composition.ts +0 -62
  371. package/src/runtime/session-liveness-marker.ts +0 -257
  372. package/src/runtime/session-pointer-surface.ts +0 -22
  373. package/src/runtime/session-storage-services.ts +0 -41
  374. package/src/runtime/surface-feature-flags.ts +0 -96
  375. package/src/runtime/terminal-output-guard.ts +0 -235
  376. package/src/runtime/trust/workspace-registration.ts +0 -192
  377. package/src/runtime/trust/workspace-trust.ts +0 -229
  378. package/src/runtime/ui/index.ts +0 -39
  379. package/src/runtime/ui/model-picker/data-provider.ts +0 -182
  380. package/src/runtime/ui/model-picker/health-enrichment.ts +0 -231
  381. package/src/runtime/ui/model-picker/index.ts +0 -59
  382. package/src/runtime/ui/model-picker/types.ts +0 -153
  383. package/src/runtime/ui/provider-health/data-provider.ts +0 -244
  384. package/src/runtime/ui/provider-health/fallback-visualizer.ts +0 -71
  385. package/src/runtime/ui/provider-health/index.ts +0 -46
  386. package/src/runtime/ui/provider-health/types.ts +0 -146
  387. package/src/runtime/ui-events.ts +0 -1
  388. package/src/runtime/ui-read-model-helpers.ts +0 -1
  389. package/src/runtime/ui-read-models-observability-maintenance.ts +0 -1
  390. package/src/runtime/ui-read-models-observability-options.ts +0 -1
  391. package/src/runtime/ui-read-models-observability-remote.ts +0 -1
  392. package/src/runtime/ui-read-models-observability-security.ts +0 -1
  393. package/src/runtime/ui-read-models-observability-system.ts +0 -1
  394. package/src/runtime/ui-read-models-observability.ts +0 -1
  395. package/src/runtime/ui-service-queries.ts +0 -1
  396. package/src/runtime/voice-setup-services.ts +0 -98
  397. package/src/runtime/workstream-attempts-validation.ts +0 -77
  398. package/src/runtime/workstream-draft-edits.ts +0 -95
  399. package/src/runtime/workstream-draft-store.ts +0 -274
  400. package/src/runtime/workstream-draft-types.ts +0 -42
  401. package/src/runtime/workstream-services.ts +0 -373
  402. package/src/tools/index.ts +0 -1
  403. package/src/types/grid.ts +0 -48
  404. package/src/types/sql-js.d.ts +0 -15
  405. package/src/work-plans/work-plan-store.ts +0 -702
@@ -1,457 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Persistent cursor + item store for the inbound feed.
3
- //
4
- // Backed by HandlerSqliteStore (sql.js WASM) at
5
- // {wd}/.goodvibes/tui/operator/inbox.sqlite
6
- //
7
- // Two tables:
8
- // items(id PK, provider, kind, fromDigest, subjectPreview, bodyPreview,
9
- // routeId, receivedAt INT, unread INT)
10
- // cursors(provider PK, nextSince INT)
11
- //
12
- // Dedup is by items.id (upsert). nextSince advances monotonically per provider
13
- // = max(receivedAt) ever seen. Triage metadata is NOT persisted here: it is
14
- // applied downstream at the triage overlay layer (triage/integration.ts) over a
15
- // separate store, so this feed store carries only the raw inbound fields.
16
- //
17
- // RETENTION. The items table is bounded by BOTH an age TTL and a count cap, and
18
- // the sweep runs at init() — the recovery point, right after the database file
19
- // is opened — and then on a timer for the life of the store, so a daemon that
20
- // stays up for weeks keeps reclaiming. `pruneOlderThan` used to exist with no
21
- // production caller at all, which meant the table grew without bound in
22
- // practice. Reclaimed counts are handed to the `onSweep` hook (counts only —
23
- // message previews and sender ids never reach a log line).
24
- //
25
- // Cursors are deliberately NOT reaped: they are monotonic watermarks, so
26
- // dropping one would re-deliver everything a provider ever sent.
27
- //
28
- // Idempotence/concurrency: a sweep re-run immediately reclaims nothing (the
29
- // DELETEs are set-based over the current contents). Two processes opening the
30
- // same file each hold their own sql.js snapshot and `save()` writes the whole
31
- // file via temp+rename, so the last writer wins — that whole-file model is
32
- // HandlerSqliteStore's, and deletion converging on the same surviving set is
33
- // what makes concurrent sweeps safe rather than corrupting.
34
- // ---------------------------------------------------------------------------
35
-
36
- import { HandlerSqliteStore } from '../sqlite-store.ts';
37
- import type { InboundChannelItem } from './provider-adapter.ts';
38
-
39
- /**
40
- * Age TTL for feed items: rows whose receivedAt is older than this are dropped
41
- * on every sweep. Long enough that "what did that person say last month" still
42
- * works, short enough that the table cannot grow indefinitely.
43
- */
44
- export const INBOX_ITEM_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
45
-
46
- /**
47
- * Count cap for feed items: the newest this many rows survive a sweep, older
48
- * ones are dropped. Guards the case the TTL cannot — a very chatty month.
49
- */
50
- export const INBOX_ITEM_CAP = 5_000;
51
-
52
- /**
53
- * Cadence of the background retention sweep. The first sweep happens at init();
54
- * this timer is what keeps it from being a startup-only reap.
55
- */
56
- export const INBOX_SWEEP_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
57
-
58
- const DEFAULT_STORE_FILE_NAME = 'inbox.sqlite';
59
-
60
- /** Result of one retention sweep. Counts only — never item content. */
61
- export interface InboxSweepSummary {
62
- /** Unix ms of the sweep. */
63
- readonly at: number;
64
- /** Rows removed by the age TTL. */
65
- readonly expired: number;
66
- /** Rows removed by the count cap. */
67
- readonly capped: number;
68
- /** Rows left in the items table afterwards. */
69
- readonly remaining: number;
70
- }
71
-
72
- export interface InboxCursorStoreOptions {
73
- /** Override the age TTL (tests / embedders). Defaults to INBOX_ITEM_TTL_MS. */
74
- readonly itemTtlMs?: number;
75
- /** Override the count cap (tests / embedders). Defaults to INBOX_ITEM_CAP. */
76
- readonly itemCap?: number;
77
- /** Sweep cadence; 0 or less disables the timer (the init sweep still runs). */
78
- readonly sweepIntervalMs?: number;
79
- /** Called after a sweep that reclaimed at least one row. Counts only. */
80
- readonly onSweep?: (summary: InboxSweepSummary) => void;
81
- /** Called when a sweep failed, so retention problems are visible rather than swallowed. */
82
- readonly onSweepError?: (message: string) => void;
83
- /** Clock seam (tests). Defaults to Date.now. */
84
- readonly now?: () => number;
85
- /** Timer seams (tests). Default to the globals. */
86
- readonly setIntervalImpl?: typeof setInterval;
87
- readonly clearIntervalImpl?: typeof clearInterval;
88
- }
89
-
90
- const SCHEMA: string[] = [
91
- `CREATE TABLE IF NOT EXISTS items (
92
- id TEXT PRIMARY KEY,
93
- provider TEXT NOT NULL,
94
- kind TEXT NOT NULL,
95
- fromDigest TEXT NOT NULL,
96
- subjectPreview TEXT NOT NULL,
97
- bodyPreview TEXT NOT NULL,
98
- routeId TEXT,
99
- receivedAt INTEGER NOT NULL,
100
- unread INTEGER NOT NULL
101
- )`,
102
- `CREATE INDEX IF NOT EXISTS idx_items_provider_received
103
- ON items(provider, receivedAt)`,
104
- `CREATE INDEX IF NOT EXISTS idx_items_received
105
- ON items(receivedAt)`,
106
- `CREATE TABLE IF NOT EXISTS cursors (
107
- provider TEXT PRIMARY KEY,
108
- nextSince INTEGER NOT NULL
109
- )`,
110
- ];
111
-
112
- interface ItemRow {
113
- id: string;
114
- provider: string;
115
- kind: string;
116
- fromDigest: string;
117
- subjectPreview: string;
118
- bodyPreview: string;
119
- routeId: string | null;
120
- receivedAt: number;
121
- unread: number;
122
- }
123
-
124
- export interface InboxQuery {
125
- providers?: readonly string[];
126
- since?: number;
127
- /** Max items returned across the whole query. */
128
- limit: number;
129
- }
130
-
131
- export class InboxCursorStore {
132
- private readonly store: HandlerSqliteStore;
133
- private dirty = false;
134
- private readonly itemTtlMs: number;
135
- private readonly itemCap: number;
136
- private readonly sweepIntervalMs: number;
137
- private readonly onSweep: ((summary: InboxSweepSummary) => void) | undefined;
138
- private readonly onSweepError: ((message: string) => void) | undefined;
139
- private readonly now: () => number;
140
- private readonly setIntervalImpl: typeof setInterval;
141
- private readonly clearIntervalImpl: typeof clearInterval;
142
- private sweepTimer: ReturnType<typeof setInterval> | null = null;
143
- /**
144
- * Set by close(). `init()` is async and arms the retention timer only after
145
- * two awaits, so a surface that is torn down while its bootstrap is still in
146
- * flight would otherwise arm a timer AFTER the only thing that could clear it
147
- * had already run. That is not hypothetical: registerInboxMethods() kicks
148
- * init() off without awaiting it, so any shutdown inside the first tick of a
149
- * daemon's life hits exactly this window.
150
- */
151
- private closed = false;
152
-
153
- constructor(
154
- workingDirectory: string,
155
- fileName: string = DEFAULT_STORE_FILE_NAME,
156
- options: InboxCursorStoreOptions = {},
157
- ) {
158
- this.store = new HandlerSqliteStore({
159
- workingDirectory,
160
- fileName: fileName || DEFAULT_STORE_FILE_NAME,
161
- schema: SCHEMA,
162
- });
163
- this.itemTtlMs = options.itemTtlMs ?? INBOX_ITEM_TTL_MS;
164
- this.itemCap = options.itemCap ?? INBOX_ITEM_CAP;
165
- this.sweepIntervalMs = options.sweepIntervalMs ?? INBOX_SWEEP_INTERVAL_MS;
166
- this.onSweep = options.onSweep;
167
- this.onSweepError = options.onSweepError;
168
- this.now = options.now ?? Date.now;
169
- this.setIntervalImpl = options.setIntervalImpl ?? setInterval;
170
- this.clearIntervalImpl = options.clearIntervalImpl ?? clearInterval;
171
- }
172
-
173
- get dbPath(): string {
174
- return this.store.dbPath;
175
- }
176
-
177
- /**
178
- * Open the database, then immediately reap: recovery is exactly when stale
179
- * rows from previous runs must go. The periodic timer starts afterwards so
180
- * retention is not a startup-only event.
181
- */
182
- async init(): Promise<void> {
183
- await this.store.init();
184
- await this.runSweep();
185
- this.startSweepTimer();
186
- }
187
-
188
- /**
189
- * One retention pass: age TTL first, then the count cap over what is left.
190
- * Returns counts only. Running it twice in a row reclaims nothing the second
191
- * time — the pass is a function of the table's current contents.
192
- */
193
- sweepRetention(): InboxSweepSummary {
194
- const at = this.now();
195
- const expired = this.pruneOlderThan(at - this.itemTtlMs);
196
- const capped = this.enforceItemCap();
197
- return { at, expired, capped, remaining: this.countItems() };
198
- }
199
-
200
- /** Sweep, persist if anything was reclaimed, and disclose the counts. Never throws. */
201
- private async runSweep(): Promise<void> {
202
- try {
203
- const summary = this.sweepRetention();
204
- if (summary.expired + summary.capped === 0) return;
205
- await this.flush();
206
- this.onSweep?.(summary);
207
- } catch (error) {
208
- this.onSweepError?.(error instanceof Error ? error.message : String(error));
209
- }
210
- }
211
-
212
- private startSweepTimer(): void {
213
- if (this.closed || this.sweepTimer !== null || this.sweepIntervalMs <= 0) return;
214
- const handle = this.setIntervalImpl(() => {
215
- void this.runSweep();
216
- }, this.sweepIntervalMs);
217
- // Retention must never be the reason the process stays alive (Bun/Node unref).
218
- (handle as unknown as { unref?: () => void }).unref?.();
219
- this.sweepTimer = handle;
220
- }
221
-
222
- private stopSweepTimer(): void {
223
- if (this.sweepTimer === null) return;
224
- this.clearIntervalImpl(this.sweepTimer);
225
- this.sweepTimer = null;
226
- }
227
-
228
- /**
229
- * Count cap: keep the newest `itemCap` rows (receivedAt DESC, id ASC — the
230
- * same order listItems() uses), delete the rest. Returns rows removed.
231
- */
232
- private enforceItemCap(): number {
233
- const before = this.countItems();
234
- if (before <= this.itemCap) return 0;
235
- this.store.run(
236
- `DELETE FROM items WHERE id NOT IN (
237
- SELECT id FROM items ORDER BY receivedAt DESC, id ASC LIMIT ?
238
- )`,
239
- [this.itemCap],
240
- );
241
- const removed = before - this.countItems();
242
- if (removed > 0) this.dirty = true;
243
- return removed;
244
- }
245
-
246
- /**
247
- * Insert/refresh items, deduping by id. On conflict the mutable feed fields
248
- * (unread, previews, routeId, receivedAt) are updated in place.
249
- * Returns the number of NEW (previously unseen) items.
250
- */
251
- upsertItems(items: readonly InboundChannelItem[]): number {
252
- if (items.length === 0) return 0;
253
- let inserted = 0;
254
- // Only the ids in THIS batch can collide, so probe for exactly those rather
255
- // than loading the whole table — bounds the lookup to the poll size instead
256
- // of growing O(n) with the (unbounded) feed.
257
- const batchIds = [...new Set(items.map((i) => i.id))];
258
- const placeholders = batchIds.map(() => '?').join(', ');
259
- const existing = new Set(
260
- this.store
261
- .all<{ id: string }>(
262
- `SELECT id FROM items WHERE id IN (${placeholders})`,
263
- batchIds,
264
- )
265
- .map((r) => r.id),
266
- );
267
- // Track ids seen within this batch so a duplicate id in a single poll is
268
- // counted (and inserted) once, not once per occurrence.
269
- const seen = new Set<string>();
270
- this.store.transaction(() => {
271
- for (const item of items) {
272
- const isNew = !existing.has(item.id) && !seen.has(item.id);
273
- if (isNew) inserted += 1;
274
- seen.add(item.id);
275
- this.store.run(
276
- `INSERT INTO items
277
- (id, provider, kind, fromDigest, subjectPreview, bodyPreview,
278
- routeId, receivedAt, unread)
279
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
280
- ON CONFLICT(id) DO UPDATE SET
281
- provider = excluded.provider,
282
- kind = excluded.kind,
283
- fromDigest = excluded.fromDigest,
284
- subjectPreview = excluded.subjectPreview,
285
- bodyPreview = excluded.bodyPreview,
286
- routeId = COALESCE(excluded.routeId, items.routeId),
287
- receivedAt = excluded.receivedAt,
288
- unread = excluded.unread`,
289
- [
290
- item.id,
291
- item.provider,
292
- item.kind,
293
- item.fromDigest,
294
- item.subjectPreview,
295
- item.bodyPreview,
296
- item.routeId ?? null,
297
- item.receivedAt,
298
- item.unread ? 1 : 0,
299
- ],
300
- );
301
- }
302
- });
303
- this.dirty = true;
304
- return inserted;
305
- }
306
-
307
- /**
308
- * Advance a provider's cursor monotonically. The stored value is always the
309
- * max of the current value and the supplied candidate.
310
- */
311
- advanceCursor(provider: string, candidate: number): void {
312
- if (!Number.isFinite(candidate)) return;
313
- const current = this.getCursor(provider);
314
- const next = Math.max(current, Math.floor(candidate));
315
- if (next === current && current !== 0) return;
316
- this.store.run(
317
- `INSERT INTO cursors (provider, nextSince) VALUES (?, ?)
318
- ON CONFLICT(provider) DO UPDATE SET
319
- nextSince = MAX(cursors.nextSince, excluded.nextSince)`,
320
- [provider, next],
321
- );
322
- this.dirty = true;
323
- }
324
-
325
- /** Current cursor for a provider (0 when unset). */
326
- getCursor(provider: string): number {
327
- const row = this.store.get<{ nextSince: number }>(
328
- 'SELECT nextSince FROM cursors WHERE provider = ?',
329
- [provider],
330
- );
331
- return row ? Number(row.nextSince) : 0;
332
- }
333
-
334
- /**
335
- * Read items for the feed, filtered by provider set + since, newest first,
336
- * capped at limit. Maps SQLite rows back to the internal item shape.
337
- */
338
- listItems(query: InboxQuery): InboundChannelItem[] {
339
- const clauses: string[] = [];
340
- const params: (string | number)[] = [];
341
- if (query.providers && query.providers.length > 0) {
342
- const placeholders = query.providers.map(() => '?').join(', ');
343
- clauses.push(`provider IN (${placeholders})`);
344
- params.push(...query.providers);
345
- }
346
- if (typeof query.since === 'number' && Number.isFinite(query.since)) {
347
- clauses.push('receivedAt > ?');
348
- params.push(Math.floor(query.since));
349
- }
350
- const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
351
- const limit = Math.max(0, Math.floor(query.limit));
352
- params.push(limit);
353
- const rows = this.store.all<ItemRow>(
354
- `SELECT id, provider, kind, fromDigest, subjectPreview, bodyPreview,
355
- routeId, receivedAt, unread
356
- FROM items ${where}
357
- ORDER BY receivedAt DESC, id ASC
358
- LIMIT ?`,
359
- params,
360
- );
361
- return rows.map(rowToItem);
362
- }
363
-
364
- /** Highest receivedAt across the (optionally provider-filtered) feed, or 0. */
365
- maxReceivedAt(providers?: readonly string[]): number {
366
- let where = '';
367
- const params: (string | number)[] = [];
368
- if (providers && providers.length > 0) {
369
- const placeholders = providers.map(() => '?').join(', ');
370
- where = `WHERE provider IN (${placeholders})`;
371
- params.push(...providers);
372
- }
373
- const row = this.store.get<{ maxReceived: number | null }>(
374
- `SELECT MAX(receivedAt) AS maxReceived FROM items ${where}`,
375
- params,
376
- );
377
- return row && row.maxReceived != null ? Number(row.maxReceived) : 0;
378
- }
379
-
380
- /** Total count of items across the (optional) provider set. */
381
- countItems(providers?: readonly string[]): number {
382
- let where = '';
383
- const params: (string | number)[] = [];
384
- if (providers && providers.length > 0) {
385
- const placeholders = providers.map(() => '?').join(', ');
386
- where = `WHERE provider IN (${placeholders})`;
387
- params.push(...providers);
388
- }
389
- const row = this.store.get<{ n: number }>(
390
- `SELECT COUNT(*) AS n FROM items ${where}`,
391
- params,
392
- );
393
- return row ? Number(row.n) : 0;
394
- }
395
-
396
- /**
397
- * Retention: delete items strictly older than `cutoff` (Unix ms), optionally
398
- * scoped to a provider set. Returns the number of rows removed. Cursors are
399
- * left untouched so already-consumed watermarks never regress. A non-finite
400
- * cutoff is a no-op (prevents an accidental whole-table wipe).
401
- */
402
- pruneOlderThan(cutoff: number, providers?: readonly string[]): number {
403
- if (!Number.isFinite(cutoff)) return 0;
404
- const clauses = ['receivedAt < ?'];
405
- const params: (string | number)[] = [Math.floor(cutoff)];
406
- if (providers && providers.length > 0) {
407
- const placeholders = providers.map(() => '?').join(', ');
408
- clauses.push(`provider IN (${placeholders})`);
409
- params.push(...providers);
410
- }
411
- const before = this.countItems(providers);
412
- this.store.run(`DELETE FROM items WHERE ${clauses.join(' AND ')}`, params);
413
- const removed = before - this.countItems(providers);
414
- if (removed > 0) this.dirty = true;
415
- return removed;
416
- }
417
-
418
- /** Persist to disk if anything changed since the last flush. */
419
- async flush(): Promise<void> {
420
- if (!this.dirty) return;
421
- await this.store.save();
422
- this.dirty = false;
423
- }
424
-
425
- /** Stop the retention timer, flush (best-effort), then close the database. */
426
- async close(): Promise<void> {
427
- if (this.closed) return;
428
- this.closed = true;
429
- this.stopSweepTimer();
430
- try {
431
- await this.flush();
432
- } finally {
433
- this.store.close();
434
- }
435
- }
436
- }
437
-
438
- function rowToItem(row: ItemRow): InboundChannelItem {
439
- const item: InboundChannelItem = {
440
- id: row.id,
441
- provider: row.provider,
442
- kind: normalizeKind(row.kind),
443
- fromDigest: row.fromDigest,
444
- subjectPreview: row.subjectPreview,
445
- bodyPreview: row.bodyPreview,
446
- receivedAt: Number(row.receivedAt),
447
- unread: Number(row.unread) !== 0,
448
- };
449
- if (row.routeId != null) item.routeId = row.routeId;
450
- return item;
451
- }
452
-
453
- function normalizeKind(value: string): InboundChannelItem['kind'] {
454
- return value === 'dm' || value === 'thread' || value === 'mention' || value === 'reaction'
455
- ? value
456
- : 'dm';
457
- }