@vellumai/assistant 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (989) hide show
  1. package/ARCHITECTURE.md +38 -56
  2. package/Dockerfile +2 -0
  3. package/README.md +3 -4
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +88 -142
  5. package/bun.lock +29 -26
  6. package/docs/architecture/security.md +38 -16
  7. package/docs/plugins.md +7 -9
  8. package/knip.json +2 -0
  9. package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
  10. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +39 -1
  11. package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
  12. package/node_modules/@vellumai/service-contracts/package.json +2 -0
  13. package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
  14. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
  15. package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
  16. package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
  17. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
  18. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
  19. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +9 -5
  20. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
  21. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
  22. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
  23. package/node_modules/@vellumai/slack-text/bun.lock +24 -0
  24. package/node_modules/@vellumai/slack-text/package.json +18 -0
  25. package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
  26. package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
  27. package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
  28. package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
  29. package/node_modules/@vellumai/twilio-client/package.json +18 -0
  30. package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
  31. package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
  32. package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
  33. package/openapi.yaml +869 -129
  34. package/package.json +8 -3
  35. package/scripts/generate-openapi.ts +16 -111
  36. package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
  37. package/src/__tests__/anthropic-provider.test.ts +56 -13
  38. package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
  39. package/src/__tests__/app-bundler.test.ts +170 -1
  40. package/src/__tests__/app-control-flow.test.ts +374 -0
  41. package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
  42. package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
  43. package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
  44. package/src/__tests__/app-conversation-ids.test.ts +151 -0
  45. package/src/__tests__/app-executors.test.ts +30 -43
  46. package/src/__tests__/approval-cascade.test.ts +0 -15
  47. package/src/__tests__/approval-routes-http.test.ts +29 -23
  48. package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
  49. package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
  50. package/src/__tests__/assistant-event-hub.test.ts +235 -79
  51. package/src/__tests__/assistant-event.test.ts +10 -5
  52. package/src/__tests__/assistant-events-sse-hardening.test.ts +44 -17
  53. package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -36
  54. package/src/__tests__/background-shell-host-bash.test.ts +46 -56
  55. package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
  56. package/src/__tests__/btw-routes.test.ts +13 -4
  57. package/src/__tests__/call-controller.test.ts +50 -2
  58. package/src/__tests__/call-domain.test.ts +0 -2
  59. package/src/__tests__/call-routes-http.test.ts +0 -2
  60. package/src/__tests__/call-site-routing-provider.test.ts +193 -0
  61. package/src/__tests__/channel-approval-routes.test.ts +10 -296
  62. package/src/__tests__/channel-approvals.test.ts +25 -17
  63. package/src/__tests__/channel-guardian.test.ts +100 -146
  64. package/src/__tests__/channel-readiness-service.test.ts +59 -1
  65. package/src/__tests__/checker.test.ts +23 -38
  66. package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
  67. package/src/__tests__/compaction-events.test.ts +2 -0
  68. package/src/__tests__/config-loader-backfill.test.ts +90 -155
  69. package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
  70. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  71. package/src/__tests__/config-schema.test.ts +6 -48
  72. package/src/__tests__/config-set-platform-guard.test.ts +48 -4
  73. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +2 -2
  74. package/src/__tests__/config-watcher.test.ts +14 -2
  75. package/src/__tests__/connection-policy.test.ts +1 -52
  76. package/src/__tests__/contacts-write.test.ts +2 -64
  77. package/src/__tests__/context-image-dimensions.test.ts +1 -1
  78. package/src/__tests__/context-search-memory-source.test.ts +120 -1
  79. package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
  80. package/src/__tests__/context-search-pkb-source.test.ts +49 -0
  81. package/src/__tests__/context-search-workspace-source.test.ts +9 -22
  82. package/src/__tests__/context-window-manager.test.ts +46 -0
  83. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
  84. package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
  85. package/src/__tests__/conversation-agent-loop.test.ts +980 -13
  86. package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
  87. package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
  88. package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
  89. package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
  90. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
  91. package/src/__tests__/conversation-history-web-search.test.ts +4 -3
  92. package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
  93. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  94. package/src/__tests__/conversation-lifecycle.test.ts +40 -4
  95. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
  96. package/src/__tests__/conversation-process-callsite.test.ts +79 -2
  97. package/src/__tests__/conversation-queue.test.ts +3 -8
  98. package/src/__tests__/conversation-routes-disk-view.test.ts +7 -161
  99. package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -104
  100. package/src/__tests__/conversation-routes-slash-commands.test.ts +76 -66
  101. package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
  102. package/src/__tests__/conversation-slash-commands.test.ts +24 -8
  103. package/src/__tests__/conversation-slash-queue.test.ts +2 -0
  104. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  105. package/src/__tests__/conversation-starter-routes.test.ts +79 -2
  106. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
  107. package/src/__tests__/conversation-surfaces-app-control.test.ts +317 -0
  108. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
  109. package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
  110. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
  111. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
  112. package/src/__tests__/conversation-usage.test.ts +253 -3
  113. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
  114. package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
  115. package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
  116. package/src/__tests__/credential-health-service.test.ts +68 -0
  117. package/src/__tests__/credential-security-e2e.test.ts +4 -3
  118. package/src/__tests__/credential-security-invariants.test.ts +1 -5
  119. package/src/__tests__/credential-token-resolver.test.ts +180 -0
  120. package/src/__tests__/credentials-cli.test.ts +5 -12
  121. package/src/__tests__/cu-unified-flow.test.ts +206 -27
  122. package/src/__tests__/daemon-assistant-events.test.ts +34 -21
  123. package/src/__tests__/daemon-credential-client.test.ts +102 -17
  124. package/src/__tests__/db-connection-isolation.test.ts +125 -0
  125. package/src/__tests__/db-migration-rollback.test.ts +101 -0
  126. package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
  127. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
  128. package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
  129. package/src/__tests__/document-conversations.test.ts +332 -0
  130. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  131. package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
  132. package/src/__tests__/emit-event-signal.test.ts +4 -6
  133. package/src/__tests__/events-client-registration.test.ts +193 -49
  134. package/src/__tests__/filing-service.test.ts +58 -7
  135. package/src/__tests__/first-greeting.test.ts +156 -150
  136. package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
  137. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  138. package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
  139. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  140. package/src/__tests__/guardian-dispatch.test.ts +1 -1
  141. package/src/__tests__/guardian-grant-minting.test.ts +7 -2
  142. package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
  143. package/src/__tests__/guardian-routing-state.test.ts +1 -1
  144. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
  145. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +30 -11
  146. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -84
  147. package/src/__tests__/headless-browser-mode.test.ts +4 -9
  148. package/src/__tests__/headless-browser-navigate.test.ts +21 -20
  149. package/src/__tests__/heartbeat-service.test.ts +1007 -8
  150. package/src/__tests__/helpers/call-route-handler.ts +7 -1
  151. package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
  152. package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
  153. package/src/__tests__/host-app-control-proxy.test.ts +602 -0
  154. package/src/__tests__/host-app-control-routes.test.ts +263 -0
  155. package/src/__tests__/host-bash-proxy.test.ts +270 -147
  156. package/src/__tests__/host-bash-routes.test.ts +294 -0
  157. package/src/__tests__/host-browser-proxy.test.ts +126 -198
  158. package/src/__tests__/host-browser-routes.test.ts +50 -54
  159. package/src/__tests__/host-cu-proxy.test.ts +78 -144
  160. package/src/__tests__/host-cu-routes-targeted.test.ts +300 -0
  161. package/src/__tests__/host-file-edit-tool.test.ts +47 -1
  162. package/src/__tests__/host-file-proxy-targeted.test.ts +339 -0
  163. package/src/__tests__/host-file-proxy.test.ts +62 -122
  164. package/src/__tests__/host-file-read-tool.test.ts +59 -21
  165. package/src/__tests__/host-file-routes-targeted.test.ts +262 -0
  166. package/src/__tests__/host-file-write-tool.test.ts +42 -1
  167. package/src/__tests__/host-proxy-base.test.ts +312 -0
  168. package/src/__tests__/host-shell-tool.test.ts +53 -70
  169. package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
  170. package/src/__tests__/host-transfer-proxy-targeted.test.ts +583 -0
  171. package/src/__tests__/host-transfer-proxy.test.ts +145 -56
  172. package/src/__tests__/host-transfer-routes-targeted.test.ts +447 -0
  173. package/src/__tests__/http-user-message-parity.test.ts +1 -6
  174. package/src/__tests__/identity-intro-cache.test.ts +29 -0
  175. package/src/__tests__/identity-routes.test.ts +103 -1
  176. package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
  177. package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
  178. package/src/__tests__/injector-chain.test.ts +10 -5
  179. package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
  180. package/src/__tests__/inline-command-runner.test.ts +0 -67
  181. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -13
  182. package/src/__tests__/install-skill-routing.test.ts +1 -13
  183. package/src/__tests__/integration-status.test.ts +85 -5
  184. package/src/__tests__/intent-routing.test.ts +0 -1
  185. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
  186. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
  187. package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
  188. package/src/__tests__/llm-catalog-parity.test.ts +90 -0
  189. package/src/__tests__/llm-context-resolution.test.ts +180 -0
  190. package/src/__tests__/llm-resolver.test.ts +80 -12
  191. package/src/__tests__/llm-usage-store.test.ts +269 -4
  192. package/src/__tests__/log-export-routes.test.ts +89 -0
  193. package/src/__tests__/managed-profile-guard.test.ts +225 -0
  194. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -11
  195. package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
  196. package/src/__tests__/mcp-auth-routes.test.ts +197 -0
  197. package/src/__tests__/mcp-cli.test.ts +338 -2
  198. package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
  199. package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
  200. package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
  201. package/src/__tests__/migration-export-http.test.ts +33 -26
  202. package/src/__tests__/migration-export-streaming.test.ts +18 -10
  203. package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
  204. package/src/__tests__/migration-import-commit-http.test.ts +172 -21
  205. package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
  206. package/src/__tests__/migration-import-from-url.test.ts +20 -6
  207. package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
  208. package/src/__tests__/migration-parity-persistence.test.ts +62 -25
  209. package/src/__tests__/migration-transport.test.ts +115 -23
  210. package/src/__tests__/migration-validate-http.test.ts +105 -80
  211. package/src/__tests__/migration-wizard.test.ts +133 -27
  212. package/src/__tests__/mock-gateway-ipc.ts +1 -0
  213. package/src/__tests__/non-member-access-request.test.ts +1 -1
  214. package/src/__tests__/notification-guardian-path.test.ts +1 -1
  215. package/src/__tests__/oauth-cli.test.ts +0 -2
  216. package/src/__tests__/oauth-store.test.ts +19 -0
  217. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
  218. package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
  219. package/src/__tests__/platform-bash-auto-approve.test.ts +26 -21
  220. package/src/__tests__/prechat-onboarding-contract.test.ts +34 -8
  221. package/src/__tests__/pricing.test.ts +68 -4
  222. package/src/__tests__/process-message-background-slack.test.ts +333 -0
  223. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  224. package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
  225. package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
  226. package/src/__tests__/provider-usage-tracking.test.ts +208 -0
  227. package/src/__tests__/public-ingress-urls.test.ts +97 -0
  228. package/src/__tests__/reaction-persistence.test.ts +9 -6
  229. package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
  230. package/src/__tests__/recording-handler.test.ts +64 -81
  231. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
  232. package/src/__tests__/relay-server.test.ts +18 -13
  233. package/src/__tests__/require-fresh-approval.test.ts +13 -23
  234. package/src/__tests__/retry-backoff.test.ts +87 -0
  235. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  236. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  237. package/src/__tests__/runtime-events-sse.test.ts +13 -18
  238. package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
  239. package/src/__tests__/schedule-retry.test.ts +715 -0
  240. package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
  241. package/src/__tests__/search-skills-unified.test.ts +9 -15
  242. package/src/__tests__/secret-ingress-cli.test.ts +2 -5
  243. package/src/__tests__/secret-ingress-http.test.ts +1 -4
  244. package/src/__tests__/secret-onetime-send.test.ts +4 -2
  245. package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
  246. package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
  247. package/src/__tests__/secret-response-routing.test.ts +29 -15
  248. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
  249. package/src/__tests__/secret-scanner.test.ts +2 -545
  250. package/src/__tests__/send-endpoint-busy.test.ts +12 -24
  251. package/src/__tests__/settings-routes.test.ts +1 -1
  252. package/src/__tests__/shell-credential-ref.test.ts +0 -8
  253. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -57
  254. package/src/__tests__/skill-feature-flags.test.ts +43 -41
  255. package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
  256. package/src/__tests__/skill-load-inline-command.test.ts +0 -51
  257. package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
  258. package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
  259. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -12
  260. package/src/__tests__/skill-tool-factory.test.ts +97 -0
  261. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
  262. package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
  263. package/src/__tests__/slack-channel-config.test.ts +9 -14
  264. package/src/__tests__/slack-inbound-verification.test.ts +1 -62
  265. package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
  266. package/src/__tests__/subagent-manager-notify.test.ts +70 -70
  267. package/src/__tests__/subagent-notify-parent.test.ts +80 -83
  268. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
  269. package/src/__tests__/system-prompt.test.ts +115 -14
  270. package/src/__tests__/telegram-config.test.ts +0 -1
  271. package/src/__tests__/terminal-tools.test.ts +0 -89
  272. package/src/__tests__/test-preload.ts +8 -0
  273. package/src/__tests__/thread-backfill.test.ts +945 -31
  274. package/src/__tests__/tool-approval-handler.test.ts +3 -4
  275. package/src/__tests__/tool-audit-listener.test.ts +48 -0
  276. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
  277. package/src/__tests__/tool-execute-pipeline.test.ts +0 -7
  278. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -17
  279. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
  280. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -8
  281. package/src/__tests__/tool-executor.test.ts +12 -20
  282. package/src/__tests__/tool-metrics-listener.test.ts +0 -35
  283. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  284. package/src/__tests__/tool-trace-listener.test.ts +0 -17
  285. package/src/__tests__/transfer-progress-screen.test.ts +63 -26
  286. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
  287. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
  288. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  289. package/src/__tests__/tts-catalog-parity.test.ts +16 -5
  290. package/src/__tests__/twilio-config.test.ts +3 -16
  291. package/src/__tests__/twilio-routes.test.ts +3 -5
  292. package/src/__tests__/twilio-validation.test.ts +93 -0
  293. package/src/__tests__/usage-attribution.test.ts +247 -0
  294. package/src/__tests__/usage-cli.test.ts +143 -0
  295. package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
  296. package/src/__tests__/usage-routes.test.ts +150 -0
  297. package/src/__tests__/validation-results-screen.test.ts +39 -16
  298. package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
  299. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +47 -138
  300. package/src/__tests__/verification-control-plane-policy.test.ts +6 -11
  301. package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
  302. package/src/__tests__/voice-session-bridge.test.ts +5 -5
  303. package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
  304. package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
  305. package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
  306. package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
  307. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
  308. package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
  309. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
  310. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
  311. package/src/acp/index.ts +0 -15
  312. package/src/acp/session-manager.ts +37 -34
  313. package/src/agent/loop.ts +16 -1
  314. package/src/approvals/AGENTS.md +4 -0
  315. package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
  316. package/src/approvals/guardian-request-resolvers.ts +10 -2
  317. package/src/backup/__tests__/paths.test.ts +0 -22
  318. package/src/backup/__tests__/restore.test.ts +94 -177
  319. package/src/backup/paths.ts +2 -15
  320. package/src/backup/restore.ts +107 -231
  321. package/src/browser-session/events.ts +0 -9
  322. package/src/bundler/app-bundler.ts +51 -3
  323. package/src/calls/call-store.ts +1 -34
  324. package/src/calls/guardian-question-copy.ts +0 -108
  325. package/src/calls/relay-server.ts +4 -68
  326. package/src/calls/twilio-config.ts +2 -17
  327. package/src/calls/twilio-rest.ts +31 -141
  328. package/src/calls/twilio-routes.ts +12 -13
  329. package/src/calls/voice-session-bridge.ts +7 -38
  330. package/src/channels/types.ts +8 -42
  331. package/src/cli/commands/__tests__/backup.test.ts +6 -277
  332. package/src/cli/commands/__tests__/cache.test.ts +152 -5
  333. package/src/cli/commands/__tests__/gateway.test.ts +288 -0
  334. package/src/cli/commands/__tests__/memory-v2.test.ts +18 -28
  335. package/src/cli/commands/__tests__/trust.test.ts +21 -387
  336. package/src/cli/commands/__tests__/webhooks.test.ts +0 -1
  337. package/src/cli/commands/backup.ts +6 -331
  338. package/src/cli/commands/cache-fs.ts +8 -0
  339. package/src/cli/commands/cache.ts +153 -82
  340. package/src/cli/commands/clients.ts +64 -7
  341. package/src/cli/commands/completions.ts +3 -3
  342. package/src/cli/commands/contacts.ts +304 -76
  343. package/src/cli/commands/conversations.ts +2 -5
  344. package/src/cli/commands/credentials.ts +15 -7
  345. package/src/cli/commands/domain.ts +66 -15
  346. package/src/cli/commands/gateway.ts +183 -0
  347. package/src/cli/commands/keys.ts +13 -7
  348. package/src/cli/commands/mcp.ts +116 -156
  349. package/src/cli/commands/memory-v2.ts +320 -53
  350. package/src/cli/commands/oauth/shared.ts +2 -29
  351. package/src/cli/commands/pending.ts +102 -0
  352. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
  353. package/src/cli/commands/platform/__tests__/connect.test.ts +0 -2
  354. package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -2
  355. package/src/cli/commands/platform/__tests__/status.test.ts +13 -15
  356. package/src/cli/commands/platform/disconnect.ts +5 -4
  357. package/src/cli/commands/platform/index.ts +0 -18
  358. package/src/cli/commands/skills.ts +77 -35
  359. package/src/cli/commands/trust.ts +70 -430
  360. package/src/cli/commands/usage.ts +25 -16
  361. package/src/cli/lib/daemon-credential-client.ts +115 -19
  362. package/src/cli/program.ts +4 -0
  363. package/src/cli.ts +0 -21
  364. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  365. package/src/config/assistant-feature-flags.ts +67 -10
  366. package/src/config/bundled-skills/acp/SKILL.md +6 -0
  367. package/src/config/bundled-skills/acp/TOOLS.json +1 -22
  368. package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
  369. package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
  370. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
  371. package/src/config/bundled-skills/app-control/SKILL.md +75 -0
  372. package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
  373. package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
  374. package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
  375. package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
  376. package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
  377. package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
  378. package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
  379. package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
  380. package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
  381. package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
  382. package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
  383. package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
  384. package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
  385. package/src/config/bundled-skills/document/TOOLS.json +0 -8
  386. package/src/config/bundled-skills/followups/TOOLS.json +0 -12
  387. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  388. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
  389. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
  390. package/src/config/bundled-skills/messaging/TOOLS.json +14 -44
  391. package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
  392. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +19 -4
  393. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
  394. package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
  395. package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
  396. package/src/config/bundled-skills/settings/SKILL.md +4 -0
  397. package/src/config/bundled-skills/settings/TOOLS.json +0 -12
  398. package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
  399. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
  400. package/src/config/bundled-skills/subagent/SKILL.md +6 -2
  401. package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
  402. package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
  403. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
  404. package/src/config/bundled-tool-registry.ts +21 -0
  405. package/src/config/env-registry.ts +12 -4
  406. package/src/config/env.ts +22 -26
  407. package/src/config/feature-flag-registry.json +40 -152
  408. package/src/config/llm-callsite-catalog.ts +12 -0
  409. package/src/config/llm-context-resolution.ts +80 -0
  410. package/src/config/llm-resolver.ts +58 -22
  411. package/src/config/loader.ts +76 -102
  412. package/src/config/sanitize-for-transfer.ts +2 -0
  413. package/src/config/schema.ts +2 -158
  414. package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
  415. package/src/config/schemas/__tests__/memory-v2.test.ts +8 -4
  416. package/src/config/schemas/call-site-catalog.ts +271 -0
  417. package/src/config/schemas/calls.ts +5 -14
  418. package/src/config/schemas/heartbeat.ts +63 -0
  419. package/src/config/schemas/inference.ts +1 -1
  420. package/src/config/schemas/ingress.ts +11 -7
  421. package/src/config/schemas/llm.ts +34 -11
  422. package/src/config/schemas/memory-lifecycle.ts +77 -24
  423. package/src/config/schemas/memory-retrieval.ts +2 -2
  424. package/src/config/schemas/memory-v2.ts +57 -4
  425. package/src/config/schemas/platform.ts +6 -0
  426. package/src/config/schemas/security.ts +1 -42
  427. package/src/config/schemas/services.ts +7 -21
  428. package/src/config/schemas/skills.ts +5 -11
  429. package/src/config/schemas/tts.ts +1 -1
  430. package/src/config/seed-inference-profiles.ts +117 -0
  431. package/src/config/skills.ts +0 -90
  432. package/src/config/types.ts +3 -6
  433. package/src/contacts/contact-store.ts +0 -47
  434. package/src/contacts/contacts-write.ts +1 -132
  435. package/src/context/window-manager.ts +43 -5
  436. package/src/credential-execution/feature-gates.ts +10 -10
  437. package/src/credential-execution/process-manager.ts +46 -51
  438. package/src/credential-health/credential-health-service.ts +21 -16
  439. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
  440. package/src/daemon/__tests__/conversation-tool-setup.test.ts +126 -5
  441. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
  442. package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
  443. package/src/daemon/config-watcher.ts +4 -3
  444. package/src/daemon/connection-policy.ts +1 -26
  445. package/src/daemon/conversation-agent-loop-handlers.ts +74 -7
  446. package/src/daemon/conversation-agent-loop.ts +309 -64
  447. package/src/daemon/conversation-history.ts +8 -8
  448. package/src/daemon/conversation-launch.ts +20 -135
  449. package/src/daemon/conversation-lifecycle.ts +8 -1
  450. package/src/daemon/conversation-messaging.ts +1 -0
  451. package/src/daemon/conversation-process.ts +97 -172
  452. package/src/daemon/conversation-runtime-assembly.ts +219 -76
  453. package/src/daemon/conversation-slash.ts +47 -5
  454. package/src/daemon/conversation-store.ts +7 -31
  455. package/src/daemon/conversation-surfaces.ts +144 -29
  456. package/src/daemon/conversation-tool-setup.ts +18 -87
  457. package/src/daemon/conversation-usage.ts +36 -0
  458. package/src/daemon/conversation.ts +134 -231
  459. package/src/daemon/daemon-control.ts +3 -71
  460. package/src/daemon/daemon-skill-host.ts +8 -11
  461. package/src/daemon/dictation-profile-store.ts +2 -26
  462. package/src/daemon/doordash-steps.ts +1 -1
  463. package/src/daemon/first-greeting.ts +44 -156
  464. package/src/daemon/handlers/config-channels.ts +12 -12
  465. package/src/daemon/handlers/config-ingress.ts +4 -165
  466. package/src/daemon/handlers/config-model.ts +1 -1
  467. package/src/daemon/handlers/config-voice.ts +0 -42
  468. package/src/daemon/handlers/conversations.ts +11 -190
  469. package/src/daemon/handlers/recording.ts +26 -158
  470. package/src/daemon/handlers/shared.ts +27 -72
  471. package/src/daemon/handlers/skills.ts +42 -93
  472. package/src/daemon/host-app-control-proxy.ts +293 -0
  473. package/src/daemon/host-bash-proxy.ts +124 -92
  474. package/src/daemon/host-browser-proxy.ts +111 -88
  475. package/src/daemon/host-cu-proxy.ts +100 -104
  476. package/src/daemon/host-file-proxy.ts +136 -91
  477. package/src/daemon/host-proxy-base.ts +294 -0
  478. package/src/daemon/host-proxy-preactivation.ts +82 -0
  479. package/src/daemon/host-transfer-proxy.ts +303 -147
  480. package/src/daemon/lifecycle.ts +164 -132
  481. package/src/daemon/message-protocol.ts +3 -8
  482. package/src/daemon/message-types/contacts.ts +23 -1
  483. package/src/daemon/message-types/conversations.ts +18 -8
  484. package/src/daemon/message-types/host-app-control.ts +150 -0
  485. package/src/daemon/message-types/host-bash.ts +5 -0
  486. package/src/daemon/message-types/host-cu.ts +3 -0
  487. package/src/daemon/message-types/host-file.ts +5 -0
  488. package/src/daemon/message-types/host-transfer.ts +4 -0
  489. package/src/daemon/message-types/messages.ts +10 -9
  490. package/src/daemon/message-types/schedules.ts +8 -3
  491. package/src/daemon/message-types/skills.ts +2 -2
  492. package/src/daemon/message-types/workspace.ts +1 -1
  493. package/src/daemon/process-message.ts +119 -239
  494. package/src/daemon/server.ts +13 -462
  495. package/src/daemon/shutdown-handlers.ts +2 -5
  496. package/src/daemon/tool-setup-types.ts +51 -0
  497. package/src/daemon/tool-side-effects.ts +126 -108
  498. package/src/daemon/trust-context.ts +13 -0
  499. package/src/daemon/wake-target-adapter.ts +4 -9
  500. package/src/events/domain-events.ts +0 -8
  501. package/src/events/tool-audit-listener.ts +5 -2
  502. package/src/events/tool-domain-event-publisher.ts +0 -10
  503. package/src/events/tool-metrics-listener.ts +0 -17
  504. package/src/events/tool-trace-listener.ts +0 -14
  505. package/src/filing/filing-service.ts +13 -1
  506. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +21 -9
  507. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +216 -0
  508. package/src/heartbeat/heartbeat-run-store.ts +236 -0
  509. package/src/heartbeat/heartbeat-service.ts +303 -54
  510. package/src/home/__tests__/feed-writer.test.ts +0 -4
  511. package/src/home/__tests__/post-connect-feed.test.ts +99 -0
  512. package/src/home/__tests__/relationship-state-writer.test.ts +41 -9
  513. package/src/home/__tests__/suggested-prompts.test.ts +89 -0
  514. package/src/home/feed-writer.ts +1 -2
  515. package/src/home/post-connect-feed.ts +68 -0
  516. package/src/home/relationship-state-writer.ts +33 -95
  517. package/src/home/suggested-prompts.ts +46 -10
  518. package/src/inbound/public-ingress-urls.ts +32 -34
  519. package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
  520. package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
  521. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
  522. package/src/ipc/assistant-server.ts +17 -11
  523. package/src/ipc/cli-client.ts +32 -1
  524. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
  525. package/src/ipc/routes/route-adapter.ts +1 -1
  526. package/src/ipc/routes/trust-rules.test.ts +0 -95
  527. package/src/ipc/skill-ipc-types.ts +41 -0
  528. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
  529. package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
  530. package/src/ipc/skill-routes/events.ts +12 -23
  531. package/src/ipc/skill-routes/identity.ts +4 -17
  532. package/src/ipc/skill-routes/index.ts +1 -1
  533. package/src/ipc/skill-server.ts +6 -39
  534. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
  535. package/src/live-voice/live-voice-metrics.ts +10 -10
  536. package/src/live-voice/protocol.ts +4 -13
  537. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
  538. package/src/mcp/manager.ts +0 -5
  539. package/src/mcp/mcp-auth-orchestrator.ts +213 -0
  540. package/src/mcp/mcp-auth-state.ts +133 -0
  541. package/src/mcp/mcp-oauth-provider.ts +19 -0
  542. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
  543. package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
  544. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
  545. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  546. package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
  547. package/src/memory/anisotropy.test.ts +247 -0
  548. package/src/memory/anisotropy.ts +443 -0
  549. package/src/memory/app-git-service.ts +0 -32
  550. package/src/memory/app-store.ts +154 -0
  551. package/src/memory/attachments-store.ts +6 -0
  552. package/src/memory/auto-analysis-constants.ts +17 -0
  553. package/src/memory/auto-analysis-guard.ts +5 -15
  554. package/src/memory/canonical-guardian-store.ts +7 -7
  555. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
  556. package/src/memory/context-search/agent-protocol.ts +6 -6
  557. package/src/memory/context-search/agent-runner.ts +32 -7
  558. package/src/memory/context-search/sources/memory-v2.ts +590 -0
  559. package/src/memory/context-search/sources/memory.ts +5 -0
  560. package/src/memory/context-search/sources/pkb.ts +10 -1
  561. package/src/memory/context-search/sources/workspace.ts +3 -2
  562. package/src/memory/conversation-crud.ts +30 -5
  563. package/src/memory/conversation-disk-view.ts +1 -5
  564. package/src/memory/conversation-key-store.ts +2 -15
  565. package/src/memory/conversation-starter-checkpoints.ts +63 -0
  566. package/src/memory/db-connection.ts +62 -0
  567. package/src/memory/db-init.ts +18 -0
  568. package/src/memory/embedding-backend.ts +12 -42
  569. package/src/memory/embedding-gemini.ts +0 -2
  570. package/src/memory/embedding-local.ts +6 -6
  571. package/src/memory/embedding-ollama.ts +6 -6
  572. package/src/memory/embedding-openai.ts +6 -6
  573. package/src/memory/embedding-types.ts +21 -0
  574. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +49 -8
  575. package/src/memory/graph/conversation-graph-memory.ts +35 -36
  576. package/src/memory/graph/graph-search.ts +8 -0
  577. package/src/memory/graph/injection.test.ts +2 -2
  578. package/src/memory/graph/injection.ts +1 -1
  579. package/src/memory/graph/retriever.ts +28 -0
  580. package/src/memory/graph/tools.ts +1 -1
  581. package/src/memory/guardian-action-store.ts +0 -83
  582. package/src/memory/guardian-approvals.ts +0 -48
  583. package/src/memory/indexer.ts +1 -15
  584. package/src/memory/job-handlers/conversation-starters.ts +36 -53
  585. package/src/memory/job-utils.ts +0 -6
  586. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
  587. package/src/memory/jobs/embed-concept-page.ts +28 -2
  588. package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
  589. package/src/memory/jobs-store.ts +66 -23
  590. package/src/memory/jobs-worker.ts +114 -79
  591. package/src/memory/llm-request-log-store.ts +0 -41
  592. package/src/memory/llm-usage-store.ts +129 -43
  593. package/src/memory/memory-v2-activation-log-store.ts +115 -0
  594. package/src/memory/migrations/233-document-conversations.ts +54 -0
  595. package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
  596. package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
  597. package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
  598. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
  599. package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
  600. package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
  601. package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
  602. package/src/memory/migrations/index.ts +19 -0
  603. package/src/memory/migrations/registry.ts +32 -0
  604. package/src/memory/pkb/pkb-search.ts +7 -0
  605. package/src/memory/qdrant-client.ts +50 -20
  606. package/src/memory/raw-query.ts +2 -68
  607. package/src/memory/schema/conversations.ts +7 -0
  608. package/src/memory/schema/infrastructure.ts +40 -0
  609. package/src/memory/search/semantic.ts +12 -16
  610. package/src/memory/sparse-tokenize.ts +49 -0
  611. package/src/memory/tool-usage-store.ts +2 -0
  612. package/src/memory/usage-buckets.ts +40 -1
  613. package/src/memory/usage-grouped-buckets.ts +127 -0
  614. package/src/memory/v2/__tests__/activation.test.ts +361 -180
  615. package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
  616. package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
  617. package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
  618. package/src/memory/v2/__tests__/injection.test.ts +424 -33
  619. package/src/memory/v2/__tests__/migration.test.ts +64 -36
  620. package/src/memory/v2/__tests__/page-store.test.ts +191 -8
  621. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
  622. package/src/memory/v2/__tests__/sim.test.ts +166 -6
  623. package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
  624. package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  625. package/src/memory/v2/__tests__/static-context.test.ts +152 -0
  626. package/src/memory/v2/activation.ts +215 -163
  627. package/src/memory/v2/backfill-jobs.ts +15 -100
  628. package/src/memory/v2/consolidation-job.ts +17 -17
  629. package/src/memory/v2/constants.ts +7 -0
  630. package/src/memory/v2/edge-index.ts +191 -0
  631. package/src/memory/v2/injection.ts +241 -84
  632. package/src/memory/v2/migration.ts +57 -64
  633. package/src/memory/v2/now-text.ts +2 -3
  634. package/src/memory/v2/page-store.ts +168 -31
  635. package/src/memory/v2/prompts/consolidation.ts +385 -88
  636. package/src/memory/v2/prompts/sweep.ts +3 -3
  637. package/src/memory/v2/qdrant.ts +99 -1
  638. package/src/memory/v2/sim.ts +126 -16
  639. package/src/memory/v2/skill-qdrant.ts +12 -3
  640. package/src/memory/v2/skill-store.ts +71 -8
  641. package/src/memory/v2/sparse-bm25.ts +245 -0
  642. package/src/memory/v2/static-context.ts +63 -0
  643. package/src/memory/v2/types.ts +10 -20
  644. package/src/memory/validation.ts +0 -11
  645. package/src/messaging/draft-store.ts +0 -6
  646. package/src/messaging/provider-types.ts +8 -0
  647. package/src/messaging/provider.ts +7 -0
  648. package/src/messaging/providers/gmail/client.ts +1 -121
  649. package/src/messaging/providers/gmail/types.ts +0 -49
  650. package/src/messaging/providers/outlook/client.ts +0 -73
  651. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
  652. package/src/messaging/providers/slack/adapter.ts +123 -52
  653. package/src/messaging/providers/slack/backfill.test.ts +95 -6
  654. package/src/messaging/providers/slack/backfill.ts +89 -11
  655. package/src/messaging/providers/slack/client.ts +10 -124
  656. package/src/messaging/providers/slack/message-metadata.ts +12 -2
  657. package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
  658. package/src/messaging/providers/slack/render-transcript.ts +126 -25
  659. package/src/messaging/providers/slack/types.ts +1 -32
  660. package/src/notifications/README.md +10 -10
  661. package/src/notifications/broadcaster.ts +1 -1
  662. package/src/notifications/guardian-question-mode.ts +5 -5
  663. package/src/oauth/connect-orchestrator.ts +4 -0
  664. package/src/oauth/connection-resolver.test.ts +8 -0
  665. package/src/oauth/connection-resolver.ts +8 -16
  666. package/src/oauth/credential-token-resolver.ts +95 -0
  667. package/src/oauth/manual-token-connection.ts +26 -34
  668. package/src/oauth/oauth-store.ts +6 -4
  669. package/src/outbound-proxy/certs.ts +0 -7
  670. package/src/outbound-proxy/index.ts +1 -59
  671. package/src/outbound-proxy/logging.ts +1 -1
  672. package/src/outbound-proxy/policy.ts +6 -5
  673. package/src/outbound-proxy/router.ts +2 -1
  674. package/src/permissions/approval-policy.test.ts +6 -275
  675. package/src/permissions/approval-policy.ts +0 -51
  676. package/src/permissions/approval-provenance.test.ts +184 -0
  677. package/src/permissions/approval-provenance.ts +70 -0
  678. package/src/permissions/checker.test.ts +0 -1
  679. package/src/permissions/checker.ts +7 -18
  680. package/src/permissions/gateway-threshold-reader.ts +6 -1
  681. package/src/permissions/prompter.ts +43 -3
  682. package/src/permissions/secret-prompter.ts +25 -48
  683. package/src/permissions/types.ts +33 -0
  684. package/src/permissions/workspace-policy.ts +0 -5
  685. package/src/platform/sync-identity.ts +0 -8
  686. package/src/plugins/defaults/injectors.ts +69 -2
  687. package/src/plugins/defaults/overflow-reduce.ts +3 -2
  688. package/src/plugins/types.ts +8 -0
  689. package/src/prompts/bootstrap-cleanup.ts +27 -0
  690. package/src/prompts/system-prompt.ts +37 -88
  691. package/src/prompts/templates/BOOTSTRAP.md +52 -6
  692. package/src/prompts/templates/SOUL.md +13 -1
  693. package/src/prompts/update-bulletin-job.ts +2 -0
  694. package/src/providers/__tests__/retry-callsite.test.ts +138 -1
  695. package/src/providers/anthropic/client.ts +72 -33
  696. package/src/providers/call-site-routing.ts +42 -3
  697. package/src/providers/gemini/client.ts +18 -2
  698. package/src/providers/managed-proxy/context.ts +0 -5
  699. package/src/providers/model-catalog.ts +105 -19
  700. package/src/providers/openai/chat-completions-provider.ts +6 -0
  701. package/src/providers/openai/responses-provider.ts +7 -1
  702. package/src/providers/provider-send-message.ts +45 -2
  703. package/src/providers/ratelimit.ts +7 -2
  704. package/src/providers/registry.ts +14 -9
  705. package/src/providers/retry.ts +96 -8
  706. package/src/providers/speech-to-text/provider-catalog.ts +7 -8
  707. package/src/providers/types.ts +13 -0
  708. package/src/providers/usage-tracking.ts +96 -0
  709. package/src/runtime/AGENTS.md +10 -6
  710. package/src/runtime/__tests__/agent-wake.test.ts +89 -0
  711. package/src/runtime/agent-wake.ts +39 -2
  712. package/src/runtime/assistant-event-hub.ts +570 -52
  713. package/src/runtime/assistant-event.ts +2 -6
  714. package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
  715. package/src/runtime/auth/context.ts +0 -9
  716. package/src/runtime/auth/middleware.ts +1 -97
  717. package/src/runtime/auth/route-policy.ts +30 -9
  718. package/src/runtime/auth/token-service.ts +0 -11
  719. package/src/runtime/btw-sidechain.ts +2 -3
  720. package/src/runtime/channel-approvals.ts +6 -2
  721. package/src/runtime/channel-invite-transport.ts +2 -48
  722. package/src/runtime/channel-invite-transports/email.ts +1 -1
  723. package/src/runtime/channel-invite-transports/slack.ts +1 -1
  724. package/src/runtime/channel-invite-transports/telegram.ts +1 -1
  725. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  726. package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
  727. package/src/runtime/channel-invite-types.ts +54 -0
  728. package/src/runtime/channel-readiness-service.ts +32 -13
  729. package/src/runtime/channel-verification-service.ts +3 -5
  730. package/src/runtime/http-errors.ts +0 -34
  731. package/src/runtime/http-router.ts +6 -3
  732. package/src/runtime/http-server.ts +16 -402
  733. package/src/runtime/http-types.ts +5 -5
  734. package/src/runtime/interactive-ui.ts +0 -1
  735. package/src/runtime/middleware/auth.ts +0 -20
  736. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
  737. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
  738. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
  739. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
  740. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
  741. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
  742. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
  743. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
  744. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
  745. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +296 -80
  746. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
  747. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
  748. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  749. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
  750. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
  751. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
  752. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
  753. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +421 -0
  754. package/src/runtime/migrations/migration-transport.ts +49 -16
  755. package/src/runtime/migrations/migration-wizard.ts +2 -2
  756. package/src/runtime/migrations/origin-mode.ts +40 -0
  757. package/src/runtime/migrations/vbundle-builder.ts +457 -136
  758. package/src/runtime/migrations/vbundle-import-analyzer.ts +13 -11
  759. package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
  760. package/src/runtime/migrations/vbundle-importer.ts +251 -74
  761. package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
  762. package/src/runtime/migrations/vbundle-streaming-importer.ts +329 -38
  763. package/src/runtime/migrations/vbundle-streaming-validator.ts +203 -28
  764. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
  765. package/src/runtime/migrations/vbundle-validator.ts +328 -41
  766. package/src/runtime/pending-interactions.ts +48 -13
  767. package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
  768. package/src/runtime/routes/__tests__/backup-routes.test.ts +49 -168
  769. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +333 -0
  770. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
  771. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
  772. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
  773. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
  774. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
  775. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
  776. package/src/runtime/routes/acp-routes.test.ts +0 -3
  777. package/src/runtime/routes/acp-routes.ts +3 -7
  778. package/src/runtime/routes/app-management-routes.ts +18 -9
  779. package/src/runtime/routes/approval-interception-types.ts +13 -0
  780. package/src/runtime/routes/approval-routes.ts +55 -14
  781. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
  782. package/src/runtime/routes/avatar-routes.ts +3 -5
  783. package/src/runtime/routes/backup-routes.ts +15 -38
  784. package/src/runtime/routes/browser-routes.ts +1 -15
  785. package/src/runtime/routes/btw-routes.ts +14 -37
  786. package/src/runtime/routes/channel-guardian-routes.ts +1 -5
  787. package/src/runtime/routes/channel-readiness-routes.ts +3 -7
  788. package/src/runtime/routes/channel-route-shared.ts +2 -28
  789. package/src/runtime/routes/client-routes.ts +46 -12
  790. package/src/runtime/routes/consolidation-routes.ts +115 -0
  791. package/src/runtime/routes/contact-prompt-routes.ts +183 -0
  792. package/src/runtime/routes/conversation-list-routes.ts +12 -29
  793. package/src/runtime/routes/conversation-management-routes.ts +14 -51
  794. package/src/runtime/routes/conversation-query-routes.ts +156 -9
  795. package/src/runtime/routes/conversation-routes.ts +72 -539
  796. package/src/runtime/routes/conversation-starter-routes.ts +19 -40
  797. package/src/runtime/routes/document-pdf-renderer.ts +165 -0
  798. package/src/runtime/routes/documents-routes.ts +83 -18
  799. package/src/runtime/routes/errors.ts +19 -4
  800. package/src/runtime/routes/events-routes.ts +68 -94
  801. package/src/runtime/routes/filing-routes.ts +18 -1
  802. package/src/runtime/routes/gateway-log-routes.ts +79 -0
  803. package/src/runtime/routes/guardian-action-routes.ts +4 -9
  804. package/src/runtime/routes/guardian-approval-interception.ts +2 -8
  805. package/src/runtime/routes/heartbeat-routes.ts +103 -38
  806. package/src/runtime/routes/host-app-control-routes.ts +134 -0
  807. package/src/runtime/routes/host-bash-routes.ts +37 -6
  808. package/src/runtime/routes/host-browser-routes.ts +96 -25
  809. package/src/runtime/routes/host-cu-routes.ts +48 -13
  810. package/src/runtime/routes/host-file-routes.ts +35 -11
  811. package/src/runtime/routes/host-transfer-routes.ts +73 -37
  812. package/src/runtime/routes/http-adapter.ts +1 -0
  813. package/src/runtime/routes/identity-intro-cache.ts +30 -0
  814. package/src/runtime/routes/identity-routes.ts +93 -49
  815. package/src/runtime/routes/inbound-message-handler.ts +581 -146
  816. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -95
  817. package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
  818. package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
  819. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
  820. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
  821. package/src/runtime/routes/index.ts +12 -0
  822. package/src/runtime/routes/integrations/slack/channel.ts +0 -24
  823. package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
  824. package/src/runtime/routes/mcp-auth-routes.ts +132 -0
  825. package/src/runtime/routes/memory-item-routes.ts +10 -12
  826. package/src/runtime/routes/memory-v2-routes.ts +451 -16
  827. package/src/runtime/routes/migration-routes.ts +284 -31
  828. package/src/runtime/routes/playground/guard.ts +1 -1
  829. package/src/runtime/routes/playground/index.ts +0 -2
  830. package/src/runtime/routes/recording-routes.ts +4 -24
  831. package/src/runtime/routes/rename-conversation-routes.ts +2 -6
  832. package/src/runtime/routes/schedule-routes.ts +10 -6
  833. package/src/runtime/routes/secret-routes.ts +87 -18
  834. package/src/runtime/routes/settings-routes.ts +29 -28
  835. package/src/runtime/routes/skills-routes.ts +12 -31
  836. package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
  837. package/src/runtime/routes/task-routes.ts +6 -6
  838. package/src/runtime/routes/trust-rules-routes.ts +3 -94
  839. package/src/runtime/routes/types.ts +4 -4
  840. package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
  841. package/src/runtime/routes/usage-routes.ts +87 -10
  842. package/src/runtime/routes/user-routes.ts +17 -31
  843. package/src/runtime/routes/work-items-routes.ts +1 -4
  844. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
  845. package/src/runtime/services/analyze-conversation.ts +7 -17
  846. package/src/runtime/services/conversation-serializer.ts +2 -4
  847. package/src/runtime/verification-outbound-actions.ts +1 -1
  848. package/src/runtime/verification-rate-limiter.ts +1 -1
  849. package/src/runtime/verification-templates.ts +4 -7
  850. package/src/schedule/integration-status.ts +66 -2
  851. package/src/schedule/recurrence-engine.ts +4 -1
  852. package/src/schedule/retry-backoff.ts +18 -0
  853. package/src/schedule/retry-policy.ts +82 -0
  854. package/src/schedule/schedule-recovery.ts +64 -0
  855. package/src/schedule/schedule-store.ts +106 -18
  856. package/src/schedule/scheduler-types.ts +25 -0
  857. package/src/schedule/scheduler.ts +63 -38
  858. package/src/security/oauth-callback-registry.ts +8 -0
  859. package/src/security/secret-scanner.ts +14 -547
  860. package/src/security/secure-keys.ts +31 -11
  861. package/src/security/token-manager.ts +7 -3
  862. package/src/sequence/analytics.ts +5 -5
  863. package/src/sequence/engine.ts +1 -1
  864. package/src/signals/cancel.ts +16 -25
  865. package/src/signals/conversation-undo.ts +2 -27
  866. package/src/signals/emit-event.ts +1 -2
  867. package/src/signals/user-message.ts +108 -22
  868. package/src/skills/catalog-files.ts +2 -8
  869. package/src/skills/catalog-install.ts +1 -0
  870. package/src/skills/clawhub.ts +2 -2
  871. package/src/skills/include-graph.ts +5 -5
  872. package/src/skills/inline-command-runner.ts +1 -7
  873. package/src/skills/remote-skill-policy.ts +5 -5
  874. package/src/skills/skill-file-provider.ts +1 -1
  875. package/src/skills/skill-file-types.ts +13 -0
  876. package/src/skills/skillssh-audit-types.ts +28 -0
  877. package/src/skills/skillssh-registry.ts +8 -21
  878. package/src/subagent/manager.ts +67 -84
  879. package/src/tasks/task-store.ts +1 -28
  880. package/src/telemetry/types.ts +8 -0
  881. package/src/telemetry/usage-telemetry-reporter.test.ts +59 -15
  882. package/src/telemetry/usage-telemetry-reporter.ts +4 -5
  883. package/src/tools/acp/spawn.test.ts +1 -2
  884. package/src/tools/acp/steer.test.ts +1 -2
  885. package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
  886. package/src/tools/apps/executors.ts +56 -69
  887. package/src/tools/browser/__tests__/browser-status.test.ts +55 -135
  888. package/src/tools/browser/browser-execution.ts +31 -147
  889. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +145 -70
  890. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
  891. package/src/tools/browser/cdp-client/factory.ts +62 -91
  892. package/src/tools/browser/cdp-client/index.ts +1 -27
  893. package/src/tools/computer-use/definitions.ts +42 -20
  894. package/src/tools/executor.ts +46 -31
  895. package/src/tools/host-filesystem/edit.ts +29 -2
  896. package/src/tools/host-filesystem/read.ts +29 -2
  897. package/src/tools/host-filesystem/transfer.test.ts +45 -42
  898. package/src/tools/host-filesystem/transfer.ts +35 -4
  899. package/src/tools/host-filesystem/write.ts +29 -2
  900. package/src/tools/host-terminal/host-shell.ts +62 -3
  901. package/src/tools/network/script-proxy/index.ts +1 -10
  902. package/src/tools/permission-checker.ts +66 -1
  903. package/src/tools/schedule/create.ts +6 -0
  904. package/src/tools/schedule/list.ts +2 -0
  905. package/src/tools/schedule/update.ts +10 -0
  906. package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
  907. package/src/tools/shared/filesystem/path-policy.ts +25 -1
  908. package/src/tools/skills/load.ts +0 -32
  909. package/src/tools/skills/sandbox-runner.ts +1 -6
  910. package/src/tools/skills/skill-tool-factory.ts +32 -0
  911. package/src/tools/terminal/safe-env.ts +1 -0
  912. package/src/tools/terminal/shell.ts +2 -78
  913. package/src/tools/tool-approval-handler.ts +1 -5
  914. package/src/tools/types.ts +16 -39
  915. package/src/tts/__tests__/provider-catalog.test.ts +2 -2
  916. package/src/tts/provider-catalog.ts +1 -1
  917. package/src/usage/actors.ts +2 -1
  918. package/src/usage/attribution.ts +185 -0
  919. package/src/usage/pricing.ts +166 -0
  920. package/src/usage/types.ts +14 -0
  921. package/src/util/json.ts +13 -0
  922. package/src/util/logger.ts +3 -3
  923. package/src/util/pricing.ts +50 -3
  924. package/src/work-items/work-item-runner.ts +15 -42
  925. package/src/workspace/hatched-date.ts +86 -0
  926. package/src/workspace/migrations/003-seed-device-id.ts +1 -1
  927. package/src/workspace/migrations/006-services-config.ts +8 -5
  928. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
  929. package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
  930. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
  931. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
  932. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
  933. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
  934. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +6 -4
  935. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
  936. package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
  937. package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
  938. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +54 -0
  939. package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
  940. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
  941. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
  942. package/src/workspace/migrations/AGENTS.md +1 -1
  943. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
  944. package/src/workspace/migrations/registry.ts +8 -0
  945. package/src/workspace/migrations/utils.ts +21 -0
  946. package/src/workspace/provider-commit-message-generator.ts +3 -3
  947. package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -904
  948. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -296
  949. package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -431
  950. package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
  951. package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
  952. package/src/__tests__/secret-detection-handler.test.ts +0 -67
  953. package/src/__tests__/secret-scanner-executor.test.ts +0 -450
  954. package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
  955. package/src/__tests__/terminal-sandbox.test.ts +0 -374
  956. package/src/__tests__/tool-notification-listener.test.ts +0 -65
  957. package/src/__tests__/twilio-rest.test.ts +0 -34
  958. package/src/backup/__tests__/backup-key.test.ts +0 -152
  959. package/src/backup/__tests__/backup-worker.test.ts +0 -754
  960. package/src/backup/__tests__/offsite-writer.test.ts +0 -641
  961. package/src/backup/__tests__/stream-crypt.test.ts +0 -228
  962. package/src/backup/backup-key.ts +0 -137
  963. package/src/backup/backup-worker.ts +0 -438
  964. package/src/backup/offsite-writer.ts +0 -222
  965. package/src/backup/stream-crypt.ts +0 -263
  966. package/src/context/__tests__/microcompact.test.ts +0 -805
  967. package/src/context/microcompact.ts +0 -443
  968. package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
  969. package/src/daemon/message-types/pairing.ts +0 -58
  970. package/src/events/tool-notification-listener.ts +0 -17
  971. package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
  972. package/src/memory/v2/__tests__/edges.test.ts +0 -435
  973. package/src/memory/v2/edges.ts +0 -217
  974. package/src/outbound-proxy/config.ts +0 -94
  975. package/src/outbound-proxy/health.ts +0 -62
  976. package/src/outbound-proxy/types.ts +0 -150
  977. package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
  978. package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
  979. package/src/runtime/__tests__/client-registry.test.ts +0 -271
  980. package/src/runtime/capability-tokens.ts +0 -190
  981. package/src/runtime/chrome-extension-registry.ts +0 -368
  982. package/src/runtime/client-registry.ts +0 -254
  983. package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
  984. package/src/signals/mcp-reload.ts +0 -18
  985. package/src/tools/secret-detection-handler.ts +0 -269
  986. package/src/tools/terminal/backends/native.ts +0 -327
  987. package/src/tools/terminal/backends/types.ts +0 -37
  988. package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
  989. package/src/tools/terminal/sandbox.ts +0 -40
@@ -18,11 +18,8 @@ import {
18
18
  createUserMessage,
19
19
  } from "../../agent/message-types.js";
20
20
  import {
21
- canServiceRegistryBrowser,
22
- canServiceSseBrowser,
23
21
  CHANNEL_IDS,
24
22
  INTERFACE_IDS,
25
- type InterfaceId,
26
23
  isInteractiveInterface,
27
24
  parseChannelId,
28
25
  parseInterfaceId,
@@ -38,8 +35,8 @@ import {
38
35
  isModelSlashCommand,
39
36
  } from "../../daemon/conversation-process.js";
40
37
  import {
38
+ buildSlashContextForContent,
41
39
  resolveSlash,
42
- type SlashContext,
43
40
  } from "../../daemon/conversation-slash.js";
44
41
  import { getOrCreateConversation as getOrCreateConversationInstance } from "../../daemon/conversation-store.js";
45
42
  import {
@@ -47,23 +44,19 @@ import {
47
44
  isWakeUpGreeting,
48
45
  } from "../../daemon/first-greeting.js";
49
46
  import { renderHistoryContent } from "../../daemon/handlers/shared.js";
50
- import { HostBashProxy } from "../../daemon/host-bash-proxy.js";
51
- import { HostBrowserProxy } from "../../daemon/host-browser-proxy.js";
47
+ import { HostAppControlProxy } from "../../daemon/host-app-control-proxy.js";
52
48
  import { HostCuProxy } from "../../daemon/host-cu-proxy.js";
53
- import { HostFileProxy } from "../../daemon/host-file-proxy.js";
54
- import { HostTransferProxy } from "../../daemon/host-transfer-proxy.js";
49
+ import { preactivateHostProxySkills } from "../../daemon/host-proxy-preactivation.js";
55
50
  import type { ServerMessage } from "../../daemon/message-protocol.js";
56
51
  import type {
57
52
  HostProxyTransportMetadata,
58
53
  NonHostProxyTransportMetadata,
59
54
  } from "../../daemon/message-types/conversations.js";
60
55
  import { HeartbeatService } from "../../heartbeat/heartbeat-service.js";
61
- import { emitFeedEvent } from "../../home/emit-feed-event.js";
62
56
  import {
63
57
  writeOnboardingSidecar,
64
58
  writeRelationshipState,
65
59
  } from "../../home/relationship-state-writer.js";
66
- import { rewriteCommandPreview } from "../../home/rewrite-command-preview.js";
67
60
  import { ipcCall } from "../../ipc/gateway-client.js";
68
61
  import {
69
62
  getAttachmentById,
@@ -72,8 +65,6 @@ import {
72
65
  getSourcePathsForAttachments,
73
66
  } from "../../memory/attachments-store.js";
74
67
  import {
75
- createCanonicalGuardianRequest,
76
- generateCanonicalRequestCode,
77
68
  listCanonicalGuardianRequests,
78
69
  listPendingRequestsByConversationScope,
79
70
  resolveCanonicalGuardianRequest,
@@ -98,8 +89,6 @@ import { searchConversations } from "../../memory/conversation-queries.js";
98
89
  import { getConfiguredProvider } from "../../providers/provider-send-message.js";
99
90
  import type { Provider } from "../../providers/types.js";
100
91
  import { checkIngressForSecrets } from "../../security/secret-ingress.js";
101
- import { redactSecrets } from "../../security/secret-scanner.js";
102
- import { summarizeToolInput } from "../../tools/tool-input-summary.js";
103
92
  import { getLogger } from "../../util/logger.js";
104
93
  import {
105
94
  getInterfacesDir,
@@ -107,11 +96,8 @@ import {
107
96
  } from "../../util/platform.js";
108
97
  import { silentlyWithLog } from "../../util/silently.js";
109
98
  import { buildAssistantEvent } from "../assistant-event.js";
110
- import { assistantEventHub } from "../assistant-event-hub.js";
99
+ import { assistantEventHub, broadcastMessage } from "../assistant-event-hub.js";
111
100
  import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
112
- import { getChromeExtensionRegistry } from "../chrome-extension-registry.js";
113
- import { getClientRegistry } from "../client-registry.js";
114
- import { bridgeConfirmationRequestToGuardian } from "../confirmation-request-guardian-bridge.js";
115
101
  import { routeGuardianReply } from "../guardian-reply-router.js";
116
102
  import { healGuardianBindingDrift } from "../guardian-vellum-migration.js";
117
103
  import type {
@@ -357,18 +343,6 @@ async function tryConsumeCanonicalGuardianReply(params: {
357
343
  return { consumed: true, messageId };
358
344
  }
359
345
 
360
- function resolveCanonicalRequestSourceType(
361
- sourceChannel: string | undefined,
362
- ): "desktop" | "channel" | "voice" {
363
- if (sourceChannel === "phone") {
364
- return "voice";
365
- }
366
- if (sourceChannel === "vellum") {
367
- return "desktop";
368
- }
369
- return "channel";
370
- }
371
-
372
346
  function getInterfaceFilesWithMtimes(
373
347
  interfacesDir: string | null,
374
348
  ): Array<{ path: string; mtimeMs: number }> {
@@ -1022,348 +996,6 @@ function mergeConsecutiveAssistantMessages(messages: MessageRow[]): {
1022
996
  return { messages: result, mergedIdMap };
1023
997
  }
1024
998
 
1025
- /**
1026
- * Build an `onEvent` callback that publishes every outbound event to the
1027
- * assistant event hub, maintaining ordered delivery through a serial chain.
1028
- *
1029
- * Also registers pending interactions when confirmation_request,
1030
- * secret_request, host_bash_request, host_browser_request, host_file_request,
1031
- * or host_cu_request events flow through, so standalone approval/result
1032
- * endpoints can look up the conversation by requestId.
1033
- */
1034
- function makeHubPublisher(
1035
- deps: SendMessageDeps,
1036
- conversationId: string,
1037
- conversation: Conversation,
1038
- ): (msg: ServerMessage) => void {
1039
- let hubChain: Promise<void> = Promise.resolve();
1040
- return (msg: ServerMessage) => {
1041
- // Register pending interactions for approval events
1042
- if (msg.type === "confirmation_request") {
1043
- pendingInteractions.register(msg.requestId, {
1044
- conversation,
1045
- conversationId,
1046
- kind: "confirmation",
1047
- confirmationDetails: {
1048
- toolName: msg.toolName,
1049
- input: msg.input,
1050
- riskLevel: msg.riskLevel,
1051
- executionTarget: msg.executionTarget,
1052
- allowlistOptions: msg.allowlistOptions,
1053
- scopeOptions: msg.scopeOptions,
1054
- persistentDecisionsAllowed: msg.persistentDecisionsAllowed,
1055
- },
1056
- });
1057
-
1058
- const inputRecord = msg.input as Record<string, unknown>;
1059
- const commandPreview =
1060
- redactSecrets(summarizeToolInput(msg.toolName, inputRecord)) ||
1061
- undefined;
1062
- const technicalTitle = commandPreview
1063
- ? `Requesting permission: ${commandPreview}`
1064
- : `Requesting approval to use ${msg.toolName}.`;
1065
- const dedupKey = `tool-approval:${msg.requestId}`;
1066
-
1067
- // Emit immediately with the technical preview.
1068
- void emitFeedEvent({
1069
- source: "assistant",
1070
- title: technicalTitle,
1071
- summary: technicalTitle,
1072
- dedupKey,
1073
- urgency: msg.riskLevel === "high" ? "high" : "medium",
1074
- conversationId,
1075
- detailPanel: { kind: "toolPermission" },
1076
- }).catch((err) => {
1077
- log.warn(
1078
- { err, requestId: msg.requestId },
1079
- "Failed to emit tool approval request feed event",
1080
- );
1081
- });
1082
-
1083
- // Background: rewrite into prose and update the feed item.
1084
- if (commandPreview) {
1085
- void rewriteCommandPreview(msg.toolName, commandPreview)
1086
- .then((prose) => {
1087
- if (prose) {
1088
- const proseTitle = `Requesting permission: ${prose}`;
1089
- return emitFeedEvent({
1090
- source: "assistant",
1091
- title: proseTitle,
1092
- summary: proseTitle,
1093
- dedupKey,
1094
- urgency: msg.riskLevel === "high" ? "high" : "medium",
1095
- conversationId,
1096
- detailPanel: { kind: "toolPermission" },
1097
- });
1098
- }
1099
- })
1100
- .catch((err) => {
1101
- log.warn(
1102
- { err, requestId: msg.requestId },
1103
- "Failed to update feed event with prose rewrite",
1104
- );
1105
- });
1106
- }
1107
-
1108
- // Create a canonical guardian request so HTTP handlers can find it
1109
- // via applyCanonicalGuardianDecision.
1110
- try {
1111
- const trustContext = conversation.trustContext;
1112
- const sourceChannel = trustContext?.sourceChannel ?? "vellum";
1113
- const inputRecord = msg.input as Record<string, unknown>;
1114
- const activityRaw =
1115
- (typeof inputRecord.activity === "string"
1116
- ? inputRecord.activity
1117
- : undefined) ??
1118
- (typeof inputRecord.reason === "string"
1119
- ? inputRecord.reason
1120
- : undefined);
1121
- const canonicalRequest = createCanonicalGuardianRequest({
1122
- id: msg.requestId,
1123
- kind: "tool_approval",
1124
- sourceType: resolveCanonicalRequestSourceType(sourceChannel),
1125
- sourceChannel,
1126
- conversationId,
1127
- requesterExternalUserId: trustContext?.requesterExternalUserId,
1128
- requesterChatId: trustContext?.requesterChatId,
1129
- guardianExternalUserId: trustContext?.guardianExternalUserId,
1130
- guardianPrincipalId: trustContext?.guardianPrincipalId ?? undefined,
1131
- toolName: msg.toolName,
1132
- commandPreview:
1133
- redactSecrets(summarizeToolInput(msg.toolName, inputRecord)) ||
1134
- undefined,
1135
- riskLevel: msg.riskLevel,
1136
- activityText: activityRaw ? redactSecrets(activityRaw) : undefined,
1137
- executionTarget: msg.executionTarget,
1138
- status: "pending",
1139
- requestCode: generateCanonicalRequestCode(),
1140
- expiresAt: Date.now() + 5 * 60 * 1000,
1141
- });
1142
-
1143
- // For trusted-contact conversations, bridge to guardian.question so the
1144
- // guardian gets notified and can approve via callback/request-code.
1145
- if (trustContext) {
1146
- bridgeConfirmationRequestToGuardian({
1147
- canonicalRequest,
1148
- trustContext,
1149
- conversationId,
1150
- toolName: msg.toolName,
1151
- assistantId:
1152
- conversation.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
1153
- });
1154
- }
1155
- } catch (err) {
1156
- log.debug(
1157
- { err, requestId: msg.requestId, conversationId },
1158
- "Failed to create canonical request from hub publisher",
1159
- );
1160
- }
1161
- } else if (msg.type === "secret_request") {
1162
- pendingInteractions.register(msg.requestId, {
1163
- conversation,
1164
- conversationId,
1165
- kind: "secret",
1166
- });
1167
- } else {
1168
- registerHostProxyPendingInteraction(msg, conversation, conversationId);
1169
- }
1170
-
1171
- // ServerMessage is a large union; conversationId exists on most but not all variants.
1172
- const msgConversationId =
1173
- "conversationId" in msg &&
1174
- typeof (msg as { conversationId?: unknown }).conversationId === "string"
1175
- ? (msg as { conversationId: string }).conversationId
1176
- : undefined;
1177
- // `conversation_list_invalidated` is a list-level system event: it
1178
- // describes no particular conversation and every connected client
1179
- // should refresh its sidebar. Publish it unscoped so the SSE hub does
1180
- // not filter it out by the subscriber's `filter.conversationId`.
1181
- // Other events (including `conversation_title_updated`) stay scoped to
1182
- // their conversation — unscoped scoped-events would leak foreign
1183
- // `conversationId` values to native clients' speculative ID-resolution
1184
- // path. For `conversation_title_updated` we instead enqueue a matching
1185
- // unscoped `conversation_list_invalidated` below so other clients'
1186
- // sidebars can refresh and pick up the new title.
1187
- const resolvedConversationId =
1188
- msg.type === "conversation_list_invalidated"
1189
- ? undefined
1190
- : (msgConversationId ?? conversationId);
1191
- const event = buildAssistantEvent(
1192
- DAEMON_INTERNAL_ASSISTANT_ID,
1193
- msg,
1194
- resolvedConversationId,
1195
- );
1196
- hubChain = (async () => {
1197
- await hubChain;
1198
- try {
1199
- await deps.assistantEventHub.publish(event);
1200
- } catch (err) {
1201
- log.warn(
1202
- { err },
1203
- "assistant-events hub subscriber threw during POST /messages",
1204
- );
1205
- }
1206
-
1207
- // When the agent loop auto-generates a conversation title, also
1208
- // broadcast an unscoped `conversation_list_invalidated` so every
1209
- // connected client's sidebar can refresh and pick up the new title.
1210
- // Without this, clients viewing other conversations (or a draft)
1211
- // would never learn that the title for this conversation changed.
1212
- // The scoped `conversation_title_updated` above still handles the
1213
- // in-place update for the client currently viewing this conversation.
1214
- if (msg.type === "conversation_title_updated") {
1215
- try {
1216
- await deps.assistantEventHub.publish(
1217
- buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
1218
- type: "conversation_list_invalidated",
1219
- reason: "renamed",
1220
- }),
1221
- );
1222
- } catch (err) {
1223
- log.warn(
1224
- { err },
1225
- "Failed to publish conversation_list_invalidated after title update",
1226
- );
1227
- }
1228
- }
1229
- })();
1230
- };
1231
- }
1232
-
1233
- /**
1234
- * Register pending interactions for host proxy request envelopes so
1235
- * standalone result endpoints can resolve by requestId.
1236
- *
1237
- * Returns the registered requestId when a host proxy request was registered.
1238
- * Callers that route through non-hub transports (e.g. registry-routed
1239
- * host_browser sends) can use this to clean up the registration if send fails.
1240
- */
1241
- function registerHostProxyPendingInteraction(
1242
- msg: ServerMessage,
1243
- conversation: Conversation,
1244
- conversationId: string,
1245
- ): string | undefined {
1246
- if (msg.type === "host_bash_request") {
1247
- pendingInteractions.register(msg.requestId, {
1248
- conversation,
1249
- conversationId,
1250
- kind: "host_bash",
1251
- });
1252
- return msg.requestId;
1253
- }
1254
- if (msg.type === "host_browser_request") {
1255
- pendingInteractions.register(msg.requestId, {
1256
- conversation,
1257
- conversationId,
1258
- kind: "host_browser",
1259
- });
1260
- return msg.requestId;
1261
- }
1262
- if (msg.type === "host_file_request") {
1263
- pendingInteractions.register(msg.requestId, {
1264
- conversation,
1265
- conversationId,
1266
- kind: "host_file",
1267
- });
1268
- return msg.requestId;
1269
- }
1270
- if (msg.type === "host_cu_request") {
1271
- pendingInteractions.register(msg.requestId, {
1272
- conversation,
1273
- conversationId,
1274
- kind: "host_cu",
1275
- });
1276
- return msg.requestId;
1277
- }
1278
- if (msg.type === "host_transfer_request") {
1279
- pendingInteractions.register(msg.requestId, {
1280
- conversation,
1281
- conversationId,
1282
- kind: "host_transfer",
1283
- });
1284
- return msg.requestId;
1285
- }
1286
- return undefined;
1287
- }
1288
-
1289
- /**
1290
- * Resolve the host_browser sender function for a conversation turn.
1291
- *
1292
- * Transport selection:
1293
- * 1. **WebSocket registry** — when the guardian has an active entry in
1294
- * ChromeExtensionRegistry (self-hosted direct WS connection), the
1295
- * registry-routed sender is returned. Frames go directly over the
1296
- * WebSocket to the extension.
1297
- * 2. **SSE event hub** — when no WebSocket connection exists but a
1298
- * chrome-extension client is connected via SSE (cloud/platform mode),
1299
- * the SSE hub sender (`onEvent`) is returned. The extension receives
1300
- * `host_browser_request` frames as SSE events and POSTs results back
1301
- * to `/v1/host-browser-result`.
1302
- *
1303
- * When neither transport is available, `onEvent` is returned as the
1304
- * default sender (used by macOS for its native host_browser path).
1305
- * `hasSseExtension` is `false` in that case so the caller can avoid
1306
- * provisioning a stale `HostBrowserProxy` for interfaces that don't
1307
- * natively support host_browser.
1308
- */
1309
- function resolveHostBrowserSender(
1310
- conversation: Conversation,
1311
- conversationId: string,
1312
- actorPrincipalId: string | undefined,
1313
- onEvent: (msg: ServerMessage) => void,
1314
- sourceInterface: InterfaceId,
1315
- ): {
1316
- sender: (msg: ServerMessage) => void;
1317
- isRegistryRouted: boolean;
1318
- hasSseExtension: boolean;
1319
- } {
1320
- const guardianId =
1321
- conversation.trustContext?.guardianPrincipalId ?? actorPrincipalId;
1322
- const hasExtensionConnection =
1323
- !!guardianId && !!getChromeExtensionRegistry().get(guardianId);
1324
-
1325
- // Priority 1: WebSocket registry — direct WS to the extension.
1326
- if (hasExtensionConnection) {
1327
- const registrySender = (msg: ServerMessage): void => {
1328
- const requestId = registerHostProxyPendingInteraction(
1329
- msg,
1330
- conversation,
1331
- conversationId,
1332
- );
1333
- const gid =
1334
- conversation.trustContext?.guardianPrincipalId ?? actorPrincipalId;
1335
- if (!gid) {
1336
- if (requestId) pendingInteractions.resolve(requestId);
1337
- throw new Error(
1338
- "host_browser send skipped: no guardianId on AuthContext",
1339
- );
1340
- }
1341
- const ok = getChromeExtensionRegistry().send(gid, msg);
1342
- if (!ok) {
1343
- if (requestId) pendingInteractions.resolve(requestId);
1344
- throw new Error(
1345
- `host_browser send failed: no active connection for guardian ${gid}`,
1346
- );
1347
- }
1348
- };
1349
- return {
1350
- sender: registrySender,
1351
- isRegistryRouted: true,
1352
- hasSseExtension: false,
1353
- };
1354
- }
1355
-
1356
- // Priority 2: SSE-connected chrome extension (cloud/platform mode).
1357
- // Check the ClientRegistry for a chrome-extension client specifically —
1358
- // getMostRecentByCapability("host_browser") would also match macOS
1359
- // clients, which handle browser frames through their own native path.
1360
- const hasSseExtension =
1361
- canServiceSseBrowser(sourceInterface) &&
1362
- !!getClientRegistry().getMostRecentByInterface("chrome-extension");
1363
-
1364
- return { sender: onEvent, isRegistryRouted: false, hasSseExtension };
1365
- }
1366
-
1367
999
  /**
1368
1000
  * Persist the pre-chat onboarding payload to disk.
1369
1001
  *
@@ -1647,7 +1279,7 @@ export async function handleSendMessage(
1647
1279
  if (!hasMessages(mapping.conversationId)) {
1648
1280
  smDeps.assistantEventHub
1649
1281
  .publish(
1650
- buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
1282
+ buildAssistantEvent({
1651
1283
  type: "conversation_list_invalidated",
1652
1284
  reason: "created",
1653
1285
  }),
@@ -1690,10 +1322,9 @@ export async function handleSendMessage(
1690
1322
 
1691
1323
  // Store pre-chat onboarding context on the conversation when this is the
1692
1324
  // very first message (no prior messages loaded). Artifact persistence
1693
- // (IDENTITY.md, USER.md, sidecar) is deferred: on the canned greeting
1694
- // path it runs inside the setTimeout right before warmPromptCache() so
1695
- // the warmed system prompt includes the identity; on the normal LLM
1696
- // path it runs immediately before inference starts.
1325
+ // (IDENTITY.md, USER.md, sidecar) runs before either the canned greeting
1326
+ // broadcast or normal LLM inference so client-side identity reads observe
1327
+ // the selected assistant name.
1697
1328
  const isFirstOnboarding =
1698
1329
  !!body.onboarding && conversation.messages.length === 0;
1699
1330
  if (isFirstOnboarding) {
@@ -1757,125 +1388,39 @@ export async function handleSendMessage(
1757
1388
  conversation.setTrustContext({ trustClass: "guardian", sourceChannel });
1758
1389
  }
1759
1390
 
1760
- const onEvent = makeHubPublisher(
1761
- smDeps,
1762
- mapping.conversationId,
1763
- conversation,
1764
- );
1765
1391
  const isInteractive = isInteractiveInterface(sourceInterface);
1766
- // Only create each host proxy for interfaces that support the matching
1767
- // capability. macOS supports all four; the chrome-extension interface only
1768
- // supports host_browser. Non-desktop conversations (CLI, channels, headless)
1769
- // fall back to local execution.
1770
- // Set the proxy BEFORE updateClient so updateClient's call to
1771
- // hostBashProxy.updateSender targets the correct (new) proxy.
1772
- if (supportsHostProxy(sourceInterface, "host_bash")) {
1773
- // Reuse the existing proxy if the conversation is actively processing a
1774
- // host bash request to avoid orphaning in-flight requests.
1775
- if (!conversation.isProcessing() || !conversation.hostBashProxy) {
1776
- const proxy = new HostBashProxy(onEvent, (requestId) => {
1777
- pendingInteractions.resolve(requestId);
1778
- });
1779
- conversation.setHostBashProxy(proxy);
1392
+ // Bash/File/Transfer singletons are globally available via isAvailable()
1393
+ // no per-conversation gating needed. CU is per-conversation (owns step
1394
+ // count, AX tree history, loop detection).
1395
+ if (supportsHostProxy(sourceInterface, "host_cu")) {
1396
+ if (!conversation.isProcessing() || !conversation.hostCuProxy) {
1397
+ conversation.setHostCuProxy(new HostCuProxy());
1780
1398
  }
1781
1399
  } else if (!conversation.isProcessing()) {
1782
- conversation.setHostBashProxy(undefined);
1783
- }
1784
- // Resolve the host_browser sender — registry-routed when the guardian has
1785
- // an active WS extension connection, SSE hub when a chrome-extension is
1786
- // connected via SSE (cloud mode), or SSE hub as default for macOS.
1787
- const {
1788
- sender: browserProxySendToClient,
1789
- isRegistryRouted,
1790
- hasSseExtension,
1791
- } = resolveHostBrowserSender(
1792
- conversation,
1793
- mapping.conversationId,
1794
- actorPrincipalId,
1795
- onEvent,
1796
- sourceInterface,
1797
- );
1798
-
1799
- // Stash the registry-routed sender on the conversation so queue-drain
1800
- // restores (which run outside of conversation-routes.ts and only have
1801
- // access to `sendToClient`) can preserve it when calling
1802
- // `restoreBrowserProxyAvailability()`. The override is set when the
1803
- // sender is registry-routed (regardless of interface) and cleared when
1804
- // the SSE hub sender is used, so the drain path always restores the
1805
- // correct transport.
1806
- if (isRegistryRouted) {
1807
- conversation.hostBrowserSenderOverride = browserProxySendToClient;
1808
- } else {
1809
- conversation.hostBrowserSenderOverride = undefined;
1400
+ conversation.setHostCuProxy(undefined);
1810
1401
  }
1811
-
1812
- // Provision the host browser proxy when a viable transport exists:
1813
- // - macOS: natively supports host_browser via its own SSE path
1814
- // - WS registry: extension connected via direct WebSocket
1815
- // - SSE extension: chrome extension connected via SSE (cloud mode)
1816
- //
1817
- // For chrome-extension, require an active transport (WS or SSE). Without
1818
- // one, host_browser_request frames would be emitted to the SSE hub with
1819
- // no consumer, causing a 30s proxy timeout instead of failing fast.
1820
- const shouldProvisionBrowserProxy =
1821
- supportsHostProxy(sourceInterface) ||
1822
- (canServiceRegistryBrowser(sourceInterface) && isRegistryRouted) ||
1823
- hasSseExtension;
1824
- if (shouldProvisionBrowserProxy) {
1825
- if (!conversation.isProcessing() || !conversation.hostBrowserProxy) {
1826
- const browserProxy = new HostBrowserProxy(
1827
- browserProxySendToClient,
1828
- (requestId) => {
1829
- pendingInteractions.resolve(requestId);
1830
- },
1402
+ // App-control mirrors CU's per-conversation lifecycle: the proxy owns a
1403
+ // singleton lock plus per-session loop tracking. Instantiation is
1404
+ // unconditional when the client supports the capability feature-flag
1405
+ // gating lives in the skill-projection layer (which reads the
1406
+ // `feature-flag: app-control` declaration in SKILL.md frontmatter), so
1407
+ // an attached proxy is harmless when the flag resolves to off.
1408
+ if (supportsHostProxy(sourceInterface, "host_app_control")) {
1409
+ if (!conversation.isProcessing() || !conversation.hostAppControlProxy) {
1410
+ conversation.setHostAppControlProxy(
1411
+ new HostAppControlProxy(mapping.conversationId),
1831
1412
  );
1832
- conversation.setHostBrowserProxy(browserProxy);
1833
1413
  }
1834
1414
  } else if (!conversation.isProcessing()) {
1835
- conversation.setHostBrowserProxy(undefined);
1415
+ conversation.setHostAppControlProxy(undefined);
1836
1416
  }
1837
- if (supportsHostProxy(sourceInterface, "host_file")) {
1838
- if (!conversation.isProcessing() || !conversation.hostFileProxy) {
1839
- const fileProxy = new HostFileProxy(onEvent, (requestId) => {
1840
- pendingInteractions.resolve(requestId);
1841
- });
1842
- conversation.setHostFileProxy(fileProxy);
1843
- }
1844
- if (!conversation.isProcessing() || !conversation.getHostTransferProxy()) {
1845
- const transferProxy = new HostTransferProxy(onEvent, (requestId) => {
1846
- pendingInteractions.resolve(requestId);
1847
- });
1848
- conversation.setHostTransferProxy(transferProxy);
1849
- }
1850
- } else if (!conversation.isProcessing()) {
1851
- conversation.setHostFileProxy(undefined);
1852
- conversation.setHostTransferProxy(undefined);
1853
- }
1854
- if (supportsHostProxy(sourceInterface, "host_cu")) {
1855
- if (!conversation.isProcessing() || !conversation.hostCuProxy) {
1856
- const cuProxy = new HostCuProxy(onEvent, (requestId) => {
1857
- pendingInteractions.resolve(requestId);
1858
- });
1859
- conversation.setHostCuProxy(cuProxy);
1860
- }
1861
- // Only preactivate CU when the conversation is idle — if the conversation is
1862
- // processing, this message will be queued and preactivation is deferred
1863
- // to dequeue time in drainQueueImpl to avoid mutating in-flight turn state.
1864
- if (!conversation.isProcessing()) {
1865
- conversation.addPreactivatedSkillId("computer-use");
1866
- }
1867
- } else if (!conversation.isProcessing()) {
1868
- conversation.setHostCuProxy(undefined);
1417
+ // Only preactivate when the conversation is idle — if it's processing,
1418
+ // this message will be queued and preactivation is deferred to dequeue
1419
+ // time in drainQueueImpl to avoid mutating in-flight turn state.
1420
+ if (!conversation.isProcessing()) {
1421
+ preactivateHostProxySkills(conversation, sourceInterface);
1869
1422
  }
1870
1423
  // Wire sendToClient to the SSE hub so all subsystems can reach the HTTP client.
1871
- // Called after setHostBashProxy so updateSender targets the current proxy.
1872
- // When proxies are preserved during an active turn (non-desktop request while
1873
- // processing), skip updating proxy senders to avoid degrading them. The gate
1874
- // matches the host_bash capability because the legacy "reject send during
1875
- // host bash" flow is what this is really protecting.
1876
- const preservingProxies =
1877
- conversation.isProcessing() &&
1878
- !supportsHostProxy(sourceInterface, "host_bash");
1879
1424
  // hasNoClient must remain `!isInteractive` so downstream tool gating
1880
1425
  // (`isToolActiveForContext` for HOST_TOOL_NAMES, `createToolExecutor`'s
1881
1426
  // `isInteractive: !ctx.hasNoClient`) keeps host_bash/host_file/host_cu
@@ -1883,23 +1428,7 @@ export async function handleSendMessage(
1883
1428
  // is non-interactive (no SSE prompter UI) but still has a connected client
1884
1429
  // that can service host_browser_request events; we restore that single
1885
1430
  // proxy explicitly below without relaxing `hasNoClient`.
1886
- conversation.updateClient(onEvent, !isInteractive, {
1887
- skipProxySenderUpdate: preservingProxies,
1888
- });
1889
- // Re-enable the browser proxy for turns that provisioned one. This covers:
1890
- // - macOS: always provisioned (SSE sender or registry-routed when extension
1891
- // is connected)
1892
- // - chrome-extension: natively supports host_browser (non-interactive but
1893
- // has a connected client for host_browser_request events)
1894
- //
1895
- // The helper bypasses the `hasNoClient` gate so chrome-extension turns can
1896
- // drive the browser via CDP without leaking host_bash/host_file tool
1897
- // availability. It reads `hostBrowserSenderOverride` (set above when
1898
- // registry-routed) and applies the correct sender — including after
1899
- // queue-drain restores run from conversation-process.ts.
1900
- if (shouldProvisionBrowserProxy) {
1901
- conversation.restoreBrowserProxyAvailability?.();
1902
- }
1431
+ conversation.updateClient(broadcastMessage, !isInteractive);
1903
1432
 
1904
1433
  // ── Canned first-greeting fast path ──
1905
1434
  // On a completely fresh workspace, skip LLM inference for the macOS
@@ -1960,25 +1489,30 @@ export async function handleSendMessage(
1960
1489
  conversationId,
1961
1490
  };
1962
1491
 
1492
+ if (isFirstOnboarding) {
1493
+ persistOnboardingArtifacts(body.onboarding!);
1494
+ }
1495
+
1963
1496
  setTimeout(() => {
1964
- onEvent({
1497
+ broadcastMessage({
1965
1498
  type: "user_message_echo",
1966
1499
  text: rawContent,
1967
1500
  conversationId,
1968
1501
  messageId: persisted.id,
1969
1502
  clientMessageId,
1970
1503
  });
1971
- onEvent({ type: "assistant_text_delta", text: cannedGreeting });
1972
- onEvent({ type: "message_complete", conversationId });
1504
+ broadcastMessage({
1505
+ type: "assistant_text_delta",
1506
+ text: cannedGreeting,
1507
+ conversationId,
1508
+ });
1509
+ broadcastMessage({ type: "message_complete", conversationId });
1973
1510
  conversation.processing = false;
1974
1511
  silentlyWithLog(
1975
1512
  conversation.drainQueue(),
1976
1513
  "canned-greeting queue drain",
1977
1514
  );
1978
1515
 
1979
- if (isFirstOnboarding) {
1980
- persistOnboardingArtifacts(body.onboarding!);
1981
- }
1982
1516
  conversation.warmPromptCache();
1983
1517
  }, 0);
1984
1518
 
@@ -2022,7 +1556,7 @@ export async function handleSendMessage(
2022
1556
  content: content ?? "",
2023
1557
  attachments,
2024
1558
  conversation,
2025
- onEvent,
1559
+ onEvent: broadcastMessage,
2026
1560
  // Desktop path: disable NL classification to avoid consuming non-decision
2027
1561
  // messages while a tool confirmation is pending. Deterministic code-prefix
2028
1562
  // and callback parsing remain active. Mirrors conversation-process.ts behavior.
@@ -2055,7 +1589,7 @@ export async function handleSendMessage(
2055
1589
  const enqueueResult = conversation.enqueueMessage(
2056
1590
  content ?? "",
2057
1591
  attachments,
2058
- onEvent,
1592
+ broadcastMessage,
2059
1593
  requestId,
2060
1594
  undefined, // activeSurfaceId
2061
1595
  undefined, // currentPage
@@ -2093,10 +1627,7 @@ export async function handleSendMessage(
2093
1627
  for (const interaction of pendingInteractions.getByConversation(
2094
1628
  mapping.conversationId,
2095
1629
  )) {
2096
- if (
2097
- interaction.conversation === conversation &&
2098
- interaction.kind === "confirmation"
2099
- ) {
1630
+ if (interaction.kind === "confirmation") {
2100
1631
  conversation.emitConfirmationStateChanged({
2101
1632
  conversationId: mapping.conversationId,
2102
1633
  requestId: interaction.requestId,
@@ -2111,7 +1642,7 @@ export async function handleSendMessage(
2111
1642
  }
2112
1643
  }
2113
1644
  conversation.denyAllPendingConfirmations();
2114
- pendingInteractions.removeByConversation(conversation);
1645
+ pendingInteractions.removeByConversation(mapping.conversationId);
2115
1646
  }
2116
1647
 
2117
1648
  // Expire any orphaned canonical requests that survived without a
@@ -2140,10 +1671,7 @@ export async function handleSendMessage(
2140
1671
  for (const interaction of pendingInteractions.getByConversation(
2141
1672
  mapping.conversationId,
2142
1673
  )) {
2143
- if (
2144
- interaction.conversation === conversation &&
2145
- interaction.kind === "confirmation"
2146
- ) {
1674
+ if (interaction.kind === "confirmation") {
2147
1675
  conversation.emitConfirmationStateChanged({
2148
1676
  conversationId: mapping.conversationId,
2149
1677
  requestId: interaction.requestId,
@@ -2158,7 +1686,7 @@ export async function handleSendMessage(
2158
1686
  }
2159
1687
  }
2160
1688
  conversation.denyAllPendingConfirmations();
2161
- pendingInteractions.removeByConversation(conversation);
1689
+ pendingInteractions.removeByConversation(mapping.conversationId);
2162
1690
  }
2163
1691
 
2164
1692
  // Expire any orphaned canonical requests that survived without a
@@ -2179,17 +1707,14 @@ export async function handleSendMessage(
2179
1707
 
2180
1708
  // Resolve slash commands before persisting or running the agent loop.
2181
1709
  const rawContent = content ?? "";
2182
- const config = getConfig();
2183
- const slashContext: SlashContext = {
1710
+ const slashContext = buildSlashContextForContent(rawContent, {
1711
+ conversationId: mapping.conversationId,
2184
1712
  messageCount: conversation.getMessages().length,
2185
1713
  inputTokens: conversation.usageStats.inputTokens,
2186
1714
  outputTokens: conversation.usageStats.outputTokens,
2187
- maxInputTokens: config.llm.default.contextWindow.maxInputTokens,
2188
- model: config.llm.default.model,
2189
- provider: config.llm.default.provider,
2190
1715
  estimatedCost: conversation.usageStats.estimatedCost,
2191
1716
  userMessageInterface: sourceInterface,
2192
- };
1717
+ });
2193
1718
  const slashResult = await resolveSlash(rawContent, slashContext);
2194
1719
 
2195
1720
  if (slashResult.kind === "unknown") {
@@ -2246,7 +1771,7 @@ export async function handleSendMessage(
2246
1771
  // Snapshot model info now so the deferred callback cannot observe
2247
1772
  // a config change from a concurrent request.
2248
1773
  const modelInfoEvent = isModelSlashCommand(rawContent)
2249
- ? await buildModelInfoEvent()
1774
+ ? await buildModelInfoEvent(mapping.conversationId)
2250
1775
  : null;
2251
1776
 
2252
1777
  const response = {
@@ -2266,7 +1791,7 @@ export async function handleSendMessage(
2266
1791
  const conversationId = mapping.conversationId;
2267
1792
  const message = slashResult.message;
2268
1793
  setTimeout(() => {
2269
- onEvent({
1794
+ broadcastMessage({
2270
1795
  type: "user_message_echo",
2271
1796
  text: rawContent,
2272
1797
  conversationId,
@@ -2274,10 +1799,14 @@ export async function handleSendMessage(
2274
1799
  clientMessageId,
2275
1800
  });
2276
1801
  if (modelInfoEvent) {
2277
- onEvent(modelInfoEvent);
1802
+ broadcastMessage(modelInfoEvent);
2278
1803
  }
2279
- onEvent({ type: "assistant_text_delta", text: message });
2280
- onEvent({
1804
+ broadcastMessage({
1805
+ type: "assistant_text_delta",
1806
+ text: message,
1807
+ conversationId,
1808
+ });
1809
+ broadcastMessage({
2281
1810
  type: "message_complete",
2282
1811
  conversationId: conversationId,
2283
1812
  });
@@ -2323,7 +1852,7 @@ export async function handleSendMessage(
2323
1852
  // HTTP timeout on large contexts, causing a false "Failed to send".
2324
1853
  (async () => {
2325
1854
  try {
2326
- onEvent({
1855
+ broadcastMessage({
2327
1856
  type: "user_message_echo",
2328
1857
  text: rawContent,
2329
1858
  conversationId,
@@ -2347,11 +1876,15 @@ export async function handleSendMessage(
2347
1876
  );
2348
1877
  conversation.getMessages().push(assistantMsg);
2349
1878
 
2350
- onEvent({ type: "assistant_text_delta", text: responseText });
2351
- onEvent({ type: "message_complete", conversationId });
1879
+ broadcastMessage({
1880
+ type: "assistant_text_delta",
1881
+ text: responseText,
1882
+ conversationId,
1883
+ });
1884
+ broadcastMessage({ type: "message_complete", conversationId });
2352
1885
  } catch (err) {
2353
1886
  log.error({ err, conversationId }, "Compact command failed");
2354
- onEvent({
1887
+ broadcastMessage({
2355
1888
  type: "conversation_error",
2356
1889
  conversationId,
2357
1890
  code: "UNKNOWN",
@@ -2389,7 +1922,7 @@ export async function handleSendMessage(
2389
1922
  throw err;
2390
1923
  }
2391
1924
 
2392
- onEvent({
1925
+ broadcastMessage({
2393
1926
  type: "user_message_echo",
2394
1927
  text: resolvedContent,
2395
1928
  conversationId: mapping.conversationId,
@@ -2398,9 +1931,9 @@ export async function handleSendMessage(
2398
1931
  clientMessageId,
2399
1932
  });
2400
1933
 
2401
- // Fire-and-forget the agent loop; events flow to the hub via onEvent.
1934
+ // Fire-and-forget the agent loop; events flow to the hub via broadcastMessage.
2402
1935
  conversation
2403
- .runAgentLoop(resolvedContent, messageId, onEvent, {
1936
+ .runAgentLoop(resolvedContent, messageId, broadcastMessage, {
2404
1937
  isInteractive,
2405
1938
  isUserMessage: true,
2406
1939
  })