@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
@@ -4,12 +4,16 @@ import {
4
4
  assistantEventHub,
5
5
  broadcastMessage,
6
6
  } from "../runtime/assistant-event-hub.js";
7
+ import {
8
+ ambiguousSameUserError,
9
+ enforceSameActorOrErrorResult,
10
+ pickSameUserAutoResolve,
11
+ } from "../runtime/auth/same-actor.js";
7
12
  import * as pendingInteractions from "../runtime/pending-interactions.js";
8
13
  import { readImageBase64 } from "../tools/shared/filesystem/image-read.js";
9
14
  import type { ToolExecutionResult } from "../tools/types.js";
10
15
  import { AssistantError, ErrorCode } from "../util/errors.js";
11
16
  import { getLogger } from "../util/logger.js";
12
- import type { ServerMessage } from "./message-protocol.js";
13
17
  import type { HostFileRequest } from "./message-types/host-file.js";
14
18
 
15
19
  /** Distributive omit that preserves union variant fields. */
@@ -25,17 +29,6 @@ export type HostFileInput = DistributiveOmit<
25
29
 
26
30
  const log = getLogger("host-file-proxy");
27
31
 
28
- interface PendingRequest {
29
- resolve: (result: ToolExecutionResult) => void;
30
- reject: (err: Error) => void;
31
- timer: ReturnType<typeof setTimeout>;
32
- operation: HostFileInput["operation"];
33
- path: string;
34
- conversationId: string;
35
- /** Detach the abort listener from the caller's signal. No-op when no signal was passed. */
36
- detachAbort: () => void;
37
- }
38
-
39
32
  export class HostFileProxy {
40
33
  private static _instance: HostFileProxy | null = null;
41
34
 
@@ -65,8 +58,6 @@ export class HostFileProxy {
65
58
  HostFileProxy._instance = null;
66
59
  }
67
60
 
68
- private pending = new Map<string, PendingRequest>();
69
-
70
61
  /**
71
62
  * Whether a client with `host_file` capability is connected.
72
63
  * Note: host_file covers both file operations and transfers.
@@ -77,56 +68,106 @@ export class HostFileProxy {
77
68
  );
78
69
  }
79
70
 
80
- private send(msg: ServerMessage): void {
81
- broadcastMessage(msg, undefined, { targetCapability: "host_file" });
82
- }
83
-
84
71
  request(
85
72
  input: HostFileInput,
86
73
  conversationId: string,
87
74
  signal?: AbortSignal,
75
+ targetClientId?: string,
76
+ sourceActorPrincipalId?: string,
88
77
  ): Promise<ToolExecutionResult> {
89
78
  if (signal?.aborted) {
90
79
  return Promise.resolve({ content: "Aborted", isError: true });
91
80
  }
92
81
 
82
+ // Resolve targetClientId: explicit → validate; single same-user
83
+ // capable client → auto-resolve. Callers may embed targetClientId in
84
+ // the input object (tool handlers) or pass it as the 4th parameter
85
+ // (legacy). Prefer the explicit param; fall back to input field.
86
+ let resolvedTargetClientId: string | undefined =
87
+ targetClientId ?? input.targetClientId;
88
+ if (resolvedTargetClientId != null) {
89
+ const client = assistantEventHub.getClientById(resolvedTargetClientId);
90
+ if (!client) {
91
+ return Promise.resolve({
92
+ content: `No connected client with id '${resolvedTargetClientId}' supports host_file. Run \`assistant clients list --capability host_file\` to see available clients.`,
93
+ isError: true,
94
+ });
95
+ }
96
+ if (!client.capabilities.includes("host_file")) {
97
+ return Promise.resolve({
98
+ content: `Client '${resolvedTargetClientId}' does not support host_file. Run \`assistant clients list --capability host_file\` to see available clients.`,
99
+ isError: true,
100
+ });
101
+ }
102
+ } else {
103
+ // Auto-resolve to the unique same-user client. Reject ambiguous
104
+ // (multi-machine) cases so a single targeted-style request cannot
105
+ // fan out across the user's machines.
106
+ const resolved = pickSameUserAutoResolve({
107
+ hub: assistantEventHub,
108
+ capability: "host_file",
109
+ sourceActorPrincipalId,
110
+ });
111
+ if (resolved.kind === "ambiguous") {
112
+ return Promise.resolve(ambiguousSameUserError("host_file"));
113
+ }
114
+ resolvedTargetClientId =
115
+ resolved.kind === "match" ? resolved.clientId : undefined;
116
+ }
117
+
118
+ // Same-user check: targeted host_file requests must be bound to the same
119
+ // authenticated user identity that opened the target client's SSE stream.
120
+ // Prevents cross-user routing through actor token mis-targeting.
121
+ if (resolvedTargetClientId != null) {
122
+ const rejection = enforceSameActorOrErrorResult({
123
+ hub: assistantEventHub,
124
+ sourceActorPrincipalId,
125
+ targetClientId: resolvedTargetClientId,
126
+ op: "host_file",
127
+ });
128
+ if (rejection) return Promise.resolve(rejection);
129
+ }
130
+
93
131
  const requestId = uuid();
94
132
 
95
133
  return new Promise<ToolExecutionResult>((resolve, reject) => {
96
- // File operations should be fast — 30 second timeout.
97
134
  const timeoutSec = 30;
98
135
 
99
136
  let detachAbort: () => void = () => {};
100
137
 
101
138
  const timer = setTimeout(() => {
102
- this.pending.delete(requestId);
103
- detachAbort();
104
139
  pendingInteractions.resolve(requestId);
105
140
  log.warn(
106
141
  { requestId, operation: input.operation },
107
142
  "Host file proxy request timed out",
108
143
  );
109
144
  resolve({
110
- content: "Host file proxy timed out waiting for client response",
145
+ content: resolvedTargetClientId
146
+ ? `Host file proxy timed out waiting for response from client '${resolvedTargetClientId}'`
147
+ : "Host file proxy timed out waiting for client response",
111
148
  isError: true,
112
149
  });
113
150
  }, timeoutSec * 1000);
114
151
 
115
152
  if (signal) {
116
153
  const onAbort = () => {
117
- if (this.pending.has(requestId)) {
118
- clearTimeout(timer);
119
- this.pending.delete(requestId);
120
- detachAbort();
154
+ if (pendingInteractions.get(requestId)) {
121
155
  pendingInteractions.resolve(requestId);
122
156
  try {
123
- this.send({
124
- type: "host_file_cancel",
125
- requestId,
157
+ broadcastMessage(
158
+ {
159
+ type: "host_file_cancel",
160
+ requestId,
161
+ conversationId,
162
+ ...(resolvedTargetClientId != null
163
+ ? { targetClientId: resolvedTargetClientId }
164
+ : {}),
165
+ },
126
166
  conversationId,
127
- });
167
+ { targetClientId: resolvedTargetClientId },
168
+ );
128
169
  } catch {
129
- // Best-effort cancel notification — connection may already be closed.
170
+ // Best-effort cancel notification
130
171
  }
131
172
  resolve({ content: "Aborted", isError: true });
132
173
  }
@@ -135,27 +176,40 @@ export class HostFileProxy {
135
176
  detachAbort = () => signal.removeEventListener("abort", onAbort);
136
177
  }
137
178
 
138
- this.pending.set(requestId, {
139
- resolve,
140
- reject,
141
- timer,
142
- operation: input.operation,
143
- path: input.path,
179
+ pendingInteractions.register(requestId, {
144
180
  conversationId,
181
+ kind: "host_file",
182
+ targetClientId: resolvedTargetClientId,
183
+ targetActorPrincipalId:
184
+ resolvedTargetClientId != null
185
+ ? assistantEventHub.getActorPrincipalIdForClient(
186
+ resolvedTargetClientId,
187
+ )
188
+ : undefined,
189
+ rpcResolve: resolve,
190
+ rpcReject: reject,
191
+ timer,
145
192
  detachAbort,
193
+ metadata: { operation: input.operation, path: input.path },
146
194
  });
147
195
 
148
196
  try {
149
- this.send({
150
- ...input,
151
- type: "host_file_request",
152
- requestId,
197
+ broadcastMessage(
198
+ {
199
+ ...input,
200
+ type: "host_file_request",
201
+ requestId,
202
+ conversationId,
203
+ // Always include in message body so the receiving client can verify
204
+ // which endpoint was targeted (even when auto-resolved).
205
+ ...(resolvedTargetClientId != null
206
+ ? { targetClientId: resolvedTargetClientId }
207
+ : {}),
208
+ },
153
209
  conversationId,
154
- });
210
+ { targetClientId: resolvedTargetClientId },
211
+ );
155
212
  } catch (err) {
156
- clearTimeout(timer);
157
- this.pending.delete(requestId);
158
- detachAbort();
159
213
  pendingInteractions.resolve(requestId);
160
214
  log.warn(
161
215
  { requestId, operation: input.operation, err },
@@ -166,55 +220,61 @@ export class HostFileProxy {
166
220
  });
167
221
  }
168
222
 
223
+ /**
224
+ * Process a client result and resolve the RPC. Called by route handlers.
225
+ */
169
226
  resolve(
170
227
  requestId: string,
171
228
  response: { content: string; isError: boolean; imageData?: string },
172
229
  ): void {
173
- const entry = this.pending.get(requestId);
174
- if (!entry) {
230
+ const interaction = pendingInteractions.resolve(requestId);
231
+ if (!interaction?.rpcResolve) {
175
232
  log.warn({ requestId }, "No pending host file request for response");
176
233
  return;
177
234
  }
178
- clearTimeout(entry.timer);
179
- entry.detachAbort();
180
- this.pending.delete(requestId);
235
+ const meta = interaction.metadata ?? {};
181
236
  if (
182
- entry.operation === "read" &&
237
+ meta.operation === "read" &&
183
238
  !response.isError &&
184
239
  typeof response.imageData === "string" &&
185
240
  response.imageData.length > 0
186
241
  ) {
187
- entry.resolve(readImageBase64(response.imageData, entry.path));
242
+ interaction.rpcResolve(
243
+ readImageBase64(response.imageData, meta.path as string),
244
+ );
188
245
  return;
189
246
  }
190
- entry.resolve({ content: response.content, isError: response.isError });
191
- }
192
-
193
- hasPendingRequest(requestId: string): boolean {
194
- return this.pending.has(requestId);
247
+ interaction.rpcResolve({
248
+ content: response.content,
249
+ isError: response.isError,
250
+ });
195
251
  }
196
252
 
197
253
  dispose(): void {
198
- for (const [requestId, entry] of this.pending) {
199
- clearTimeout(entry.timer);
200
- entry.detachAbort();
201
- pendingInteractions.resolve(requestId);
254
+ for (const entry of pendingInteractions.getByKind("host_file")) {
255
+ pendingInteractions.resolve(entry.requestId);
202
256
  try {
203
- this.send({
204
- type: "host_file_cancel",
205
- requestId,
206
- conversationId: entry.conversationId,
207
- });
257
+ broadcastMessage(
258
+ {
259
+ type: "host_file_cancel",
260
+ requestId: entry.requestId,
261
+ conversationId: entry.conversationId,
262
+ ...(entry.targetClientId != null
263
+ ? { targetClientId: entry.targetClientId }
264
+ : {}),
265
+ },
266
+ entry.conversationId,
267
+ { targetClientId: entry.targetClientId as string | undefined },
268
+ );
208
269
  } catch {
209
- // Best-effort cancel notification — connection may already be closed.
270
+ // Best-effort cancel notification
210
271
  }
211
- entry.reject(
272
+ entry.rpcReject?.(
212
273
  new AssistantError(
213
274
  "Host file proxy disposed",
214
275
  ErrorCode.INTERNAL_ERROR,
215
276
  ),
216
277
  );
217
278
  }
218
- this.pending.clear();
219
279
  }
220
280
  }
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Shared lifecycle base for host-proxy classes (HostBashProxy, HostCuProxy,
3
+ * HostFileProxy, HostTransferProxy, HostBrowserProxy, ...).
4
+ *
5
+ * Each host proxy:
6
+ * - dispatches a request to the desktop client via the assistant event hub,
7
+ * - tracks the request in a pending map keyed by `requestId`,
8
+ * - times the request out after a configurable interval,
9
+ * - cancels the request when the caller's `AbortSignal` fires,
10
+ * - rejects all pending requests on `dispose()`,
11
+ * - exposes `isAvailable()` based on the connected client's capabilities.
12
+ *
13
+ * Subclasses keep proxy-specific concerns (envelope shape, observation
14
+ * formatting, per-proxy state like CU's step counter) out of the base.
15
+ */
16
+ import { v4 as uuid } from "uuid";
17
+
18
+ import type { HostProxyCapability } from "../channels/types.js";
19
+ import {
20
+ assistantEventHub,
21
+ broadcastMessage,
22
+ } from "../runtime/assistant-event-hub.js";
23
+ import type { PendingInteraction } from "../runtime/pending-interactions.js";
24
+ import * as pendingInteractions from "../runtime/pending-interactions.js";
25
+ import { AssistantError, ErrorCode } from "../util/errors.js";
26
+ import { getLogger } from "../util/logger.js";
27
+ import type { ServerMessage } from "./message-protocol.js";
28
+
29
+ const log = getLogger("host-proxy-base");
30
+
31
+ /**
32
+ * `broadcastMessage` is statically typed against the discriminated
33
+ * `ServerMessage` union. The base class assembles envelopes from
34
+ * constructor-supplied event names and untyped extra fields, so static
35
+ * narrowing is impossible — subclasses are responsible for passing event
36
+ * names that match a real `ServerMessage` variant.
37
+ */
38
+ function broadcastDynamic(
39
+ envelope: Record<string, unknown>,
40
+ targetClientId?: string,
41
+ ): void {
42
+ broadcastMessage(
43
+ envelope as unknown as ServerMessage,
44
+ undefined,
45
+ targetClientId ? { targetClientId } : undefined,
46
+ );
47
+ }
48
+
49
+ const DEFAULT_TIMEOUT_MS = 60_000;
50
+
51
+ /** Reason a pending request was rejected by the base. */
52
+ export type HostProxyRejectionReason = "timeout" | "aborted" | "disposed";
53
+
54
+ /**
55
+ * Error thrown by the base when a pending request is rejected via the
56
+ * lifecycle paths (timeout, abort, dispose). Subclasses inspect `reason`
57
+ * to map back to their proxy-specific error / observation shape.
58
+ */
59
+ export class HostProxyRequestError extends AssistantError {
60
+ constructor(
61
+ message: string,
62
+ public readonly reason: HostProxyRejectionReason,
63
+ ) {
64
+ super(message, ErrorCode.INTERNAL_ERROR);
65
+ this.name = "HostProxyRequestError";
66
+ }
67
+ }
68
+
69
+ interface PendingEntry<TResultPayload> {
70
+ resolve: (payload: TResultPayload) => void;
71
+ reject: (err: Error) => void;
72
+ timer: ReturnType<typeof setTimeout>;
73
+ conversationId: string;
74
+ targetClientId?: string;
75
+ /** Detach the abort listener from the caller's signal. No-op when no signal was passed. */
76
+ detachAbort: () => void;
77
+ }
78
+
79
+ export interface HostProxyBaseOptions {
80
+ /** Capability advertised by clients that can service this proxy. */
81
+ capabilityName: HostProxyCapability;
82
+ /** Outbound message `type` for new requests (e.g. `"host_cu_request"`). */
83
+ requestEventName: string;
84
+ /** Outbound message `type` for cancellation (e.g. `"host_cu_cancel"`). */
85
+ cancelEventName: string;
86
+ /** Tag used to identify this proxy's requests in `pendingInteractions`. */
87
+ resultPendingKind: PendingInteraction["kind"];
88
+ /** Per-request timeout. Defaults to 60s. */
89
+ timeoutMs?: number;
90
+ /** Customizable disposed-rejection message (used in test assertions). */
91
+ disposedMessage?: string;
92
+ }
93
+
94
+ export abstract class HostProxyBase<TRequest, TResultPayload> {
95
+ protected pending = new Map<string, PendingEntry<TResultPayload>>();
96
+
97
+ protected readonly capabilityName: HostProxyCapability;
98
+ protected readonly requestEventName: string;
99
+ protected readonly cancelEventName: string;
100
+ protected readonly resultPendingKind: PendingInteraction["kind"];
101
+ protected readonly timeoutMs: number;
102
+ protected readonly disposedMessage: string;
103
+
104
+ constructor(opts: HostProxyBaseOptions) {
105
+ this.capabilityName = opts.capabilityName;
106
+ this.requestEventName = opts.requestEventName;
107
+ this.cancelEventName = opts.cancelEventName;
108
+ this.resultPendingKind = opts.resultPendingKind;
109
+ this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
110
+ this.disposedMessage = opts.disposedMessage ?? "Host proxy disposed";
111
+ }
112
+
113
+ /**
114
+ * Whether a client advertising the configured capability is connected.
115
+ */
116
+ isAvailable(): boolean {
117
+ return (
118
+ assistantEventHub.getMostRecentClientByCapability(this.capabilityName) !=
119
+ null
120
+ );
121
+ }
122
+
123
+ /**
124
+ * Dispatch a request envelope to the connected client and return a
125
+ * promise that resolves when the client responds (via `resolve()`),
126
+ * rejects on timeout/abort/dispose, or rejects synchronously if the
127
+ * broadcast itself fails.
128
+ *
129
+ * `extraFields` is shallow-merged into the broadcast envelope so
130
+ * subclasses can include proxy-specific top-level fields (e.g. CU's
131
+ * `stepNumber` / `reasoning`) without nesting them inside `input`.
132
+ *
133
+ * Named `dispatchRequest` rather than `request` so subclasses are free to
134
+ * expose their own public `request(...)` with a proxy-specific signature
135
+ * (e.g. CU passes `stepNumber` and `reasoning` to its callers).
136
+ */
137
+ protected dispatchRequest(
138
+ toolName: string,
139
+ input: TRequest,
140
+ conversationId: string,
141
+ signal?: AbortSignal,
142
+ extraFields?: Record<string, unknown>,
143
+ targetClientId?: string,
144
+ ): Promise<TResultPayload> {
145
+ const requestId = uuid();
146
+
147
+ return new Promise<TResultPayload>((resolve, reject) => {
148
+ // Declared up-front so onAbort can close over a stable reference once
149
+ // it's wired below.
150
+ let detachAbort: () => void = () => {};
151
+
152
+ const timer = setTimeout(() => {
153
+ this.pending.delete(requestId);
154
+ detachAbort();
155
+ pendingInteractions.resolve(requestId);
156
+ log.warn(
157
+ { requestId, toolName, kind: this.resultPendingKind },
158
+ "Host proxy request timed out",
159
+ );
160
+ reject(new HostProxyRequestError("timeout", "timeout"));
161
+ }, this.timeoutMs);
162
+
163
+ if (signal) {
164
+ const onAbort = () => {
165
+ if (this.pending.has(requestId)) {
166
+ clearTimeout(timer);
167
+ this.pending.delete(requestId);
168
+ detachAbort();
169
+ pendingInteractions.resolve(requestId);
170
+ try {
171
+ broadcastDynamic(
172
+ {
173
+ type: this.cancelEventName,
174
+ requestId,
175
+ conversationId,
176
+ targetClientId,
177
+ },
178
+ targetClientId,
179
+ );
180
+ } catch {
181
+ // Best-effort cancel notification — connection may already be closed.
182
+ }
183
+ reject(new HostProxyRequestError("aborted", "aborted"));
184
+ }
185
+ };
186
+ signal.addEventListener("abort", onAbort, { once: true });
187
+ detachAbort = () => signal.removeEventListener("abort", onAbort);
188
+ }
189
+
190
+ this.pending.set(requestId, {
191
+ resolve,
192
+ reject,
193
+ timer,
194
+ conversationId,
195
+ targetClientId,
196
+ detachAbort,
197
+ });
198
+
199
+ // Register in the global pendingInteractions store so the result-route
200
+ // handler (e.g. POST /v1/host-app-control-result) can look up the
201
+ // request by id and route it back to this proxy. Without this the
202
+ // route silently drops the response — see host-app-control-routes.ts:
203
+ // `if (!peeked || peeked.kind !== "host_app_control") return ...`.
204
+ // (HostCuProxy bypasses dispatchRequest entirely with its own inline
205
+ // request method that registers directly, which is why CU works
206
+ // without this base-level fix.)
207
+ pendingInteractions.register(requestId, {
208
+ conversationId,
209
+ kind: this.resultPendingKind,
210
+ ...(targetClientId != null ? { targetClientId } : {}),
211
+ });
212
+
213
+ try {
214
+ broadcastDynamic(
215
+ {
216
+ type: this.requestEventName,
217
+ requestId,
218
+ conversationId,
219
+ toolName,
220
+ input,
221
+ targetClientId,
222
+ ...(extraFields ?? {}),
223
+ },
224
+ targetClientId,
225
+ );
226
+ } catch (err) {
227
+ clearTimeout(timer);
228
+ this.pending.delete(requestId);
229
+ detachAbort();
230
+ pendingInteractions.resolve(requestId);
231
+ log.warn(
232
+ { requestId, toolName, kind: this.resultPendingKind, err },
233
+ "Host proxy send failed",
234
+ );
235
+ reject(err instanceof Error ? err : new Error(String(err)));
236
+ }
237
+ });
238
+ }
239
+
240
+ /**
241
+ * Resolve a pending request with the client-provided payload. No-op when
242
+ * no entry is registered for `requestId` (late responses after timeout
243
+ * or abort fall through to here).
244
+ */
245
+ resolve(requestId: string, payload: TResultPayload): void {
246
+ const entry = this.pending.get(requestId);
247
+ if (!entry) {
248
+ log.warn(
249
+ { requestId, kind: this.resultPendingKind },
250
+ "No pending host proxy request for response",
251
+ );
252
+ return;
253
+ }
254
+ clearTimeout(entry.timer);
255
+ entry.detachAbort();
256
+ this.pending.delete(requestId);
257
+ entry.resolve(payload);
258
+ }
259
+
260
+ /**
261
+ * Whether `requestId` is still registered as pending. Useful to subclasses
262
+ * that need to reason about the lifecycle in tests.
263
+ */
264
+ hasPendingRequest(requestId: string): boolean {
265
+ return this.pending.has(requestId);
266
+ }
267
+
268
+ /**
269
+ * Reject every pending request and clear the map. Called during graceful
270
+ * shutdown or proxy teardown.
271
+ */
272
+ dispose(): void {
273
+ for (const [requestId, entry] of this.pending) {
274
+ clearTimeout(entry.timer);
275
+ entry.detachAbort();
276
+ pendingInteractions.resolve(requestId);
277
+ try {
278
+ broadcastDynamic(
279
+ {
280
+ type: this.cancelEventName,
281
+ requestId,
282
+ conversationId: entry.conversationId,
283
+ targetClientId: entry.targetClientId,
284
+ },
285
+ entry.targetClientId,
286
+ );
287
+ } catch {
288
+ // Best-effort cancel notification — connection may already be closed.
289
+ }
290
+ entry.reject(new HostProxyRequestError(this.disposedMessage, "disposed"));
291
+ }
292
+ this.pending.clear();
293
+ }
294
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Shared host-proxy skill preactivation registry.
3
+ *
4
+ * Several call sites need to mark host-proxy-backed skills as preactivated
5
+ * for a turn whenever the source interface supports the corresponding
6
+ * `HostProxyCapability`:
7
+ *
8
+ * - `runtime/routes/conversation-routes.ts` (create path, /v1/messages)
9
+ * - `daemon/process-message.ts` (create path, prepareConversationForMessage)
10
+ * - `daemon/conversation-process.ts` `drainSingleMessage` (re-add after dequeue)
11
+ * - `daemon/conversation-process.ts` `drainBatch` (re-add after dequeue)
12
+ *
13
+ * The create paths additionally instantiate the proxy itself; that
14
+ * instantiation logic is per-proxy-class and stays inline at each create
15
+ * site (constructors take different argument shapes — `HostCuProxy()` vs
16
+ * `HostAppControlProxy(conversationId)`). This module owns only the
17
+ * capability-to-skill mapping and the preactivation step. Adding a new
18
+ * host-proxy-backed skill is a one-line registry change here instead of
19
+ * touching all four call sites.
20
+ *
21
+ * Why a registry instead of repeated branches: each new host-proxy-backed
22
+ * skill that ships (e.g. a future `host_focus` capability with a `focus`
23
+ * skill) would otherwise add four near-identical `if (supportsHostProxy(...))
24
+ * conversation.addPreactivatedSkillId("...")` blocks across these files.
25
+ * Centralizing the list makes the contract obvious and prevents drift
26
+ * where one call site re-adds a skill but another forgets to.
27
+ */
28
+
29
+ import type { HostProxyCapability, InterfaceId } from "../channels/types.js";
30
+ import { supportsHostProxy } from "../channels/types.js";
31
+
32
+ /**
33
+ * Subset of Conversation/ProcessConversationContext that
34
+ * `preactivateHostProxySkills` needs. Both `Conversation` and
35
+ * `ProcessConversationContext` satisfy this structurally.
36
+ */
37
+ export interface HostProxyPreactivationTarget {
38
+ addPreactivatedSkillId(id: string): void;
39
+ }
40
+
41
+ /**
42
+ * Registry mapping each host-proxy capability to the skill that must be
43
+ * preactivated when that capability is supported by the source interface.
44
+ *
45
+ * Keep this list in sync with `HostProxyCapability` for any capability that
46
+ * has a corresponding bundled skill.
47
+ *
48
+ * Capabilities NOT listed here:
49
+ * - `host_bash`, `host_file` — these are surfaced as built-in tools rather
50
+ * than skills, so there is nothing to preactivate.
51
+ * - `host_browser` — the browser proxy is provisioned via the assistant
52
+ * event hub for chrome-extension and its skill projection is governed by
53
+ * a different code path (`host-browser-proxy.ts`).
54
+ */
55
+ export const HOST_PROXY_SKILL_PREACTIVATIONS: ReadonlyArray<{
56
+ capability: HostProxyCapability;
57
+ skillId: string;
58
+ }> = [
59
+ { capability: "host_cu", skillId: "computer-use" },
60
+ { capability: "host_app_control", skillId: "app-control" },
61
+ ];
62
+
63
+ /**
64
+ * Preactivate every host-proxy-backed skill that the given source interface
65
+ * supports. No-op when `sourceInterface` is undefined.
66
+ *
67
+ * Callers are responsible for any additional gating (e.g. only preactivating
68
+ * when the conversation is idle vs. when re-adding after dequeue), since
69
+ * those constraints differ across create vs. drain paths. This helper just
70
+ * iterates the registry and dispatches.
71
+ */
72
+ export function preactivateHostProxySkills(
73
+ conversation: HostProxyPreactivationTarget,
74
+ sourceInterface: InterfaceId | undefined,
75
+ ): void {
76
+ if (!sourceInterface) return;
77
+ for (const { capability, skillId } of HOST_PROXY_SKILL_PREACTIVATIONS) {
78
+ if (supportsHostProxy(sourceInterface, capability)) {
79
+ conversation.addPreactivatedSkillId(skillId);
80
+ }
81
+ }
82
+ }