@vellumai/assistant 0.10.2-dev.202606250318.5e7cfb0 → 0.10.2

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 (430) hide show
  1. package/bun.lock +0 -20
  2. package/docs/workspace-tools.md +33 -42
  3. package/eslint-rules/cli-no-daemon-internals.js +0 -6
  4. package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +0 -31
  5. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +0 -44
  6. package/node_modules/@vellumai/gateway-client/src/index.ts +0 -14
  7. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +0 -17
  8. package/node_modules/@vellumai/service-contracts/package.json +0 -1
  9. package/node_modules/@vellumai/service-contracts/src/index.ts +0 -1
  10. package/openapi.yaml +0 -155
  11. package/package.json +1 -4
  12. package/scripts/test.sh +15 -36
  13. package/src/__tests__/actor-token-service.test.ts +14 -36
  14. package/src/__tests__/agent-loop-override-profile.test.ts +0 -1
  15. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -2
  16. package/src/__tests__/agent-wake-override-profile.test.ts +0 -2
  17. package/src/__tests__/annotate-activity-metadata.test.ts +0 -2
  18. package/src/__tests__/annotate-risk-options.test.ts +0 -2
  19. package/src/__tests__/approval-cascade.test.ts +0 -2
  20. package/src/__tests__/assistant-attachments.test.ts +0 -42
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
  22. package/src/__tests__/btw-routes.test.ts +0 -2
  23. package/src/__tests__/build-persisted-content.test.ts +0 -2
  24. package/src/__tests__/call-controller.test.ts +0 -19
  25. package/src/__tests__/channel-guardian.test.ts +58 -94
  26. package/src/__tests__/channel-reply-delivery.test.ts +0 -2
  27. package/src/__tests__/compaction-events.test.ts +0 -2
  28. package/src/__tests__/compaction.benchmark.test.ts +0 -2
  29. package/src/__tests__/compactor-call-site-logging.test.ts +0 -2
  30. package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -2
  31. package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -2
  32. package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -2
  33. package/src/__tests__/compactor-web-search-strip.test.ts +0 -2
  34. package/src/__tests__/config-loader-backfill.test.ts +10 -123
  35. package/src/__tests__/config-schema.test.ts +0 -1
  36. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -31
  37. package/src/__tests__/contacts-relay-reads.test.ts +15 -13
  38. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -2
  39. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -2
  40. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -2
  41. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
  42. package/src/__tests__/conversation-agent-loop.test.ts +0 -134
  43. package/src/__tests__/conversation-analysis-routes.test.ts +0 -2
  44. package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -2
  45. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -2
  46. package/src/__tests__/conversation-history-web-search.test.ts +0 -2
  47. package/src/__tests__/conversation-load-history-repair.test.ts +0 -2
  48. package/src/__tests__/conversation-load-history-stripped.test.ts +0 -2
  49. package/src/__tests__/conversation-pairing.test.ts +0 -2
  50. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -2
  51. package/src/__tests__/conversation-process-callsite.test.ts +0 -2
  52. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -2
  53. package/src/__tests__/conversation-queue.test.ts +0 -91
  54. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -14
  55. package/src/__tests__/conversation-routes-slash-commands.test.ts +0 -14
  56. package/src/__tests__/conversation-slash-queue.test.ts +0 -2
  57. package/src/__tests__/conversation-slash-unknown.test.ts +0 -2
  58. package/src/__tests__/conversation-speed-override.test.ts +0 -2
  59. package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -29
  60. package/src/__tests__/conversation-title-service.test.ts +0 -2
  61. package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -47
  62. package/src/__tests__/conversation-usage.test.ts +0 -2
  63. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -2
  64. package/src/__tests__/conversation-workspace-injection.test.ts +0 -2
  65. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -2
  66. package/src/__tests__/credential-security-invariants.test.ts +1 -1
  67. package/src/__tests__/db-migration-rollback.test.ts +171 -205
  68. package/src/__tests__/db-test-helpers.ts +4 -5
  69. package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -4
  70. package/src/__tests__/disk-pressure-guard.test.ts +0 -41
  71. package/src/__tests__/dm-persistence.test.ts +0 -2
  72. package/src/__tests__/emit-signal-routing-intent.test.ts +5 -10
  73. package/src/__tests__/events-dev-bypass-actor.test.ts +1 -7
  74. package/src/__tests__/exploration-drift-hook.test.ts +2 -3
  75. package/src/__tests__/filing-service.test.ts +0 -2
  76. package/src/__tests__/guardian-binding-drift-heal.test.ts +10 -75
  77. package/src/__tests__/guardian-dispatch.test.ts +1 -95
  78. package/src/__tests__/guardian-outbound-http.test.ts +0 -13
  79. package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -2
  80. package/src/__tests__/heartbeat-service.test.ts +0 -2
  81. package/src/__tests__/helpers/channel-test-adapter.ts +7 -1
  82. package/src/__tests__/host-app-control-routes.test.ts +30 -24
  83. package/src/__tests__/host-bash-routes.test.ts +41 -31
  84. package/src/__tests__/host-browser-routes.test.ts +32 -26
  85. package/src/__tests__/host-cu-routes-targeted.test.ts +33 -25
  86. package/src/__tests__/host-file-routes-targeted.test.ts +52 -40
  87. package/src/__tests__/host-transfer-routes-targeted.test.ts +43 -31
  88. package/src/__tests__/http-user-message-parity.test.ts +8 -290
  89. package/src/__tests__/inbound-invite-redemption.test.ts +0 -28
  90. package/src/__tests__/inbound-slack-persistence.test.ts +0 -2
  91. package/src/__tests__/invite-redemption-service.test.ts +0 -198
  92. package/src/__tests__/llm-context-normalization.test.ts +0 -105
  93. package/src/__tests__/llm-request-log-error-payload.test.ts +9 -71
  94. package/src/__tests__/llm-usage-store.test.ts +0 -25
  95. package/src/__tests__/mcp-health-check.test.ts +1 -2
  96. package/src/__tests__/media-stream-server-integration.test.ts +0 -127
  97. package/src/__tests__/memory-retrieval-hook.test.ts +0 -2
  98. package/src/__tests__/messaging-send-tool.test.ts +0 -2
  99. package/src/__tests__/migration-import-from-url.test.ts +2 -2
  100. package/src/__tests__/mtime-cache.test.ts +5 -146
  101. package/src/__tests__/native-web-search.test.ts +0 -2
  102. package/src/__tests__/non-member-access-request.test.ts +17 -189
  103. package/src/__tests__/notification-broadcaster.test.ts +0 -4
  104. package/src/__tests__/notification-decision-recipient-context.test.ts +32 -33
  105. package/src/__tests__/notification-deep-link.test.ts +0 -6
  106. package/src/__tests__/notification-guardian-path.test.ts +0 -19
  107. package/src/__tests__/openai-provider.test.ts +12 -22
  108. package/src/__tests__/openai-responses-provider.test.ts +2 -12
  109. package/src/__tests__/outbound-slack-persistence.test.ts +0 -2
  110. package/src/__tests__/pending-interactions-resolved-event.test.ts +4 -7
  111. package/src/__tests__/persistence-secret-redaction.test.ts +0 -2
  112. package/src/__tests__/plugin-bootstrap.test.ts +73 -3
  113. package/src/__tests__/plugin-route-contribution.test.ts +17 -4
  114. package/src/__tests__/plugin-tool-contribution.test.ts +18 -3
  115. package/src/__tests__/plugin-types.test.ts +2 -0
  116. package/src/__tests__/process-message-background-slack.test.ts +0 -2
  117. package/src/__tests__/process-message-display-content.test.ts +0 -2
  118. package/src/__tests__/provider-error-scenarios.test.ts +4 -5
  119. package/src/__tests__/provider-usage-tracking.test.ts +0 -39
  120. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -2
  121. package/src/__tests__/registry.test.ts +1 -4
  122. package/src/__tests__/relay-server.test.ts +25 -694
  123. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -0
  124. package/src/__tests__/secret-ingress-http.test.ts +0 -14
  125. package/src/__tests__/send-endpoint-busy.test.ts +8 -30
  126. package/src/__tests__/skills.test.ts +0 -44
  127. package/src/__tests__/slack-inbound-verification.test.ts +2 -47
  128. package/src/__tests__/stt-hints.test.ts +13 -44
  129. package/src/__tests__/subagent-detail.test.ts +0 -27
  130. package/src/__tests__/subagent-disposal.test.ts +0 -65
  131. package/src/__tests__/subagent-notify-parent.test.ts +0 -2
  132. package/src/__tests__/subagent-role-registry.test.ts +2 -7
  133. package/src/__tests__/subagent-spawn-tool-fork.test.ts +0 -2
  134. package/src/__tests__/subagent-tools.test.ts +0 -2
  135. package/src/__tests__/suggestion-routes.test.ts +0 -2
  136. package/src/__tests__/title-generate-hook.test.ts +0 -2
  137. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -2
  138. package/src/__tests__/tool-executor.test.ts +11 -16
  139. package/src/__tests__/tool-preview-lifecycle.test.ts +0 -2
  140. package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -2
  141. package/src/__tests__/tool-start-timestamp.test.ts +0 -2
  142. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +10 -10
  143. package/src/__tests__/twilio-routes.test.ts +0 -96
  144. package/src/__tests__/ui-file-upload-surface.test.ts +0 -86
  145. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  146. package/src/__tests__/voice-invite-redemption.test.ts +0 -33
  147. package/src/__tests__/web-search-backend-failure.test.ts +0 -2
  148. package/src/__tests__/workspace-migration-remove-hooks.test.ts +35 -14
  149. package/src/__tests__/workspace-tool-loader.test.ts +2 -195
  150. package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
  151. package/src/agent/loop.ts +0 -56
  152. package/src/api/index.ts +1 -19
  153. package/src/api/responses/llm-request-log-entry.ts +0 -29
  154. package/src/api/responses/subagent-detail.ts +0 -17
  155. package/src/api/surfaces.ts +3 -39
  156. package/src/approvals/guardian-request-resolvers.ts +11 -1
  157. package/src/calls/__tests__/relay-setup-router.test.ts +4 -262
  158. package/src/calls/call-domain.ts +3 -3
  159. package/src/calls/guardian-dispatch.ts +8 -10
  160. package/src/calls/inbound-trust-reader.ts +1 -17
  161. package/src/calls/media-stream-server.ts +0 -21
  162. package/src/calls/relay-server.ts +50 -167
  163. package/src/calls/relay-setup-router.ts +7 -37
  164. package/src/calls/relay-verification.ts +4 -4
  165. package/src/calls/stt-hints.ts +12 -9
  166. package/src/calls/twilio-routes.ts +4 -14
  167. package/src/channels/types.ts +20 -10
  168. package/src/cli/commands/__tests__/cache.test.ts +1 -8
  169. package/src/cli/commands/cache.ts +181 -194
  170. package/src/cli/commands/db/__tests__/repair.test.ts +5 -6
  171. package/src/cli/commands/db/status.ts +1 -37
  172. package/src/cli/commands/mcp.ts +218 -252
  173. package/src/cli/commands/memory/index.ts +0 -2
  174. package/src/cli/commands/plugins.ts +3 -75
  175. package/src/cli/lib/__tests__/install-from-github.test.ts +0 -102
  176. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +1 -160
  177. package/src/cli/lib/list-installed-plugins.ts +1 -179
  178. package/src/config/__tests__/sync-gated-profiles.test.ts +3 -11
  179. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +17 -27
  180. package/src/config/bundled-skills/contacts/tools/contact-search.ts +3 -13
  181. package/src/config/bundled-skills/subagent/SKILL.md +1 -1
  182. package/src/config/bundled-skills/subagent/TOOLS.json +1 -1
  183. package/src/config/feature-flag-registry.json +13 -5
  184. package/src/config/loader.ts +5 -38
  185. package/src/config/schemas/__tests__/memory-v3.test.ts +0 -1
  186. package/src/config/schemas/memory-lifecycle.ts +0 -12
  187. package/src/config/schemas/memory-v3.ts +0 -7
  188. package/src/config/schemas/memory.ts +0 -4
  189. package/src/config/schemas/timeouts.ts +0 -8
  190. package/src/config/seed-inference-profiles.ts +11 -21
  191. package/src/config/skills.ts +5 -27
  192. package/src/config/sync-gated-profiles.ts +13 -12
  193. package/src/contacts/contacts-write.ts +0 -3
  194. package/src/daemon/assistant-attachments.ts +4 -27
  195. package/src/daemon/conversation-agent-loop.ts +0 -28
  196. package/src/daemon/conversation-process.ts +16 -35
  197. package/src/daemon/conversation-surfaces.ts +38 -111
  198. package/src/daemon/conversation-tool-setup.ts +16 -50
  199. package/src/daemon/conversation.ts +1 -13
  200. package/src/daemon/disk-pressure-guard.ts +2 -12
  201. package/src/daemon/event-loop-watchdog.ts +1 -28
  202. package/src/daemon/external-plugins-bootstrap.ts +34 -4
  203. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -25
  204. package/src/daemon/handlers/config-a2a.ts +14 -6
  205. package/src/daemon/handlers/config-channels.ts +22 -78
  206. package/src/daemon/handlers/conversations.ts +0 -77
  207. package/src/daemon/lifecycle.ts +0 -4
  208. package/src/daemon/mcp-reload-service.ts +0 -10
  209. package/src/daemon/memory-v2-startup.test.ts +0 -72
  210. package/src/daemon/memory-v2-startup.ts +19 -87
  211. package/src/daemon/message-types/conversations.ts +0 -2
  212. package/src/daemon/message-types/surfaces.ts +12 -12
  213. package/src/daemon/server.ts +4 -0
  214. package/src/daemon/shutdown-handlers.ts +0 -20
  215. package/src/daemon/tool-setup-types.ts +0 -9
  216. package/src/daemon/workspace-tools-watcher.ts +328 -0
  217. package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
  218. package/src/ipc/assistant-server.ts +2 -2
  219. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
  220. package/src/mcp/client.ts +1 -15
  221. package/src/mcp/mcp-auth-orchestrator.ts +1 -6
  222. package/src/mcp/mcp-oauth-provider.ts +8 -19
  223. package/src/memory/__tests__/memory-retrospective-job.test.ts +0 -8
  224. package/src/memory/conversation-crud.ts +0 -38
  225. package/src/memory/db-connection.ts +3 -22
  226. package/src/memory/db-init.ts +502 -36
  227. package/src/memory/db-singleton.ts +4 -6
  228. package/src/memory/jobs-worker.ts +0 -58
  229. package/src/memory/llm-request-log-store.ts +1 -26
  230. package/src/memory/llm-usage-store.ts +20 -48
  231. package/src/memory/memory-retrospective-job.ts +8 -9
  232. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +56 -130
  233. package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
  234. package/src/memory/migrations/registry.ts +573 -0
  235. package/src/memory/migrations/run-migrations.ts +6 -90
  236. package/src/memory/migrations/validate-migration-state.ts +66 -101
  237. package/src/memory/schema/conversations.ts +0 -9
  238. package/src/memory/schema/infrastructure.ts +0 -20
  239. package/src/memory/v2/__tests__/cli-command-store.test.ts +0 -25
  240. package/src/memory/v2/__tests__/skill-store.test.ts +0 -80
  241. package/src/memory/v2/cli-command-store.ts +38 -75
  242. package/src/memory/v2/prompts/consolidation.ts +82 -13
  243. package/src/memory/v2/prompts/router.ts +93 -21
  244. package/src/memory/v2/skill-store.ts +31 -68
  245. package/src/notifications/__tests__/broadcaster.test.ts +8 -16
  246. package/src/notifications/__tests__/decision-engine.test.ts +9 -78
  247. package/src/notifications/broadcaster.ts +1 -8
  248. package/src/notifications/decision-engine.ts +7 -15
  249. package/src/notifications/destination-resolver.ts +24 -68
  250. package/src/notifications/emit-signal.ts +14 -39
  251. package/src/permissions/question-prompter.test.ts +1 -1
  252. package/src/permissions/question-prompter.ts +4 -7
  253. package/src/plugin-api/index.ts +6 -6
  254. package/src/plugin-api/types.ts +5 -3
  255. package/src/plugin-api/vision-support.test.ts +4 -28
  256. package/src/plugin-api/vision-support.ts +31 -66
  257. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -161
  258. package/src/plugins/defaults/advisor/consult.ts +6 -110
  259. package/src/plugins/defaults/advisor/steering.ts +2 -14
  260. package/src/plugins/defaults/advisor/tools/advisor.ts +5 -32
  261. package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +1 -2
  262. package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +7 -47
  263. package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +11 -10
  264. package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +20 -12
  265. package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +11 -42
  266. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +3 -33
  267. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +4 -48
  268. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +8 -4
  269. package/src/plugins/defaults/memory-v3-shadow/injector.ts +15 -43
  270. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +2 -11
  271. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +13 -77
  272. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +11 -12
  273. package/src/plugins/mtime-cache.ts +291 -76
  274. package/src/plugins/pipeline.ts +13 -111
  275. package/src/plugins/types.ts +2 -0
  276. package/src/providers/anthropic/client.ts +0 -5
  277. package/src/providers/call-site-routing.ts +0 -4
  278. package/src/providers/model-catalog.ts +0 -16
  279. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  280. package/src/providers/openai/chat-completions-provider.ts +83 -37
  281. package/src/providers/openai/responses-provider.ts +46 -50
  282. package/src/providers/openrouter/client.ts +0 -5
  283. package/src/providers/provider-send-message.ts +0 -4
  284. package/src/providers/ratelimit.ts +0 -4
  285. package/src/providers/retry.ts +0 -4
  286. package/src/providers/types.ts +0 -9
  287. package/src/providers/usage-tracking.ts +0 -4
  288. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +3 -335
  289. package/src/runtime/access-request-helper.ts +39 -19
  290. package/src/runtime/actor-trust-resolver.ts +2 -2
  291. package/src/runtime/assistant-event-hub.ts +1 -1
  292. package/src/runtime/assistant-stream-state.ts +2 -9
  293. package/src/runtime/auth/require-bound-guardian.ts +11 -21
  294. package/src/runtime/channel-verification-service.ts +31 -56
  295. package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
  296. package/src/runtime/guardian-vellum-migration.ts +7 -66
  297. package/src/runtime/invite-redemption-service.ts +187 -198
  298. package/src/runtime/local-actor-identity.ts +11 -76
  299. package/src/runtime/pending-interactions.ts +1 -11
  300. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +5 -56
  301. package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
  302. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +0 -187
  303. package/src/runtime/routes/browser-routes.ts +1 -1
  304. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -13
  305. package/src/runtime/routes/channel-verification-routes.ts +3 -3
  306. package/src/runtime/routes/contact-routes.ts +32 -8
  307. package/src/runtime/routes/conversation-cli-routes.ts +5 -4
  308. package/src/runtime/routes/conversation-list-routes.ts +7 -4
  309. package/src/runtime/routes/conversation-query-routes.ts +0 -72
  310. package/src/runtime/routes/conversation-routes.ts +85 -84
  311. package/src/runtime/routes/events-routes.ts +2 -2
  312. package/src/runtime/routes/global-search-routes.ts +1 -3
  313. package/src/runtime/routes/guardian-action-routes.ts +5 -4
  314. package/src/runtime/routes/host-app-control-routes.ts +4 -5
  315. package/src/runtime/routes/host-bash-routes.ts +4 -5
  316. package/src/runtime/routes/host-browser-routes.ts +11 -9
  317. package/src/runtime/routes/host-cu-routes.ts +4 -5
  318. package/src/runtime/routes/host-file-routes.ts +4 -5
  319. package/src/runtime/routes/host-transfer-routes.ts +6 -6
  320. package/src/runtime/routes/http-adapter.ts +1 -1
  321. package/src/runtime/routes/identity-routes.ts +2 -3
  322. package/src/runtime/routes/inbound-message-handler.ts +5 -5
  323. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +5 -97
  324. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +49 -61
  325. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -16
  326. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
  327. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +8 -21
  328. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +3 -14
  329. package/src/runtime/routes/index.ts +0 -2
  330. package/src/runtime/routes/llm-context-normalization.ts +0 -83
  331. package/src/runtime/routes/mcp-auth-routes.ts +19 -171
  332. package/src/runtime/routes/migration-rollback-routes.ts +3 -4
  333. package/src/runtime/routes/migration-routes.ts +1 -4
  334. package/src/runtime/routes/subagents-routes.ts +0 -5
  335. package/src/runtime/routes/surface-action-routes.ts +56 -42
  336. package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -1
  337. package/src/runtime/services/conversation-serializer.ts +9 -7
  338. package/src/runtime/tool-grant-request-helper.ts +3 -3
  339. package/src/runtime/trust-verdict-consumer.ts +9 -85
  340. package/src/runtime/verification-outbound-actions.ts +18 -18
  341. package/src/signals/user-message.ts +0 -16
  342. package/src/subagent/manager.ts +0 -9
  343. package/src/subagent/types.ts +3 -3
  344. package/src/telemetry/types.ts +1 -34
  345. package/src/telemetry/usage-telemetry-reporter.test.ts +2 -3
  346. package/src/telemetry/usage-telemetry-reporter.ts +3 -87
  347. package/src/tools/ask-question/ask-question-tool.test.ts +0 -29
  348. package/src/tools/ask-question/ask-question-tool.ts +0 -13
  349. package/src/tools/executor.ts +4 -4
  350. package/src/tools/registry.ts +0 -18
  351. package/src/tools/shared/filesystem/path-policy.ts +5 -12
  352. package/src/tools/tool-approval-handler.ts +1 -1
  353. package/src/tools/tool-defaults.ts +2 -9
  354. package/src/tools/tool-manifest.ts +0 -3
  355. package/src/tools/types.ts +2 -17
  356. package/src/tools/workspace-tools/loader.ts +244 -348
  357. package/src/util/errors.ts +1 -26
  358. package/src/util/platform.ts +0 -5
  359. package/src/workflows/library.test.ts +0 -140
  360. package/src/workflows/library.ts +28 -82
  361. package/src/workspace/migrations/017-seed-persona-dirs.ts +34 -3
  362. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +24 -3
  363. package/src/workspace/migrations/048-remove-workspace-hooks.ts +66 -14
  364. package/src/workspace/migrations/registry.ts +0 -2
  365. package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +0 -91
  366. package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +0 -48
  367. package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +0 -28
  368. package/node_modules/@vellumai/service-contracts/src/channels.ts +0 -41
  369. package/src/__tests__/code-search-tool.test.ts +0 -585
  370. package/src/__tests__/guardian-expiry-notifier.test.ts +0 -282
  371. package/src/__tests__/mcp-config-secret-boundary.test.ts +0 -390
  372. package/src/__tests__/plugin-pipeline.test.ts +0 -96
  373. package/src/__tests__/sse-actor-principal-guardian-source.test.ts +0 -102
  374. package/src/__tests__/steer-on-enqueue-question.test.ts +0 -181
  375. package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +0 -208
  376. package/src/agent/loop-exclusive-tool.test.ts +0 -150
  377. package/src/api/constants/sse-replay.ts +0 -41
  378. package/src/api/events/conversation-notice.ts +0 -26
  379. package/src/approvals/guardian-channel-delivery.ts +0 -30
  380. package/src/approvals/guardian-expiry-notifier.ts +0 -148
  381. package/src/cli/commands/memory/__tests__/worker.test.ts +0 -302
  382. package/src/cli/commands/memory/worker.ts +0 -175
  383. package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -143
  384. package/src/config/prune-seeded-callsite-defaults.ts +0 -110
  385. package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -129
  386. package/src/contacts/__tests__/guardian-delivery-reader.test.ts +0 -312
  387. package/src/contacts/__tests__/member-write-relay.test.ts +0 -202
  388. package/src/contacts/guardian-delivery-reader.ts +0 -223
  389. package/src/contacts/member-write-relay.ts +0 -189
  390. package/src/daemon/conversation-notices.ts +0 -60
  391. package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -225
  392. package/src/hooks/hook-loader.ts +0 -341
  393. package/src/mcp/mcp-header-store.ts +0 -134
  394. package/src/memory/__tests__/301-create-watchdog-events.test.ts +0 -110
  395. package/src/memory/__tests__/prompt-override.test.ts +0 -192
  396. package/src/memory/__tests__/watchdog-events-store.test.ts +0 -161
  397. package/src/memory/migrations/300-add-processing-started-at.ts +0 -30
  398. package/src/memory/migrations/301-create-watchdog-events.ts +0 -45
  399. package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +0 -224
  400. package/src/memory/prompt-override.ts +0 -129
  401. package/src/memory/steps.ts +0 -573
  402. package/src/memory/watchdog-events-store.ts +0 -87
  403. package/src/memory/worker-control.ts +0 -118
  404. package/src/memory/worker-process.ts +0 -72
  405. package/src/notifications/__tests__/connected-channels.test.ts +0 -114
  406. package/src/notifications/__tests__/destination-resolver.test.ts +0 -256
  407. package/src/onboarding/checkin-event.test.ts +0 -222
  408. package/src/onboarding/checkin-event.ts +0 -321
  409. package/src/onboarding/schedule-checkin.ts +0 -190
  410. package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
  411. package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
  412. package/src/plugins/defaults/advisor/context-pack.ts +0 -288
  413. package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +0 -146
  414. package/src/plugins/surface-import.ts +0 -121
  415. package/src/providers/openai/__tests__/api-error-normalization.test.ts +0 -321
  416. package/src/providers/openai/api-error-normalization.ts +0 -270
  417. package/src/runtime/__tests__/channel-verification-service.test.ts +0 -133
  418. package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -181
  419. package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +0 -66
  420. package/src/runtime/__tests__/local-principal-trust.test.ts +0 -164
  421. package/src/runtime/anchored-guardian.test.ts +0 -156
  422. package/src/runtime/anchored-guardian.ts +0 -135
  423. package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +0 -99
  424. package/src/runtime/local-principal-trust.ts +0 -52
  425. package/src/runtime/routes/__tests__/contact-routes.test.ts +0 -212
  426. package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -93
  427. package/src/runtime/routes/onboarding-checkin-routes.ts +0 -86
  428. package/src/tools/filesystem/search.ts +0 -543
  429. package/src/util/telemetry-db-path.ts +0 -24
  430. package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +0 -134
@@ -0,0 +1,328 @@
1
+ /**
2
+ * Filesystem watcher for `<workspaceDir>/tools/`.
3
+ *
4
+ * Watches the workspace-tools directory non-recursively using fs.watch.
5
+ * On any add/change/delete event, debounces per filename stem (= tool
6
+ * name) and reconciles registry state against on-disk state: registers
7
+ * newly added tools, re-imports changed tools (cache-busting via the
8
+ * loader's per-import URL query string), unregisters deleted tools,
9
+ * strips core tools when a `.removed` sentinel appears, restores them
10
+ * when the sentinel disappears.
11
+ *
12
+ * No assistant restart is required — the file watcher closes the
13
+ * "edit a file, see the change" loop the same way the apps watcher and
14
+ * plugin source watcher do for their respective directories.
15
+ *
16
+ * ## Why per-stem reconciliation
17
+ *
18
+ * The watcher receives `(eventType, filename)` from fs.watch but the
19
+ * eventType ("rename" vs "change") is unreliable across editors and
20
+ * platforms — vim atomic-save shows as a rename of the original file
21
+ * plus an add of a new file, VS Code shows as a change in place, etc.
22
+ * Rather than route on eventType, we debounce per stem and re-derive
23
+ * the world: "given what's on disk right now for `<stem>.*`, what
24
+ * registry state should the assistant be in?"
25
+ *
26
+ * This is the same eventual-consistency pattern the plugin mtime cache
27
+ * uses — the watcher exists to KICK the reconciler, not to be the
28
+ * source of truth about what changed.
29
+ *
30
+ * ## Lifecycle position
31
+ *
32
+ * Started after the initial `loadWorkspaceTools()` scan completes
33
+ * during daemon startup, gated on the `workspace-tools-watcher` feature
34
+ * flag — when the flag is off the initial scan still runs but no watch
35
+ * loop is mounted, so workspace tools load from disk once and live edits
36
+ * need a restart. Stopped on assistant shutdown alongside the
37
+ * other long-lived watchers. Stoppage during shutdown does not
38
+ * unregister tools — those go away with the process; the watcher's
39
+ * only job is to keep the registry fresh while the assistant is up.
40
+ */
41
+
42
+ import { existsSync, type FSWatcher, watch } from "node:fs";
43
+
44
+ import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
45
+ import { getConfig } from "../config/loader.js";
46
+ import {
47
+ getCoreToolOverride,
48
+ getTool,
49
+ getToolOwner,
50
+ removeCoreToolViaWorkspace,
51
+ restoreStrippedCoreTool,
52
+ unregisterWorkspaceTool,
53
+ } from "../tools/registry.js";
54
+ import {
55
+ classifyWorkspaceToolEntry,
56
+ findWinningWorkspaceToolPath,
57
+ loadSingleWorkspaceTool,
58
+ } from "../tools/workspace-tools/loader.js";
59
+ import { DebouncerMap } from "../util/debounce.js";
60
+ import { attachFsWatcherErrorHandler } from "../util/fs-watcher-error.js";
61
+ import { getLogger } from "../util/logger.js";
62
+ import { getWorkspaceToolsDir } from "../util/platform.js";
63
+
64
+ const log = getLogger("workspace-tools-watcher");
65
+
66
+ /**
67
+ * Gates the dynamic hot-reload path. When disabled, workspace tools still
68
+ * load from disk once at daemon startup via {@link loadWorkspaceTools}; only
69
+ * the live watch → re-registration loop is suppressed. Read at its point of
70
+ * use in {@link WorkspaceToolsWatcher.start} so a daemon restart picks up a
71
+ * changed value.
72
+ */
73
+ const WORKSPACE_TOOLS_WATCHER_FLAG = "workspace-tools-watcher" as const;
74
+
75
+ /**
76
+ * Wait this long after the last fs event for a given stem before
77
+ * reconciling. Editor saves often emit a burst of 2–4 events; the
78
+ * debounce collapses them into a single load.
79
+ */
80
+ const RECONCILE_DEBOUNCE_MS = 250;
81
+
82
+ export class WorkspaceToolsWatcher {
83
+ /**
84
+ * Process-wide singleton. Callers reach the watcher via
85
+ * {@link WorkspaceToolsWatcher.getInstance} rather than instantiating
86
+ * directly so the daemon `start()`/`stop()` lifecycle and any future
87
+ * "trigger a manual reconcile" code paths share one watcher across the
88
+ * assistant process lifetime.
89
+ */
90
+ private static singleton: WorkspaceToolsWatcher | null = null;
91
+
92
+ static getInstance(): WorkspaceToolsWatcher {
93
+ WorkspaceToolsWatcher.singleton ??= new WorkspaceToolsWatcher();
94
+ return WorkspaceToolsWatcher.singleton;
95
+ }
96
+
97
+ /** Test-only — drops the singleton so the next `getInstance()` rebuilds. */
98
+ static resetForTests(): void {
99
+ WorkspaceToolsWatcher.singleton?.stop();
100
+ WorkspaceToolsWatcher.singleton = null;
101
+ }
102
+
103
+ /** Test-only — whether a live `fs.watch` loop is currently mounted. */
104
+ isWatchingForTests(): boolean {
105
+ return this.watcher !== null;
106
+ }
107
+
108
+ private watcher: FSWatcher | null = null;
109
+ private debouncer = new DebouncerMap({
110
+ defaultDelayMs: RECONCILE_DEBOUNCE_MS,
111
+ maxEntries: 100,
112
+ });
113
+ /**
114
+ * Promise queue per stem — guarantees that two events for the same
115
+ * stem can't run concurrently and corrupt the unregister/load
116
+ * sequence. The queue is single-deep (the chained promise simply
117
+ * awaits the in-flight one before running its own work), so the
118
+ * debouncer's collapsing already does most of the deduplication; this
119
+ * queue exists for the case where a second event lands during the
120
+ * in-flight reconcile's `await loadSingleWorkspaceTool`.
121
+ */
122
+ private inflight = new Map<string, Promise<void>>();
123
+
124
+ start(): void {
125
+ if (this.watcher) return;
126
+ if (
127
+ !isAssistantFeatureFlagEnabled(WORKSPACE_TOOLS_WATCHER_FLAG, getConfig())
128
+ ) {
129
+ log.debug(
130
+ "Workspace tools watcher disabled by feature flag; workspace tools load from disk at startup only (restart required to pick up edits)",
131
+ );
132
+ return;
133
+ }
134
+ const toolsDir = getWorkspaceToolsDir();
135
+ if (!existsSync(toolsDir)) {
136
+ log.debug(
137
+ { toolsDir },
138
+ "Workspace tools directory does not exist; watcher not started (will not auto-start on directory creation — restart required)",
139
+ );
140
+ return;
141
+ }
142
+ try {
143
+ this.watcher = watch(
144
+ toolsDir,
145
+ { recursive: false },
146
+ (_eventType, filename) => {
147
+ if (!filename) return;
148
+ const classified = classifyWorkspaceToolEntry(filename);
149
+ if (!classified) {
150
+ // Not a workspace-tool file — ignore (README.md, .DS_Store, etc.)
151
+ return;
152
+ }
153
+ this.debouncer.schedule(`stem:${classified.stem}`, () => {
154
+ this.scheduleReconcile(classified.stem);
155
+ });
156
+ },
157
+ );
158
+ // Async FSWatcher errors (e.g. ENOSPC, ENXIO) arrive as an 'error' event;
159
+ // without a listener they crash the daemon. Degrade to a dead watcher.
160
+ attachFsWatcherErrorHandler(this.watcher, log, toolsDir);
161
+ log.info({ toolsDir }, "Workspace tools watcher started");
162
+ } catch (err) {
163
+ log.warn(
164
+ { err, toolsDir },
165
+ "Failed to start workspace tools watcher — workspace tools will only register at startup",
166
+ );
167
+ }
168
+ }
169
+
170
+ stop(): void {
171
+ this.debouncer.cancelAll();
172
+ if (this.watcher) {
173
+ this.watcher.close();
174
+ this.watcher = null;
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Chain `reconcileStem(stem)` after any in-flight reconcile for the
180
+ * same stem so we never run two `loadSingleWorkspaceTool` calls
181
+ * concurrently for the same name.
182
+ */
183
+ private scheduleReconcile(stem: string): void {
184
+ const prev = this.inflight.get(stem) ?? Promise.resolve();
185
+ const next = prev
186
+ .catch(() => {
187
+ /* swallow — error already logged in the prior tick */
188
+ })
189
+ .then(() => this.reconcileStem(stem))
190
+ .catch((err) => {
191
+ const message = err instanceof Error ? err.message : String(err);
192
+ log.error(
193
+ { err, stem },
194
+ `workspace-tools-watcher: reconcile for "${stem}" threw: ${message}`,
195
+ );
196
+ })
197
+ .finally(() => {
198
+ // Only clear if we're still the current in-flight promise.
199
+ if (this.inflight.get(stem) === next) {
200
+ this.inflight.delete(stem);
201
+ }
202
+ });
203
+ this.inflight.set(stem, next);
204
+ }
205
+
206
+ /**
207
+ * Reconcile a single stem (= tool name) with on-disk state.
208
+ *
209
+ * Possible (live, removed) tuples and their resolution:
210
+ *
211
+ * - `(present, absent)` → ensure workspace tool is registered using
212
+ * the winning live file; re-import if a previous registration
213
+ * pointed at a different path
214
+ * - `(absent, present)` → ensure core tool is stripped (and any
215
+ * previous workspace registration torn down first)
216
+ * - `(absent, absent)` → ensure neither stripped state nor live
217
+ * registration remains
218
+ * - `(present, present)` → ambiguous; tear down both so neither
219
+ * state survives (matches the initial-scan contract)
220
+ */
221
+ private async reconcileStem(stem: string): Promise<void> {
222
+ const toolsDir = getWorkspaceToolsDir();
223
+ if (!existsSync(toolsDir)) {
224
+ this.teardownStem(stem);
225
+ return;
226
+ }
227
+
228
+ const { livePath, hasRemovedSentinel } = findWinningWorkspaceToolPath(
229
+ toolsDir,
230
+ stem,
231
+ );
232
+
233
+ // Ambiguous: tear down everything for this stem.
234
+ if (hasRemovedSentinel && livePath !== null) {
235
+ log.error(
236
+ { stem, toolsDir, livePath },
237
+ `workspace-tools-watcher: "${stem}" has both a live file and a .removed sentinel — tearing down both`,
238
+ );
239
+ this.teardownStem(stem);
240
+ return;
241
+ }
242
+
243
+ // Neither: tear down anything we own.
244
+ if (!hasRemovedSentinel && livePath === null) {
245
+ this.teardownStem(stem);
246
+ return;
247
+ }
248
+
249
+ if (hasRemovedSentinel) {
250
+ // Strip the core tool. Unregister any prior workspace registration
251
+ // first so removeCoreToolViaWorkspace doesn't throw on the
252
+ // workspace-owned-name check.
253
+ if (getToolOwner(stem)?.kind === "workspace") {
254
+ unregisterWorkspaceTool(stem);
255
+ }
256
+ try {
257
+ removeCoreToolViaWorkspace(stem);
258
+ } catch (err) {
259
+ const message = err instanceof Error ? err.message : String(err);
260
+ log.error(
261
+ { err, stem },
262
+ `workspace-tools-watcher: failed to strip "${stem}": ${message}`,
263
+ );
264
+ }
265
+ return;
266
+ }
267
+
268
+ if (livePath !== null) {
269
+ // If we previously stripped this core tool, restore it before the
270
+ // workspace registration runs so the override path sees the
271
+ // expected baseline (core tool present → stash + replace).
272
+ if (getCoreToolOverride(stem) && !getTool(stem)) {
273
+ restoreStrippedCoreTool(stem);
274
+ }
275
+
276
+ // If a workspace tool is already registered under this name,
277
+ // unregister it so the loader can re-import cleanly. This covers
278
+ // file-change events (same path, new contents) as well as
279
+ // extension-precedence flips (e.g. user added foo.js next to
280
+ // foo.ts — now .js wins and the registration must update).
281
+ if (getToolOwner(stem)?.kind === "workspace") {
282
+ unregisterWorkspaceTool(stem);
283
+ }
284
+
285
+ const registered = await loadSingleWorkspaceTool(livePath);
286
+ if (registered) {
287
+ log.info(
288
+ { stem, livePath },
289
+ `Workspace tool "${stem}" registered via watcher`,
290
+ );
291
+ }
292
+ // loadSingleWorkspaceTool already logs failures with attribution.
293
+ }
294
+ }
295
+
296
+ /**
297
+ * Tear down any workspace-tool state we own for `stem`: unregister a
298
+ * live workspace tool, restore a core tool we stripped. Both no-ops
299
+ * when there's nothing to undo.
300
+ */
301
+ private teardownStem(stem: string): void {
302
+ if (getToolOwner(stem)?.kind === "workspace") {
303
+ unregisterWorkspaceTool(stem);
304
+ log.info(
305
+ { stem },
306
+ `Workspace tool "${stem}" unregistered via watcher (file removed)`,
307
+ );
308
+ }
309
+ if (getCoreToolOverride(stem) && !getTool(stem)) {
310
+ restoreStrippedCoreTool(stem);
311
+ }
312
+ }
313
+
314
+ // ── Test affordances ────────────────────────────────────────────────
315
+ //
316
+ // These are intentionally narrow — exposed for the watcher tests so
317
+ // they can drive reconcile() deterministically without waiting on the
318
+ // debouncer, and inspect whether an in-flight promise is settled.
319
+ // Not part of the public lifecycle API.
320
+
321
+ /**
322
+ * Run a reconcile for `stem` synchronously (well, asynchronously, but
323
+ * without going through the debouncer). For tests.
324
+ */
325
+ async _testReconcile(stem: string): Promise<void> {
326
+ await this.reconcileStem(stem);
327
+ }
328
+ }
@@ -36,7 +36,7 @@ mock.module("../../config/env.js", () => ({
36
36
  }));
37
37
 
38
38
  mock.module("../../runtime/local-actor-identity.js", () => ({
39
- findLocalGuardianPrincipalIdFromStore: () => fakeLocalPrincipalId,
39
+ findLocalGuardianPrincipalId: () => fakeLocalPrincipalId,
40
40
  }));
41
41
 
42
42
  // ── Real imports (after mocks) ────────────────────────────────────────────
@@ -33,7 +33,7 @@ import { createServer, type Server, type Socket } from "node:net";
33
33
 
34
34
  import { ensureSocketDir, SocketWatchdog } from "@vellumai/ipc-server-utils";
35
35
 
36
- import { findLocalGuardianPrincipalIdFromStore } from "../runtime/local-actor-identity.js";
36
+ import { findLocalGuardianPrincipalId } from "../runtime/local-actor-identity.js";
37
37
  import { RouteError } from "../runtime/routes/errors.js";
38
38
  import { ROUTES } from "../runtime/routes/index.js";
39
39
  import type {
@@ -637,7 +637,7 @@ function injectLocalActorHeader(
637
637
  // that require the header will fail-closed on their own.
638
638
  let localActor: string | undefined;
639
639
  try {
640
- localActor = findLocalGuardianPrincipalIdFromStore();
640
+ localActor = findLocalGuardianPrincipalId();
641
641
  } catch (err) {
642
642
  log.debug(
643
643
  { err },
@@ -68,7 +68,6 @@ mock.module("../../daemon/mcp-reload-service.js", () => ({
68
68
 
69
69
  mock.module("../../config/env-registry.js", () => ({
70
70
  getIsContainerized: () => false,
71
- getWorkspaceDirOverride: () => undefined,
72
71
  }));
73
72
 
74
73
  mock.module("../../util/logger.js", () => ({
package/src/mcp/client.ts CHANGED
@@ -8,7 +8,6 @@ import { getIsPlatform } from "../config/env-registry.js";
8
8
  import type { McpTransport } from "../config/schemas/mcp.js";
9
9
  import { getSecureKeyAsync } from "../security/secure-keys.js";
10
10
  import { getLogger } from "../util/logger.js";
11
- import { getMcpHeaders } from "./mcp-header-store.js";
12
11
  import { McpOAuthProvider } from "./mcp-oauth-provider.js";
13
12
 
14
13
  const log = getLogger("mcp-client");
@@ -109,21 +108,8 @@ export class McpClient {
109
108
  }
110
109
  }
111
110
 
112
- // Resolve static auth headers from credential store, falling back to
113
- // any legacy headers in the transport config for backward compatibility.
114
- let effectiveConfig = transportConfig;
115
- if (isHttpTransport) {
116
- const storedHeaders = await getMcpHeaders(this.serverId);
117
- if (storedHeaders) {
118
- effectiveConfig = {
119
- ...transportConfig,
120
- headers: { ...transportConfig.headers, ...storedHeaders },
121
- } as McpTransport;
122
- }
123
- }
124
-
125
111
  log.info({ serverId: this.serverId }, "Connecting to MCP server");
126
- this.transport = this.createTransport(effectiveConfig);
112
+ this.transport = this.createTransport(transportConfig);
127
113
 
128
114
  try {
129
115
  await Promise.race([
@@ -21,7 +21,6 @@ import {
21
21
  setMcpAuthError,
22
22
  setMcpAuthPending,
23
23
  } from "./mcp-auth-state.js";
24
- import { getMcpHeaders } from "./mcp-header-store.js";
25
24
  import {
26
25
  type McpOAuthCallbackTransport,
27
26
  McpOAuthProvider,
@@ -81,10 +80,6 @@ export async function orchestrateMcpOAuthConnect(args: {
81
80
  // Register the pending callback in the daemon heap
82
81
  const { codePromise } = await provider.startCallbackServer();
83
82
 
84
- // Resolve effective headers: credential store takes precedence, then config
85
- const storedHeaders = await getMcpHeaders(serverId);
86
- const effectiveHeaders = storedHeaders ?? transport.headers;
87
-
88
83
  // Build the MCP transport and client
89
84
  const serverUrl = new URL(transport.url);
90
85
  const TransportClass =
@@ -93,7 +88,7 @@ export async function orchestrateMcpOAuthConnect(args: {
93
88
  : StreamableHTTPClientTransport;
94
89
  const mcpTransport = new TransportClass(serverUrl, {
95
90
  authProvider: provider,
96
- requestInit: effectiveHeaders ? { headers: effectiveHeaders } : undefined,
91
+ requestInit: transport.headers ? { headers: transport.headers } : undefined,
97
92
  });
98
93
  const client = new Client({ name: "vellum-assistant", version: "1.0.0" });
99
94
 
@@ -569,21 +569,13 @@ export class McpOAuthProvider implements OAuthClientProvider {
569
569
 
570
570
  // --- Static helpers ---
571
571
 
572
- /**
573
- * Check whether OAuth tokens exist in the credential store for a server.
574
- */
575
- export async function hasMcpOAuthTokens(serverId: string): Promise<boolean> {
576
- const raw = await getSecureKeyAsync(tokensKey(serverId));
577
- return raw != null && raw.length > 0;
578
- }
579
-
580
572
  /**
581
573
  * Delete all OAuth credentials for a given MCP server.
582
574
  * Used by `mcp remove` for cleanup.
583
575
  */
584
576
  export async function deleteMcpOAuthCredentials(
585
577
  serverId: string,
586
- ): Promise<{ ok: boolean; failedKeys: string[] }> {
578
+ ): Promise<void> {
587
579
  const [tokensResult, clientResult, discoveryResult] = await Promise.all([
588
580
  deleteSecureKeyAsync(tokensKey(serverId)),
589
581
  deleteSecureKeyAsync(clientInfoKey(serverId)),
@@ -594,23 +586,20 @@ export async function deleteMcpOAuthCredentials(
594
586
  { key: "client_info", result: clientResult },
595
587
  { key: "discovery", result: discoveryResult },
596
588
  ];
597
- const failedKeys = results
598
- .filter((r) => r.result === "error")
599
- .map((r) => r.key);
600
- if (failedKeys.length > 0) {
589
+ const errors = results.filter((r) => r.result === "error").map((r) => r.key);
590
+ if (errors.length > 0) {
601
591
  log.warn(
602
- { serverId, failedKeys },
592
+ { serverId, failedKeys: errors },
603
593
  "Some OAuth credentials could not be deleted from secure storage",
604
594
  );
605
595
  }
606
- const ok = failedKeys.length === 0;
596
+ const hasErrors = errors.length > 0;
607
597
  log.info(
608
598
  { serverId },
609
- ok
610
- ? "OAuth credentials deleted"
611
- : "OAuth credential deletion completed with errors",
599
+ hasErrors
600
+ ? "OAuth credential deletion completed with errors"
601
+ : "OAuth credentials deleted",
612
602
  );
613
- return { ok, failedKeys };
614
603
  }
615
604
 
616
605
  // --- HTML rendering ---
@@ -161,14 +161,6 @@ mock.module("../conversation-crud.js", () => ({
161
161
  title: "Source conversation",
162
162
  };
163
163
  },
164
- // Mirrors the real `isConversationProcessing` which reads the persisted
165
- // `processing_started_at` column. In tests, the mock registry
166
- // (`loadedConversations`) is the source of truth — a conversation id
167
- // present with `processing: true` simulates a mid-turn conversation.
168
- isConversationProcessing: (id: string) => {
169
- const entry = loadedConversations[id];
170
- return entry?.processing ?? false;
171
- },
172
164
  forkConversationForRetrospective: async (params: {
173
165
  conversationId: string;
174
166
  throughMessageId?: string;
@@ -25,7 +25,6 @@ import { parseChannelId, parseInterfaceId } from "../channels/types.js";
25
25
  import { CHANNEL_IDS, isChannelId } from "../channels/types.js";
26
26
  import { getConfig } from "../config/loader.js";
27
27
  import { findDisplayTurnEndIndex } from "../conversations/message-consolidation.js";
28
- import { findConversation } from "../daemon/conversation-registry.js";
29
28
  import { conversationMetadataSyncTag } from "../daemon/message-types/sync.js";
30
29
  import type { TrustContext } from "../daemon/trust-context.js";
31
30
  import { clearAllConversationIds } from "../home/feed-writer.js";
@@ -305,7 +304,6 @@ export interface ConversationRow {
305
304
  inferenceProfileSessionId: string | null;
306
305
  inferenceProfileExpiresAt: number | null;
307
306
  lastNotifiedInferenceProfile: string | null;
308
- processingStartedAt: number | null;
309
307
  }
310
308
 
311
309
  export const parseConversation = createRowMapper<
@@ -341,7 +339,6 @@ export const parseConversation = createRowMapper<
341
339
  inferenceProfileSessionId: "inferenceProfileSessionId",
342
340
  inferenceProfileExpiresAt: "inferenceProfileExpiresAt",
343
341
  lastNotifiedInferenceProfile: "lastNotifiedInferenceProfile",
344
- processingStartedAt: "processingStartedAt",
345
342
  });
346
343
 
347
344
  /** Allowed values for the `role` column on `messages`. */
@@ -2183,41 +2180,6 @@ export function unarchiveConversation(id: string): boolean {
2183
2180
  return true;
2184
2181
  }
2185
2182
 
2186
- /**
2187
- * Persist the processing-start timestamp for a conversation. Called by
2188
- * `Conversation.setProcessing(true)` so out-of-process callers can detect
2189
- * mid-turn state by reading the `conversations` row directly. Pass `null`
2190
- * to clear (turn ended).
2191
- */
2192
- export function setConversationProcessingStartedAt(
2193
- id: string,
2194
- startedAt: number | null,
2195
- ): void {
2196
- rawRun(
2197
- "UPDATE conversations SET processing_started_at = ? WHERE id = ?",
2198
- startedAt,
2199
- id,
2200
- );
2201
- }
2202
-
2203
- /**
2204
- * Read whether a conversation is currently processing. Checks the in-memory
2205
- * `Conversation._processing` flag first (hot path for resident conversations),
2206
- * falling back to the persisted `processing_started_at` column for cold
2207
- * (evicted / never-loaded) conversations. This is the single entry point for
2208
- * processing state — callers don't need to layer `findConversation` themselves.
2209
- * Returns `false` when the conversation row doesn't exist.
2210
- */
2211
- export function isConversationProcessing(id: string): boolean {
2212
- const inMemory = findConversation(id)?.isProcessing();
2213
- if (inMemory != null) return inMemory;
2214
- const row = rawGet<{ processing_started_at: number | null }>(
2215
- "SELECT processing_started_at FROM conversations WHERE id = ?",
2216
- id,
2217
- );
2218
- return row?.processing_started_at != null;
2219
- }
2220
-
2221
2183
  /**
2222
2184
  * Set or clear the `surfaced_at` promotion marker for a conversation.
2223
2185
  *
@@ -8,7 +8,6 @@ import { drizzle } from "drizzle-orm/bun-sqlite";
8
8
  import { getLogsDbPath } from "../util/logs-db-path.js";
9
9
  import { getMemoryDbPath } from "../util/memory-db-path.js";
10
10
  import { ensureDataDir, getDbPath } from "../util/platform.js";
11
- import { getTelemetryDbPath } from "../util/telemetry-db-path.js";
12
11
  import { clearStoredDb, getStoredDb, setStoredDb } from "./db-singleton.js";
13
12
  import * as schema from "./schema.js";
14
13
 
@@ -137,7 +136,7 @@ export function getSqliteFrom(drizzleDb: DrizzleDb): Database {
137
136
  * path so this file stays import-light. Callers tolerate a `null` result.
138
137
  */
139
138
  function openDedicatedDb(
140
- key: "logs" | "memory" | "telemetry",
139
+ key: "logs" | "memory",
141
140
  dbPath: string,
142
141
  ): DrizzleDb | null {
143
142
  assertTestDbIsIsolated();
@@ -193,28 +192,11 @@ export function getMemorySqlite(): Database | null {
193
192
  return db ? getSqliteFrom(db) : null;
194
193
  }
195
194
 
196
- /**
197
- * The telemetry database (`assistant-telemetry.db`), opened lazily as its own
198
- * connection. Houses telemetry event tables (starting with `watchdog_events`).
199
- * Returns `null` if the file cannot be opened (logged; the daemon stays up).
200
- */
201
- export function getTelemetryDb(): DrizzleDb | null {
202
- const existing = getStoredDb<DrizzleDb>("telemetry");
203
- if (existing) return existing;
204
- return openDedicatedDb("telemetry", getTelemetryDbPath());
205
- }
206
-
207
- /** Underlying bun:sqlite Database for the telemetry connection, or `null`. */
208
- export function getTelemetrySqlite(): Database | null {
209
- const db = getTelemetryDb();
210
- return db ? getSqliteFrom(db) : null;
211
- }
212
-
213
195
  /**
214
196
  * Reset all DB singletons. Used by production callers that need to close the
215
197
  * live connections so the files can be replaced (post-migration, post-restore,
216
- * post-vbundle-import) and on graceful shutdown. Clears the main, logs, memory,
217
- * and telemetry slots together so none lingers open against a swapped-out file.
198
+ * post-vbundle-import) and on graceful shutdown. Clears the main, logs, and
199
+ * memory slots together so none lingers open against a swapped-out file.
218
200
  *
219
201
  * Tests should use `resetDbForTesting()` from
220
202
  * `__tests__/db-test-helpers.ts` instead so they don't depend on this
@@ -224,5 +206,4 @@ export function resetDb(): void {
224
206
  clearStoredDb("main");
225
207
  clearStoredDb("logs");
226
208
  clearStoredDb("memory");
227
- clearStoredDb("telemetry");
228
209
  }