@vellumai/assistant 0.4.44 → 0.4.45

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 (681) hide show
  1. package/.prettierignore +4 -0
  2. package/ARCHITECTURE.md +34 -31
  3. package/README.md +4 -4
  4. package/bun.lock +10 -35
  5. package/docs/architecture/integrations.md +102 -197
  6. package/docs/architecture/keychain-broker.md +1 -1
  7. package/docs/architecture/memory.md +2 -2
  8. package/docs/architecture/scheduling.md +1 -1
  9. package/docs/architecture/security.md +11 -11
  10. package/docs/error-handling.md +1 -1
  11. package/docs/trusted-contact-access.md +3 -3
  12. package/drizzle/meta/0000_snapshot.json +34 -100
  13. package/drizzle/meta/_journal.json +1 -1
  14. package/drizzle.config.ts +4 -4
  15. package/package.json +3 -2
  16. package/scripts/capture-x-graphql.ts +237 -141
  17. package/scripts/generate-bundled-tool-registry.ts +223 -0
  18. package/src/__tests__/access-request-decision.test.ts +0 -1
  19. package/src/__tests__/actor-token-service.test.ts +23 -24
  20. package/src/__tests__/agent-loop.test.ts +0 -131
  21. package/src/__tests__/always-loaded-tools-guard.test.ts +71 -0
  22. package/src/__tests__/amazon-cdp-integration.test.ts +11 -9
  23. package/src/__tests__/approval-primitive.test.ts +0 -1
  24. package/src/__tests__/approval-routes-http.test.ts +11 -1
  25. package/src/__tests__/asset-materialize-tool.test.ts +0 -1
  26. package/src/__tests__/asset-search-tool.test.ts +0 -1
  27. package/src/__tests__/assistant-attachment-directive.test.ts +1 -1
  28. package/src/__tests__/assistant-events-sse-hardening.test.ts +0 -1
  29. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +70 -18
  31. package/src/__tests__/assistant-id-boundary-guard.test.ts +6 -6
  32. package/src/__tests__/attachments-store.test.ts +0 -1
  33. package/src/__tests__/avatar-e2e.test.ts +74 -115
  34. package/src/__tests__/avatar-router.test.ts +25 -62
  35. package/src/__tests__/browser-manager.test.ts +24 -0
  36. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +4 -3
  37. package/src/__tests__/browser-skill-endstate.test.ts +8 -11
  38. package/src/__tests__/btw-routes.test.ts +326 -0
  39. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +23 -9
  40. package/src/__tests__/call-controller.test.ts +0 -1
  41. package/src/__tests__/call-conversation-messages.test.ts +0 -1
  42. package/src/__tests__/call-domain.test.ts +0 -1
  43. package/src/__tests__/call-pointer-messages.test.ts +0 -1
  44. package/src/__tests__/call-recovery.test.ts +0 -1
  45. package/src/__tests__/call-routes-http.test.ts +0 -1
  46. package/src/__tests__/call-store.test.ts +0 -1
  47. package/src/__tests__/canonical-guardian-store.test.ts +0 -1
  48. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  49. package/src/__tests__/channel-approvals.test.ts +1 -1
  50. package/src/__tests__/channel-delivery-store.test.ts +0 -1
  51. package/src/__tests__/channel-guardian.test.ts +5 -7
  52. package/src/__tests__/channel-retry-sweep.test.ts +0 -1
  53. package/src/__tests__/checker.test.ts +4 -11
  54. package/src/__tests__/compaction.benchmark.test.ts +16 -14
  55. package/src/__tests__/computer-use-session-lifecycle.test.ts +10 -11
  56. package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
  57. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +2 -5
  58. package/src/__tests__/computer-use-tools.test.ts +35 -31
  59. package/src/__tests__/config-schema.test.ts +11 -15
  60. package/src/__tests__/config-watcher.test.ts +0 -1
  61. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  62. package/src/__tests__/conflict-store.test.ts +0 -1
  63. package/src/__tests__/connection-policy.test.ts +4 -7
  64. package/src/__tests__/contacts-tools.test.ts +0 -1
  65. package/src/__tests__/context-memory-e2e.test.ts +2 -4
  66. package/src/__tests__/context-overflow-reducer.test.ts +2 -4
  67. package/src/__tests__/context-window-manager.test.ts +147 -60
  68. package/src/__tests__/contradiction-checker.test.ts +0 -1
  69. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  70. package/src/__tests__/conversation-attention-telegram.test.ts +1 -1
  71. package/src/__tests__/conversation-pairing.test.ts +2 -2
  72. package/src/__tests__/conversation-routes-guardian-reply.test.ts +25 -1
  73. package/src/__tests__/conversation-routes-slash-commands.test.ts +381 -0
  74. package/src/__tests__/conversation-store.test.ts +0 -1
  75. package/src/__tests__/conversation-unread-route.test.ts +1 -2
  76. package/src/__tests__/credential-security-invariants.test.ts +7 -8
  77. package/src/__tests__/cross-provider-web-search.test.ts +353 -0
  78. package/src/__tests__/daemon-assistant-events.test.ts +6 -7
  79. package/src/__tests__/db-schedule-syntax-migration.test.ts +15 -3
  80. package/src/__tests__/delete-managed-skill-tool.test.ts +5 -9
  81. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
  82. package/src/__tests__/diagnostics-export.test.ts +189 -0
  83. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  84. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
  85. package/src/__tests__/entity-extractor.test.ts +0 -1
  86. package/src/__tests__/entity-search.test.ts +0 -1
  87. package/src/__tests__/ephemeral-permissions.test.ts +2 -4
  88. package/src/__tests__/file-read-tool.test.ts +86 -0
  89. package/src/__tests__/followup-tools.test.ts +0 -1
  90. package/src/__tests__/frontmatter.test.ts +77 -34
  91. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  92. package/src/__tests__/gateway-only-guard.test.ts +1 -1
  93. package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -1
  94. package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
  95. package/src/__tests__/guardian-action-followup-store.test.ts +0 -1
  96. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  97. package/src/__tests__/guardian-action-late-reply.test.ts +0 -1
  98. package/src/__tests__/guardian-action-store.test.ts +0 -1
  99. package/src/__tests__/guardian-action-sweep.test.ts +0 -1
  100. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  101. package/src/__tests__/guardian-dispatch.test.ts +1 -2
  102. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  103. package/src/__tests__/guardian-outbound-http.test.ts +0 -1
  104. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -1
  105. package/src/__tests__/guardian-routing-invariants.test.ts +1 -1
  106. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  107. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  108. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +3 -5
  109. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +28 -426
  110. package/src/__tests__/host-bash-proxy.test.ts +335 -0
  111. package/src/__tests__/host-file-proxy.test.ts +374 -0
  112. package/src/__tests__/host-shell-tool.test.ts +147 -1
  113. package/src/__tests__/http-user-message-parity.test.ts +361 -0
  114. package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
  115. package/src/__tests__/integration-status.test.ts +3 -8
  116. package/src/__tests__/intent-routing.test.ts +7 -46
  117. package/src/__tests__/invite-redemption-service.test.ts +0 -1
  118. package/src/__tests__/invite-routes-http.test.ts +0 -1
  119. package/src/__tests__/llm-usage-store.test.ts +0 -1
  120. package/src/__tests__/managed-avatar-client.test.ts +101 -55
  121. package/src/__tests__/managed-skill-lifecycle.test.ts +9 -18
  122. package/src/__tests__/managed-store.test.ts +94 -21
  123. package/src/__tests__/media-reuse-story.e2e.test.ts +0 -1
  124. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +2 -4
  125. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -1
  126. package/src/__tests__/memory-recall-quality.test.ts +0 -1
  127. package/src/__tests__/memory-regressions.experimental.test.ts +0 -1
  128. package/src/__tests__/memory-regressions.test.ts +0 -1
  129. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -1
  130. package/src/__tests__/memory-upsert-concurrency.test.ts +0 -1
  131. package/src/__tests__/messaging-send-tool.test.ts +35 -0
  132. package/src/__tests__/messaging-skill-split.test.ts +138 -0
  133. package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1
  134. package/src/__tests__/migration-export-http.test.ts +2 -3
  135. package/src/__tests__/migration-import-commit-http.test.ts +1 -2
  136. package/src/__tests__/migration-import-preflight-http.test.ts +1 -2
  137. package/src/__tests__/migration-validate-http.test.ts +1 -2
  138. package/src/__tests__/native-web-search.test.ts +475 -0
  139. package/src/__tests__/navigate-settings-tab.test.ts +84 -0
  140. package/src/__tests__/non-member-access-request.test.ts +0 -1
  141. package/src/__tests__/notification-broadcaster.test.ts +15 -15
  142. package/src/__tests__/notification-decision-strategy.test.ts +6 -6
  143. package/src/__tests__/notification-deep-link.test.ts +7 -7
  144. package/src/__tests__/notification-guardian-path.test.ts +2 -3
  145. package/src/__tests__/notification-telegram-adapter.test.ts +1 -1
  146. package/src/__tests__/notification-thread-candidates.test.ts +4 -4
  147. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  148. package/src/__tests__/playbook-execution.test.ts +0 -1
  149. package/src/__tests__/playbook-tools.test.ts +0 -1
  150. package/src/__tests__/profile-compiler.test.ts +0 -1
  151. package/src/__tests__/provider-managed-proxy-integration.test.ts +25 -0
  152. package/src/__tests__/qdrant-collection-migration.test.ts +223 -0
  153. package/src/__tests__/recording-handler.test.ts +30 -94
  154. package/src/__tests__/registry.test.ts +28 -35
  155. package/src/__tests__/relay-server.test.ts +0 -1
  156. package/src/__tests__/ride-shotgun-handler.test.ts +4 -20
  157. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  158. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  159. package/src/__tests__/runtime-events-sse.test.ts +0 -1
  160. package/src/__tests__/sandbox-diagnostics.test.ts +0 -1
  161. package/src/__tests__/scaffold-managed-skill-tool.test.ts +30 -28
  162. package/src/__tests__/schedule-store.test.ts +441 -1
  163. package/src/__tests__/schedule-tools.test.ts +468 -7
  164. package/src/__tests__/scheduler-recurrence.test.ts +196 -23
  165. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  166. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  167. package/src/__tests__/secret-prompt-log-hygiene.test.ts +6 -3
  168. package/src/__tests__/secret-response-routing.test.ts +4 -1
  169. package/src/__tests__/send-endpoint-busy.test.ts +14 -2
  170. package/src/__tests__/send-notification-tool.test.ts +0 -7
  171. package/src/__tests__/sequence-store.test.ts +0 -1
  172. package/src/__tests__/server-history-render.test.ts +1 -2
  173. package/src/__tests__/session-abort-tool-results.test.ts +0 -1
  174. package/src/__tests__/session-agent-loop.test.ts +46 -6
  175. package/src/__tests__/session-confirmation-signals.test.ts +0 -1
  176. package/src/__tests__/session-conflict-gate.test.ts +2 -6
  177. package/src/__tests__/session-error.test.ts +5 -14
  178. package/src/__tests__/session-init.benchmark.test.ts +3 -5
  179. package/src/__tests__/session-load-history-repair.test.ts +0 -1
  180. package/src/__tests__/session-media-retry.test.ts +12 -74
  181. package/src/__tests__/session-pre-run-repair.test.ts +0 -1
  182. package/src/__tests__/session-profile-injection.test.ts +2 -6
  183. package/src/__tests__/session-provider-retry-repair.test.ts +2 -6
  184. package/src/__tests__/session-queue.test.ts +94 -139
  185. package/src/__tests__/session-skill-tools.test.ts +115 -115
  186. package/src/__tests__/session-slash-known.test.ts +0 -1
  187. package/src/__tests__/session-slash-queue.test.ts +0 -1
  188. package/src/__tests__/session-slash-unknown.test.ts +0 -1
  189. package/src/__tests__/session-surfaces-task-progress.test.ts +34 -0
  190. package/src/__tests__/session-usage.test.ts +0 -1
  191. package/src/__tests__/session-workspace-cache-state.test.ts +2 -6
  192. package/src/__tests__/session-workspace-injection.test.ts +2 -6
  193. package/src/__tests__/session-workspace-tool-tracking.test.ts +2 -6
  194. package/src/__tests__/skill-feature-flags-integration.test.ts +180 -184
  195. package/src/__tests__/skill-feature-flags.test.ts +125 -18
  196. package/src/__tests__/skill-load-feature-flag.test.ts +1 -2
  197. package/src/__tests__/skill-load-tool.test.ts +194 -2
  198. package/src/__tests__/skill-projection-feature-flag.test.ts +27 -16
  199. package/src/__tests__/skill-projection.benchmark.test.ts +15 -14
  200. package/src/__tests__/skills.test.ts +14 -53
  201. package/src/__tests__/slack-channel-config.test.ts +0 -1
  202. package/src/__tests__/slack-inbound-verification.test.ts +0 -1
  203. package/src/__tests__/slack-skill.test.ts +1 -1
  204. package/src/__tests__/subagent-tools.test.ts +2 -2
  205. package/src/__tests__/system-prompt.test.ts +4 -3
  206. package/src/__tests__/task-compiler.test.ts +0 -1
  207. package/src/__tests__/task-management-tools.test.ts +0 -1
  208. package/src/__tests__/task-memory-cleanup.test.ts +0 -1
  209. package/src/__tests__/task-runner.test.ts +0 -1
  210. package/src/__tests__/task-scheduler.test.ts +0 -1
  211. package/src/__tests__/terminal-tools.test.ts +0 -1
  212. package/src/__tests__/test-support/computer-use-skill-harness.ts +2 -4
  213. package/src/__tests__/thread-seed-composer.test.ts +5 -5
  214. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  215. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  216. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  217. package/src/__tests__/tool-executor.test.ts +8 -86
  218. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  219. package/src/__tests__/tool-notification-listener.test.ts +1 -1
  220. package/src/__tests__/tool-preview-lifecycle.test.ts +416 -0
  221. package/src/__tests__/trust-store.test.ts +80 -4
  222. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  223. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  224. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -1
  225. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  226. package/src/__tests__/trusted-contact-verification.test.ts +0 -1
  227. package/src/__tests__/twilio-provider.test.ts +0 -1
  228. package/src/__tests__/twilio-routes.test.ts +0 -1
  229. package/src/__tests__/{request-file-tool.test.ts → ui-file-upload-surface.test.ts} +11 -72
  230. package/src/__tests__/update-bulletin.test.ts +0 -1
  231. package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -1
  232. package/src/__tests__/usage-routes.test.ts +0 -1
  233. package/src/__tests__/verification-control-plane-policy.test.ts +4 -4
  234. package/src/__tests__/voice-invite-redemption.test.ts +0 -1
  235. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  236. package/src/__tests__/voice-session-bridge.test.ts +9 -1
  237. package/src/__tests__/web-fetch.test.ts +57 -0
  238. package/src/__tests__/workspace-git-service.test.ts +5 -14
  239. package/src/__tests__/workspace-policy.test.ts +0 -1
  240. package/src/agent/loop.ts +22 -34
  241. package/src/bundler/bundle-signer.ts +4 -4
  242. package/src/calls/call-controller.ts +1 -1
  243. package/src/calls/relay-server.ts +1 -1
  244. package/src/calls/twilio-rest.ts +1 -1
  245. package/src/calls/voice-session-bridge.ts +3 -1
  246. package/src/cli/__tests__/notifications.test.ts +3 -4
  247. package/src/cli/commands/map.ts +2 -6
  248. package/src/cli/commands/mcp.ts +73 -15
  249. package/src/cli/commands/notifications.ts +4 -4
  250. package/src/cli/commands/sessions.ts +9 -1
  251. package/src/cli/commands/skills.ts +6 -10
  252. package/src/cli/http-client.ts +2 -3
  253. package/src/cli/main-screen.tsx +10 -10
  254. package/src/cli/program.ts +0 -4
  255. package/src/cli/reference.ts +0 -2
  256. package/src/cli.ts +15 -9
  257. package/src/config/__tests__/bundled-tool-registry-guard.test.ts +120 -0
  258. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +11 -0
  259. package/src/config/bundled-skills/app-builder/SKILL.md +6 -1
  260. package/src/config/bundled-skills/browser/SKILL.md +6 -1
  261. package/src/config/bundled-skills/chatgpt-import/SKILL.md +5 -1
  262. package/src/config/bundled-skills/claude-code/SKILL.md +5 -1
  263. package/src/config/bundled-skills/computer-use/SKILL.md +6 -1
  264. package/src/config/bundled-skills/computer-use/TOOLS.json +6 -69
  265. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +10 -1
  266. package/src/config/bundled-skills/contacts/SKILL.md +10 -1
  267. package/src/config/bundled-skills/contacts/TOOLS.json +35 -0
  268. package/src/config/bundled-skills/{messaging → contacts}/tools/google-contacts.ts +9 -2
  269. package/src/config/bundled-skills/document/SKILL.md +4 -1
  270. package/src/config/bundled-skills/doordash/SKILL.md +8 -1
  271. package/src/config/bundled-skills/doordash/lib/shared/platform.ts +4 -1
  272. package/src/config/bundled-skills/followups/SKILL.md +4 -1
  273. package/src/config/bundled-skills/gmail/SKILL.md +180 -0
  274. package/src/config/bundled-skills/gmail/TOOLS.json +506 -0
  275. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +149 -0
  276. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +110 -0
  277. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-draft.ts +1 -1
  278. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-filters.ts +1 -1
  279. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-follow-up.ts +1 -1
  280. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-forward.ts +1 -1
  281. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +50 -0
  282. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-outreach-scan.ts +8 -90
  283. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-send-draft.ts +1 -1
  284. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-sender-digest.ts +2 -2
  285. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-trash.ts +1 -1
  286. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-unsubscribe.ts +1 -1
  287. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-vacation.ts +1 -1
  288. package/src/config/bundled-skills/gmail/tools/shared.ts +47 -0
  289. package/src/config/bundled-skills/google-calendar/SKILL.md +5 -1
  290. package/src/config/bundled-skills/image-studio/SKILL.md +5 -1
  291. package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -1
  292. package/src/config/bundled-skills/media-processing/SKILL.md +7 -13
  293. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -22
  294. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +12 -1
  295. package/src/config/bundled-skills/messaging/SKILL.md +23 -139
  296. package/src/config/bundled-skills/messaging/TOOLS.json +33 -1215
  297. package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +42 -0
  298. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +165 -2
  299. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +1 -13
  300. package/src/config/bundled-skills/messaging/tools/shared.ts +81 -34
  301. package/src/config/bundled-skills/notifications/SKILL.md +5 -1
  302. package/src/config/bundled-skills/orchestration/SKILL.md +30 -0
  303. package/src/config/bundled-skills/orchestration/TOOLS.json +35 -0
  304. package/src/config/bundled-skills/{reminder/tools/reminder-create.ts → orchestration/tools/swarm-delegate.ts} +3 -3
  305. package/src/config/bundled-skills/phone-calls/SKILL.md +9 -1
  306. package/src/config/bundled-skills/playbooks/SKILL.md +4 -1
  307. package/src/config/bundled-skills/schedule/SKILL.md +70 -9
  308. package/src/config/bundled-skills/schedule/TOOLS.json +38 -6
  309. package/src/config/bundled-skills/screen-watch/SKILL.md +28 -0
  310. package/src/config/bundled-skills/screen-watch/TOOLS.json +35 -0
  311. package/src/config/bundled-skills/{reminder/tools/reminder-cancel.ts → screen-watch/tools/start-screen-watch.ts} +3 -3
  312. package/src/config/bundled-skills/sequences/SKILL.md +47 -0
  313. package/src/config/bundled-skills/sequences/TOOLS.json +340 -0
  314. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +128 -0
  315. package/src/config/bundled-skills/sequences/tools/shared.ts +9 -0
  316. package/src/config/bundled-skills/settings/SKILL.md +12 -0
  317. package/src/config/bundled-skills/settings/TOOLS.json +112 -0
  318. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +43 -0
  319. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +52 -0
  320. package/src/config/bundled-skills/{computer-use/tools/computer-use-right-click.ts → settings/tools/set-avatar.ts} +2 -6
  321. package/src/{tools/system/voice-config.ts → config/bundled-skills/settings/tools/voice-config-update.ts} +59 -96
  322. package/src/config/bundled-skills/skill-management/SKILL.md +18 -0
  323. package/src/config/bundled-skills/skill-management/TOOLS.json +90 -0
  324. package/src/config/bundled-skills/{computer-use/tools/computer-use-double-click.ts → skill-management/tools/delete-managed.ts} +2 -6
  325. package/src/config/bundled-skills/skill-management/tools/scaffold-managed.ts +12 -0
  326. package/src/config/bundled-skills/slack/SKILL.md +5 -1
  327. package/src/config/bundled-skills/subagent/SKILL.md +4 -1
  328. package/src/config/bundled-skills/tasks/SKILL.md +5 -2
  329. package/src/config/bundled-skills/transcribe/SKILL.md +4 -1
  330. package/src/config/bundled-skills/watcher/SKILL.md +4 -1
  331. package/src/config/bundled-tool-registry.ts +118 -107
  332. package/src/config/env.ts +5 -2
  333. package/src/config/feature-flag-registry.json +25 -9
  334. package/src/config/loader.ts +10 -2
  335. package/src/config/schema.ts +19 -16
  336. package/src/config/schemas/inference.ts +12 -22
  337. package/src/config/schemas/memory-storage.ts +19 -1
  338. package/src/config/schemas/platform.ts +0 -16
  339. package/src/config/skill-state.ts +11 -8
  340. package/src/config/skills.ts +83 -32
  341. package/src/context/token-estimator.ts +11 -0
  342. package/src/context/window-manager.ts +180 -151
  343. package/src/daemon/computer-use-session.ts +11 -43
  344. package/src/daemon/daemon-control.ts +4 -1
  345. package/src/daemon/handlers/config-channels.ts +5 -9
  346. package/src/daemon/handlers/config-ingress.ts +0 -4
  347. package/src/daemon/handlers/config-model.ts +7 -13
  348. package/src/daemon/handlers/config-telegram.ts +4 -8
  349. package/src/daemon/handlers/config-voice.ts +2 -5
  350. package/src/daemon/handlers/dictation.ts +2 -12
  351. package/src/daemon/handlers/identity.ts +0 -105
  352. package/src/daemon/handlers/recording.ts +3 -23
  353. package/src/daemon/handlers/session-history.ts +1 -1
  354. package/src/daemon/handlers/sessions.ts +53 -72
  355. package/src/daemon/handlers/shared.ts +7 -28
  356. package/src/daemon/handlers/skills.ts +31 -27
  357. package/src/daemon/host-bash-proxy.ts +148 -0
  358. package/src/daemon/host-file-proxy.ts +135 -0
  359. package/src/daemon/lifecycle.ts +49 -24
  360. package/src/daemon/mcp-reload-service.ts +123 -0
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/browser.ts +1 -1
  363. package/src/daemon/message-types/computer-use.ts +1 -4
  364. package/src/daemon/message-types/guardian-actions.ts +1 -1
  365. package/src/daemon/message-types/host-bash.ts +18 -0
  366. package/src/daemon/message-types/host-file.ts +44 -0
  367. package/src/daemon/message-types/integrations.ts +1 -67
  368. package/src/daemon/message-types/messages.ts +15 -0
  369. package/src/daemon/message-types/schedules.ts +11 -27
  370. package/src/daemon/message-types/sessions.ts +2 -1
  371. package/src/daemon/message-types/settings.ts +1 -1
  372. package/src/daemon/message-types/shared.ts +1 -1
  373. package/src/daemon/ride-shotgun-handler.ts +2 -42
  374. package/src/daemon/server.ts +43 -10
  375. package/src/daemon/session-agent-loop-handlers.ts +48 -7
  376. package/src/daemon/session-agent-loop.ts +97 -66
  377. package/src/daemon/session-attachments.ts +1 -1
  378. package/src/daemon/session-error.ts +17 -16
  379. package/src/daemon/session-lifecycle.ts +20 -1
  380. package/src/daemon/session-media-retry.ts +1 -15
  381. package/src/daemon/session-messaging.ts +14 -6
  382. package/src/daemon/session-process.ts +36 -7
  383. package/src/daemon/session-queue-manager.ts +62 -103
  384. package/src/daemon/session-runtime-assembly.ts +27 -0
  385. package/src/daemon/session-skill-tools.ts +12 -11
  386. package/src/daemon/session-slash.ts +7 -0
  387. package/src/daemon/session-surfaces.ts +19 -97
  388. package/src/daemon/session-tool-setup.ts +146 -6
  389. package/src/daemon/session.ts +77 -13
  390. package/src/errors.ts +0 -2
  391. package/src/export/formatter.ts +6 -0
  392. package/src/mcp/mcp-oauth-provider.ts +1 -3
  393. package/src/media/avatar-router.ts +20 -28
  394. package/src/media/avatar-types.ts +7 -14
  395. package/src/media/managed-avatar-client.ts +70 -34
  396. package/src/memory/conversation-title-service.ts +1 -2
  397. package/src/memory/db-init.ts +16 -0
  398. package/src/memory/embedding-backend.ts +129 -27
  399. package/src/memory/embedding-gemini.test.ts +256 -0
  400. package/src/memory/embedding-gemini.ts +47 -13
  401. package/src/memory/embedding-local.ts +14 -2
  402. package/src/memory/embedding-ollama.ts +15 -2
  403. package/src/memory/embedding-openai.ts +15 -2
  404. package/src/memory/embedding-types.test.ts +116 -0
  405. package/src/memory/embedding-types.ts +61 -0
  406. package/src/memory/fingerprint.ts +1 -1
  407. package/src/memory/indexer.ts +25 -1
  408. package/src/memory/job-handlers/embedding.test.ts +258 -0
  409. package/src/memory/job-handlers/embedding.ts +81 -1
  410. package/src/memory/job-handlers/index-maintenance.ts +35 -1
  411. package/src/memory/job-handlers/media-processing.ts +11 -1
  412. package/src/memory/job-utils.ts +21 -6
  413. package/src/memory/jobs-store.ts +5 -1
  414. package/src/memory/jobs-worker.ts +8 -0
  415. package/src/memory/message-content.ts +66 -0
  416. package/src/memory/migrations/100-core-tables.ts +1 -31
  417. package/src/memory/migrations/104-core-indexes.ts +0 -11
  418. package/src/memory/migrations/145-drop-accounts-table.ts +19 -0
  419. package/src/memory/migrations/146-schedule-oneshot-routing.ts +94 -0
  420. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +129 -0
  421. package/src/memory/migrations/148-drop-reminders-table.ts +18 -0
  422. package/src/memory/migrations/index.ts +4 -0
  423. package/src/memory/migrations/registry.ts +19 -0
  424. package/src/memory/qdrant-client.ts +158 -43
  425. package/src/memory/retriever.test.ts +0 -1
  426. package/src/memory/retriever.ts +12 -2
  427. package/src/memory/schema/infrastructure.ts +5 -29
  428. package/src/memory/search/formatting.ts +34 -9
  429. package/src/memory/search/semantic.ts +57 -2
  430. package/src/memory/search/types.ts +2 -1
  431. package/src/notifications/AGENTS.md +2 -2
  432. package/src/notifications/README.md +59 -58
  433. package/src/notifications/adapters/macos.ts +1 -1
  434. package/src/notifications/broadcaster.ts +5 -5
  435. package/src/notifications/copy-composer.ts +1 -1
  436. package/src/notifications/decision-engine.ts +2 -2
  437. package/src/notifications/destination-resolver.ts +2 -2
  438. package/src/notifications/emit-signal.ts +8 -8
  439. package/src/notifications/signal.ts +1 -1
  440. package/src/notifications/thread-seed-composer.ts +1 -1
  441. package/src/oauth/connect-orchestrator.ts +1 -1
  442. package/src/oauth/token-persistence.ts +1 -1
  443. package/src/permissions/checker.ts +12 -1
  444. package/src/permissions/defaults.ts +10 -14
  445. package/src/permissions/trust-store.ts +37 -0
  446. package/src/permissions/workspace-policy.ts +0 -1
  447. package/src/prompts/__tests__/build-cli-reference-section.test.ts +11 -0
  448. package/src/prompts/computer-use-prompt.ts +1 -1
  449. package/src/prompts/system-prompt.ts +29 -30
  450. package/src/prompts/templates/SOUL.md +1 -2
  451. package/src/prompts/templates/UPDATES.md +16 -7
  452. package/src/providers/anthropic/client.ts +87 -33
  453. package/src/providers/gemini/client.ts +6 -0
  454. package/src/providers/managed-proxy/constants.ts +5 -0
  455. package/src/providers/openai/client.ts +15 -0
  456. package/src/providers/registry.ts +2 -2
  457. package/src/providers/types.ts +24 -2
  458. package/src/runtime/AGENTS.md +18 -0
  459. package/src/runtime/assistant-event-hub.ts +2 -3
  460. package/src/runtime/assistant-event.ts +4 -4
  461. package/src/runtime/auth/__tests__/context.test.ts +5 -5
  462. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  463. package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -2
  464. package/src/runtime/auth/__tests__/{ipc-auth-context.test.ts → local-auth-context.test.ts} +21 -21
  465. package/src/runtime/auth/__tests__/route-policy.test.ts +2 -2
  466. package/src/runtime/auth/__tests__/scopes.test.ts +7 -7
  467. package/src/runtime/auth/__tests__/subject.test.ts +8 -8
  468. package/src/runtime/auth/__tests__/token-service.test.ts +0 -1
  469. package/src/runtime/auth/route-policy.ts +8 -4
  470. package/src/runtime/auth/scopes.ts +1 -1
  471. package/src/runtime/auth/subject.ts +4 -4
  472. package/src/runtime/auth/token-service.ts +0 -23
  473. package/src/runtime/auth/types.ts +3 -3
  474. package/src/runtime/guardian-action-followup-executor.ts +1 -1
  475. package/src/runtime/guardian-action-grant-minter.ts +1 -1
  476. package/src/runtime/guardian-action-service.ts +3 -3
  477. package/src/runtime/http-server.ts +15 -2
  478. package/src/runtime/invite-service.ts +3 -3
  479. package/src/runtime/local-actor-identity.ts +17 -22
  480. package/src/runtime/pending-interactions.ts +21 -9
  481. package/src/runtime/routes/app-management-routes.ts +2 -3
  482. package/src/runtime/routes/approval-routes.ts +1 -3
  483. package/src/runtime/routes/btw-routes.ts +155 -0
  484. package/src/runtime/routes/computer-use-routes.ts +77 -31
  485. package/src/runtime/routes/conversation-routes.ts +230 -46
  486. package/src/runtime/routes/diagnostics-routes.ts +63 -29
  487. package/src/runtime/routes/documents-routes.ts +2 -2
  488. package/src/runtime/routes/global-search-routes.ts +1 -1
  489. package/src/runtime/routes/host-bash-routes.ts +83 -0
  490. package/src/runtime/routes/host-file-routes.ts +79 -0
  491. package/src/runtime/routes/integrations/slack/share.ts +1 -1
  492. package/src/runtime/routes/log-export-routes.ts +120 -0
  493. package/src/runtime/routes/mcp-routes.ts +20 -0
  494. package/src/runtime/routes/migration-routes.ts +3 -3
  495. package/src/runtime/routes/pairing-routes.ts +1 -1
  496. package/src/runtime/routes/recording-routes.ts +6 -4
  497. package/src/runtime/routes/schedule-routes.ts +31 -5
  498. package/src/runtime/routes/session-management-routes.ts +2 -6
  499. package/src/runtime/routes/session-query-routes.ts +18 -15
  500. package/src/runtime/routes/settings-routes.ts +7 -261
  501. package/src/runtime/routes/skills-routes.ts +7 -6
  502. package/src/runtime/routes/subagents-routes.ts +4 -10
  503. package/src/runtime/routes/surface-action-routes.ts +3 -14
  504. package/src/runtime/routes/surface-content-routes.ts +22 -5
  505. package/src/runtime/routes/work-items-routes.ts +21 -25
  506. package/src/runtime/routes/workspace-routes.test.ts +3 -3
  507. package/src/runtime/routes/workspace-utils.ts +1 -1
  508. package/src/runtime/telegram-streaming-delivery.ts +3 -0
  509. package/src/runtime/verification-outbound-actions.ts +2 -2
  510. package/src/schedule/integration-status.ts +0 -6
  511. package/src/schedule/schedule-store.ts +234 -43
  512. package/src/schedule/scheduler.ts +73 -74
  513. package/src/security/oauth2.ts +1 -1
  514. package/src/sequence/store.ts +12 -2
  515. package/src/skills/frontmatter.ts +19 -77
  516. package/src/skills/managed-store.ts +11 -2
  517. package/src/subagent/manager.ts +5 -3
  518. package/src/tasks/ephemeral-permissions.ts +3 -5
  519. package/src/tools/AGENTS.md +0 -1
  520. package/src/tools/browser/browser-manager.ts +17 -11
  521. package/src/tools/browser/jit-auth.ts +4 -1
  522. package/src/tools/claude-code/claude-code.ts +1 -1
  523. package/src/tools/computer-use/definitions.ts +48 -60
  524. package/src/tools/document/document-tool.ts +6 -6
  525. package/src/tools/filesystem/edit.ts +2 -1
  526. package/src/tools/filesystem/read.ts +20 -2
  527. package/src/tools/filesystem/write.ts +2 -1
  528. package/src/tools/host-filesystem/edit.ts +17 -1
  529. package/src/tools/host-filesystem/read.ts +16 -1
  530. package/src/tools/host-filesystem/write.ts +15 -1
  531. package/src/tools/host-terminal/host-shell.ts +24 -0
  532. package/src/tools/memory/definitions.ts +45 -81
  533. package/src/tools/memory/handlers.test.ts +0 -1
  534. package/src/tools/memory/handlers.ts +1 -1
  535. package/src/tools/memory/register.ts +26 -60
  536. package/src/tools/network/script-proxy/session-manager.ts +6 -8
  537. package/src/tools/network/web-fetch.ts +7 -1
  538. package/src/tools/network/web-search.ts +2 -1
  539. package/src/tools/registry.ts +23 -0
  540. package/src/tools/schedule/create.ts +113 -5
  541. package/src/tools/schedule/list.ts +57 -15
  542. package/src/tools/schedule/update.ts +73 -3
  543. package/src/tools/shared/filesystem/image-read.ts +192 -0
  544. package/src/tools/side-effects.ts +1 -7
  545. package/src/tools/skills/delete-managed.ts +27 -64
  546. package/src/tools/skills/execute.ts +54 -0
  547. package/src/tools/skills/load.ts +127 -5
  548. package/src/tools/skills/scaffold-managed.ts +93 -172
  549. package/src/tools/subagent/message.ts +0 -7
  550. package/src/tools/subagent/spawn.ts +1 -1
  551. package/src/tools/swarm/delegate.ts +0 -3
  552. package/src/tools/system/avatar-generator.ts +13 -19
  553. package/src/tools/system/request-permission.ts +2 -1
  554. package/src/tools/terminal/safe-env.ts +1 -0
  555. package/src/tools/tool-manifest.ts +41 -47
  556. package/src/tools/types.ts +6 -2
  557. package/src/tools/ui-surface/definitions.ts +0 -55
  558. package/src/util/errors.ts +0 -10
  559. package/src/workspace/git-service.ts +0 -2
  560. package/src/__tests__/account-registry.test.ts +0 -258
  561. package/src/__tests__/email-classifier.test.ts +0 -25
  562. package/src/__tests__/gmail-integration.test.ts +0 -97
  563. package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -172
  564. package/src/__tests__/managed-twitter-guardrails.test.ts +0 -357
  565. package/src/__tests__/recording-intent-fallback.test.ts +0 -199
  566. package/src/__tests__/recording-intent.test.ts +0 -985
  567. package/src/__tests__/recording-state-machine.test.ts +0 -1574
  568. package/src/__tests__/reminder-store.test.ts +0 -350
  569. package/src/__tests__/reminder.test.ts +0 -337
  570. package/src/__tests__/scan-result-store.test.ts +0 -121
  571. package/src/__tests__/twitter-platform-proxy-client.test.ts +0 -475
  572. package/src/__tests__/view-image-tool.test.ts +0 -241
  573. package/src/cli/commands/amazon/cart.ts +0 -513
  574. package/src/cli/commands/amazon/checkout.ts +0 -394
  575. package/src/cli/commands/amazon/client.ts +0 -513
  576. package/src/cli/commands/amazon/index.ts +0 -885
  577. package/src/cli/commands/amazon/product-details.ts +0 -145
  578. package/src/cli/commands/amazon/request-extractor.ts +0 -187
  579. package/src/cli/commands/amazon/search.ts +0 -76
  580. package/src/cli/commands/amazon/session.ts +0 -108
  581. package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +0 -345
  582. package/src/cli/commands/twitter/__tests__/cli-routing.test.ts +0 -252
  583. package/src/cli/commands/twitter/__tests__/oauth-client.test.ts +0 -151
  584. package/src/cli/commands/twitter/index.ts +0 -420
  585. package/src/cli/commands/twitter/oauth-client.ts +0 -60
  586. package/src/cli/commands/twitter/router.ts +0 -351
  587. package/src/cli/commands/twitter/types.ts +0 -30
  588. package/src/config/bundled-skills/agentmail/SKILL.md +0 -132
  589. package/src/config/bundled-skills/agentmail/icon.svg +0 -21
  590. package/src/config/bundled-skills/amazon/SKILL.md +0 -136
  591. package/src/config/bundled-skills/amazon/icon.svg +0 -13
  592. package/src/config/bundled-skills/api-mapping/SKILL.md +0 -78
  593. package/src/config/bundled-skills/api-mapping/icon.svg +0 -18
  594. package/src/config/bundled-skills/cli-discover/SKILL.md +0 -68
  595. package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +0 -179
  596. package/src/config/bundled-skills/document-writer/SKILL.md +0 -195
  597. package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +0 -140
  598. package/src/config/bundled-skills/email-setup/SKILL.md +0 -68
  599. package/src/config/bundled-skills/frontend-design/SKILL.md +0 -44
  600. package/src/config/bundled-skills/frontend-design/icon.svg +0 -16
  601. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +0 -452
  602. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +0 -203
  603. package/src/config/bundled-skills/influencer/SKILL.md +0 -144
  604. package/src/config/bundled-skills/influencer/scripts/client.ts +0 -1269
  605. package/src/config/bundled-skills/influencer/scripts/influencer.ts +0 -267
  606. package/src/config/bundled-skills/macos-automation/SKILL.md +0 -65
  607. package/src/config/bundled-skills/macos-automation/icon.svg +0 -12
  608. package/src/config/bundled-skills/mcp-setup/SKILL.md +0 -75
  609. package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +0 -184
  610. package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +0 -80
  611. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +0 -29
  612. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +0 -56
  613. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +0 -34
  614. package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +0 -47
  615. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +0 -31
  616. package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +0 -67
  617. package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +0 -97
  618. package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +0 -87
  619. package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +0 -135
  620. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +0 -24
  621. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +0 -201
  622. package/src/config/bundled-skills/messaging/tools/send-notification.ts +0 -1
  623. package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +0 -27
  624. package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +0 -48
  625. package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +0 -27
  626. package/src/config/bundled-skills/messaging/tools/sequence-update.ts +0 -56
  627. package/src/config/bundled-skills/notion/SKILL.md +0 -240
  628. package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +0 -126
  629. package/src/config/bundled-skills/oauth-setup/SKILL.md +0 -143
  630. package/src/config/bundled-skills/public-ingress/SKILL.md +0 -258
  631. package/src/config/bundled-skills/reminder/SKILL.md +0 -79
  632. package/src/config/bundled-skills/reminder/TOOLS.json +0 -89
  633. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +0 -12
  634. package/src/config/bundled-skills/restaurant-reservation/SKILL.md +0 -141
  635. package/src/config/bundled-skills/screen-recording/SKILL.md +0 -148
  636. package/src/config/bundled-skills/self-upgrade/SKILL.md +0 -69
  637. package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -78
  638. package/src/config/bundled-skills/slack-app-setup/SKILL.md +0 -178
  639. package/src/config/bundled-skills/slack-digest-setup/SKILL.md +0 -163
  640. package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +0 -157
  641. package/src/config/bundled-skills/start-the-day/SKILL.md +0 -70
  642. package/src/config/bundled-skills/start-the-day/icon.svg +0 -13
  643. package/src/config/bundled-skills/telegram-setup/SKILL.md +0 -105
  644. package/src/config/bundled-skills/time-based-actions/SKILL.md +0 -142
  645. package/src/config/bundled-skills/twilio-setup/SKILL.md +0 -232
  646. package/src/config/bundled-skills/twitter/SKILL.md +0 -206
  647. package/src/config/bundled-skills/twitter/icon.svg +0 -14
  648. package/src/config/bundled-skills/typescript-eval/SKILL.md +0 -60
  649. package/src/config/bundled-skills/vercel-token-setup/SKILL.md +0 -214
  650. package/src/config/bundled-skills/voice-setup/SKILL.md +0 -131
  651. package/src/config/bundled-skills/voice-setup/icon.svg +0 -20
  652. package/src/daemon/handlers/pairing.ts +0 -119
  653. package/src/daemon/handlers/session-user-message.ts +0 -961
  654. package/src/daemon/recording-executor.ts +0 -180
  655. package/src/daemon/recording-intent-fallback.ts +0 -162
  656. package/src/daemon/recording-intent.ts +0 -493
  657. package/src/memory/account-store.ts +0 -117
  658. package/src/messaging/activity-analyzer.ts +0 -76
  659. package/src/messaging/email-classifier.ts +0 -208
  660. package/src/messaging/index.ts +0 -2
  661. package/src/messaging/outreach-classifier.ts +0 -185
  662. package/src/messaging/thread-summarizer.ts +0 -346
  663. package/src/messaging/types.ts +0 -17
  664. package/src/tools/browser/x-auto-navigate.ts +0 -254
  665. package/src/tools/credentials/account-registry.ts +0 -144
  666. package/src/tools/filesystem/view-image.ts +0 -244
  667. package/src/tools/reminder/reminder-store.ts +0 -194
  668. package/src/tools/reminder/reminder.ts +0 -158
  669. package/src/tools/system/navigate-settings.ts +0 -74
  670. package/src/tools/system/open-system-settings.ts +0 -85
  671. package/src/tools/system/version.ts +0 -54
  672. package/src/twitter/platform-proxy-client.ts +0 -408
  673. /package/src/config/bundled-skills/{messaging → gmail}/tools/scan-result-store.ts +0 -0
  674. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-analytics.ts +0 -0
  675. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-create.ts +0 -0
  676. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-delete.ts +0 -0
  677. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enroll.ts +0 -0
  678. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enrollment-list.ts +0 -0
  679. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-get.ts +0 -0
  680. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-import.ts +0 -0
  681. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-list.ts +0 -0
@@ -1,13 +1,14 @@
1
1
  import { existsSync, rmSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
+ import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
4
5
  import {
5
6
  getConfig,
6
7
  invalidateConfigCache,
7
8
  loadRawConfig,
8
9
  saveRawConfig,
9
10
  } from "../../config/loader.js";
10
- import { resolveSkillStates } from "../../config/skill-state.js";
11
+ import { resolveSkillStates, skillFlagKey } from "../../config/skill-state.js";
11
12
  import {
12
13
  ensureSkillIcon,
13
14
  loadSkillBySelector,
@@ -51,7 +52,6 @@ import type {
51
52
  } from "../message-protocol.js";
52
53
  import {
53
54
  CONFIG_RELOAD_DEBOUNCE_MS,
54
- defineHandlers,
55
55
  ensureSkillEntry,
56
56
  type HandlerContext,
57
57
  log,
@@ -62,7 +62,7 @@ import {
62
62
  /**
63
63
  * Minimal context needed by the standalone skill business-logic functions.
64
64
  * HandlerContext satisfies this interface, but HTTP routes can also provide
65
- * a compatible object without coupling to IPC internals.
65
+ * a compatible object without coupling to handler internals.
66
66
  */
67
67
  export interface SkillOperationContext {
68
68
  debounceTimers: HandlerContext["debounceTimers"];
@@ -204,7 +204,7 @@ function heuristicDraft(body: string): {
204
204
  const LLM_DRAFT_TIMEOUT_MS = 15_000;
205
205
 
206
206
  // ─── Standalone business-logic functions ─────────────────────────────────────
207
- // These are consumed by both the IPC handlers below and the HTTP route layer.
207
+ // These are consumed by both the handlers below and the HTTP route layer.
208
208
 
209
209
  /** Helper: suppress config reload, save, debounce, and update fingerprint. */
210
210
  function saveConfigWithSuppression(
@@ -318,7 +318,11 @@ export function disableSkill(
318
318
 
319
319
  export function configureSkill(
320
320
  skillId: string,
321
- config: { env?: Record<string, string>; apiKey?: string; config?: Record<string, unknown> },
321
+ config: {
322
+ env?: Record<string, string>;
323
+ apiKey?: string;
324
+ config?: Record<string, unknown>;
325
+ },
322
326
  ctx: SkillOperationContext,
323
327
  ): { success: true } | { success: false; error: string } {
324
328
  try {
@@ -343,6 +347,20 @@ export async function installSkill(
343
347
  try {
344
348
  // Bundled skills are already available — no install needed
345
349
  const catalog = loadSkillCatalog();
350
+
351
+ // Feature flag gate: reject install if the skill's flag is disabled
352
+ const config = getConfig();
353
+ const flaggedSkill = catalog.find((s) => s.id === spec.slug);
354
+ if (flaggedSkill) {
355
+ const flagKey = skillFlagKey(flaggedSkill);
356
+ if (flagKey && !isAssistantFeatureFlagEnabled(flagKey, config)) {
357
+ return {
358
+ success: false,
359
+ error: `Skill "${spec.slug}" is currently unavailable (disabled by feature flag)`,
360
+ };
361
+ }
362
+ }
363
+
346
364
  const bundled = catalog.find(
347
365
  (s) => s.id === spec.slug && s.source === "bundled",
348
366
  );
@@ -484,7 +502,9 @@ export async function updateSkill(
484
502
 
485
503
  export async function checkSkillUpdates(
486
504
  _ctx: SkillOperationContext,
487
- ): Promise<{ success: true; data: unknown } | { success: false; error: string }> {
505
+ ): Promise<
506
+ { success: true; data: unknown } | { success: false; error: string }
507
+ > {
488
508
  try {
489
509
  const updates = await clawhubCheckUpdates();
490
510
  return { success: true, data: updates };
@@ -498,7 +518,9 @@ export async function checkSkillUpdates(
498
518
  export async function searchSkills(
499
519
  query: string,
500
520
  _ctx: SkillOperationContext,
501
- ): Promise<{ success: true; data: unknown } | { success: false; error: string }> {
521
+ ): Promise<
522
+ { success: true; data: unknown } | { success: false; error: string }
523
+ > {
502
524
  try {
503
525
  const result = await clawhubSearch(query);
504
526
  return { success: true, data: result };
@@ -742,11 +764,9 @@ export async function createSkill(
742
764
  }
743
765
  }
744
766
 
745
- // ─── IPC handlers (thin wrappers) ───────────────────────────────────────────
767
+ // ─── HTTP handlers (thin wrappers) ──────────────────────────────────────────
746
768
 
747
- export function handleSkillsList(
748
- ctx: HandlerContext,
749
- ): void {
769
+ export function handleSkillsList(ctx: HandlerContext): void {
750
770
  const skills = listSkills(ctx);
751
771
  ctx.send({ type: "skills_list_response", skills });
752
772
  }
@@ -923,19 +943,3 @@ export async function handleSkillsCreate(
923
943
  ...result,
924
944
  });
925
945
  }
926
-
927
- export const skillHandlers = defineHandlers({
928
- skills_list: (_msg, ctx) => handleSkillsList(ctx),
929
- skill_detail: handleSkillDetail,
930
- skills_enable: handleSkillsEnable,
931
- skills_disable: handleSkillsDisable,
932
- skills_configure: handleSkillsConfigure,
933
- skills_install: handleSkillsInstall,
934
- skills_uninstall: handleSkillsUninstall,
935
- skills_update: handleSkillsUpdate,
936
- skills_check_updates: handleSkillsCheckUpdates,
937
- skills_search: handleSkillsSearch,
938
- skills_inspect: handleSkillsInspect,
939
- skills_draft: handleSkillsDraft,
940
- skills_create: handleSkillsCreate,
941
- });
@@ -0,0 +1,148 @@
1
+ import { v4 as uuid } from "uuid";
2
+
3
+ import { getConfig } from "../config/loader.js";
4
+ import { formatShellOutput } from "../tools/shared/shell-output.js";
5
+ import type { ToolExecutionResult } from "../tools/types.js";
6
+ import { AssistantError, ErrorCode } from "../util/errors.js";
7
+ import { getLogger } from "../util/logger.js";
8
+ import type { ServerMessage } from "./message-protocol.js";
9
+
10
+ const log = getLogger("host-bash-proxy");
11
+
12
+ interface PendingRequest {
13
+ resolve: (result: ToolExecutionResult) => void;
14
+ reject: (err: Error) => void;
15
+ timer: ReturnType<typeof setTimeout>;
16
+ timeoutSec: number;
17
+ }
18
+
19
+ export class HostBashProxy {
20
+ private pending = new Map<string, PendingRequest>();
21
+ private sendToClient: (msg: ServerMessage) => void;
22
+ private onInternalResolve?: (requestId: string) => void;
23
+ private clientConnected = false;
24
+
25
+ constructor(
26
+ sendToClient: (msg: ServerMessage) => void,
27
+ onInternalResolve?: (requestId: string) => void,
28
+ ) {
29
+ this.sendToClient = sendToClient;
30
+ this.onInternalResolve = onInternalResolve;
31
+ }
32
+
33
+ updateSender(
34
+ sendToClient: (msg: ServerMessage) => void,
35
+ clientConnected: boolean,
36
+ ): void {
37
+ this.sendToClient = sendToClient;
38
+ this.clientConnected = clientConnected;
39
+ }
40
+
41
+ request(
42
+ input: { command: string; working_dir?: string; timeout_seconds?: number },
43
+ sessionId: string,
44
+ signal?: AbortSignal,
45
+ ): Promise<ToolExecutionResult> {
46
+ if (signal?.aborted) {
47
+ const result = formatShellOutput("", "Aborted", null, false, 0);
48
+ return Promise.resolve(result);
49
+ }
50
+
51
+ const requestId = uuid();
52
+
53
+ return new Promise<ToolExecutionResult>((resolve, reject) => {
54
+ const shellMaxTimeoutSec = getConfig().timeouts.shellMaxTimeoutSec;
55
+ const timeoutSec = input.timeout_seconds ?? shellMaxTimeoutSec;
56
+ // Proxy timeout: slightly after client-side timeout, but before executor's outer timeout
57
+ const proxyTimeoutSec = timeoutSec + 3;
58
+ const timer = setTimeout(() => {
59
+ this.pending.delete(requestId);
60
+ this.onInternalResolve?.(requestId);
61
+ log.warn(
62
+ { requestId, command: input.command },
63
+ "Host bash proxy request timed out",
64
+ );
65
+ resolve(
66
+ formatShellOutput(
67
+ "",
68
+ "Host bash proxy timed out waiting for client response",
69
+ null,
70
+ true,
71
+ timeoutSec,
72
+ ),
73
+ );
74
+ }, proxyTimeoutSec * 1000);
75
+
76
+ this.pending.set(requestId, { resolve, reject, timer, timeoutSec });
77
+
78
+ if (signal) {
79
+ const onAbort = () => {
80
+ if (this.pending.has(requestId)) {
81
+ clearTimeout(timer);
82
+ this.pending.delete(requestId);
83
+ this.onInternalResolve?.(requestId);
84
+ resolve(formatShellOutput("", "Aborted", null, false, 0));
85
+ }
86
+ };
87
+ signal.addEventListener("abort", onAbort, { once: true });
88
+ }
89
+
90
+ this.sendToClient({
91
+ type: "host_bash_request",
92
+ requestId,
93
+ sessionId,
94
+ command: input.command,
95
+ working_dir: input.working_dir,
96
+ timeout_seconds: input.timeout_seconds,
97
+ } as ServerMessage);
98
+ });
99
+ }
100
+
101
+ resolve(
102
+ requestId: string,
103
+ response: {
104
+ stdout: string;
105
+ stderr: string;
106
+ exitCode: number | null;
107
+ timedOut: boolean;
108
+ },
109
+ ): void {
110
+ const entry = this.pending.get(requestId);
111
+ if (!entry) {
112
+ log.warn({ requestId }, "No pending host bash request for response");
113
+ return;
114
+ }
115
+ clearTimeout(entry.timer);
116
+ this.pending.delete(requestId);
117
+ const result = formatShellOutput(
118
+ response.stdout,
119
+ response.stderr,
120
+ response.exitCode,
121
+ response.timedOut,
122
+ entry.timeoutSec,
123
+ );
124
+ entry.resolve(result);
125
+ }
126
+
127
+ hasPendingRequest(requestId: string): boolean {
128
+ return this.pending.has(requestId);
129
+ }
130
+
131
+ isAvailable(): boolean {
132
+ return this.clientConnected;
133
+ }
134
+
135
+ dispose(): void {
136
+ for (const [requestId, entry] of this.pending) {
137
+ clearTimeout(entry.timer);
138
+ this.onInternalResolve?.(requestId);
139
+ entry.reject(
140
+ new AssistantError(
141
+ "Host bash proxy disposed",
142
+ ErrorCode.INTERNAL_ERROR,
143
+ ),
144
+ );
145
+ }
146
+ this.pending.clear();
147
+ }
148
+ }
@@ -0,0 +1,135 @@
1
+ import { v4 as uuid } from "uuid";
2
+
3
+ import type { ToolExecutionResult } from "../tools/types.js";
4
+ import { AssistantError, ErrorCode } from "../util/errors.js";
5
+ import { getLogger } from "../util/logger.js";
6
+ import type { ServerMessage } from "./message-protocol.js";
7
+ import type { HostFileRequest } from "./message-types/host-file.js";
8
+
9
+ /** Distributive omit that preserves union variant fields. */
10
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown
11
+ ? Omit<T, K>
12
+ : never;
13
+
14
+ /** Clean input type for callers — transport envelope fields are added by the proxy. */
15
+ export type HostFileInput = DistributiveOmit<
16
+ HostFileRequest,
17
+ "type" | "requestId" | "sessionId"
18
+ >;
19
+
20
+ const log = getLogger("host-file-proxy");
21
+
22
+ interface PendingRequest {
23
+ resolve: (result: ToolExecutionResult) => void;
24
+ reject: (err: Error) => void;
25
+ timer: ReturnType<typeof setTimeout>;
26
+ }
27
+
28
+ export class HostFileProxy {
29
+ private pending = new Map<string, PendingRequest>();
30
+ private sendToClient: (msg: ServerMessage) => void;
31
+ private onInternalResolve?: (requestId: string) => void;
32
+ private clientConnected = false;
33
+
34
+ constructor(
35
+ sendToClient: (msg: ServerMessage) => void,
36
+ onInternalResolve?: (requestId: string) => void,
37
+ ) {
38
+ this.sendToClient = sendToClient;
39
+ this.onInternalResolve = onInternalResolve;
40
+ }
41
+
42
+ updateSender(
43
+ sendToClient: (msg: ServerMessage) => void,
44
+ clientConnected: boolean,
45
+ ): void {
46
+ this.sendToClient = sendToClient;
47
+ this.clientConnected = clientConnected;
48
+ }
49
+
50
+ request(
51
+ input: HostFileInput,
52
+ sessionId: string,
53
+ signal?: AbortSignal,
54
+ ): Promise<ToolExecutionResult> {
55
+ if (signal?.aborted) {
56
+ return Promise.resolve({ content: "Aborted", isError: true });
57
+ }
58
+
59
+ const requestId = uuid();
60
+
61
+ return new Promise<ToolExecutionResult>((resolve, reject) => {
62
+ // File operations should be fast — 30 second timeout.
63
+ const timeoutSec = 30;
64
+ const timer = setTimeout(() => {
65
+ this.pending.delete(requestId);
66
+ this.onInternalResolve?.(requestId);
67
+ log.warn(
68
+ { requestId, operation: input.operation },
69
+ "Host file proxy request timed out",
70
+ );
71
+ resolve({
72
+ content: "Host file proxy timed out waiting for client response",
73
+ isError: true,
74
+ });
75
+ }, timeoutSec * 1000);
76
+
77
+ this.pending.set(requestId, { resolve, reject, timer });
78
+
79
+ if (signal) {
80
+ const onAbort = () => {
81
+ if (this.pending.has(requestId)) {
82
+ clearTimeout(timer);
83
+ this.pending.delete(requestId);
84
+ this.onInternalResolve?.(requestId);
85
+ resolve({ content: "Aborted", isError: true });
86
+ }
87
+ };
88
+ signal.addEventListener("abort", onAbort, { once: true });
89
+ }
90
+
91
+ this.sendToClient({
92
+ ...input,
93
+ type: "host_file_request",
94
+ requestId,
95
+ sessionId,
96
+ } as ServerMessage);
97
+ });
98
+ }
99
+
100
+ resolve(
101
+ requestId: string,
102
+ response: { content: string; isError: boolean },
103
+ ): void {
104
+ const entry = this.pending.get(requestId);
105
+ if (!entry) {
106
+ log.warn({ requestId }, "No pending host file request for response");
107
+ return;
108
+ }
109
+ clearTimeout(entry.timer);
110
+ this.pending.delete(requestId);
111
+ entry.resolve({ content: response.content, isError: response.isError });
112
+ }
113
+
114
+ hasPendingRequest(requestId: string): boolean {
115
+ return this.pending.has(requestId);
116
+ }
117
+
118
+ isAvailable(): boolean {
119
+ return this.clientConnected;
120
+ }
121
+
122
+ dispose(): void {
123
+ for (const [requestId, entry] of this.pending) {
124
+ clearTimeout(entry.timer);
125
+ this.onInternalResolve?.(requestId);
126
+ entry.reject(
127
+ new AssistantError(
128
+ "Host file proxy disposed",
129
+ ErrorCode.INTERNAL_ERROR,
130
+ ),
131
+ );
132
+ }
133
+ this.pending.clear();
134
+ }
135
+ }
@@ -1,3 +1,4 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { chmodSync, writeFileSync } from "node:fs";
2
3
  import { join } from "node:path";
3
4
 
@@ -30,6 +31,7 @@ import {
30
31
  getMessages,
31
32
  } from "../memory/conversation-crud.js";
32
33
  import { initializeDb } from "../memory/db.js";
34
+ import { selectEmbeddingBackend } from "../memory/embedding-backend.js";
33
35
  import { startMemoryJobsWorker } from "../memory/jobs-worker.js";
34
36
  import { initQdrantClient } from "../memory/qdrant-client.js";
35
37
  import { QdrantManager } from "../memory/qdrant-manager.js";
@@ -43,10 +45,10 @@ import { syncUpdateBulletinOnStartup } from "../prompts/update-bulletin.js";
43
45
  import { buildAssistantEvent } from "../runtime/assistant-event.js";
44
46
  import { assistantEventHub } from "../runtime/assistant-event-hub.js";
45
47
  import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
48
+ import { mintCredentialPair } from "../runtime/auth/credential-service.js";
46
49
  import {
47
50
  initAuthSigningKey,
48
51
  loadOrCreateSigningKey,
49
- mintCliEdgeToken,
50
52
  mintPairingBearerToken,
51
53
  } from "../runtime/auth/token-service.js";
52
54
  import { ensureVellumGuardianBinding } from "../runtime/guardian-vellum-migration.js";
@@ -77,7 +79,6 @@ import {
77
79
  createGuardianActionCopyGenerator,
78
80
  createGuardianFollowUpConversationGenerator,
79
81
  } from "./guardian-action-generators.js";
80
- import { initPairingHandlers } from "./handlers/pairing.js";
81
82
  import {
82
83
  cancelGeneration,
83
84
  clearAllSessions,
@@ -141,14 +142,6 @@ export async function runDaemon(): Promise<void> {
141
142
  const signingKey = loadOrCreateSigningKey();
142
143
  initAuthSigningKey(signingKey);
143
144
 
144
- // Mint a CLI edge token (JWT) so the CLI can authenticate with the
145
- // gateway. Written early so the CLI doesn't time out polling.
146
- const httpTokenPath = join(getRootDir(), "http-token");
147
- const bearerToken = mintCliEdgeToken();
148
- writeFileSync(httpTokenPath, bearerToken, { mode: 0o600 });
149
- chmodSync(httpTokenPath, 0o600);
150
- log.info("Daemon startup: bearer token written");
151
-
152
145
  log.info("Daemon startup: migrations complete");
153
146
 
154
147
  seedInterfaceFiles();
@@ -168,9 +161,13 @@ export async function runDaemon(): Promise<void> {
168
161
  initializeDb();
169
162
  log.info("Daemon startup: DB initialized");
170
163
 
171
- // Backfill vellum guardian binding for existing installations
164
+ // Ensure a vellum guardian binding exists and mint the CLI edge token
165
+ // as an actor token bound to the guardian principal.
166
+ let guardianPrincipalId: string | undefined;
172
167
  try {
173
- ensureVellumGuardianBinding(DAEMON_INTERNAL_ASSISTANT_ID);
168
+ guardianPrincipalId = ensureVellumGuardianBinding(
169
+ DAEMON_INTERNAL_ASSISTANT_ID,
170
+ );
174
171
  } catch (err) {
175
172
  log.warn(
176
173
  { err },
@@ -178,6 +175,29 @@ export async function runDaemon(): Promise<void> {
178
175
  );
179
176
  }
180
177
 
178
+ if (guardianPrincipalId) {
179
+ const cliDeviceId = "daemon-cli";
180
+ const hashedDeviceId = createHash("sha256")
181
+ .update(cliDeviceId)
182
+ .digest("hex");
183
+ const credentials = mintCredentialPair({
184
+ platform: "cli",
185
+ deviceId: cliDeviceId,
186
+ guardianPrincipalId,
187
+ hashedDeviceId,
188
+ });
189
+
190
+ // DEPRECATED: The http-token file is deprecated. Readers will be
191
+ // migrated to use the credential store instead. This write is kept
192
+ // for backward compatibility until all consumers are updated.
193
+ const httpTokenPath = join(getRootDir(), "http-token");
194
+ writeFileSync(httpTokenPath, credentials.accessToken, { mode: 0o600 });
195
+ chmodSync(httpTokenPath, 0o600);
196
+ log.info("Daemon startup: CLI edge token written to credential store and http-token");
197
+ } else {
198
+ log.warn("No guardian principal available — CLI edge token not written");
199
+ }
200
+
181
201
  try {
182
202
  syncUpdateBulletinOnStartup();
183
203
  } catch (err) {
@@ -252,12 +272,17 @@ export async function runDaemon(): Promise<void> {
252
272
  const qdrantManager = new QdrantManager({ url: qdrantUrl });
253
273
  try {
254
274
  await qdrantManager.start();
275
+ const embeddingSelection = selectEmbeddingBackend(config);
276
+ const embeddingModel = embeddingSelection.backend
277
+ ? `${embeddingSelection.backend.provider}:${embeddingSelection.backend.model}`
278
+ : undefined;
255
279
  initQdrantClient({
256
280
  url: qdrantUrl,
257
281
  collection: config.memory.qdrant.collection,
258
282
  vectorSize: config.memory.qdrant.vectorSize,
259
283
  onDisk: config.memory.qdrant.onDisk,
260
284
  quantization: config.memory.qdrant.quantization,
285
+ embeddingModel,
261
286
  });
262
287
  log.info("Qdrant vector store initialized");
263
288
  } catch (err) {
@@ -293,11 +318,11 @@ export async function runDaemon(): Promise<void> {
293
318
  : undefined,
294
319
  );
295
320
  },
296
- (reminder) => {
297
- void emitNotificationSignal({
298
- sourceEventName: "reminder.fired",
321
+ async (schedule) => {
322
+ await emitNotificationSignal({
323
+ sourceEventName: "schedule.notify",
299
324
  sourceChannel: "scheduler",
300
- sourceSessionId: reminder.id,
325
+ sourceSessionId: schedule.id,
301
326
  attentionHints: {
302
327
  requiresAction: true,
303
328
  urgency: "high",
@@ -305,13 +330,14 @@ export async function runDaemon(): Promise<void> {
305
330
  visibleInSourceNow: false,
306
331
  },
307
332
  contextPayload: {
308
- reminderId: reminder.id,
309
- label: reminder.label,
310
- message: reminder.message,
333
+ scheduleId: schedule.id,
334
+ label: schedule.label,
335
+ message: schedule.message,
311
336
  },
312
- routingIntent: reminder.routingIntent,
313
- routingHints: reminder.routingHints,
314
- dedupeKey: `reminder:${reminder.id}`,
337
+ routingIntent: schedule.routingIntent,
338
+ routingHints: schedule.routingHints,
339
+ dedupeKey: `schedule:notify:${schedule.id}:${Date.now()}`,
340
+ throwOnError: true,
315
341
  });
316
342
  },
317
343
  (schedule) => {
@@ -384,7 +410,7 @@ export async function runDaemon(): Promise<void> {
384
410
  const hostname = getRuntimeHttpHost();
385
411
 
386
412
  // Mint a JWT bearer token for the pairing flow. This replaces the
387
- // old static http-token that was removed — the pairing IPC handler
413
+ // old static http-token that was removed — the pairing handler
388
414
  // and HTTP auto-approve logic both guard on a non-empty bearer token.
389
415
  const pairingBearerToken = mintPairingBearerToken();
390
416
 
@@ -706,7 +732,6 @@ export async function runDaemon(): Promise<void> {
706
732
  runtimeHttp.setPairingBroadcast((msg) =>
707
733
  server.broadcast(msg as ServerMessage),
708
734
  );
709
- initPairingHandlers(runtimeHttp.getPairingStore(), pairingBearerToken);
710
735
  initSlashPairingContext(runtimeHttp.getPairingStore());
711
736
  server.setHttpPort(httpPort);
712
737
  log.info(
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Shared MCP reload business logic.
3
+ *
4
+ * Used by the HTTP route (`runtime/routes/mcp-routes.ts`) so the reload
5
+ * behaviour is defined in exactly one place.
6
+ */
7
+
8
+ import { getConfig, invalidateConfigCache } from "../config/loader.js";
9
+ import { getMcpServerManager } from "../mcp/manager.js";
10
+ import { createMcpToolsFromServer } from "../tools/mcp/mcp-tool-factory.js";
11
+ import { registerMcpTools, unregisterAllMcpTools } from "../tools/registry.js";
12
+ import { getLogger } from "../util/logger.js";
13
+
14
+ const log = getLogger("mcp-reload-service");
15
+
16
+ /** Per-server reload result. */
17
+ export interface McpReloadServerResult {
18
+ id: string;
19
+ connected: boolean;
20
+ /** True when the server is explicitly disabled in config. */
21
+ disabled?: boolean;
22
+ toolCount: number;
23
+ tools: string[];
24
+ }
25
+
26
+ export interface McpReloadResult {
27
+ success: boolean;
28
+ serverCount?: number;
29
+ toolCount?: number;
30
+ servers?: McpReloadServerResult[];
31
+ error?: string;
32
+ }
33
+
34
+ let reloadInProgress: Promise<McpReloadResult> | null = null;
35
+
36
+ /**
37
+ * Stop all MCP servers, reload configuration from disk, and restart
38
+ * servers with the updated config. Returns a summary of the reload.
39
+ *
40
+ * Concurrent calls are serialized — if a reload is already in progress
41
+ * the caller receives the same promise instead of starting a second one.
42
+ */
43
+ export function reloadMcpServers(): Promise<McpReloadResult> {
44
+ if (reloadInProgress) {
45
+ log.info("MCP reload already in progress, awaiting existing operation");
46
+ return reloadInProgress;
47
+ }
48
+ reloadInProgress = doReload().finally(() => {
49
+ reloadInProgress = null;
50
+ });
51
+ return reloadInProgress;
52
+ }
53
+
54
+ async function doReload(): Promise<McpReloadResult> {
55
+ try {
56
+ const manager = getMcpServerManager();
57
+
58
+ // 1. Validate new config before tearing down existing servers.
59
+ // If the config is broken we abort early, preserving the current
60
+ // working MCP setup instead of leaving zero servers.
61
+ invalidateConfigCache();
62
+ const config = getConfig();
63
+
64
+ // 2. Stop existing MCP servers + unregister their tools
65
+ await manager.stop();
66
+ unregisterAllMcpTools();
67
+ const serverIds = config.mcp?.servers
68
+ ? Object.keys(config.mcp.servers)
69
+ : [];
70
+
71
+ // 3. Restart MCP servers
72
+ let serverCount = 0;
73
+ let toolCount = 0;
74
+ const servers: McpReloadServerResult[] = [];
75
+
76
+ if (config.mcp?.servers && Object.keys(config.mcp.servers).length > 0) {
77
+ const serverToolInfos = await manager.start(config.mcp);
78
+ for (const { serverId, serverConfig, tools } of serverToolInfos) {
79
+ const mcpTools = createMcpToolsFromServer(
80
+ tools,
81
+ serverId,
82
+ serverConfig,
83
+ manager,
84
+ );
85
+ const accepted = registerMcpTools(mcpTools);
86
+ const acceptedNames = accepted.map((t) => t.name);
87
+ toolCount += accepted.length;
88
+ servers.push({
89
+ id: serverId,
90
+ connected: true,
91
+ toolCount: accepted.length,
92
+ tools: acceptedNames,
93
+ });
94
+ }
95
+ // Include servers that were configured but failed to connect or are disabled
96
+ for (const id of serverIds) {
97
+ if (!servers.some((s) => s.id === id)) {
98
+ const serverConfig = config.mcp!.servers![id];
99
+ const isDisabled = serverConfig?.enabled === false;
100
+ servers.push({
101
+ id,
102
+ connected: false,
103
+ disabled: isDisabled || undefined,
104
+ toolCount: 0,
105
+ tools: [],
106
+ });
107
+ }
108
+ }
109
+ serverCount = servers.length;
110
+ }
111
+
112
+ // Sessions pick up new MCP tools automatically on their next turn
113
+ // via the dynamic resolver in createResolveToolsCallback — no need
114
+ // to evict sessions.
115
+
116
+ log.info({ serverCount, toolCount }, "MCP servers reloaded");
117
+ return { success: true, serverCount, toolCount, servers };
118
+ } catch (err) {
119
+ const error = err instanceof Error ? err.message : String(err);
120
+ log.error({ err }, "MCP reload failed");
121
+ return { success: false, error };
122
+ }
123
+ }