@pellux/goodvibes-tui 1.27.0 → 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 (404) hide show
  1. package/CHANGELOG.md +125 -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 +12 -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 +15 -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 -641
  288. package/src/daemon/handlers/context.ts +0 -29
  289. package/src/daemon/handlers/contracts.ts +0 -77
  290. package/src/daemon/handlers/credentials.ts +0 -139
  291. package/src/daemon/handlers/drafts/draft-store.ts +0 -427
  292. package/src/daemon/handlers/drafts/index.ts +0 -17
  293. package/src/daemon/handlers/drafts/register.ts +0 -331
  294. package/src/daemon/handlers/errors.ts +0 -18
  295. package/src/daemon/handlers/inbox/cursor-store.ts +0 -457
  296. package/src/daemon/handlers/inbox/index.ts +0 -284
  297. package/src/daemon/handlers/inbox/mapping.ts +0 -192
  298. package/src/daemon/handlers/inbox/poller.ts +0 -212
  299. package/src/daemon/handlers/inbox/provider-adapter.ts +0 -156
  300. package/src/daemon/handlers/inbox/providers/discord.ts +0 -252
  301. package/src/daemon/handlers/inbox/providers/email.ts +0 -152
  302. package/src/daemon/handlers/inbox/providers/imap-client.ts +0 -300
  303. package/src/daemon/handlers/inbox/providers/route-util.ts +0 -24
  304. package/src/daemon/handlers/inbox/providers/slack.ts +0 -263
  305. package/src/daemon/handlers/index.ts +0 -117
  306. package/src/daemon/handlers/register.ts +0 -168
  307. package/src/daemon/handlers/remote/backends/cloud-terminal.ts +0 -142
  308. package/src/daemon/handlers/remote/backends/docker.ts +0 -79
  309. package/src/daemon/handlers/remote/backends/index.ts +0 -40
  310. package/src/daemon/handlers/remote/backends/local-process.ts +0 -113
  311. package/src/daemon/handlers/remote/backends/process-runner.ts +0 -127
  312. package/src/daemon/handlers/remote/backends/ssh.ts +0 -125
  313. package/src/daemon/handlers/remote/backends/types.ts +0 -97
  314. package/src/daemon/handlers/remote/dispatcher.ts +0 -181
  315. package/src/daemon/handlers/remote/index.ts +0 -119
  316. package/src/daemon/handlers/remote/peer-registry.ts +0 -357
  317. package/src/daemon/handlers/remote/service.ts +0 -191
  318. package/src/daemon/handlers/routing/inbox-bridge.ts +0 -71
  319. package/src/daemon/handlers/routing/index.ts +0 -261
  320. package/src/daemon/handlers/routing/route-store.ts +0 -319
  321. package/src/daemon/handlers/routing/routing-resolver.ts +0 -75
  322. package/src/daemon/handlers/sqlite-store.ts +0 -278
  323. package/src/daemon/handlers/triage/index.ts +0 -57
  324. package/src/daemon/handlers/triage/integration.ts +0 -213
  325. package/src/daemon/handlers/triage/pipeline.ts +0 -274
  326. package/src/daemon/handlers/triage/scorer.ts +0 -287
  327. package/src/daemon/handlers/triage/tagger/discord.ts +0 -187
  328. package/src/daemon/handlers/triage/tagger/imap.ts +0 -384
  329. package/src/daemon/handlers/triage/tagger/index.ts +0 -184
  330. package/src/daemon/handlers/triage/tagger/shared.ts +0 -70
  331. package/src/daemon/handlers/triage/tagger/slack.ts +0 -69
  332. package/src/daemon/handlers/triage/types.ts +0 -50
  333. package/src/daemon/lifecycle.ts +0 -41
  334. package/src/daemon/provision-wake-model.ts +0 -81
  335. package/src/daemon/safe-serve.ts +0 -61
  336. package/src/daemon/send/channels.ts +0 -200
  337. package/src/daemon/send/command.ts +0 -332
  338. package/src/daemon/send/composition.ts +0 -99
  339. package/src/daemon/send/failure-text.ts +0 -93
  340. package/src/daemon/send/inert-text.ts +0 -225
  341. package/src/daemon/send/stdin.ts +0 -24
  342. package/src/daemon/service-commands.ts +0 -329
  343. package/src/export/cost-utils.ts +0 -319
  344. package/src/input/selection.ts +0 -135
  345. package/src/plugins/loader.ts +0 -15
  346. package/src/renderer/bottom-bar.ts +0 -58
  347. package/src/renderer/conversation-tree.ts +0 -228
  348. package/src/runtime/agent-graph-composition.ts +0 -78
  349. package/src/runtime/channel-composition.ts +0 -46
  350. package/src/runtime/cluster-composition.ts +0 -124
  351. package/src/runtime/cluster-group-composition.ts +0 -284
  352. package/src/runtime/code-index-services.ts +0 -167
  353. package/src/runtime/daemon-handler-composition.ts +0 -76
  354. package/src/runtime/device-posture-composition.ts +0 -110
  355. package/src/runtime/durability-housekeeping.ts +0 -183
  356. package/src/runtime/durability-services.ts +0 -155
  357. package/src/runtime/embedded-service-factories.ts +0 -58
  358. package/src/runtime/feature-settings.ts +0 -154
  359. package/src/runtime/fleet-needs-input-push.ts +0 -70
  360. package/src/runtime/fleet-services.ts +0 -41
  361. package/src/runtime/idle-power-services.ts +0 -85
  362. package/src/runtime/mail-composition.ts +0 -65
  363. package/src/runtime/memory-fold.ts +0 -55
  364. package/src/runtime/operator-token-cleanup.ts +0 -109
  365. package/src/runtime/path-shadow.ts +0 -418
  366. package/src/runtime/perf/panel-health-monitor.ts +0 -18
  367. package/src/runtime/provider-optimizer-wiring.ts +0 -55
  368. package/src/runtime/reachability-notice.ts +0 -100
  369. package/src/runtime/remote-execution-composition.ts +0 -62
  370. package/src/runtime/session-liveness-marker.ts +0 -257
  371. package/src/runtime/session-pointer-surface.ts +0 -22
  372. package/src/runtime/session-storage-services.ts +0 -41
  373. package/src/runtime/surface-feature-flags.ts +0 -96
  374. package/src/runtime/terminal-output-guard.ts +0 -235
  375. package/src/runtime/trust/workspace-registration.ts +0 -192
  376. package/src/runtime/trust/workspace-trust.ts +0 -229
  377. package/src/runtime/ui/index.ts +0 -39
  378. package/src/runtime/ui/model-picker/data-provider.ts +0 -182
  379. package/src/runtime/ui/model-picker/health-enrichment.ts +0 -231
  380. package/src/runtime/ui/model-picker/index.ts +0 -59
  381. package/src/runtime/ui/model-picker/types.ts +0 -153
  382. package/src/runtime/ui/provider-health/data-provider.ts +0 -244
  383. package/src/runtime/ui/provider-health/fallback-visualizer.ts +0 -71
  384. package/src/runtime/ui/provider-health/index.ts +0 -46
  385. package/src/runtime/ui/provider-health/types.ts +0 -146
  386. package/src/runtime/ui-events.ts +0 -1
  387. package/src/runtime/ui-read-model-helpers.ts +0 -1
  388. package/src/runtime/ui-read-models-observability-maintenance.ts +0 -1
  389. package/src/runtime/ui-read-models-observability-options.ts +0 -1
  390. package/src/runtime/ui-read-models-observability-remote.ts +0 -1
  391. package/src/runtime/ui-read-models-observability-security.ts +0 -1
  392. package/src/runtime/ui-read-models-observability-system.ts +0 -1
  393. package/src/runtime/ui-read-models-observability.ts +0 -1
  394. package/src/runtime/ui-service-queries.ts +0 -1
  395. package/src/runtime/voice-setup-services.ts +0 -98
  396. package/src/runtime/workstream-attempts-validation.ts +0 -77
  397. package/src/runtime/workstream-draft-edits.ts +0 -95
  398. package/src/runtime/workstream-draft-store.ts +0 -274
  399. package/src/runtime/workstream-draft-types.ts +0 -42
  400. package/src/runtime/workstream-services.ts +0 -373
  401. package/src/tools/index.ts +0 -1
  402. package/src/types/grid.ts +0 -48
  403. package/src/types/sql-js.d.ts +0 -15
  404. package/src/work-plans/work-plan-store.ts +0 -702
@@ -1,261 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Channel routing surface — HANDLERS for the SDK-defined methods
3
- // - channels.routing.list (read-only)
4
- // - channels.routing.assign (admin, confirmation-gated)
5
- // - channels.routing.delete (admin, dangerous, confirmation-gated)
6
- //
7
- // The SDK's GatewayMethodCatalog already registered the canonical descriptors
8
- // (id, input/output schema, access, scopes, dangerous) for these three method
9
- // ids with `handler: undefined`. This module NEVER re-declares an id, schema,
10
- // or descriptor: it looks each one up by id and attaches a typed handler via
11
- // `registerCatalogHandlers`, flipping the builtin method from HTTP-fallback to
12
- // in-process execution. Handler outputs match the SDK output schemas exactly.
13
- //
14
- // Confirmation posture (per the daemon handoff, Responsibility 2): assign and
15
- // delete are control-plane mutations that require explicit user confirmation
16
- // (the SDK marks assign access:admin + 'Requires explicit confirmation', and
17
- // delete dangerous:true). Both pass `{ confirm: true }` so the register wrapper
18
- // enforces `body.confirm === true` AND `context.explicitUserRequest === true`.
19
- // list is read-only and ungated.
20
- // ---------------------------------------------------------------------------
21
-
22
- import type { HandlerContext } from '../context.ts';
23
- import type { RoutingRegistration as FoundationRoutingRegistration } from '../index.ts';
24
- import {
25
- registerCatalogHandlers,
26
- type CatalogHandlerEntry,
27
- type TypedHandler,
28
- type Unregister,
29
- } from '../register.ts';
30
- import {
31
- buildChannelId,
32
- parseChannelId,
33
- RouteStore,
34
- toRouteListItem,
35
- type RoutingChannelRoute,
36
- type RoutingRouteListItem,
37
- } from './route-store.ts';
38
- import { createRoutingResolver, type RoutingResolver } from './routing-resolver.ts';
39
-
40
- export { createInboxRouteResolver, type RouteResolver, type RouteResolverInput } from './inbox-bridge.ts';
41
- export {
42
- buildChannelId,
43
- parseChannelId,
44
- RouteStore,
45
- toRouteListItem,
46
- type RoutingChannelRoute,
47
- type RoutingRouteListItem,
48
- } from './route-store.ts';
49
- export {
50
- createRoutingResolver,
51
- resolveProfile,
52
- WILDCARD_SURFACE,
53
- type RoutingResolver,
54
- } from './routing-resolver.ts';
55
-
56
- // ---------------------------------------------------------------------------
57
- // Wire shapes (derived from the SDK contracts; NOT re-declared schemas).
58
- //
59
- // list in : { profileId?, surfaceKind?, limit? }
60
- // out: { routes: [{ id, createdAt, updatedAt, surfaceKind, routeId?,
61
- // profileId, label? }], total } (SDK route-item shape)
62
- // assign in : { channelId?, surfaceKind, routeId?, profileId, label? }
63
- // out: { assignmentId, channelId?, surfaceKind, routeId?, profileId, label?, createdAt, updatedAt }
64
- // delete in : { assignmentId } out: { deleted, assignmentId }
65
- // ---------------------------------------------------------------------------
66
-
67
- interface RoutingListBody {
68
- profileId?: unknown;
69
- surfaceKind?: unknown;
70
- limit?: unknown;
71
- }
72
- interface RoutingListResult {
73
- routes: RoutingRouteListItem[];
74
- total: number;
75
- }
76
-
77
- interface RoutingAssignBody {
78
- channelId?: unknown;
79
- surfaceKind?: unknown;
80
- routeId?: unknown;
81
- profileId?: unknown;
82
- label?: unknown;
83
- }
84
- interface RoutingAssignResult {
85
- assignmentId: string;
86
- channelId: string;
87
- surfaceKind: string;
88
- routeId?: string;
89
- profileId: string;
90
- label?: string;
91
- createdAt: string;
92
- updatedAt: string;
93
- }
94
-
95
- interface RoutingDeleteBody {
96
- assignmentId?: unknown;
97
- }
98
- interface RoutingDeleteResult {
99
- deleted: boolean;
100
- assignmentId: string;
101
- }
102
-
103
- const LIST_METHOD = 'channels.routing.list';
104
- const ASSIGN_METHOD = 'channels.routing.assign';
105
- const DELETE_METHOD = 'channels.routing.delete';
106
-
107
- function optionalString(value: unknown): string | undefined {
108
- return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
109
- }
110
-
111
- function clampLimit(value: unknown): number | undefined {
112
- if (value === undefined || value === null || value === '') return undefined;
113
- const n = typeof value === 'number' ? value : Number(value);
114
- if (!Number.isFinite(n)) return undefined;
115
- return Math.max(1, Math.floor(n));
116
- }
117
-
118
- /**
119
- * Routing surface handle. Satisfies the foundation `RoutingRegistration`
120
- * (`{ unregister, resolveProfileId }`) and additionally exposes the live
121
- * {@link RoutingResolver} and {@link RouteStore} so the inbox surface and tests
122
- * can reuse routing resolution without going through the catalog.
123
- */
124
- export interface RoutingRegistration extends FoundationRoutingRegistration {
125
- readonly resolver: RoutingResolver;
126
- readonly store: RouteStore;
127
- }
128
-
129
- /**
130
- * Attach the channel-routing handlers to the SDK gateway catalog held by `ctx`.
131
- *
132
- * The {@link RouteStore} is lazily initialized on first invocation (the
133
- * register contract is synchronous) so registration never blocks on disk I/O.
134
- * Returns the teardown plus the resolver/store handles.
135
- */
136
- export function registerRoutingMethods(ctx: HandlerContext): RoutingRegistration {
137
- const store = new RouteStore({ workingDirectory: ctx.workingDirectory });
138
- const resolver = createRoutingResolver(store);
139
-
140
- let initPromise: Promise<void> | null = null;
141
- const ensureInit = async (): Promise<void> => {
142
- if (!initPromise) {
143
- initPromise = store.init().catch((error) => {
144
- // Allow a later invocation to retry initialization.
145
- initPromise = null;
146
- throw error;
147
- });
148
- }
149
- await initPromise;
150
- };
151
-
152
- const listHandler: TypedHandler<RoutingListBody, RoutingListResult> = async ({ body }) => {
153
- await ensureInit();
154
- const routes = store.list({
155
- profileId: optionalString(body.profileId),
156
- surfaceKind: optionalString(body.surfaceKind),
157
- });
158
- const limit = clampLimit(body.limit);
159
- const limited = limit !== undefined ? routes.slice(0, limit) : routes;
160
- // Project to the SDK `channels.routing.list` item shape: emit `id`
161
- // (= assignmentId) and drop the daemon-internal `channelId`/`assignmentId`,
162
- // which additionalProperties:false forbids.
163
- const items = limited.map(toRouteListItem);
164
- return { routes: items, total: items.length };
165
- };
166
-
167
- const assignHandler: TypedHandler<RoutingAssignBody, RoutingAssignResult> = async ({ body, context }) => {
168
- await ensureInit();
169
- const profileId = optionalString(body.profileId);
170
- if (profileId === undefined) {
171
- throw new Error('profileId is required');
172
- }
173
- // The SDK contract accepts either a composite `channelId` or the
174
- // `surfaceKind` (+ optional `routeId`) parts. Prefer an explicit
175
- // channelId; otherwise build one from the parts.
176
- const explicitChannelId = optionalString(body.channelId);
177
- const surfaceKind = optionalString(body.surfaceKind);
178
- const routeId = optionalString(body.routeId);
179
- const channelId = explicitChannelId ?? (
180
- surfaceKind !== undefined ? buildChannelId(surfaceKind, routeId) : undefined
181
- );
182
- if (channelId === undefined) {
183
- throw new Error('surfaceKind (or channelId) is required');
184
- }
185
- const { route, created } = await store.upsert({
186
- channelId,
187
- profileId,
188
- label: optionalString(body.label),
189
- });
190
- ctx.logger.info('channels.routing.assign', {
191
- assignmentId: route.assignmentId,
192
- channelId: route.channelId,
193
- surfaceKind: route.surfaceKind,
194
- profileId: route.profileId,
195
- created,
196
- principalId: context.principalId,
197
- });
198
- const result: RoutingAssignResult = {
199
- assignmentId: route.assignmentId,
200
- channelId: route.channelId,
201
- surfaceKind: route.surfaceKind,
202
- profileId: route.profileId,
203
- createdAt: route.createdAt,
204
- updatedAt: route.updatedAt,
205
- };
206
- if (route.routeId !== undefined) result.routeId = route.routeId;
207
- if (route.label !== undefined) result.label = route.label;
208
- return result;
209
- };
210
-
211
- const deleteHandler: TypedHandler<RoutingDeleteBody, RoutingDeleteResult> = async ({ body, context }) => {
212
- await ensureInit();
213
- const assignmentId = optionalString(body.assignmentId);
214
- if (assignmentId === undefined) {
215
- throw new Error('assignmentId is required');
216
- }
217
- const deleted = await store.delete(assignmentId);
218
- ctx.logger.info('channels.routing.delete', {
219
- assignmentId,
220
- deleted,
221
- principalId: context.principalId,
222
- });
223
- return { deleted, assignmentId };
224
- };
225
-
226
- const entries: CatalogHandlerEntry[] = [
227
- { id: LIST_METHOD, handler: listHandler as TypedHandler<unknown, unknown> },
228
- {
229
- id: ASSIGN_METHOD,
230
- handler: assignHandler as TypedHandler<unknown, unknown>,
231
- options: { confirm: true },
232
- },
233
- {
234
- id: DELETE_METHOD,
235
- handler: deleteHandler as TypedHandler<unknown, unknown>,
236
- options: { confirm: true },
237
- },
238
- ];
239
-
240
- const teardownHandlers = registerCatalogHandlers(ctx.catalog, entries);
241
-
242
- const unregister: Unregister = () => {
243
- teardownHandlers();
244
- store.close();
245
- };
246
-
247
- return {
248
- unregister,
249
- resolveProfileId: (surfaceKind: string, routeId?: string) =>
250
- resolver.getProfileForChannel(surfaceKind, routeId),
251
- resolver,
252
- store,
253
- };
254
- }
255
-
256
- /**
257
- * Provider entry point consumed by `registerDaemonHandlers`
258
- * (`DaemonHandlerSurfaceProviders.registerRouting`).
259
- */
260
- export const registerRouting = (ctx: HandlerContext): RoutingRegistration =>
261
- registerRoutingMethods(ctx);
@@ -1,319 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { HandlerSqliteStore } from '../sqlite-store.ts';
3
- import { HandlerError } from '../errors.ts';
4
-
5
- /**
6
- * A persisted channel-to-profile routing assignment, in the exact shape the
7
- * `channels.routing.*` methods serve. Keyed on a composite `channelId`
8
- * (`surfaceKind` or `surfaceKind:routeId`). The SDK output schemas require
9
- * `surfaceKind`, `profileId`, `createdAt`, and `updatedAt`; `channelId`,
10
- * `routeId`, and `label` are carried through as optional refinements.
11
- */
12
- export interface RoutingChannelRoute {
13
- assignmentId: string;
14
- /** Composite key: `surfaceKind` or `surfaceKind:routeId`. */
15
- channelId: string;
16
- surfaceKind: string;
17
- routeId?: string;
18
- profileId: string;
19
- label?: string;
20
- createdAt: string; // ISO-8601
21
- updatedAt: string; // ISO-8601
22
- }
23
-
24
- /**
25
- * Per-route item shape emitted by `channels.routing.list`, matching the SDK
26
- * `CHANNEL_ROUTING_RULE_SCHEMA` exactly: properties
27
- * {id, createdAt, updatedAt, surfaceKind, routeId, profileId, label},
28
- * required [id, createdAt, updatedAt, surfaceKind, profileId], and
29
- * additionalProperties:false. The store's `assignmentId` is projected to `id`,
30
- * and the daemon-internal `channelId` is dropped (it is forbidden by the
31
- * schema's additionalProperties:false).
32
- */
33
- export interface RoutingRouteListItem {
34
- id: string;
35
- createdAt: string; // ISO-8601
36
- updatedAt: string; // ISO-8601
37
- surfaceKind: string;
38
- routeId?: string;
39
- profileId: string;
40
- label?: string;
41
- }
42
-
43
- /**
44
- * Project a stored route to the SDK `channels.routing.list` item shape. Pure;
45
- * only includes optional `routeId`/`label` when present so the payload never
46
- * carries `undefined`-valued or schema-forbidden keys.
47
- */
48
- export function toRouteListItem(route: RoutingChannelRoute): RoutingRouteListItem {
49
- const item: RoutingRouteListItem = {
50
- id: route.assignmentId,
51
- createdAt: route.createdAt,
52
- updatedAt: route.updatedAt,
53
- surfaceKind: route.surfaceKind,
54
- profileId: route.profileId,
55
- };
56
- if (route.routeId !== undefined) {
57
- item.routeId = route.routeId;
58
- }
59
- if (route.label !== undefined) {
60
- item.label = route.label;
61
- }
62
- return item;
63
- }
64
-
65
- /** Parsed components of a composite channelId. */
66
- export interface ParsedChannelId {
67
- surfaceKind: string;
68
- routeId?: string;
69
- }
70
-
71
- export interface RouteUpsertInput {
72
- channelId: string;
73
- profileId: string;
74
- label?: string;
75
- }
76
-
77
- export interface RouteUpsertResult {
78
- route: RoutingChannelRoute;
79
- created: boolean;
80
- }
81
-
82
- export interface RouteListFilter {
83
- profileId?: string;
84
- surfaceKind?: string;
85
- }
86
-
87
- const SCHEMA: string[] = [
88
- `CREATE TABLE IF NOT EXISTS routes (
89
- assignmentId TEXT PRIMARY KEY,
90
- channelId TEXT NOT NULL,
91
- surfaceKind TEXT NOT NULL,
92
- routeId TEXT,
93
- profileId TEXT NOT NULL,
94
- label TEXT,
95
- createdAt TEXT NOT NULL,
96
- updatedAt TEXT NOT NULL
97
- )`,
98
- `CREATE INDEX IF NOT EXISTS idx_routes_surface_route ON routes (surfaceKind, routeId)`,
99
- // Enforce one assignment per channel — the upsert path relies on this.
100
- `CREATE UNIQUE INDEX IF NOT EXISTS idx_routes_channel ON routes (channelId)`,
101
- ];
102
-
103
- interface RouteRow {
104
- assignmentId: string;
105
- channelId: string;
106
- surfaceKind: string;
107
- routeId: string | null;
108
- profileId: string;
109
- label: string | null;
110
- createdAt: string;
111
- updatedAt: string;
112
- }
113
-
114
- /**
115
- * Parse a composite channelId into its `surfaceKind` and optional `routeId`.
116
- *
117
- * The channelId format is `surfaceKind` (surface-only / wildcard) or
118
- * `surfaceKind:routeId`. Everything after the FIRST colon is the routeId, so
119
- * route IDs may themselves contain colons (e.g. `slack:C123:thread`).
120
- */
121
- export function parseChannelId(channelId: string): ParsedChannelId {
122
- const raw = typeof channelId === 'string' ? channelId.trim() : '';
123
- if (raw.length === 0) {
124
- throw new HandlerError('channelId is required', 'ROUTING_INVALID_CHANNEL_ID', 400);
125
- }
126
- const separator = raw.indexOf(':');
127
- if (separator === -1) {
128
- return { surfaceKind: raw };
129
- }
130
- const surfaceKind = raw.slice(0, separator).trim();
131
- const routeId = raw.slice(separator + 1).trim();
132
- if (surfaceKind.length === 0) {
133
- throw new HandlerError('channelId is missing a surfaceKind', 'ROUTING_INVALID_CHANNEL_ID', 400);
134
- }
135
- // A trailing colon with no routeId collapses to a surface-only assignment.
136
- return routeId.length === 0 ? { surfaceKind } : { surfaceKind, routeId };
137
- }
138
-
139
- /** Build a canonical composite channelId from its parts. */
140
- export function buildChannelId(surfaceKind: string, routeId?: string): string {
141
- return routeId === undefined || routeId === '' ? surfaceKind : `${surfaceKind}:${routeId}`;
142
- }
143
-
144
- function rowToRoute(row: RouteRow): RoutingChannelRoute {
145
- const route: RoutingChannelRoute = {
146
- assignmentId: row.assignmentId,
147
- channelId: row.channelId,
148
- surfaceKind: row.surfaceKind,
149
- profileId: row.profileId,
150
- createdAt: row.createdAt,
151
- updatedAt: row.updatedAt,
152
- };
153
- if (row.routeId !== null && row.routeId !== '') route.routeId = row.routeId;
154
- if (row.label !== null && row.label !== '') route.label = row.label;
155
- return route;
156
- }
157
-
158
- /**
159
- * SQLite-backed store for channel-to-profile routing assignments.
160
- *
161
- * Wraps {@link HandlerSqliteStore} (file `channel-routes.sqlite`) and persists
162
- * after every mutation. The store owns the composite-key parsing so callers only
163
- * ever deal with `channelId` strings.
164
- */
165
- export class RouteStore {
166
- private readonly store: HandlerSqliteStore;
167
- private initialized = false;
168
-
169
- constructor(options: { workingDirectory: string }) {
170
- this.store = new HandlerSqliteStore({
171
- workingDirectory: options.workingDirectory,
172
- fileName: 'channel-routes.sqlite',
173
- schema: SCHEMA,
174
- });
175
- }
176
-
177
- get dbPath(): string {
178
- return this.store.dbPath;
179
- }
180
-
181
- async init(): Promise<void> {
182
- if (this.initialized) return;
183
- await this.store.init();
184
- this.initialized = true;
185
- }
186
-
187
- close(): void {
188
- this.store.close();
189
- this.initialized = false;
190
- }
191
-
192
- private requireInit(): void {
193
- if (!this.initialized) {
194
- throw new HandlerError('RouteStore not initialized', 'ROUTING_STORE_UNINITIALIZED', 500);
195
- }
196
- }
197
-
198
- /** All assignments, ordered most-recently-updated first. */
199
- listAll(): RoutingChannelRoute[] {
200
- this.requireInit();
201
- const rows = this.store.all<RouteRow>(
202
- `SELECT assignmentId, channelId, surfaceKind, routeId, profileId, label, createdAt, updatedAt
203
- FROM routes ORDER BY updatedAt DESC, assignmentId ASC`,
204
- );
205
- return rows.map(rowToRoute);
206
- }
207
-
208
- /** Assignments filtered by optional profileId and/or surfaceKind. */
209
- list(filter: RouteListFilter = {}): RoutingChannelRoute[] {
210
- this.requireInit();
211
- const clauses: string[] = [];
212
- const params: (string | number)[] = [];
213
- if (filter.profileId !== undefined && filter.profileId !== '') {
214
- clauses.push('profileId = ?');
215
- params.push(filter.profileId);
216
- }
217
- if (filter.surfaceKind !== undefined && filter.surfaceKind !== '') {
218
- clauses.push('surfaceKind = ?');
219
- params.push(filter.surfaceKind);
220
- }
221
- const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
222
- const rows = this.store.all<RouteRow>(
223
- `SELECT assignmentId, channelId, surfaceKind, routeId, profileId, label, createdAt, updatedAt
224
- FROM routes ${where} ORDER BY updatedAt DESC, assignmentId ASC`,
225
- params,
226
- );
227
- return rows.map(rowToRoute);
228
- }
229
-
230
- /** Lookup a single assignment by its composite channelId. */
231
- findByChannelId(channelId: string): RoutingChannelRoute | null {
232
- this.requireInit();
233
- const row = this.store.get<RouteRow>(
234
- `SELECT assignmentId, channelId, surfaceKind, routeId, profileId, label, createdAt, updatedAt
235
- FROM routes WHERE channelId = ?`,
236
- [channelId],
237
- );
238
- return row ? rowToRoute(row) : null;
239
- }
240
-
241
- /** Lookup a single assignment by its assignmentId. */
242
- findById(assignmentId: string): RoutingChannelRoute | null {
243
- this.requireInit();
244
- const row = this.store.get<RouteRow>(
245
- `SELECT assignmentId, channelId, surfaceKind, routeId, profileId, label, createdAt, updatedAt
246
- FROM routes WHERE assignmentId = ?`,
247
- [assignmentId],
248
- );
249
- return row ? rowToRoute(row) : null;
250
- }
251
-
252
- /**
253
- * Create or update the assignment for a channel.
254
- *
255
- * `created` is true when no prior assignment existed for the channelId, false
256
- * when an existing row was updated. The assignmentId is stable across updates
257
- * (it is preserved from the existing row). Persists to disk after the write.
258
- */
259
- async upsert(input: RouteUpsertInput): Promise<RouteUpsertResult> {
260
- this.requireInit();
261
- const profileId = typeof input.profileId === 'string' ? input.profileId.trim() : '';
262
- if (profileId.length === 0) {
263
- throw new HandlerError('profileId is required', 'ROUTING_INVALID_PROFILE_ID', 400);
264
- }
265
- const { surfaceKind, routeId } = parseChannelId(input.channelId);
266
- const channelId = buildChannelId(surfaceKind, routeId);
267
- const label = typeof input.label === 'string' && input.label.trim().length > 0
268
- ? input.label.trim()
269
- : null;
270
- const now = new Date().toISOString();
271
-
272
- const existing = this.findByChannelId(channelId);
273
- if (existing) {
274
- this.store.run(
275
- `UPDATE routes
276
- SET profileId = ?, label = ?, surfaceKind = ?, routeId = ?, updatedAt = ?
277
- WHERE assignmentId = ?`,
278
- [profileId, label, surfaceKind, routeId ?? null, now, existing.assignmentId],
279
- );
280
- await this.store.save();
281
- const route = this.findById(existing.assignmentId);
282
- if (!route) {
283
- throw new HandlerError('Failed to read back updated route', 'ROUTING_WRITE_FAILED', 500);
284
- }
285
- return { route, created: false };
286
- }
287
-
288
- const assignmentId = randomUUID();
289
- this.store.run(
290
- `INSERT INTO routes
291
- (assignmentId, channelId, surfaceKind, routeId, profileId, label, createdAt, updatedAt)
292
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
293
- [assignmentId, channelId, surfaceKind, routeId ?? null, profileId, label, now, now],
294
- );
295
- await this.store.save();
296
- const route = this.findById(assignmentId);
297
- if (!route) {
298
- throw new HandlerError('Failed to read back inserted route', 'ROUTING_WRITE_FAILED', 500);
299
- }
300
- return { route, created: true };
301
- }
302
-
303
- /**
304
- * Delete an assignment by assignmentId. Returns true when a row was removed,
305
- * false when no matching assignment existed. Persists to disk after a delete.
306
- */
307
- async delete(assignmentId: string): Promise<boolean> {
308
- this.requireInit();
309
- const id = typeof assignmentId === 'string' ? assignmentId.trim() : '';
310
- if (id.length === 0) {
311
- throw new HandlerError('assignmentId is required', 'ROUTING_INVALID_ASSIGNMENT_ID', 400);
312
- }
313
- const existing = this.findById(id);
314
- if (!existing) return false;
315
- this.store.run('DELETE FROM routes WHERE assignmentId = ?', [id]);
316
- await this.store.save();
317
- return true;
318
- }
319
- }
@@ -1,75 +0,0 @@
1
- import type { RoutingChannelRoute } from './route-store.ts';
2
- import type { RouteStore } from './route-store.ts';
3
-
4
- /** Wildcard surfaceKind that matches any surface as a last resort. */
5
- export const WILDCARD_SURFACE = 'any';
6
-
7
- /**
8
- * Pure resolution of a profileId from a set of routes, applying the EXACT same
9
- * order as the agent-side `getProfileForChannel()` so offline and online
10
- * routing produce identical results:
11
- *
12
- * 1. exact match — surfaceKind AND routeId both match
13
- * 2. surface-only — surfaceKind matches, route has no routeId
14
- * 3. wildcard — a route with surfaceKind === 'any' (no routeId)
15
- *
16
- * Returns the matching profileId, or `null` when nothing matches.
17
- */
18
- export function resolveProfile(
19
- routes: readonly RoutingChannelRoute[],
20
- surfaceKind: string,
21
- routeId?: string,
22
- ): string | null {
23
- const surface = typeof surfaceKind === 'string' ? surfaceKind.trim() : '';
24
- if (surface.length === 0) return null;
25
- const route = typeof routeId === 'string' && routeId.trim().length > 0 ? routeId.trim() : undefined;
26
-
27
- // 1. Exact match (surfaceKind + routeId). Only attempted when a routeId is
28
- // supplied by the caller.
29
- if (route !== undefined) {
30
- const exact = routes.find(
31
- (entry) => entry.surfaceKind === surface && entry.routeId === route,
32
- );
33
- if (exact) return exact.profileId;
34
- }
35
-
36
- // 2. Surface-only match (surfaceKind, no routeId on the route).
37
- const surfaceOnly = routes.find(
38
- (entry) => entry.surfaceKind === surface && (entry.routeId === undefined || entry.routeId === ''),
39
- );
40
- if (surfaceOnly) return surfaceOnly.profileId;
41
-
42
- // 3. Wildcard match (surfaceKind === 'any', no routeId).
43
- const wildcard = routes.find(
44
- (entry) => entry.surfaceKind === WILDCARD_SURFACE && (entry.routeId === undefined || entry.routeId === ''),
45
- );
46
- if (wildcard) return wildcard.profileId;
47
-
48
- return null;
49
- }
50
-
51
- /** Resolver bound to a live {@link RouteStore}. */
52
- export interface RoutingResolver {
53
- /**
54
- * Resolve the profileId that should handle an inbound message on the given
55
- * surface/route, applying the agent resolution order. Returns null when no
56
- * assignment matches (caller falls back to the default session).
57
- */
58
- getProfileForChannel(surfaceKind: string, routeId?: string): string | null;
59
- /** Alias of {@link getProfileForChannel}, exported for inbox surface reuse. */
60
- resolveProfile(surfaceKind: string, routeId?: string): string | null;
61
- }
62
-
63
- /**
64
- * Create a resolver backed by a {@link RouteStore}. The store must already be
65
- * initialized; each call reads the current route set so assignments take effect
66
- * immediately after a mutation.
67
- */
68
- export function createRoutingResolver(store: RouteStore): RoutingResolver {
69
- const resolve = (surfaceKind: string, routeId?: string): string | null =>
70
- resolveProfile(store.listAll(), surfaceKind, routeId);
71
- return {
72
- getProfileForChannel: resolve,
73
- resolveProfile: resolve,
74
- };
75
- }