@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
@@ -411,28 +411,6 @@ describe("compilePlaybooks", () => {
411
411
  describe("playbook tool edge cases", () => {
412
412
  beforeEach(clearPlaybooks);
413
413
 
414
- test("create uses memoryScopeId from context when present", async () => {
415
- const scopedCtx: ToolContext = { ...ctx, memoryScopeId: "custom-scope" };
416
- const result = await executePlaybookCreate(
417
- {
418
- trigger: "scoped trigger",
419
- action: "scoped action",
420
- },
421
- scopedCtx,
422
- );
423
-
424
- expect(result.isError).toBe(false);
425
- expect(result.content).toContain("Playbook created successfully");
426
-
427
- // Verify it's invisible to default scope
428
- const defaultList = await executePlaybookList({}, ctx);
429
- expect(defaultList.content).toContain("No playbooks found");
430
-
431
- // Visible to custom scope
432
- const scopedList = await executePlaybookList({}, scopedCtx);
433
- expect(scopedList.content).toContain("scoped trigger");
434
- });
435
-
436
414
  test("update detects collision with another playbook", async () => {
437
415
  const _r1 = await executePlaybookCreate(
438
416
  { trigger: "trigger A", action: "action A" },
@@ -587,25 +565,4 @@ describe("playbook tool edge cases", () => {
587
565
  expect(result.content).toContain("Found 1 playbook");
588
566
  expect(result.content).toContain("**a**");
589
567
  });
590
-
591
- test("delete is scoped and does not affect other scopes", async () => {
592
- const scopedCtx: ToolContext = { ...ctx, memoryScopeId: "scope-A" };
593
- const createResult = await executePlaybookCreate(
594
- { trigger: "x", action: "y" },
595
- scopedCtx,
596
- );
597
- const id = createResult.content.match(/ID: (\S+)/)![1];
598
-
599
- // Try to delete from default scope
600
- const deleteResult = await executePlaybookDelete({ playbook_id: id }, ctx);
601
- expect(deleteResult.isError).toBe(true);
602
- expect(deleteResult.content).toContain("not found");
603
-
604
- // Delete from correct scope succeeds
605
- const correctDelete = await executePlaybookDelete(
606
- { playbook_id: id },
607
- scopedCtx,
608
- );
609
- expect(correctDelete.isError).toBe(false);
610
- });
611
568
  });
@@ -236,6 +236,53 @@ describe("registerPluginTools / unregisterPluginTools helpers", () => {
236
236
  expect(retrieved?.ownerPluginId).toBe("my-plugin");
237
237
  });
238
238
 
239
+ test("registerPluginTools exposes provider-safe aliases for unsafe plugin tool names", async () => {
240
+ const execute = mock(
241
+ async (
242
+ _input: Record<string, unknown>,
243
+ _context: ToolContext,
244
+ ): Promise<ToolExecutionResult> => ({ content: "ok", isError: false }),
245
+ );
246
+ const accepted = registerPluginTools("stripe-plugin", [
247
+ makeFakeTool("Stripe Link CLI", { execute }),
248
+ ]);
249
+
250
+ expect(accepted).toHaveLength(1);
251
+ const alias = accepted[0]!.name;
252
+ expect(alias).toMatch(/^[a-zA-Z0-9_-]{1,64}$/);
253
+ expect(alias.startsWith("Stripe_Link_CLI__")).toBe(true);
254
+ expect(getTool(alias)).toBeDefined();
255
+ expect(accepted[0]!.getDefinition().name).toBe(alias);
256
+
257
+ await accepted[0]!.execute(
258
+ {},
259
+ {
260
+ workingDir: "/tmp",
261
+ conversationId: "conv-1",
262
+ trustClass: "guardian",
263
+ },
264
+ );
265
+
266
+ expect(execute).toHaveBeenCalledTimes(1);
267
+ });
268
+
269
+ test("registerPluginTools keeps edge-whitespace tool names distinct", () => {
270
+ const accepted = registerPluginTools("deploy-plugin", [
271
+ makeFakeTool("deploy"),
272
+ makeFakeTool(" deploy "),
273
+ ]);
274
+
275
+ expect(accepted).toHaveLength(2);
276
+ const aliases = accepted.map((tool) => tool.name);
277
+ expect(new Set(aliases).size).toBe(2);
278
+ expect(aliases).toContain("deploy");
279
+
280
+ const paddedAlias = aliases.find((name) => name !== "deploy");
281
+ expect(paddedAlias).toMatch(/^deploy__[a-f0-9]{12}$/);
282
+ expect(getTool("deploy")).toBeDefined();
283
+ expect(getTool(paddedAlias!)).toBeDefined();
284
+ });
285
+
239
286
  test("registerPluginTools overwrites any pre-existing ownership metadata", () => {
240
287
  // A plugin author could (maliciously or mistakenly) hand in a tool
241
288
  // pre-tagged with another skill's or plugin's ID. The helper must
@@ -47,7 +47,6 @@ mock.module("../config/loader.js", () => ({
47
47
  }),
48
48
  loadConfig: () => mockLoadedConfig,
49
49
  loadRawConfig: () => ({}),
50
- saveConfig: () => {},
51
50
  saveRawConfig: () => {},
52
51
  invalidateConfigCache: () => {},
53
52
  getNestedValue: () => undefined,
@@ -154,22 +153,18 @@ describe("pre-chat onboarding contract", () => {
154
153
  const result = buildSystemPrompt({ onboardingContext: context });
155
154
  const dynamic = dynamicBlock(result);
156
155
 
157
- expect(dynamic).toContain("## Pre-chat Onboarding Context");
156
+ expect(dynamic).toContain("## First-Run User Context");
158
157
  expect(dynamic).toContain(
159
- "The user completed the native pre-chat onboarding.",
160
- );
161
- expect(dynamic).toContain('"tools"');
162
- expect(dynamic).toContain('"slack"');
163
- expect(dynamic).toContain('"linear"');
164
- expect(dynamic).toContain('"tasks"');
165
- expect(dynamic).toContain('"code-building"');
166
- expect(dynamic).toContain('"tone": "warm"');
167
- expect(dynamic).toContain('"userName": "Alex"');
168
- expect(dynamic).toContain('"assistantName": "Nova"');
169
- expect(dynamic).toContain("```json");
170
- expect(dynamic).toContain(
171
- "Use this to personalize your opener and skip redundant discovery.",
158
+ "The user completed setup before this conversation.",
172
159
  );
160
+ expect(dynamic).toContain("- Daily tools: Slack, Linear");
161
+ expect(dynamic).toContain("- Common work: builds code, apps, or tools");
162
+ expect(dynamic).toContain("- Name: Alex");
163
+ expect(dynamic).toContain("- Chosen assistant name: Nova");
164
+ expect(dynamic).toContain("Apply this context quietly.");
165
+
166
+ // Raw JSON must NOT be present
167
+ expect(dynamic).not.toContain("```json");
173
168
  });
174
169
 
175
170
  test("does NOT inject onboarding context when BOOTSTRAP.md does not exist", () => {
@@ -184,9 +179,9 @@ describe("pre-chat onboarding contract", () => {
184
179
  const result = buildSystemPrompt({ onboardingContext: context });
185
180
  const dynamic = dynamicBlock(result);
186
181
 
187
- expect(dynamic).not.toContain("## Pre-chat Onboarding Context");
188
- expect(dynamic).not.toContain("pre-chat onboarding");
189
- expect(dynamic).not.toContain('"tools"');
182
+ expect(dynamic).not.toContain("## First-Run User Context");
183
+ expect(dynamic).not.toContain("First-Run User Context");
184
+ expect(dynamic).not.toContain("- Daily tools:");
190
185
  });
191
186
 
192
187
  test("does NOT inject onboarding context when excludeBootstrap is true", () => {
@@ -207,7 +202,7 @@ describe("pre-chat onboarding contract", () => {
207
202
  });
208
203
  const dynamic = dynamicBlock(result);
209
204
 
210
- expect(dynamic).not.toContain("## Pre-chat Onboarding Context");
205
+ expect(dynamic).not.toContain("## First-Run User Context");
211
206
  expect(dynamic).not.toContain("First-Run Ritual");
212
207
  });
213
208
 
@@ -223,7 +218,7 @@ describe("pre-chat onboarding contract", () => {
223
218
  // Bootstrap should still be present
224
219
  expect(dynamic).toContain("First-Run Ritual");
225
220
  // But no onboarding context section
226
- expect(dynamic).not.toContain("## Pre-chat Onboarding Context");
221
+ expect(dynamic).not.toContain("## First-Run User Context");
227
222
  });
228
223
 
229
224
  test("accepts all four personality tones", () => {
@@ -245,12 +240,12 @@ describe("pre-chat onboarding contract", () => {
245
240
  const result = buildSystemPrompt({ onboardingContext: context });
246
241
  const dynamic = dynamicBlock(result);
247
242
 
248
- expect(dynamic).toContain("## Pre-chat Onboarding Context");
249
- expect(dynamic).toContain(`"tone": "${tone}"`);
243
+ expect(dynamic).toContain("## First-Run User Context");
244
+ expect(dynamic).toContain(`- Preferred initial voice: ${tone}`);
250
245
  }
251
246
  });
252
247
 
253
- test("serializes onboarding context as pretty-printed JSON", () => {
248
+ test("renders compact markdown, not JSON", () => {
254
249
  writeFileSync(
255
250
  join(TEST_DIR, "BOOTSTRAP.md"),
256
251
  "# Bootstrap\n\nOnboarding.",
@@ -267,9 +262,65 @@ describe("pre-chat onboarding contract", () => {
267
262
  const result = buildSystemPrompt({ onboardingContext: context });
268
263
  const dynamic = dynamicBlock(result);
269
264
 
270
- // Verify it contains the pretty-printed JSON (indented with 2 spaces)
265
+ // Should contain compact markdown lines
266
+ expect(dynamic).toContain("## First-Run User Context");
267
+ expect(dynamic).toContain("- Name: Jane");
268
+ expect(dynamic).toContain("- Common work: plans and coordinates work");
269
+ expect(dynamic).toContain("- Daily tools: Notion");
270
+ expect(dynamic).toContain("- Chosen assistant name: Kit");
271
+ expect(dynamic).toContain("- Preferred initial voice: warm");
272
+
273
+ // Must NOT contain JSON output
274
+ expect(dynamic).not.toContain("```json");
271
275
  const expectedJson = JSON.stringify(context, null, 2);
272
- expect(dynamic).toContain(expectedJson);
276
+ expect(dynamic).not.toContain(expectedJson);
277
+ });
278
+
279
+ test("empty tools/tasks arrays result in no Daily tools / Common work lines", () => {
280
+ writeFileSync(
281
+ join(TEST_DIR, "BOOTSTRAP.md"),
282
+ "# Bootstrap\n\nOnboarding.",
283
+ );
284
+
285
+ const context: OnboardingContext = {
286
+ tools: [],
287
+ tasks: [],
288
+ tone: "warm",
289
+ userName: "Alex",
290
+ };
291
+
292
+ const result = buildSystemPrompt({ onboardingContext: context });
293
+ const dynamic = dynamicBlock(result);
294
+
295
+ expect(dynamic).toContain("## First-Run User Context");
296
+ expect(dynamic).toContain("- Name: Alex");
297
+ expect(dynamic).not.toContain("- Daily tools:");
298
+ expect(dynamic).not.toContain("- Common work:");
299
+ });
300
+
301
+ test("absent userName results in no Name line", () => {
302
+ writeFileSync(
303
+ join(TEST_DIR, "BOOTSTRAP.md"),
304
+ "# Bootstrap\n\nOnboarding.",
305
+ );
306
+
307
+ const context: OnboardingContext = {
308
+ tools: ["slack"],
309
+ tasks: ["writing"],
310
+ tone: "warm",
311
+ };
312
+
313
+ const result = buildSystemPrompt({ onboardingContext: context });
314
+ const dynamic = dynamicBlock(result);
315
+
316
+ expect(dynamic).toContain("## First-Run User Context");
317
+ expect(dynamic).not.toContain("- Name:");
318
+ // Other fields should still be present
319
+ expect(dynamic).toContain("- Daily tools: Slack");
320
+ expect(dynamic).toContain(
321
+ "- Common work: writes docs, emails, or content",
322
+ );
323
+ expect(dynamic).toContain("- Preferred initial voice: warm");
273
324
  });
274
325
  });
275
326
 
@@ -288,4 +339,142 @@ describe("pre-chat onboarding contract", () => {
288
339
  expect(true).toBe(true); // structural acknowledgment
289
340
  });
290
341
  });
342
+
343
+ describe("end-to-end onboarding integration", () => {
344
+ test("with BOOTSTRAP.md present, onboarding context produces compact markdown with normalized labels", () => {
345
+ writeFileSync(
346
+ join(TEST_DIR, "BOOTSTRAP.md"),
347
+ "# Bootstrap\n\nWelcome to your first conversation.",
348
+ );
349
+
350
+ const context: OnboardingContext = {
351
+ tools: ["slack", "notion", "linear"],
352
+ tasks: ["code-building", "writing", "project-management"],
353
+ tone: "grounded",
354
+ userName: "Alice",
355
+ assistantName: "Pax",
356
+ };
357
+
358
+ const result = buildSystemPrompt({ onboardingContext: context });
359
+ const dynamic = dynamicBlock(result);
360
+
361
+ // Heading is present
362
+ expect(dynamic).toContain("## First-Run User Context");
363
+
364
+ // Normalized labels appear (capitalised tool names, human-readable task descriptions)
365
+ expect(dynamic).toContain("- Daily tools: Slack, Notion, Linear");
366
+ expect(dynamic).toContain("- Name: Alice");
367
+ expect(dynamic).toContain("- Chosen assistant name: Pax");
368
+ expect(dynamic).toContain("- Preferred initial voice: grounded");
369
+ // Common work descriptions are normalised from task IDs
370
+ expect(dynamic).toContain("- Common work:");
371
+
372
+ // No raw JSON anywhere in the dynamic block
373
+ expect(dynamic).not.toContain("```json");
374
+ expect(dynamic).not.toContain('"tools"');
375
+ expect(dynamic).not.toContain('"tasks"');
376
+ expect(dynamic).not.toContain('"tone"');
377
+ expect(dynamic).not.toContain('"userName"');
378
+ expect(dynamic).not.toContain('"assistantName"');
379
+ });
380
+
381
+ test("without BOOTSTRAP.md, onboarding context does NOT appear in system prompt", () => {
382
+ // No BOOTSTRAP.md created — simulates a returning user session
383
+ const context: OnboardingContext = {
384
+ tools: ["slack", "figma"],
385
+ tasks: ["design", "writing"],
386
+ tone: "warm",
387
+ userName: "Bob",
388
+ assistantName: "Kit",
389
+ };
390
+
391
+ const result = buildSystemPrompt({ onboardingContext: context });
392
+ const dynamic = dynamicBlock(result);
393
+
394
+ // Onboarding section must be absent
395
+ expect(dynamic).not.toContain("## First-Run User Context");
396
+ expect(dynamic).not.toContain("First-Run Ritual");
397
+ expect(dynamic).not.toContain("- Daily tools:");
398
+ expect(dynamic).not.toContain("- Name: Bob");
399
+ expect(dynamic).not.toContain("- Chosen assistant name:");
400
+ expect(dynamic).not.toContain("Apply this context quietly.");
401
+ });
402
+
403
+ test("excludeBootstrap suppresses both bootstrap and onboarding sections", () => {
404
+ writeFileSync(
405
+ join(TEST_DIR, "BOOTSTRAP.md"),
406
+ "# Bootstrap\n\nFirst run instructions.",
407
+ );
408
+
409
+ const context: OnboardingContext = {
410
+ tools: ["linear"],
411
+ tasks: ["code-building"],
412
+ tone: "energetic",
413
+ userName: "Charlie",
414
+ assistantName: "Nova",
415
+ };
416
+
417
+ const result = buildSystemPrompt({
418
+ onboardingContext: context,
419
+ excludeBootstrap: true,
420
+ });
421
+ const dynamic = dynamicBlock(result);
422
+
423
+ // Both bootstrap and onboarding must be suppressed
424
+ expect(dynamic).not.toContain("First-Run Ritual");
425
+ expect(dynamic).not.toContain("## First-Run User Context");
426
+ expect(dynamic).not.toContain("- Daily tools:");
427
+ expect(dynamic).not.toContain("- Name: Charlie");
428
+ expect(dynamic).not.toContain("Apply this context quietly.");
429
+ });
430
+
431
+ test("userPersona is included independently of onboarding context", () => {
432
+ // No BOOTSTRAP.md — the durable persona path after bootstrap is deleted
433
+ const personaContent =
434
+ "# User Persona\n\nPrefers concise answers. Works in fintech.";
435
+
436
+ const result = buildSystemPrompt({
437
+ userPersona: personaContent,
438
+ // No onboardingContext — simulates post-onboarding conversation
439
+ });
440
+ const dynamic = dynamicBlock(result);
441
+
442
+ // Persona content appears in prompt even without bootstrap or onboarding
443
+ expect(dynamic).toContain("# User Persona");
444
+ expect(dynamic).toContain("Prefers concise answers. Works in fintech.");
445
+
446
+ // No onboarding section should be present
447
+ expect(dynamic).not.toContain("## First-Run User Context");
448
+ expect(dynamic).not.toContain("First-Run Ritual");
449
+ });
450
+
451
+ test("userPersona appears alongside onboarding context during first run", () => {
452
+ writeFileSync(
453
+ join(TEST_DIR, "BOOTSTRAP.md"),
454
+ "# Bootstrap\n\nOnboarding flow.",
455
+ );
456
+
457
+ const personaContent =
458
+ "# User Persona\n\nEarly-stage startup founder. Likes bullet points.";
459
+ const context: OnboardingContext = {
460
+ tools: ["slack"],
461
+ tasks: ["writing"],
462
+ tone: "warm",
463
+ userName: "Dana",
464
+ };
465
+
466
+ const result = buildSystemPrompt({
467
+ userPersona: personaContent,
468
+ onboardingContext: context,
469
+ });
470
+ const dynamic = dynamicBlock(result);
471
+
472
+ // Both persona and onboarding context appear
473
+ expect(dynamic).toContain("# User Persona");
474
+ expect(dynamic).toContain("Likes bullet points.");
475
+ expect(dynamic).toContain("## First-Run User Context");
476
+ expect(dynamic).toContain("- Name: Dana");
477
+ expect(dynamic).toContain("- Daily tools: Slack");
478
+ });
479
+ });
291
480
  });
@@ -101,6 +101,7 @@ interface TestConversation {
101
101
  ensureActorScopedHistory: () => Promise<void>;
102
102
  setChannelCapabilities: () => void;
103
103
  setHostCuProxy: () => void;
104
+ setHostAppControlProxy: () => void;
104
105
  addPreactivatedSkillId: () => void;
105
106
  setCommandIntent: () => void;
106
107
  setTurnChannelContext: (ctx: TurnChannelContext) => void;
@@ -188,6 +189,7 @@ function makeConversation(): TestConversation {
188
189
  ensureActorScopedHistory: async () => {},
189
190
  setChannelCapabilities: () => {},
190
191
  setHostCuProxy: () => {},
192
+ setHostAppControlProxy: () => {},
191
193
  addPreactivatedSkillId: () => {},
192
194
  setCommandIntent: () => {},
193
195
  setTurnChannelContext: (ctx: TurnChannelContext) => {
@@ -46,7 +46,6 @@ mock.module("../config/loader.js", () => ({
46
46
  getConfig: () => currentConfig,
47
47
  loadConfig: () => currentConfig,
48
48
  invalidateConfigCache: () => {},
49
- saveConfig: () => {},
50
49
  loadRawConfig: () => ({}),
51
50
  saveRawConfig: () => {},
52
51
  getNestedValue: () => undefined,
@@ -0,0 +1,23 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ isProviderSafeToolName,
5
+ toProviderSafeToolName,
6
+ } from "../tools/provider-tool-name.js";
7
+
8
+ describe("provider tool names", () => {
9
+ test("leaves already-safe names unchanged", () => {
10
+ expect(toProviderSafeToolName("deploy")).toBe("deploy");
11
+ expect(isProviderSafeToolName("deploy")).toBe(true);
12
+ });
13
+
14
+ test("preserves raw-name identity for names that differ by edge whitespace", () => {
15
+ const plain = toProviderSafeToolName("deploy");
16
+ const padded = toProviderSafeToolName(" deploy ");
17
+
18
+ expect(plain).toBe("deploy");
19
+ expect(padded).toMatch(/^deploy__[a-f0-9]{12}$/);
20
+ expect(padded).not.toBe(plain);
21
+ expect(isProviderSafeToolName(padded)).toBe(true);
22
+ });
23
+ });
@@ -26,16 +26,49 @@ mock.module("../util/logger.js", () => ({
26
26
  }));
27
27
 
28
28
  import { setIngressPublicBaseUrl } from "../config/env.js";
29
+ import { IngressConfigSchema } from "../config/schemas/ingress.js";
29
30
  import {
30
31
  getOAuthCallbackUrl,
31
32
  getPublicBaseUrl,
32
33
  getTelegramWebhookUrl,
33
34
  getTwilioConnectActionUrl,
35
+ getTwilioMediaStreamUrl,
34
36
  getTwilioRelayUrl,
35
37
  getTwilioStatusCallbackUrl,
36
38
  getTwilioVoiceWebhookUrl,
37
39
  } from "../inbound/public-ingress-urls.js";
38
40
 
41
+ // ---------------------------------------------------------------------------
42
+ // IngressConfigSchema
43
+ // ---------------------------------------------------------------------------
44
+
45
+ describe("IngressConfigSchema", () => {
46
+ test("accepts an absolute HTTP(S) public base URL", () => {
47
+ const result = IngressConfigSchema.parse({
48
+ publicBaseUrl: "https://example.com",
49
+ });
50
+
51
+ expect(result.publicBaseUrl).toBe("https://example.com");
52
+ });
53
+
54
+ test("accepts an empty public base URL", () => {
55
+ const result = IngressConfigSchema.parse({
56
+ publicBaseUrl: "",
57
+ });
58
+
59
+ expect(result.publicBaseUrl).toBe("");
60
+ });
61
+
62
+ test("rejects a relative public base URL", () => {
63
+ expect(() =>
64
+ IngressConfigSchema.parse({
65
+ publicBaseUrl: "/webhooks/twilio",
66
+ }),
67
+ ).toThrow(/ingress\.publicBaseUrl must be an absolute URL/);
68
+ });
69
+
70
+ });
71
+
39
72
  // ---------------------------------------------------------------------------
40
73
  // getPublicBaseUrl — fallback chain
41
74
  // ---------------------------------------------------------------------------
@@ -155,6 +188,70 @@ describe("getPublicBaseUrl", () => {
155
188
  });
156
189
  });
157
190
 
191
+ // ---------------------------------------------------------------------------
192
+ // Twilio-specific public base URL selection
193
+ // ---------------------------------------------------------------------------
194
+
195
+ describe("Twilio URL builders use publicBaseUrl", () => {
196
+ beforeEach(() => {
197
+ setIngressPublicBaseUrl(undefined);
198
+ });
199
+
200
+ afterEach(() => {
201
+ setIngressPublicBaseUrl(undefined);
202
+ });
203
+
204
+ test("Twilio URL builders use ingress.publicBaseUrl", () => {
205
+ const config = {
206
+ ingress: {
207
+ publicBaseUrl: " https://example.com/// ",
208
+ },
209
+ };
210
+
211
+ expect(getTwilioVoiceWebhookUrl(config, "session-123")).toBe(
212
+ "https://example.com/webhooks/twilio/voice?callSessionId=session-123",
213
+ );
214
+ expect(getTwilioStatusCallbackUrl(config)).toBe(
215
+ "https://example.com/webhooks/twilio/status",
216
+ );
217
+ expect(getTwilioConnectActionUrl(config)).toBe(
218
+ "https://example.com/webhooks/twilio/connect-action",
219
+ );
220
+ expect(getTwilioRelayUrl(config)).toBe(
221
+ "wss://example.com/webhooks/twilio/relay",
222
+ );
223
+ expect(getTwilioMediaStreamUrl(config)).toBe(
224
+ "wss://example.com/webhooks/twilio/media-stream",
225
+ );
226
+ });
227
+
228
+ test("Twilio URL builders fall back to module-level ingress state", () => {
229
+ setIngressPublicBaseUrl("https://ingress-env.example.com");
230
+
231
+ expect(
232
+ getTwilioStatusCallbackUrl({
233
+ ingress: { publicBaseUrl: "" },
234
+ }),
235
+ ).toBe("https://ingress-env.example.com/webhooks/twilio/status");
236
+ });
237
+
238
+ test("all URL builders share the same publicBaseUrl", () => {
239
+ const config = {
240
+ ingress: {
241
+ publicBaseUrl: "https://example.com",
242
+ },
243
+ };
244
+
245
+ expect(getPublicBaseUrl(config)).toBe("https://example.com");
246
+ expect(getOAuthCallbackUrl(config)).toBe(
247
+ "https://example.com/webhooks/oauth/callback",
248
+ );
249
+ expect(getTelegramWebhookUrl(config)).toBe(
250
+ "https://example.com/webhooks/telegram",
251
+ );
252
+ });
253
+ });
254
+
158
255
  // ---------------------------------------------------------------------------
159
256
  // getTwilioVoiceWebhookUrl
160
257
  // ---------------------------------------------------------------------------
@@ -362,11 +362,22 @@ function getLatestAssistantText(conversationId: string): string | null {
362
362
  if (Array.isArray(parsed)) {
363
363
  return parsed
364
364
  .filter(
365
- (block): block is { type: string; text?: string } =>
366
- typeof block === "object" && block != null,
365
+ (block): block is {
366
+ type: string;
367
+ text?: string;
368
+ surfaceType?: string;
369
+ data?: { summaryText?: string };
370
+ } => typeof block === "object" && block != null,
367
371
  )
368
- .filter((block) => block.type === "text")
369
- .map((block) => block.text ?? "")
372
+ .map((block) => {
373
+ if (block.type === "text") return block.text ?? "";
374
+ if (
375
+ block.type === "ui_surface" &&
376
+ block.surfaceType === "call_summary"
377
+ )
378
+ return block.data?.summaryText ?? "";
379
+ return "";
380
+ })
370
381
  .join("");
371
382
  }
372
383
  if (typeof parsed === "string") return parsed;
@@ -72,7 +72,6 @@ mock.module("../config/loader.js", () => ({
72
72
  getConfig: () => mockConfig,
73
73
  loadConfig: () => mockConfig,
74
74
  invalidateConfigCache: () => {},
75
- saveConfig: () => {},
76
75
  loadRawConfig: () => ({}),
77
76
  saveRawConfig: () => {},
78
77
  getNestedValue: () => undefined,