@vellumai/assistant 0.7.1 → 0.7.3

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 (739) hide show
  1. package/ARCHITECTURE.md +48 -50
  2. package/Dockerfile +1 -0
  3. package/README.md +1 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
  5. package/bun.lock +26 -26
  6. package/docs/architecture/memory.md +5 -2
  7. package/docs/architecture/security.md +20 -0
  8. package/docs/plugins.md +7 -9
  9. package/knip.json +1 -0
  10. package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
  11. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
  12. package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
  13. package/node_modules/@vellumai/service-contracts/package.json +2 -0
  14. package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
  15. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
  16. package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
  17. package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
  18. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
  19. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  20. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  21. package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
  22. package/node_modules/@vellumai/twilio-client/package.json +18 -0
  23. package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
  24. package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
  25. package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
  26. package/openapi.yaml +1020 -40
  27. package/package.json +6 -3
  28. package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
  29. package/src/__tests__/app-bundler.test.ts +170 -1
  30. package/src/__tests__/app-control-flow.test.ts +384 -0
  31. package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
  32. package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
  33. package/src/__tests__/app-executors.test.ts +30 -43
  34. package/src/__tests__/approval-routes-http.test.ts +23 -6
  35. package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
  36. package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
  37. package/src/__tests__/assistant-event-hub.test.ts +157 -2
  38. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
  39. package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
  40. package/src/__tests__/background-shell-host-bash.test.ts +14 -15
  41. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  42. package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
  43. package/src/__tests__/btw-routes.test.ts +13 -4
  44. package/src/__tests__/call-controller.test.ts +49 -1
  45. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  46. package/src/__tests__/call-domain.test.ts +0 -2
  47. package/src/__tests__/call-routes-http.test.ts +0 -2
  48. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  49. package/src/__tests__/channel-readiness-service.test.ts +62 -2
  50. package/src/__tests__/checker.test.ts +3 -4
  51. package/src/__tests__/config-loader-backfill.test.ts +461 -147
  52. package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
  53. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  54. package/src/__tests__/config-schema.test.ts +1 -0
  55. package/src/__tests__/config-set-platform-guard.test.ts +48 -4
  56. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
  57. package/src/__tests__/config-watcher.test.ts +142 -71
  58. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  59. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  60. package/src/__tests__/context-search-fanout.test.ts +0 -1
  61. package/src/__tests__/context-search-memory-source.test.ts +3 -7
  62. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  63. package/src/__tests__/context-search-pkb-source.test.ts +0 -1
  64. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  65. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  66. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  67. package/src/__tests__/conversation-agent-loop.test.ts +454 -5
  68. package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
  69. package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
  70. package/src/__tests__/conversation-error.test.ts +150 -3
  71. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  72. package/src/__tests__/conversation-lifecycle.test.ts +36 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
  74. package/src/__tests__/conversation-process-callsite.test.ts +43 -0
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  76. package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
  77. package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
  78. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  79. package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
  80. package/src/__tests__/conversation-slash-commands.test.ts +0 -4
  81. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  82. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  83. package/src/__tests__/conversation-store.test.ts +0 -18
  84. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
  85. package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
  86. package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
  87. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
  88. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  89. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  90. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
  91. package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
  92. package/src/__tests__/credentials-cli.test.ts +12 -12
  93. package/src/__tests__/cu-unified-flow.test.ts +351 -23
  94. package/src/__tests__/daemon-credential-client.test.ts +101 -19
  95. package/src/__tests__/date-context.test.ts +164 -2
  96. package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
  97. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  98. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  99. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  100. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  101. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  102. package/src/__tests__/disk-usage.test.ts +150 -0
  103. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  104. package/src/__tests__/events-client-registration.test.ts +52 -0
  105. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  106. package/src/__tests__/file-write-tool.test.ts +4 -10
  107. package/src/__tests__/filing-service.test.ts +3 -4
  108. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  109. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
  110. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
  111. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
  112. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  113. package/src/__tests__/heartbeat-service.test.ts +968 -2
  114. package/src/__tests__/helpers/call-route-handler.ts +7 -1
  115. package/src/__tests__/host-app-control-proxy.test.ts +772 -0
  116. package/src/__tests__/host-app-control-routes.test.ts +263 -0
  117. package/src/__tests__/host-bash-proxy.test.ts +439 -47
  118. package/src/__tests__/host-bash-routes.test.ts +459 -0
  119. package/src/__tests__/host-browser-proxy.test.ts +24 -22
  120. package/src/__tests__/host-browser-routes.test.ts +39 -13
  121. package/src/__tests__/host-cu-proxy.test.ts +248 -52
  122. package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
  123. package/src/__tests__/host-file-edit-tool.test.ts +47 -1
  124. package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
  125. package/src/__tests__/host-file-proxy.test.ts +301 -45
  126. package/src/__tests__/host-file-read-tool.test.ts +17 -0
  127. package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
  128. package/src/__tests__/host-file-write-tool.test.ts +42 -1
  129. package/src/__tests__/host-proxy-base.test.ts +312 -0
  130. package/src/__tests__/host-shell-tool.test.ts +22 -4
  131. package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
  132. package/src/__tests__/host-transfer-proxy.test.ts +121 -22
  133. package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
  134. package/src/__tests__/http-user-message-parity.test.ts +108 -1
  135. package/src/__tests__/identity-intro-cache.test.ts +29 -0
  136. package/src/__tests__/identity-routes.test.ts +103 -1
  137. package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
  138. package/src/__tests__/injector-chain.test.ts +18 -6
  139. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  140. package/src/__tests__/inline-command-runner.test.ts +0 -1
  141. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
  142. package/src/__tests__/integration-status.test.ts +85 -5
  143. package/src/__tests__/intent-routing.test.ts +0 -1
  144. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
  145. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
  146. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  147. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
  148. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  149. package/src/__tests__/mcp-auth-routes.test.ts +197 -0
  150. package/src/__tests__/mcp-cli.test.ts +338 -2
  151. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
  153. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  154. package/src/__tests__/migration-import-commit-http.test.ts +108 -2
  155. package/src/__tests__/mock-gateway-ipc.ts +1 -0
  156. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  157. package/src/__tests__/oauth-cli.test.ts +0 -2
  158. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  159. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  160. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
  161. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  162. package/src/__tests__/openai-provider.test.ts +45 -8
  163. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  164. package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
  165. package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
  166. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  167. package/src/__tests__/platform.test.ts +2 -1
  168. package/src/__tests__/playbook-execution.test.ts +0 -43
  169. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  170. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
  171. package/src/__tests__/process-message-background-slack.test.ts +2 -0
  172. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  173. package/src/__tests__/provider-tool-name.test.ts +23 -0
  174. package/src/__tests__/public-ingress-urls.test.ts +97 -0
  175. package/src/__tests__/relay-server.test.ts +15 -4
  176. package/src/__tests__/require-fresh-approval.test.ts +0 -1
  177. package/src/__tests__/retry-backoff.test.ts +87 -0
  178. package/src/__tests__/runtime-events-sse.test.ts +2 -2
  179. package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
  180. package/src/__tests__/schedule-retry.test.ts +715 -0
  181. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  182. package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
  183. package/src/__tests__/secret-ingress-http.test.ts +1 -1
  184. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  185. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
  186. package/src/__tests__/skill-feature-flags.test.ts +43 -41
  187. package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
  188. package/src/__tests__/skill-load-inline-command.test.ts +0 -51
  189. package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
  190. package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
  191. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
  192. package/src/__tests__/slack-channel-config.test.ts +9 -14
  193. package/src/__tests__/suggestion-routes.test.ts +46 -0
  194. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
  195. package/src/__tests__/system-prompt.test.ts +0 -1
  196. package/src/__tests__/telegram-config.test.ts +0 -1
  197. package/src/__tests__/test-preload.ts +8 -0
  198. package/src/__tests__/tool-approval-handler.test.ts +3 -4
  199. package/src/__tests__/tool-audit-listener.test.ts +48 -0
  200. package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
  201. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  202. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  203. package/src/__tests__/tool-executor.test.ts +0 -1
  204. package/src/__tests__/twilio-config.test.ts +3 -16
  205. package/src/__tests__/twilio-routes.test.ts +3 -5
  206. package/src/__tests__/twilio-validation.test.ts +93 -0
  207. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
  208. package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
  209. package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
  210. package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
  211. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  212. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  213. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  214. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
  215. package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
  216. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
  217. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
  218. package/src/approvals/guardian-decision-primitive.ts +13 -0
  219. package/src/approvals/guardian-request-resolvers.ts +16 -17
  220. package/src/backup/__tests__/paths.test.ts +0 -22
  221. package/src/backup/__tests__/restore.test.ts +51 -151
  222. package/src/backup/paths.ts +2 -18
  223. package/src/backup/restore.ts +107 -231
  224. package/src/backup/snapshot-lock.ts +2 -27
  225. package/src/bundler/app-bundler.ts +51 -3
  226. package/src/bundler/compiler-tools.ts +3 -2
  227. package/src/calls/call-conversation-messages.ts +46 -10
  228. package/src/calls/relay-server.ts +4 -44
  229. package/src/calls/twilio-config.ts +2 -17
  230. package/src/calls/twilio-rest.ts +33 -105
  231. package/src/calls/twilio-routes.ts +11 -12
  232. package/src/channels/types.ts +8 -7
  233. package/src/cli/commands/__tests__/backup.test.ts +6 -277
  234. package/src/cli/commands/__tests__/gateway.test.ts +288 -0
  235. package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
  236. package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
  237. package/src/cli/commands/backup.ts +6 -331
  238. package/src/cli/commands/bash.ts +35 -108
  239. package/src/cli/commands/clients.ts +36 -37
  240. package/src/cli/commands/contacts.ts +137 -25
  241. package/src/cli/commands/conversations.ts +2 -5
  242. package/src/cli/commands/credentials.ts +71 -7
  243. package/src/cli/commands/domain.ts +66 -15
  244. package/src/cli/commands/gateway.ts +183 -0
  245. package/src/cli/commands/keys.ts +9 -6
  246. package/src/cli/commands/mcp.ts +116 -156
  247. package/src/cli/commands/memory-v2.ts +303 -7
  248. package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
  249. package/src/cli/commands/oauth/connect.ts +127 -1
  250. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
  251. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
  252. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
  253. package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
  254. package/src/cli/commands/platform/disconnect.ts +5 -4
  255. package/src/cli/commands/platform/index.ts +16 -25
  256. package/src/cli/commands/status.ts +57 -0
  257. package/src/cli/lib/daemon-credential-client.ts +110 -28
  258. package/src/cli/program.ts +6 -2
  259. package/src/config/assistant-feature-flags.ts +79 -12
  260. package/src/config/bundled-skills/acp/SKILL.md +6 -0
  261. package/src/config/bundled-skills/acp/TOOLS.json +1 -22
  262. package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
  263. package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
  264. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
  265. package/src/config/bundled-skills/app-control/SKILL.md +75 -0
  266. package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
  267. package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
  268. package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
  269. package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
  270. package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
  271. package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
  272. package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
  273. package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
  274. package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
  275. package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
  276. package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
  277. package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
  278. package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
  279. package/src/config/bundled-skills/document/TOOLS.json +0 -8
  280. package/src/config/bundled-skills/followups/TOOLS.json +0 -12
  281. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  282. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
  283. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
  284. package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
  285. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  286. package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
  287. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
  288. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
  289. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  290. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  291. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  292. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  293. package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
  294. package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
  295. package/src/config/bundled-skills/settings/SKILL.md +4 -0
  296. package/src/config/bundled-skills/settings/TOOLS.json +0 -12
  297. package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
  298. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
  299. package/src/config/bundled-skills/subagent/SKILL.md +6 -2
  300. package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
  301. package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
  302. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
  303. package/src/config/bundled-tool-registry.ts +21 -0
  304. package/src/config/env-registry.ts +0 -2
  305. package/src/config/env.ts +19 -20
  306. package/src/config/feature-flag-registry.json +47 -135
  307. package/src/config/loader.ts +197 -104
  308. package/src/config/sanitize-for-transfer.ts +2 -0
  309. package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
  310. package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
  311. package/src/config/schemas/call-site-catalog.ts +14 -0
  312. package/src/config/schemas/calls.ts +0 -9
  313. package/src/config/schemas/channels.ts +0 -5
  314. package/src/config/schemas/heartbeat.ts +64 -1
  315. package/src/config/schemas/ingress.ts +10 -6
  316. package/src/config/schemas/llm.ts +7 -10
  317. package/src/config/schemas/memory-lifecycle.ts +90 -24
  318. package/src/config/schemas/memory-v2.ts +121 -13
  319. package/src/config/schemas/platform.ts +49 -3
  320. package/src/config/schemas/services.ts +29 -15
  321. package/src/config/schemas/skills.ts +0 -6
  322. package/src/config/seed-inference-profiles.ts +230 -33
  323. package/src/contacts/contact-store.ts +0 -55
  324. package/src/contacts/contacts-write.ts +0 -27
  325. package/src/context/window-manager.ts +1 -2
  326. package/src/credential-execution/feature-gates.ts +10 -10
  327. package/src/credential-execution/process-manager.ts +12 -41
  328. package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
  329. package/src/daemon/assistant-attachments.ts +4 -4
  330. package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
  331. package/src/daemon/config-watcher.ts +89 -60
  332. package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
  333. package/src/daemon/conversation-agent-loop.ts +202 -61
  334. package/src/daemon/conversation-error.ts +87 -15
  335. package/src/daemon/conversation-lifecycle.ts +9 -4
  336. package/src/daemon/conversation-process.ts +24 -11
  337. package/src/daemon/conversation-runtime-assembly.ts +28 -2
  338. package/src/daemon/conversation-store.ts +2 -2
  339. package/src/daemon/conversation-surfaces.ts +305 -4
  340. package/src/daemon/conversation-tool-setup.ts +66 -62
  341. package/src/daemon/conversation.ts +38 -24
  342. package/src/daemon/date-context.ts +71 -22
  343. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  344. package/src/daemon/disk-pressure-guard.ts +343 -0
  345. package/src/daemon/disk-pressure-policy.ts +163 -0
  346. package/src/daemon/doordash-steps.ts +1 -1
  347. package/src/daemon/handlers/shared.ts +4 -2
  348. package/src/daemon/handlers/skills.ts +3 -4
  349. package/src/daemon/host-app-control-proxy.ts +389 -0
  350. package/src/daemon/host-bash-proxy.ts +117 -82
  351. package/src/daemon/host-browser-proxy.ts +67 -82
  352. package/src/daemon/host-cu-proxy.ts +127 -86
  353. package/src/daemon/host-file-proxy.ts +129 -69
  354. package/src/daemon/host-proxy-base.ts +294 -0
  355. package/src/daemon/host-proxy-preactivation.ts +82 -0
  356. package/src/daemon/host-transfer-proxy.ts +338 -129
  357. package/src/daemon/lifecycle.ts +194 -145
  358. package/src/daemon/meet-host-supervisor.ts +4 -4
  359. package/src/daemon/meet-manifest-loader.ts +0 -1
  360. package/src/daemon/memory-v2-startup.ts +14 -4
  361. package/src/daemon/message-protocol.ts +6 -8
  362. package/src/daemon/message-types/contacts.ts +23 -1
  363. package/src/daemon/message-types/conversations.ts +15 -8
  364. package/src/daemon/message-types/disk-pressure.ts +9 -0
  365. package/src/daemon/message-types/host-app-control.ts +150 -0
  366. package/src/daemon/message-types/host-bash.ts +4 -0
  367. package/src/daemon/message-types/host-cu.ts +2 -0
  368. package/src/daemon/message-types/host-file.ts +4 -0
  369. package/src/daemon/message-types/host-transfer.ts +3 -0
  370. package/src/daemon/message-types/messages.ts +3 -0
  371. package/src/daemon/message-types/schedules.ts +8 -3
  372. package/src/daemon/message-types/skills.ts +2 -2
  373. package/src/daemon/process-message.ts +18 -1
  374. package/src/daemon/profiler-run-store.ts +5 -5
  375. package/src/daemon/shutdown-handlers.ts +0 -3
  376. package/src/daemon/tool-setup-types.ts +51 -0
  377. package/src/daemon/tool-side-effects.ts +1 -1
  378. package/src/documents/document-store.ts +85 -0
  379. package/src/events/tool-audit-listener.ts +2 -1
  380. package/src/filing/filing-service.ts +30 -5
  381. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
  382. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
  383. package/src/heartbeat/heartbeat-run-store.ts +249 -0
  384. package/src/heartbeat/heartbeat-service.ts +459 -54
  385. package/src/home/__tests__/post-connect-feed.test.ts +99 -0
  386. package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
  387. package/src/home/__tests__/suggested-prompts.test.ts +89 -0
  388. package/src/home/feed-scheduler.ts +18 -0
  389. package/src/home/post-connect-feed.ts +68 -0
  390. package/src/home/relationship-state-writer.ts +17 -92
  391. package/src/home/suggested-prompts.ts +46 -10
  392. package/src/inbound/platform-callback-registration.ts +8 -15
  393. package/src/inbound/public-ingress-urls.ts +32 -34
  394. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  395. package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
  396. package/src/ipc/assistant-server.ts +70 -3
  397. package/src/ipc/cli-client.ts +32 -1
  398. package/src/ipc/gateway-client.ts +37 -3
  399. package/src/live-voice/live-voice-archive.ts +4 -4
  400. package/src/live-voice/live-voice-metrics.ts +10 -10
  401. package/src/live-voice/protocol.ts +5 -7
  402. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
  403. package/src/mcp/mcp-auth-orchestrator.ts +213 -0
  404. package/src/mcp/mcp-auth-state.ts +133 -0
  405. package/src/mcp/mcp-oauth-provider.ts +19 -0
  406. package/src/media/image-service.ts +1 -7
  407. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  408. package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
  409. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  412. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  413. package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
  414. package/src/memory/admin.ts +5 -9
  415. package/src/memory/anisotropy.test.ts +247 -0
  416. package/src/memory/anisotropy.ts +443 -0
  417. package/src/memory/auto-analysis-constants.ts +17 -0
  418. package/src/memory/auto-analysis-guard.ts +5 -15
  419. package/src/memory/canonical-guardian-store.ts +7 -7
  420. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
  421. package/src/memory/context-search/agent-protocol.ts +6 -6
  422. package/src/memory/context-search/agent-runner.ts +51 -9
  423. package/src/memory/context-search/sources/conversations.ts +2 -11
  424. package/src/memory/context-search/sources/memory-v2.ts +22 -9
  425. package/src/memory/context-search/sources/memory.ts +0 -1
  426. package/src/memory/context-search/types.ts +0 -1
  427. package/src/memory/conversation-crud.ts +5 -13
  428. package/src/memory/conversation-key-store.ts +2 -15
  429. package/src/memory/db-init.ts +6 -0
  430. package/src/memory/embedding-backend.ts +9 -21
  431. package/src/memory/embedding-runtime-manager.ts +119 -5
  432. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
  433. package/src/memory/graph/conversation-graph-memory.ts +43 -78
  434. package/src/memory/graph/extraction.ts +1 -3
  435. package/src/memory/graph/graph-search.test.ts +10 -67
  436. package/src/memory/graph/graph-search.ts +9 -20
  437. package/src/memory/graph/retriever.test.ts +6 -0
  438. package/src/memory/graph/retriever.ts +34 -10
  439. package/src/memory/graph/tools.ts +1 -1
  440. package/src/memory/indexer.ts +54 -45
  441. package/src/memory/job-handlers/backfill.ts +2 -11
  442. package/src/memory/job-handlers/cleanup.ts +43 -0
  443. package/src/memory/job-handlers/embedding.ts +6 -8
  444. package/src/memory/job-handlers/summarization.ts +2 -7
  445. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
  446. package/src/memory/jobs/embed-concept-page.ts +28 -2
  447. package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
  448. package/src/memory/jobs-store.ts +114 -22
  449. package/src/memory/jobs-worker.ts +193 -106
  450. package/src/memory/memory-v2-activation-log-store.ts +33 -15
  451. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  452. package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
  453. package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
  454. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  455. package/src/memory/migrations/index.ts +6 -0
  456. package/src/memory/migrations/registry.ts +8 -0
  457. package/src/memory/pkb/pkb-search.test.ts +6 -0
  458. package/src/memory/pkb/pkb-search.ts +7 -0
  459. package/src/memory/qdrant-client.ts +49 -32
  460. package/src/memory/rerank-local.ts +374 -0
  461. package/src/memory/schema/infrastructure.ts +15 -0
  462. package/src/memory/search/semantic.ts +13 -67
  463. package/src/memory/sparse-tokenize.ts +49 -0
  464. package/src/memory/trace-event-store.ts +1 -17
  465. package/src/memory/v2/__tests__/activation.test.ts +387 -344
  466. package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
  467. package/src/memory/v2/__tests__/injection.test.ts +181 -169
  468. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  469. package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
  470. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  471. package/src/memory/v2/__tests__/sim.test.ts +154 -188
  472. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  473. package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  474. package/src/memory/v2/__tests__/static-context.test.ts +76 -2
  475. package/src/memory/v2/activation.ts +213 -239
  476. package/src/memory/v2/consolidation-job.ts +65 -17
  477. package/src/memory/v2/constants.ts +7 -0
  478. package/src/memory/v2/injection.ts +123 -103
  479. package/src/memory/v2/prompts/consolidation.ts +348 -92
  480. package/src/memory/v2/qdrant.ts +198 -1
  481. package/src/memory/v2/reranker.ts +177 -0
  482. package/src/memory/v2/sim.ts +113 -77
  483. package/src/memory/v2/skill-content.ts +4 -3
  484. package/src/memory/v2/skill-store.ts +91 -53
  485. package/src/memory/v2/sparse-bm25.ts +245 -0
  486. package/src/memory/v2/static-context.ts +28 -5
  487. package/src/memory/v2/types.ts +10 -10
  488. package/src/messaging/providers/gmail/types.ts +0 -49
  489. package/src/messaging/providers/slack/adapter.ts +1 -31
  490. package/src/messaging/providers/slack/types.ts +0 -32
  491. package/src/notifications/README.md +10 -10
  492. package/src/notifications/broadcaster.ts +1 -1
  493. package/src/notifications/copy-composer.ts +13 -0
  494. package/src/notifications/guardian-question-mode.ts +5 -5
  495. package/src/notifications/signal.ts +4 -0
  496. package/src/oauth/AGENTS.md +3 -1
  497. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  498. package/src/oauth/connect-orchestrator.ts +6 -0
  499. package/src/oauth/connection-resolver.test.ts +66 -1
  500. package/src/oauth/connection-resolver.ts +55 -1
  501. package/src/oauth/credential-token-resolver.ts +1 -3
  502. package/src/oauth/manual-token-connection.ts +0 -4
  503. package/src/oauth/oauth-connect-state.ts +77 -0
  504. package/src/oauth/seed-providers.ts +58 -1
  505. package/src/outbound-proxy/index.ts +1 -37
  506. package/src/outbound-proxy/logging.ts +1 -1
  507. package/src/outbound-proxy/policy.ts +6 -5
  508. package/src/outbound-proxy/router.ts +2 -1
  509. package/src/permissions/approval-policy.test.ts +6 -275
  510. package/src/permissions/approval-policy.ts +0 -51
  511. package/src/permissions/checker.test.ts +0 -1
  512. package/src/permissions/checker.ts +3 -17
  513. package/src/permissions/gateway-threshold-reader.ts +2 -0
  514. package/src/permissions/prompter.ts +34 -1
  515. package/src/permissions/secret-prompter.ts +6 -2
  516. package/src/plugins/defaults/injectors.ts +35 -2
  517. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  518. package/src/plugins/types.ts +7 -0
  519. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  520. package/src/proactive-artifact/decision.test.ts +226 -0
  521. package/src/proactive-artifact/decision.ts +165 -0
  522. package/src/proactive-artifact/index.ts +7 -0
  523. package/src/proactive-artifact/job.test.ts +867 -0
  524. package/src/proactive-artifact/job.ts +352 -0
  525. package/src/proactive-artifact/message-copy.ts +41 -0
  526. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  527. package/src/proactive-artifact/trigger-state.ts +119 -0
  528. package/src/prompts/bootstrap-cleanup.ts +27 -0
  529. package/src/prompts/normalize-onboarding.ts +80 -0
  530. package/src/prompts/persona-resolver.ts +101 -9
  531. package/src/prompts/system-prompt.ts +23 -24
  532. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  533. package/src/prompts/templates/SOUL.md +13 -1
  534. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  535. package/src/providers/model-intents.ts +7 -0
  536. package/src/providers/openrouter/client.ts +8 -0
  537. package/src/providers/retry.ts +50 -0
  538. package/src/providers/speech-to-text/provider-catalog.ts +7 -8
  539. package/src/providers/types.ts +1 -0
  540. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  541. package/src/runtime/agent-wake.ts +238 -100
  542. package/src/runtime/assistant-event-hub.ts +151 -99
  543. package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
  544. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  545. package/src/runtime/auth/middleware.ts +0 -96
  546. package/src/runtime/auth/route-policy.ts +32 -0
  547. package/src/runtime/auth/same-actor.ts +216 -0
  548. package/src/runtime/btw-sidechain.ts +2 -3
  549. package/src/runtime/channel-invite-transport.ts +2 -48
  550. package/src/runtime/channel-invite-transports/email.ts +1 -1
  551. package/src/runtime/channel-invite-transports/slack.ts +1 -1
  552. package/src/runtime/channel-invite-transports/telegram.ts +1 -1
  553. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  554. package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
  555. package/src/runtime/channel-invite-types.ts +54 -0
  556. package/src/runtime/channel-readiness-service.ts +32 -13
  557. package/src/runtime/channel-retry-sweep.ts +65 -1
  558. package/src/runtime/guardian-reply-router.ts +10 -0
  559. package/src/runtime/http-server.ts +3 -329
  560. package/src/runtime/http-types.ts +0 -5
  561. package/src/runtime/local-actor-identity.ts +52 -11
  562. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
  563. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
  564. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
  565. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
  566. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
  567. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  568. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
  569. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
  570. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
  571. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
  572. package/src/runtime/migrations/migration-transport.ts +7 -7
  573. package/src/runtime/migrations/vbundle-builder.ts +327 -60
  574. package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
  575. package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
  576. package/src/runtime/migrations/vbundle-importer.ts +245 -68
  577. package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
  578. package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
  579. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
  580. package/src/runtime/migrations/vbundle-validator.ts +114 -0
  581. package/src/runtime/pending-interactions.ts +43 -9
  582. package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
  583. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  584. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
  585. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
  586. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
  587. package/src/runtime/routes/approval-interception-types.ts +13 -0
  588. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
  589. package/src/runtime/routes/backup-routes.ts +15 -38
  590. package/src/runtime/routes/btw-routes.ts +14 -37
  591. package/src/runtime/routes/client-routes.ts +21 -2
  592. package/src/runtime/routes/contact-prompt-routes.ts +183 -0
  593. package/src/runtime/routes/contact-routes.ts +0 -25
  594. package/src/runtime/routes/conversation-query-routes.ts +36 -1
  595. package/src/runtime/routes/conversation-routes.ts +65 -39
  596. package/src/runtime/routes/debug-bash-routes.ts +163 -0
  597. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  598. package/src/runtime/routes/document-pdf-renderer.ts +169 -0
  599. package/src/runtime/routes/documents-routes.ts +32 -75
  600. package/src/runtime/routes/errors.ts +19 -4
  601. package/src/runtime/routes/events-routes.ts +38 -0
  602. package/src/runtime/routes/gateway-log-routes.ts +79 -0
  603. package/src/runtime/routes/guardian-approval-interception.ts +2 -8
  604. package/src/runtime/routes/heartbeat-routes.ts +103 -38
  605. package/src/runtime/routes/host-app-control-routes.ts +134 -0
  606. package/src/runtime/routes/host-bash-routes.ts +56 -6
  607. package/src/runtime/routes/host-browser-routes.ts +108 -13
  608. package/src/runtime/routes/host-cu-routes.ts +66 -9
  609. package/src/runtime/routes/host-file-routes.ts +54 -5
  610. package/src/runtime/routes/host-transfer-routes.ts +122 -19
  611. package/src/runtime/routes/http-adapter.ts +1 -0
  612. package/src/runtime/routes/identity-intro-cache.ts +30 -0
  613. package/src/runtime/routes/identity-routes.ts +21 -180
  614. package/src/runtime/routes/inbound-message-handler.ts +78 -21
  615. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
  616. package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
  617. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
  618. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
  619. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
  620. package/src/runtime/routes/index.ts +14 -0
  621. package/src/runtime/routes/mcp-auth-routes.ts +132 -0
  622. package/src/runtime/routes/memory-item-routes.test.ts +41 -15
  623. package/src/runtime/routes/memory-item-routes.ts +10 -12
  624. package/src/runtime/routes/memory-v2-routes.ts +474 -1
  625. package/src/runtime/routes/migration-routes.ts +96 -0
  626. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  627. package/src/runtime/routes/schedule-routes.ts +7 -0
  628. package/src/runtime/verification-outbound-actions.ts +4 -4
  629. package/src/runtime/verification-templates.ts +4 -7
  630. package/src/schedule/integration-status.ts +66 -2
  631. package/src/schedule/recurrence-engine.ts +4 -1
  632. package/src/schedule/retry-backoff.ts +18 -0
  633. package/src/schedule/retry-policy.ts +82 -0
  634. package/src/schedule/run-script.ts +37 -5
  635. package/src/schedule/schedule-recovery.ts +64 -0
  636. package/src/schedule/schedule-store.ts +106 -2
  637. package/src/schedule/scheduler-types.ts +25 -0
  638. package/src/schedule/scheduler.ts +83 -39
  639. package/src/security/encrypted-store.ts +2 -0
  640. package/src/security/oauth-callback-registry.ts +8 -0
  641. package/src/security/secure-keys.ts +55 -0
  642. package/src/sequence/analytics.ts +5 -5
  643. package/src/sequence/engine.ts +1 -1
  644. package/src/skills/catalog-files.ts +2 -8
  645. package/src/skills/include-graph.ts +5 -5
  646. package/src/skills/remote-skill-policy.ts +10 -16
  647. package/src/skills/skill-file-provider.ts +1 -1
  648. package/src/skills/skill-file-types.ts +13 -0
  649. package/src/skills/skillssh-audit-types.ts +28 -0
  650. package/src/skills/skillssh-registry.ts +8 -21
  651. package/src/subagent/index.ts +1 -7
  652. package/src/subagent/manager.ts +1 -15
  653. package/src/tasks/task-runner.ts +0 -1
  654. package/src/tasks/task-store.ts +0 -3
  655. package/src/telemetry/types.ts +2 -0
  656. package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
  657. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  658. package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
  659. package/src/tools/apps/executors.ts +56 -69
  660. package/src/tools/background-tool-registry.ts +17 -3
  661. package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
  662. package/src/tools/browser/browser-execution.ts +2 -2
  663. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
  664. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
  665. package/src/tools/browser/cdp-client/factory.ts +23 -24
  666. package/src/tools/browser/cdp-client/index.ts +1 -14
  667. package/src/tools/computer-use/definitions.ts +42 -20
  668. package/src/tools/executor.ts +2 -0
  669. package/src/tools/host-filesystem/edit.test.ts +151 -0
  670. package/src/tools/host-filesystem/edit.ts +68 -0
  671. package/src/tools/host-filesystem/read.test.ts +129 -0
  672. package/src/tools/host-filesystem/read.ts +68 -0
  673. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  674. package/src/tools/host-filesystem/transfer.ts +78 -3
  675. package/src/tools/host-filesystem/write.test.ts +134 -0
  676. package/src/tools/host-filesystem/write.ts +68 -0
  677. package/src/tools/host-terminal/host-shell.ts +66 -1
  678. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  679. package/src/tools/memory/register.test.ts +12 -9
  680. package/src/tools/memory/register.ts +1 -2
  681. package/src/tools/provider-tool-name.ts +28 -0
  682. package/src/tools/registry.ts +30 -9
  683. package/src/tools/schedule/create.ts +6 -0
  684. package/src/tools/schedule/list.ts +2 -0
  685. package/src/tools/schedule/update.ts +10 -0
  686. package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
  687. package/src/tools/shared/filesystem/path-policy.ts +25 -1
  688. package/src/tools/skills/load.ts +0 -32
  689. package/src/tools/terminal/shell.ts +9 -1
  690. package/src/tools/tool-approval-handler.ts +32 -11
  691. package/src/tools/types.ts +28 -2
  692. package/src/tts/provider-catalog.ts +3 -5
  693. package/src/usage/pricing.ts +1 -1
  694. package/src/util/disk-usage.ts +138 -0
  695. package/src/util/platform.ts +21 -11
  696. package/src/util/process-liveness.ts +26 -0
  697. package/src/workspace/hatched-date.ts +86 -0
  698. package/src/workspace/heartbeat-service.ts +19 -0
  699. package/src/workspace/migrations/003-seed-device-id.ts +1 -1
  700. package/src/workspace/migrations/006-services-config.ts +8 -5
  701. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
  702. package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
  703. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
  704. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
  705. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
  706. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
  707. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
  708. package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
  709. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
  710. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  711. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  712. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
  713. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  714. package/src/workspace/migrations/AGENTS.md +1 -1
  715. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
  716. package/src/workspace/migrations/registry.ts +8 -0
  717. package/src/workspace/migrations/utils.ts +21 -0
  718. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  719. package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
  720. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
  721. package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
  722. package/src/__tests__/twilio-rest.test.ts +0 -34
  723. package/src/backup/__tests__/backup-key.test.ts +0 -152
  724. package/src/backup/__tests__/backup-worker.test.ts +0 -782
  725. package/src/backup/__tests__/offsite-writer.test.ts +0 -641
  726. package/src/backup/__tests__/stream-crypt.test.ts +0 -228
  727. package/src/backup/backup-key.ts +0 -137
  728. package/src/backup/backup-worker.ts +0 -472
  729. package/src/backup/offsite-writer.ts +0 -222
  730. package/src/backup/stream-crypt.ts +0 -263
  731. package/src/daemon/message-types/pairing.ts +0 -58
  732. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  733. package/src/memory/v2/skill-qdrant.ts +0 -395
  734. package/src/outbound-proxy/config.ts +0 -20
  735. package/src/outbound-proxy/health.ts +0 -18
  736. package/src/outbound-proxy/types.ts +0 -150
  737. package/src/runtime/capability-tokens.ts +0 -190
  738. package/src/signals/bash.ts +0 -198
  739. package/src/signals/mcp-reload.ts +0 -18
@@ -76,11 +76,6 @@ export interface SlackUser {
76
76
  deleted?: boolean;
77
77
  }
78
78
 
79
- export interface SlackUsersListResponse extends SlackApiResponse {
80
- members: SlackUser[];
81
- response_metadata?: { next_cursor?: string };
82
- }
83
-
84
79
  export interface SlackUserInfoResponse extends SlackApiResponse {
85
80
  user: SlackUser;
86
81
  }
@@ -110,35 +105,8 @@ export interface SlackSearchMatch {
110
105
  thread_ts?: string;
111
106
  }
112
107
 
113
- export interface SlackConversationInfoResponse extends SlackApiResponse {
114
- channel: SlackConversation;
115
- }
116
-
117
108
  export interface SlackConversationsOpenResponse extends SlackApiResponse {
118
109
  channel: { id: string };
119
110
  }
120
111
 
121
- export type SlackReactionAddResponse = SlackApiResponse;
122
-
123
- export type SlackConversationJoinResponse = SlackApiResponse & {
124
- channel?: SlackConversation;
125
- };
126
-
127
- export type SlackConversationLeaveResponse = SlackApiResponse;
128
-
129
- export interface SlackChatDeleteResponse extends SlackApiResponse {
130
- channel: string;
131
- ts: string;
132
- }
133
-
134
- export interface SlackChatUpdateResponse extends SlackApiResponse {
135
- channel: string;
136
- ts: string;
137
- text: string;
138
- }
139
-
140
112
  export type SlackConversationMarkResponse = SlackApiResponse;
141
-
142
- export interface SlackPostEphemeralResponse extends SlackApiResponse {
143
- message_ts: string;
144
- }
@@ -133,7 +133,7 @@ The system produces **three distinct copy outputs** per notification:
133
133
 
134
134
  | Output | Purpose | Verbosity |
135
135
  | ------------------------- | ------------------------------------------------ | ------------------------ |
136
- | `title` + `body` | Native notification popup (macOS/iOS banner) | Short and glanceable |
136
+ | `title` + `body` | Native notification popup (macOS banner) | Short and glanceable |
137
137
  | `deliveryText` | Channel-native chat message text (Telegram) | Natural chat phrasing |
138
138
  | Conversation seed message | Opening message in the notification conversation | Richer and context-aware |
139
139
 
@@ -185,7 +185,7 @@ Reminder. Take out the trash. Action required.
185
185
 
186
186
  ## Conversation Surfacing via `notification_conversation_created` Event (Creation-Only)
187
187
 
188
- The `notification_conversation_created` SSE event is emitted **only when a brand-new conversation is actually created** by the broadcaster. Reused conversations do not trigger this event — the macOS/iOS client already knows about the conversation from the original creation.
188
+ The `notification_conversation_created` SSE event is emitted **only when a brand-new conversation is actually created** by the broadcaster. Reused conversations do not trigger this event — the macOS client already knows about the conversation from the original creation.
189
189
 
190
190
  This is enforced in `broadcaster.ts` by gating the event emission on `pairing.createdNewConversation === true`:
191
191
 
@@ -214,7 +214,7 @@ The SSE event payload:
214
214
  }
215
215
  ```
216
216
 
217
- The macOS/iOS client listens for this event and surfaces the conversation in the sidebar, enabling deep-link navigation to the notification conversation.
217
+ The macOS client listens for this event and surfaces the conversation in the sidebar, enabling deep-link navigation to the notification conversation.
218
218
 
219
219
  ### Per-Dispatch Conversation Callback
220
220
 
@@ -223,7 +223,7 @@ The macOS/iOS client listens for this event and surfaces the conversation in the
223
223
  **Important distinction between the two callbacks:**
224
224
 
225
225
  - **Per-dispatch `options.onConversationCreated`**: Fires for **both** new and reused vellum conversation pairings. Callers like `dispatchGuardianQuestion` rely on this to create delivery bookkeeping rows before `emitNotificationSignal()` returns, regardless of whether the conversation was newly created or reused.
226
- - **Class-level `this.onConversationCreated` (SSE broadcast)**: Fires **only** when a brand-new conversation is created (`createdNewConversation === true && strategy === 'start_new_conversation'`). This emits the `notification_conversation_created` SSE event so macOS/iOS clients surface the new conversation in the sidebar. Reused conversations do not trigger this event because the client already knows about the conversation.
226
+ - **Class-level `this.onConversationCreated` (SSE broadcast)**: Fires **only** when a brand-new conversation is created (`createdNewConversation === true && strategy === 'start_new_conversation'`). This emits the `notification_conversation_created` SSE event so macOS clients surface the new conversation in the sidebar. Reused conversations do not trigger this event because the client already knows about the conversation.
227
227
 
228
228
  ## Schedule Routing Metadata and Trigger-Time Enforcement
229
229
 
@@ -295,7 +295,7 @@ Local SSE via the daemon's broadcast mechanism. The `VellumAdapter` emits a `not
295
295
  - `title` and `body` -- rendered notification copy
296
296
  - `deepLinkMetadata` -- optional metadata for navigating to the relevant context (e.g. `{ conversationId }`)
297
297
 
298
- The macOS/iOS client posts a native `UNUserNotificationCenter` notification from this payload. When the user taps the notification, the client uses `deepLinkMetadata` to navigate to the relevant conversation.
298
+ The macOS client posts a native `UNUserNotificationCenter` notification from this payload. When the user taps the notification, the client uses `deepLinkMetadata` to navigate to the relevant conversation.
299
299
 
300
300
  ### Telegram (when guardian binding exists)
301
301
 
@@ -480,7 +480,7 @@ Three SQLite tables form the audit chain:
480
480
 
481
481
  ### Client Delivery Ack
482
482
 
483
- For vellum (macOS/iOS) deliveries, the audit trail now extends past the SSE broadcast to the actual OS notification post. The `notification_intent` message carries an optional `deliveryId` that the client echoes back in a `notification_intent_result` ack after `UNUserNotificationCenter.add()` completes (or fails).
483
+ For vellum (macOS) deliveries, the audit trail now extends past the SSE broadcast to the actual OS notification post. The `notification_intent` message carries an optional `deliveryId` that the client echoes back in a `notification_intent_result` ack after `UNUserNotificationCenter.add()` completes (or fails).
484
484
 
485
485
  The ack populates three columns on `notification_deliveries`:
486
486
 
@@ -541,10 +541,10 @@ Preferences are sanitized against prompt injection (angle brackets replaced with
541
541
  The decision engine and preference extractor pick their per-call LLM config
542
542
  from the unified `llm` block. Override defaults by setting either of:
543
543
 
544
- | Key | Type | Default | Description |
545
- | ------------------------------------ | ------- | -------------- | --------------------------------------------------------------------------- |
546
- | `llm.callSites.notificationDecision` | object | _(unset)_ | Provider/model/effort/etc. override for the decision engine call site |
547
- | `llm.callSites.preferenceExtraction` | object | _(unset)_ | Provider/model/effort/etc. override for the preference extractor call site |
544
+ | Key | Type | Default | Description |
545
+ | ------------------------------------ | ------ | --------- | -------------------------------------------------------------------------- |
546
+ | `llm.callSites.notificationDecision` | object | _(unset)_ | Provider/model/effort/etc. override for the decision engine call site |
547
+ | `llm.callSites.preferenceExtraction` | object | _(unset)_ | Provider/model/effort/etc. override for the preference extractor call site |
548
548
 
549
549
  When a call site override is unset, the resolver falls back to `llm.default`.
550
550
 
@@ -211,7 +211,7 @@ export class NotificationBroadcaster {
211
211
  );
212
212
 
213
213
  // For the vellum channel, merge the conversationId into deep-link metadata
214
- // so the macOS/iOS client can navigate directly to the notification conversation.
214
+ // so the macOS client can navigate directly to the notification conversation.
215
215
  let deepLinkTarget = decision.deepLinkTarget;
216
216
  if (channel === "vellum" && pairing.conversationId) {
217
217
  deepLinkTarget = {
@@ -505,6 +505,19 @@ const TEMPLATES: Partial<Record<NotificationSourceEventName, CopyTemplate>> = {
505
505
  body: str(payload.body, "A watcher event requires your attention"),
506
506
  }),
507
507
 
508
+ "heartbeat.alert": (payload) => {
509
+ const body = str(
510
+ payload.summary,
511
+ str(payload.body, "Your assistant found something worth your attention."),
512
+ );
513
+ return {
514
+ title: str(payload.title, "Heartbeat Alert"),
515
+ body,
516
+ conversationTitle: str(payload.conversationTitle, "Heartbeat"),
517
+ conversationSeedMessage: body,
518
+ };
519
+ },
520
+
508
521
  "tool_confirmation.required_action": (payload) => ({
509
522
  title: "Tool Confirmation",
510
523
  body: str(payload.toolName, "A tool") + " requires your confirmation",
@@ -6,12 +6,12 @@
6
6
  * fields like `toolName`.
7
7
  */
8
8
 
9
- export type GuardianQuestionRequestKind =
9
+ type GuardianQuestionRequestKind =
10
10
  | "pending_question"
11
11
  | "tool_approval"
12
12
  | "tool_grant_request"
13
13
  | "access_request";
14
- export type GuardianQuestionInstructionMode = "approval" | "answer";
14
+ type GuardianQuestionInstructionMode = "approval" | "answer";
15
15
 
16
16
  interface GuardianRequestKindModeConfig {
17
17
  defaultMode: GuardianQuestionInstructionMode;
@@ -48,12 +48,12 @@ interface GuardianQuestionPayloadBaseWithDiscriminator extends GuardianQuestionP
48
48
  [key: string]: unknown;
49
49
  }
50
50
 
51
- export interface GuardianRequestModeInput {
51
+ interface GuardianRequestModeInput {
52
52
  kind: unknown;
53
53
  toolName?: unknown;
54
54
  }
55
55
 
56
- export interface GuardianRequestTextInput {
56
+ interface GuardianRequestTextInput {
57
57
  requestCode: string;
58
58
  questionText?: string | null;
59
59
  toolName?: string | null;
@@ -136,7 +136,7 @@ export type GuardianQuestionPayload =
136
136
  | ToolGrantGuardianPayload
137
137
  | AccessRequestGuardianPayload;
138
138
 
139
- export interface GuardianQuestionModeResolution {
139
+ interface GuardianQuestionModeResolution {
140
140
  mode: GuardianQuestionInstructionMode;
141
141
  requestKind: GuardianQuestionRequestKind | null;
142
142
  }
@@ -101,6 +101,10 @@ export const NOTIFICATION_SOURCE_EVENT_NAMES = [
101
101
  description:
102
102
  "OAuth credential health issue detected (expired, revoked, missing scopes)",
103
103
  },
104
+ {
105
+ id: "heartbeat.alert",
106
+ description: "Heartbeat found something worth surfacing to the guardian",
107
+ },
104
108
  ] as const;
105
109
 
106
110
  export type NotificationSourceEventName =
@@ -54,7 +54,9 @@ Most existing logos come from [Simple Icons](https://simpleicons.org) (CC0-licen
54
54
 
55
55
  If the service is not on Simple Icons, source or create an SVG and convert it the same way. The result must be a true vector PDF (not a rasterized image wrapped in PDF) so it scales cleanly.
56
56
 
57
- The `logoUrl` field in `seed-providers.ts` still serves as the remote fallback (typically a Simple Icons CDN URL like `https://cdn.simpleicons.org/acme`). The client renders the local PDF first, then falls back to `logoUrl`, then to an initials avatar.
57
+ The `logoUrl` field in `seed-providers.ts` serves as the remote fallback (most providers use a Simple Icons CDN URL like `https://cdn.simpleicons.org/acme`). The client renders the local PDF first, then falls back to `logoUrl`, then to an initials avatar.
58
+
59
+ For brands Simple Icons doesn't host (e.g. Salesforce, which Simple Icons removed for trademark reasons), use the same `glincker/thesvg` source via jsDelivr — `https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/<key>/default.svg`. The recognised `logoUrl` prefixes are enforced by `oauth-provider-seed-logos.test.ts`; if you need a third source, extend that allowlist alongside the manifest in `clients/shared/Resources/integration-logos-manifest.json`.
58
60
 
59
61
  ### 5. Secret patterns (if applicable) — `../security/secret-patterns.ts`
60
62
 
@@ -0,0 +1,137 @@
1
+ import { beforeEach, describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ _clearAllOAuthConnectStates,
5
+ clearExpiredOAuthConnectStates,
6
+ getOAuthConnectState,
7
+ setOAuthConnectComplete,
8
+ setOAuthConnectError,
9
+ setOAuthConnectPending,
10
+ } from "../oauth-connect-state.js";
11
+
12
+ describe("oauth-connect-state", () => {
13
+ beforeEach(() => {
14
+ _clearAllOAuthConnectStates();
15
+ });
16
+
17
+ test("setOAuthConnectPending → getOAuthConnectState returns pending", () => {
18
+ setOAuthConnectPending("state-1", "google");
19
+ const result = getOAuthConnectState("state-1");
20
+ expect(result).toMatchObject({ status: "pending", service: "google" });
21
+ });
22
+
23
+ test("setOAuthConnectComplete without accountInfo → returns complete", () => {
24
+ setOAuthConnectComplete("state-1", "google");
25
+ const result = getOAuthConnectState("state-1");
26
+ expect(result).toMatchObject({ status: "complete", service: "google" });
27
+ });
28
+
29
+ test("setOAuthConnectComplete with accountInfo → returns complete with accountInfo", () => {
30
+ setOAuthConnectComplete("state-1", "google", "user@example.com");
31
+ const result = getOAuthConnectState("state-1");
32
+ expect(result).toMatchObject({
33
+ status: "complete",
34
+ service: "google",
35
+ accountInfo: "user@example.com",
36
+ });
37
+ });
38
+
39
+ test("setOAuthConnectComplete with grantedScopes → returns complete with grantedScopes", () => {
40
+ setOAuthConnectComplete("state-1", "google", "user@example.com", ["scope:read", "scope:write"]);
41
+ const result = getOAuthConnectState("state-1");
42
+ expect(result).toMatchObject({
43
+ status: "complete",
44
+ service: "google",
45
+ accountInfo: "user@example.com",
46
+ grantedScopes: ["scope:read", "scope:write"],
47
+ });
48
+ });
49
+
50
+ test("setOAuthConnectError → returns error with message", () => {
51
+ setOAuthConnectError("state-1", "google", "token exchange failed");
52
+ const result = getOAuthConnectState("state-1");
53
+ expect(result).toMatchObject({
54
+ status: "error",
55
+ service: "google",
56
+ error: "token exchange failed",
57
+ });
58
+ });
59
+
60
+ test("re-setting same state token overwrites previous", () => {
61
+ setOAuthConnectPending("state-1", "google");
62
+ setOAuthConnectComplete("state-1", "google", "user@example.com");
63
+ const result = getOAuthConnectState("state-1");
64
+ expect(result?.status).toBe("complete");
65
+ });
66
+
67
+ test("getOAuthConnectState returns null for unknown state", () => {
68
+ expect(getOAuthConnectState("nonexistent")).toBeNull();
69
+ });
70
+
71
+ test("_clearAllOAuthConnectStates removes all entries", () => {
72
+ setOAuthConnectPending("state-1", "google");
73
+ setOAuthConnectPending("state-2", "github");
74
+ _clearAllOAuthConnectStates();
75
+ expect(getOAuthConnectState("state-1")).toBeNull();
76
+ expect(getOAuthConnectState("state-2")).toBeNull();
77
+ });
78
+
79
+ test("clearExpiredOAuthConnectStates removes expired pending entries", () => {
80
+ setOAuthConnectPending("state-1", "google");
81
+ // Advance Date.now by 6 minutes past PENDING_TTL_MS (5 min)
82
+ const originalNow = Date.now;
83
+ Date.now = () => originalNow() + 6 * 60 * 1000;
84
+ clearExpiredOAuthConnectStates();
85
+ Date.now = originalNow;
86
+ expect(getOAuthConnectState("state-1")).toBeNull();
87
+ });
88
+
89
+ test("clearExpiredOAuthConnectStates removes expired complete entries (past 60s grace)", () => {
90
+ setOAuthConnectComplete("state-1", "google");
91
+ const originalNow = Date.now;
92
+ Date.now = () => originalNow() + 2 * 60 * 1000; // advance 2 minutes past 60s grace
93
+ clearExpiredOAuthConnectStates();
94
+ Date.now = originalNow;
95
+ expect(getOAuthConnectState("state-1")).toBeNull();
96
+ });
97
+
98
+ test("clearExpiredOAuthConnectStates removes expired error entries (past 60s grace)", () => {
99
+ setOAuthConnectError("state-1", "google", "token exchange failed");
100
+ const originalNow = Date.now;
101
+ Date.now = () => originalNow() + 2 * 60 * 1000; // advance 2 minutes past 60s grace
102
+ clearExpiredOAuthConnectStates();
103
+ Date.now = originalNow;
104
+ expect(getOAuthConnectState("state-1")).toBeNull();
105
+ });
106
+
107
+ test("clearExpiredOAuthConnectStates does not remove non-expired pending entries", () => {
108
+ setOAuthConnectPending("state-1", "google");
109
+ clearExpiredOAuthConnectStates(); // called without advancing time
110
+ expect(getOAuthConnectState("state-1")).not.toBeNull();
111
+ });
112
+
113
+ test("sweep-on-insert: setOAuthConnectPending purges expired entries before inserting new one", () => {
114
+ // 1. Add an entry that will expire
115
+ setOAuthConnectPending("expired-state", "google");
116
+
117
+ // 2. Advance Date.now past the PENDING_TTL_MS (5 min)
118
+ const originalNow = Date.now;
119
+ Date.now = () => originalNow() + 6 * 60 * 1000;
120
+
121
+ // 3. Insert a new entry — this should trigger clearExpiredOAuthConnectStates() internally
122
+ setOAuthConnectPending("new-state", "github");
123
+
124
+ // 4. Restore Date.now before assertions (getOAuthConnectState also calls clearExpiredOAuthConnectStates)
125
+ Date.now = originalNow;
126
+
127
+ // The expired entry must have been swept out during the insert
128
+ // Use the map directly via getOAuthConnectState — expired-state is gone
129
+ // We call _clearAllOAuthConnectStates in beforeEach so we know the map started empty.
130
+ // After the insert the map should only contain "new-state".
131
+ const expiredResult = getOAuthConnectState("expired-state");
132
+ expect(expiredResult).toBeNull();
133
+
134
+ const newResult = getOAuthConnectState("new-state");
135
+ expect(newResult).toMatchObject({ status: "pending", service: "github" });
136
+ });
137
+ });
@@ -19,6 +19,7 @@
19
19
  * - Running identity verifiers
20
20
  */
21
21
 
22
+ import { emitPostConnectNudge } from "../home/post-connect-feed.js";
22
23
  import type { TokenEndpointAuthMethod } from "../security/oauth2.js";
23
24
  import { prepareOAuth2Flow, startOAuth2Flow } from "../security/oauth2.js";
24
25
  import { getLogger } from "../util/logger.js";
@@ -80,6 +81,7 @@ export interface OAuthConnectOptions {
80
81
  success: boolean;
81
82
  service: string;
82
83
  accountInfo?: string;
84
+ grantedScopes?: string[];
83
85
  error?: string;
84
86
  }) => void;
85
87
  }
@@ -250,10 +252,12 @@ export async function orchestrateOAuthConnect(
250
252
  },
251
253
  "Deferred OAuth2 flow completed — tokens stored",
252
254
  );
255
+ void emitPostConnectNudge(options.service);
253
256
  options.onDeferredComplete?.({
254
257
  success: true,
255
258
  service: options.service,
256
259
  accountInfo: stored.accountInfo ?? parsedAccountIdentifier,
260
+ grantedScopes: result.grantedScopes,
257
261
  });
258
262
  } catch (err) {
259
263
  log.error(
@@ -371,6 +375,8 @@ export async function orchestrateOAuthConnect(
371
375
  "orchestrateOAuthConnect: tokens stored, connect complete",
372
376
  );
373
377
 
378
+ void emitPostConnectNudge(options.service);
379
+
374
380
  return {
375
381
  success: true,
376
382
  deferred: false,
@@ -62,7 +62,10 @@ mock.module("../platform/client.js", () => ({
62
62
  // ---------------------------------------------------------------------------
63
63
 
64
64
  import { BYOOAuthConnection } from "./byo-connection.js";
65
- import { resolveOAuthConnection } from "./connection-resolver.js";
65
+ import {
66
+ resolveEffectiveBaseUrl,
67
+ resolveOAuthConnection,
68
+ } from "./connection-resolver.js";
66
69
  import { PlatformOAuthConnection } from "./platform-connection.js";
67
70
 
68
71
  // ---------------------------------------------------------------------------
@@ -214,3 +217,65 @@ describe("resolveOAuthConnection", () => {
214
217
  ).rejects.toThrow(/No active OAuth connection found/);
215
218
  });
216
219
  });
220
+
221
+ describe("resolveEffectiveBaseUrl", () => {
222
+ const fallback = "https://login.salesforce.com";
223
+
224
+ test("uses instance_url from JSON-string metadata for Salesforce", () => {
225
+ const metadata = JSON.stringify({
226
+ instance_url: "https://acme.my.salesforce.com",
227
+ issued_at: "1714000000000",
228
+ });
229
+ expect(resolveEffectiveBaseUrl("salesforce", fallback, metadata)).toBe(
230
+ "https://acme.my.salesforce.com",
231
+ );
232
+ });
233
+
234
+ test("uses instance_url from already-parsed object metadata", () => {
235
+ const metadata = { instance_url: "https://na162.salesforce.com" };
236
+ expect(resolveEffectiveBaseUrl("salesforce", fallback, metadata)).toBe(
237
+ "https://na162.salesforce.com",
238
+ );
239
+ });
240
+
241
+ test("falls back to seed baseUrl when metadata is null", () => {
242
+ expect(resolveEffectiveBaseUrl("salesforce", fallback, null)).toBe(
243
+ fallback,
244
+ );
245
+ });
246
+
247
+ test("falls back to seed baseUrl when instance_url is empty string", () => {
248
+ const metadata = JSON.stringify({ instance_url: "" });
249
+ expect(resolveEffectiveBaseUrl("salesforce", fallback, metadata)).toBe(
250
+ fallback,
251
+ );
252
+ });
253
+
254
+ test("falls back to seed baseUrl when metadata is unparseable JSON", () => {
255
+ expect(
256
+ resolveEffectiveBaseUrl("salesforce", fallback, "{ not valid json"),
257
+ ).toBe(fallback);
258
+ });
259
+
260
+ test("falls back to seed baseUrl when instance_url is the wrong type", () => {
261
+ const metadata = JSON.stringify({ instance_url: 12345 });
262
+ expect(resolveEffectiveBaseUrl("salesforce", fallback, metadata)).toBe(
263
+ fallback,
264
+ );
265
+ });
266
+
267
+ test("ignores instance_url for non-Salesforce providers", () => {
268
+ // A different provider whose token response happens to include an
269
+ // instance_url-shaped field MUST NOT have its baseUrl rewritten.
270
+ const metadata = JSON.stringify({
271
+ instance_url: "https://attacker.example.com",
272
+ });
273
+ expect(
274
+ resolveEffectiveBaseUrl(
275
+ "google",
276
+ "https://gmail.googleapis.com/gmail/v1/users/me",
277
+ metadata,
278
+ ),
279
+ ).toBe("https://gmail.googleapis.com/gmail/v1/users/me");
280
+ });
281
+ });
@@ -116,11 +116,65 @@ export async function resolveOAuthConnection(
116
116
  return new BYOOAuthConnection({
117
117
  id: conn.id,
118
118
  provider: conn.provider,
119
- baseUrl,
119
+ baseUrl: resolveEffectiveBaseUrl(conn.provider, baseUrl, conn.metadata),
120
120
  accountInfo: conn.accountInfo,
121
121
  });
122
122
  }
123
123
 
124
+ /**
125
+ * Resolve the effective API base URL for a connection, preferring per-tenant
126
+ * values stored on the connection's `metadata` over the provider's static
127
+ * seed value when applicable.
128
+ *
129
+ * Salesforce is the only provider that needs this: every org has its own
130
+ * API instance host (``acme.my.salesforce.com``, ``na162.salesforce.com``)
131
+ * which is returned in the OAuth token response as ``instance_url`` and
132
+ * captured into ``oauth_connection.metadata`` by ``storeOAuth2Tokens``.
133
+ * The seed's ``baseUrl`` for Salesforce is the login domain
134
+ * (``https://login.salesforce.com``) — correct for the OAuth handshake but
135
+ * wrong for REST API calls. Pulling the per-connection ``instance_url``
136
+ * here avoids forcing every caller to override ``baseUrl`` per-request.
137
+ *
138
+ * For all other providers the seed value is correct (single API domain),
139
+ * so we return it unchanged.
140
+ *
141
+ * If a future provider needs the same treatment, generalize via a
142
+ * declarative ``baseUrlMetadataKey`` field on the seed entry rather than
143
+ * adding more provider-name branches here.
144
+ */
145
+ export function resolveEffectiveBaseUrl(
146
+ provider: string,
147
+ fallbackBaseUrl: string,
148
+ rawMetadata: unknown,
149
+ ): string {
150
+ if (provider !== "salesforce") return fallbackBaseUrl;
151
+
152
+ const metadata = parseConnectionMetadata(rawMetadata);
153
+ const instanceUrl = metadata?.instance_url;
154
+ if (typeof instanceUrl === "string" && instanceUrl.length > 0) {
155
+ return instanceUrl;
156
+ }
157
+ return fallbackBaseUrl;
158
+ }
159
+
160
+ function parseConnectionMetadata(
161
+ raw: unknown,
162
+ ): Record<string, unknown> | undefined {
163
+ if (raw == null) return undefined;
164
+ if (typeof raw === "object") {
165
+ return raw as Record<string, unknown>;
166
+ }
167
+ if (typeof raw !== "string") return undefined;
168
+ try {
169
+ const parsed = JSON.parse(raw);
170
+ return typeof parsed === "object" && parsed !== null
171
+ ? (parsed as Record<string, unknown>)
172
+ : undefined;
173
+ } catch {
174
+ return undefined;
175
+ }
176
+ }
177
+
124
178
  // ---------------------------------------------------------------------------
125
179
  // Platform connection ID resolution
126
180
  // ---------------------------------------------------------------------------
@@ -43,9 +43,7 @@ export interface ConnectionAccessTokenResult {
43
43
  * providers (e.g. credential-health checks) must resolve the path through here
44
44
  * rather than assuming the OAuth access-token path.
45
45
  */
46
- export function manualTokenAccessCredentialKey(
47
- provider: string,
48
- ): string | null {
46
+ function manualTokenAccessCredentialKey(provider: string): string | null {
49
47
  switch (provider) {
50
48
  case "slack_channel":
51
49
  return credentialKey("slack_channel", "bot_token");
@@ -19,10 +19,6 @@ import {
19
19
  upsertApp,
20
20
  } from "./oauth-store.js";
21
21
 
22
- // Re-export from the centralized resolver so existing callers that import
23
- // from this module continue to work without changes.
24
- export { manualTokenAccessCredentialKey } from "./credential-token-resolver.js";
25
-
26
22
  const log = getLogger("manual-token-connection");
27
23
 
28
24
  /** Sentinel client_id used for non-OAuth providers that don't have a real app. */
@@ -0,0 +1,77 @@
1
+ /**
2
+ * In-memory OAuth connect flow status map.
3
+ *
4
+ * Tracks the current state of daemon-owned OAuth connect flows so the CLI
5
+ * can poll for completion via the IPC route.
6
+ */
7
+ type OAuthConnectState =
8
+ | { status: "pending"; service: string; expiresAt: number }
9
+ | { status: "complete"; service: string; accountInfo?: string; grantedScopes?: string[]; completedAt: number }
10
+ | { status: "error"; service: string; error: string; failedAt: number };
11
+
12
+ const activeOAuthConnectFlows = new Map<string, OAuthConnectState>();
13
+
14
+ const PENDING_TTL_MS = 5 * 60 * 1000; // 5 min — matches oauth-callback-registry.ts:14
15
+ const COMPLETION_GRACE_MS = 60 * 1000; // 60s so the polling CLI gets one final read
16
+
17
+ export function setOAuthConnectPending(state: string, service: string): void {
18
+ clearExpiredOAuthConnectStates();
19
+ activeOAuthConnectFlows.set(state, {
20
+ status: "pending",
21
+ service,
22
+ expiresAt: Date.now() + PENDING_TTL_MS,
23
+ });
24
+ }
25
+
26
+ export function setOAuthConnectComplete(
27
+ state: string,
28
+ service: string,
29
+ accountInfo?: string,
30
+ grantedScopes?: string[],
31
+ ): void {
32
+ clearExpiredOAuthConnectStates();
33
+ activeOAuthConnectFlows.set(state, {
34
+ status: "complete",
35
+ service,
36
+ accountInfo,
37
+ grantedScopes,
38
+ completedAt: Date.now(),
39
+ });
40
+ }
41
+
42
+ export function setOAuthConnectError(
43
+ state: string,
44
+ service: string,
45
+ error: string,
46
+ ): void {
47
+ clearExpiredOAuthConnectStates();
48
+ activeOAuthConnectFlows.set(state, {
49
+ status: "error",
50
+ service,
51
+ error,
52
+ failedAt: Date.now(),
53
+ });
54
+ }
55
+
56
+ export function getOAuthConnectState(state: string): OAuthConnectState | null {
57
+ clearExpiredOAuthConnectStates();
58
+ return activeOAuthConnectFlows.get(state) ?? null;
59
+ }
60
+
61
+ export function clearExpiredOAuthConnectStates(): void {
62
+ const now = Date.now();
63
+ for (const [key, state] of activeOAuthConnectFlows) {
64
+ if (state.status === "pending" && now > state.expiresAt) {
65
+ activeOAuthConnectFlows.delete(key);
66
+ } else if (state.status === "complete" && now > state.completedAt + COMPLETION_GRACE_MS) {
67
+ activeOAuthConnectFlows.delete(key);
68
+ } else if (state.status === "error" && now > state.failedAt + COMPLETION_GRACE_MS) {
69
+ activeOAuthConnectFlows.delete(key);
70
+ }
71
+ }
72
+ }
73
+
74
+ /** Test-only helper — clears all state for test isolation. */
75
+ export function _clearAllOAuthConnectStates(): void {
76
+ activeOAuthConnectFlows.clear();
77
+ }