@vellumai/assistant 0.7.3 → 0.8.1

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 (778) hide show
  1. package/AGENTS.md +11 -0
  2. package/ARCHITECTURE.md +29 -28
  3. package/Dockerfile +6 -4
  4. package/README.md +2 -2
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  6. package/bun.lock +3 -0
  7. package/docker-entrypoint.sh +16 -0
  8. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  9. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  10. package/eslint.config.mjs +12 -0
  11. package/knip.json +3 -1
  12. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  13. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  14. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  15. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  16. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  17. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  18. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  19. package/openapi.yaml +4126 -959
  20. package/package.json +5 -1
  21. package/scripts/generate-openapi.ts +52 -4
  22. package/scripts/sync-llm-catalog.ts +165 -0
  23. package/scripts/sync-web-search-catalog.ts +107 -0
  24. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  25. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  26. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  27. package/src/__tests__/anthropic-provider.test.ts +92 -2
  28. package/src/__tests__/app-control-flow.test.ts +7 -0
  29. package/src/__tests__/approval-cascade.test.ts +8 -16
  30. package/src/__tests__/approval-routes-http.test.ts +6 -0
  31. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  32. package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
  33. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  34. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  35. package/src/__tests__/btw-routes.test.ts +1 -0
  36. package/src/__tests__/call-constants.test.ts +10 -1
  37. package/src/__tests__/call-controller.test.ts +127 -0
  38. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  39. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  40. package/src/__tests__/channel-policy.test.ts +12 -0
  41. package/src/__tests__/checker.test.ts +89 -0
  42. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
  43. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  44. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  45. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  46. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
  48. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  49. package/src/__tests__/config-schema.test.ts +14 -3
  50. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  51. package/src/__tests__/config-set-route.test.ts +198 -0
  52. package/src/__tests__/config-watcher.test.ts +6 -0
  53. package/src/__tests__/contacts-tools.test.ts +51 -199
  54. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  55. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  56. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  57. package/src/__tests__/context-search-fanout.test.ts +20 -157
  58. package/src/__tests__/context-search-memory-source.test.ts +3 -26
  59. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  60. package/src/__tests__/context-search-types.test.ts +7 -2
  61. package/src/__tests__/context-window-manager.test.ts +389 -1
  62. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
  63. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  64. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
  65. package/src/__tests__/conversation-agent-loop.test.ts +3 -3
  66. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  67. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  68. package/src/__tests__/conversation-error.test.ts +38 -0
  69. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  70. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  71. package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
  72. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  74. package/src/__tests__/conversation-process-callsite.test.ts +22 -7
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
  76. package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
  77. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  78. package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
  79. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  80. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  81. package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
  82. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
  83. package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
  84. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
  85. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  86. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  87. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  88. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  89. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  90. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  91. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  92. package/src/__tests__/filing-service.test.ts +25 -22
  93. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  94. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  95. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  96. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
  97. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  98. package/src/__tests__/heartbeat-service.test.ts +50 -233
  99. package/src/__tests__/history-repair.test.ts +89 -0
  100. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  101. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  102. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  103. package/src/__tests__/host-browser-routes.test.ts +325 -33
  104. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  105. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  106. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  107. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  108. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  109. package/src/__tests__/injector-chain.test.ts +24 -16
  110. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  111. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  112. package/src/__tests__/install-skill-routing.test.ts +2 -2
  113. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
  114. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  115. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  116. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  117. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  118. package/src/__tests__/llm-resolver.test.ts +46 -0
  119. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  120. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  121. package/src/__tests__/mcp-cli.test.ts +182 -220
  122. package/src/__tests__/mcp-health-check.test.ts +56 -27
  123. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  124. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  125. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  126. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  127. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  128. package/src/__tests__/oauth-cli.test.ts +38 -1888
  129. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  130. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  131. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  132. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  133. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  134. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  135. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  136. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  137. package/src/__tests__/plugin-types.test.ts +13 -11
  138. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  139. package/src/__tests__/profile-entry-status.test.ts +43 -0
  140. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  141. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  142. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  143. package/src/__tests__/relay-server.test.ts +164 -2
  144. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  145. package/src/__tests__/schedule-retry.test.ts +56 -4
  146. package/src/__tests__/schedule-routes.test.ts +104 -0
  147. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  148. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  149. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  150. package/src/__tests__/scheduler-wake.test.ts +0 -63
  151. package/src/__tests__/secret-allowlist.test.ts +1 -0
  152. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  153. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  154. package/src/__tests__/secret-response-routing.test.ts +7 -5
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  156. package/src/__tests__/server-history-render.test.ts +82 -0
  157. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  158. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  159. package/src/__tests__/skill-include-graph.test.ts +31 -0
  160. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  161. package/src/__tests__/skill-load-tool.test.ts +42 -16
  162. package/src/__tests__/skills.test.ts +39 -0
  163. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  164. package/src/__tests__/suggestion-routes.test.ts +3 -3
  165. package/src/__tests__/sync-message-contract.test.ts +63 -0
  166. package/src/__tests__/task-scheduler.test.ts +88 -23
  167. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  168. package/src/__tests__/tool-executor.test.ts +155 -0
  169. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  170. package/src/__tests__/usage-cli.test.ts +11 -73
  171. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  172. package/src/__tests__/vercel-config.test.ts +168 -0
  173. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  174. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  175. package/src/__tests__/web-search.test.ts +303 -2
  176. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  177. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  178. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
  179. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  180. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  181. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  182. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  183. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  184. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  185. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  186. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  187. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
  188. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  189. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  190. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  191. package/src/acp/resolve-agent.test.ts +25 -0
  192. package/src/acp/resolve-agent.ts +13 -2
  193. package/src/acp/session-manager.ts +14 -0
  194. package/src/agent/loop.ts +11 -0
  195. package/src/approvals/guardian-decision-primitive.ts +0 -13
  196. package/src/approvals/guardian-request-resolvers.ts +19 -102
  197. package/src/calls/call-constants.ts +5 -8
  198. package/src/calls/call-controller.ts +130 -67
  199. package/src/calls/relay-server.ts +42 -1
  200. package/src/calls/relay-setup-router.ts +36 -0
  201. package/src/calls/types.ts +1 -0
  202. package/src/calls/voice-session-bridge.ts +24 -5
  203. package/src/channels/config.ts +14 -1
  204. package/src/channels/types.ts +1 -0
  205. package/src/cli/AGENTS.md +164 -4
  206. package/src/cli/__tests__/notifications.test.ts +54 -0
  207. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  208. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  209. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  210. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  211. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  212. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  213. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  214. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  215. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  216. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  217. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  218. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  219. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  220. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  221. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  222. package/src/cli/commands/__tests__/status.test.ts +249 -0
  223. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  224. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  225. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  226. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  227. package/src/cli/commands/attachment.ts +8 -3
  228. package/src/cli/commands/audit.ts +95 -64
  229. package/src/cli/commands/auth.ts +61 -58
  230. package/src/cli/commands/avatar.ts +276 -390
  231. package/src/cli/commands/backup.ts +409 -505
  232. package/src/cli/commands/bash.ts +9 -5
  233. package/src/cli/commands/browser.ts +28 -9
  234. package/src/cli/commands/cache.ts +9 -4
  235. package/src/cli/commands/changelog.ts +414 -0
  236. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  237. package/src/cli/commands/clients.ts +8 -3
  238. package/src/cli/commands/completions.ts +9 -9
  239. package/src/cli/commands/config.ts +102 -72
  240. package/src/cli/commands/contacts.ts +575 -696
  241. package/src/cli/commands/conversations-defer.ts +17 -69
  242. package/src/cli/commands/conversations-import.ts +90 -253
  243. package/src/cli/commands/conversations.ts +346 -436
  244. package/src/cli/commands/credential-execution.ts +9 -6
  245. package/src/cli/commands/credentials.ts +456 -736
  246. package/src/cli/commands/domain.ts +128 -206
  247. package/src/cli/commands/email.ts +606 -794
  248. package/src/cli/commands/gateway.ts +8 -1
  249. package/src/cli/commands/image-generation.ts +157 -205
  250. package/src/cli/commands/inference-providers.ts +352 -0
  251. package/src/cli/commands/inference-session.ts +415 -0
  252. package/src/cli/commands/inference.ts +87 -65
  253. package/src/cli/commands/keys.ts +8 -3
  254. package/src/cli/commands/mcp.ts +103 -287
  255. package/src/cli/commands/memory-v2.ts +163 -517
  256. package/src/cli/commands/notifications.ts +33 -7
  257. package/src/cli/commands/oauth/apps.ts +292 -261
  258. package/src/cli/commands/oauth/connect.ts +182 -345
  259. package/src/cli/commands/oauth/disconnect.ts +16 -215
  260. package/src/cli/commands/oauth/index.ts +49 -45
  261. package/src/cli/commands/oauth/mode.ts +43 -199
  262. package/src/cli/commands/oauth/ping.ts +17 -125
  263. package/src/cli/commands/oauth/providers.ts +732 -921
  264. package/src/cli/commands/oauth/request.ts +60 -350
  265. package/src/cli/commands/oauth/shared.ts +11 -121
  266. package/src/cli/commands/oauth/status.ts +31 -121
  267. package/src/cli/commands/oauth/token.ts +13 -55
  268. package/src/cli/commands/pending.ts +19 -10
  269. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  270. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  271. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  272. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  273. package/src/cli/commands/platform/connect.ts +16 -80
  274. package/src/cli/commands/platform/disconnect.ts +14 -112
  275. package/src/cli/commands/platform/index.ts +177 -246
  276. package/src/cli/commands/routes.ts +153 -336
  277. package/src/cli/commands/sequence.ts +316 -360
  278. package/src/cli/commands/skills.ts +449 -671
  279. package/src/cli/commands/status.ts +58 -37
  280. package/src/cli/commands/stt.ts +94 -262
  281. package/src/cli/commands/task.ts +14 -40
  282. package/src/cli/commands/trust.ts +8 -3
  283. package/src/cli/commands/tts.ts +162 -167
  284. package/src/cli/commands/ui.ts +35 -42
  285. package/src/cli/commands/usage.ts +188 -126
  286. package/src/cli/commands/watchers.ts +8 -3
  287. package/src/cli/commands/webhooks.ts +99 -193
  288. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  289. package/src/cli/lib/daemon-credential-client.ts +4 -5
  290. package/src/cli/lib/nested-value.ts +44 -0
  291. package/src/cli/lib/open-browser.ts +36 -0
  292. package/src/cli/lib/register-command.ts +19 -0
  293. package/src/cli/lib/time-ago.ts +34 -0
  294. package/src/cli/program.ts +2 -4
  295. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  296. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  297. package/src/cli/utils/conversation-id.ts +30 -0
  298. package/src/cli/utils/parse-duration.ts +41 -0
  299. package/src/config/acp-defaults.test.ts +5 -1
  300. package/src/config/acp-defaults.ts +11 -4
  301. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  302. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  303. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  304. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  305. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  306. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  307. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  308. package/src/config/bundled-tool-registry.ts +0 -2
  309. package/src/config/feature-flag-registry.json +17 -17
  310. package/src/config/llm-resolver.ts +16 -1
  311. package/src/config/loader.ts +148 -33
  312. package/src/config/raw-config-utils.ts +2 -30
  313. package/src/config/schema.ts +4 -0
  314. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  315. package/src/config/schemas/call-site-catalog.ts +29 -7
  316. package/src/config/schemas/llm-request-logs.ts +57 -0
  317. package/src/config/schemas/llm.ts +52 -2
  318. package/src/config/schemas/memory-retrospective.ts +48 -0
  319. package/src/config/schemas/memory-v2.ts +33 -2
  320. package/src/config/schemas/memory.ts +4 -0
  321. package/src/config/schemas/services.ts +15 -12
  322. package/src/config/seed-inference-profiles.ts +195 -134
  323. package/src/contacts/contact-store.ts +0 -61
  324. package/src/context/window-manager.ts +191 -5
  325. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
  326. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  327. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  328. package/src/daemon/approval-generators.ts +23 -29
  329. package/src/daemon/config-watcher.ts +2 -0
  330. package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
  331. package/src/daemon/conversation-agent-loop.ts +140 -107
  332. package/src/daemon/conversation-error.ts +21 -0
  333. package/src/daemon/conversation-lifecycle.ts +68 -13
  334. package/src/daemon/conversation-process.ts +36 -19
  335. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  336. package/src/daemon/conversation-slash.ts +175 -23
  337. package/src/daemon/conversation-store.ts +17 -10
  338. package/src/daemon/conversation-surfaces.ts +92 -26
  339. package/src/daemon/conversation-tool-setup.ts +33 -19
  340. package/src/daemon/conversation.ts +49 -10
  341. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  342. package/src/daemon/guardian-action-generators.ts +7 -22
  343. package/src/daemon/handlers/config-model.ts +8 -126
  344. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  345. package/src/daemon/handlers/config-vercel.ts +3 -1
  346. package/src/daemon/handlers/shared.ts +26 -0
  347. package/src/daemon/handlers/skills.ts +84 -5
  348. package/src/daemon/history-repair.ts +33 -6
  349. package/src/daemon/host-app-control-proxy.ts +44 -19
  350. package/src/daemon/host-bash-proxy.ts +85 -158
  351. package/src/daemon/host-browser-proxy.ts +97 -36
  352. package/src/daemon/host-cu-proxy.ts +1 -1
  353. package/src/daemon/host-file-proxy.ts +1 -1
  354. package/src/daemon/host-proxy-base.ts +13 -1
  355. package/src/daemon/host-proxy-preactivation.ts +25 -1
  356. package/src/daemon/host-transfer-proxy.ts +2 -2
  357. package/src/daemon/identity-helpers.ts +19 -0
  358. package/src/daemon/lifecycle.ts +128 -114
  359. package/src/daemon/meet-host-supervisor.ts +15 -15
  360. package/src/daemon/memory-v2-startup.ts +62 -14
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/bookmarks.ts +18 -0
  363. package/src/daemon/message-types/conversations.ts +12 -9
  364. package/src/daemon/message-types/messages.ts +28 -2
  365. package/src/daemon/message-types/sync.ts +60 -0
  366. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  367. package/src/daemon/pkb-reminder-builder.ts +21 -7
  368. package/src/daemon/process-message.ts +56 -23
  369. package/src/daemon/server.ts +23 -18
  370. package/src/daemon/shutdown-handlers.ts +0 -2
  371. package/src/daemon/tool-setup-types.ts +9 -0
  372. package/src/daemon/tool-side-effects.ts +6 -4
  373. package/src/daemon/wake-target-adapter.ts +11 -0
  374. package/src/documents/document-store.ts +35 -1
  375. package/src/export/transcript-formatter.ts +61 -2
  376. package/src/filing/filing-service.ts +42 -56
  377. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  378. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  379. package/src/heartbeat/heartbeat-service.ts +149 -128
  380. package/src/home/__tests__/feed-types.test.ts +63 -131
  381. package/src/home/__tests__/feed-writer.test.ts +77 -278
  382. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  383. package/src/home/feed-types.ts +19 -73
  384. package/src/home/feed-writer.ts +25 -156
  385. package/src/home/post-connect-feed.ts +1 -3
  386. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  387. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  388. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  389. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  390. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  391. package/src/ipc/assistant-server.ts +148 -42
  392. package/src/ipc/cli-client.ts +370 -50
  393. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  394. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  395. package/src/ipc/skill-routes/events.ts +30 -3
  396. package/src/ipc/skill-server.ts +99 -42
  397. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  398. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  399. package/src/live-voice/live-voice-session-manager.ts +11 -4
  400. package/src/live-voice/live-voice-session.ts +14 -6
  401. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  402. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  403. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  404. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  405. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
  406. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  407. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  408. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  409. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  412. package/src/memory/bookmark-crud.ts +179 -0
  413. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  414. package/src/memory/context-search/agent-protocol.ts +5 -1
  415. package/src/memory/context-search/agent-runner.ts +60 -85
  416. package/src/memory/context-search/limits.ts +1 -4
  417. package/src/memory/context-search/search.ts +23 -113
  418. package/src/memory/context-search/sources/conversations.ts +18 -6
  419. package/src/memory/context-search/sources/memory-v2.ts +40 -31
  420. package/src/memory/context-search/sources/memory.ts +9 -2
  421. package/src/memory/context-search/sources/workspace.ts +13 -10
  422. package/src/memory/context-search/types.ts +1 -1
  423. package/src/memory/conversation-bootstrap.ts +11 -0
  424. package/src/memory/conversation-crud.ts +312 -10
  425. package/src/memory/conversation-queries.ts +9 -5
  426. package/src/memory/conversation-title-service.ts +1 -0
  427. package/src/memory/conversation-types.ts +16 -0
  428. package/src/memory/db-init.ts +14 -0
  429. package/src/memory/embedding-backend.ts +2 -1
  430. package/src/memory/embedding-runtime-manager.ts +1 -2
  431. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
  432. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  433. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  434. package/src/memory/graph/conversation-graph-memory.ts +108 -14
  435. package/src/memory/graph/extraction.ts +4 -0
  436. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  437. package/src/memory/graph/graph-search.test.ts +6 -5
  438. package/src/memory/graph/graph-search.ts +3 -4
  439. package/src/memory/graph/retriever.test.ts +12 -7
  440. package/src/memory/graph/retriever.ts +4 -5
  441. package/src/memory/graph/tool-handlers.ts +20 -11
  442. package/src/memory/graph/tools.ts +48 -9
  443. package/src/memory/indexer.ts +18 -2
  444. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
  445. package/src/memory/jobs/embed-concept-page.ts +261 -89
  446. package/src/memory/jobs-store.ts +51 -1
  447. package/src/memory/jobs-worker.ts +60 -7
  448. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  449. package/src/memory/llm-request-log-source-local.ts +26 -0
  450. package/src/memory/llm-request-log-source.ts +97 -0
  451. package/src/memory/llm-request-log-store.ts +1 -1
  452. package/src/memory/memory-retrospective-constants.ts +13 -0
  453. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  454. package/src/memory/memory-retrospective-job.ts +351 -0
  455. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  456. package/src/memory/memory-retrospective-state.ts +162 -0
  457. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  458. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  459. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  460. package/src/memory/message-content.ts +38 -1
  461. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  462. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  463. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  464. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  465. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  466. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  467. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  468. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  469. package/src/memory/migrations/243-provider-connections.ts +68 -0
  470. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  471. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  472. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  473. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  474. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  475. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  476. package/src/memory/migrations/index.ts +7 -0
  477. package/src/memory/pkb/pkb-search.test.ts +6 -5
  478. package/src/memory/pkb/pkb-search.ts +4 -5
  479. package/src/memory/published-pages-store.ts +16 -0
  480. package/src/memory/qdrant-client.ts +3 -0
  481. package/src/memory/schema/bookmarks.ts +38 -0
  482. package/src/memory/schema/conversations.ts +2 -0
  483. package/src/memory/schema/index.ts +2 -0
  484. package/src/memory/schema/inference.ts +29 -0
  485. package/src/memory/schema/memory-core.ts +9 -0
  486. package/src/memory/search/semantic.ts +5 -9
  487. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  488. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  489. package/src/memory/v2/__tests__/activation.test.ts +46 -9
  490. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  491. package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
  492. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  493. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  494. package/src/memory/v2/__tests__/injection.test.ts +768 -33
  495. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  496. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  497. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  498. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  499. package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
  500. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  501. package/src/memory/v2/__tests__/router.test.ts +516 -0
  502. package/src/memory/v2/__tests__/sim.test.ts +163 -8
  503. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  504. package/src/memory/v2/__tests__/static-context.test.ts +8 -35
  505. package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
  506. package/src/memory/v2/activation-store.ts +34 -5
  507. package/src/memory/v2/activation.ts +40 -27
  508. package/src/memory/v2/backfill-jobs.ts +17 -84
  509. package/src/memory/v2/consolidation-job.ts +92 -86
  510. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  511. package/src/memory/v2/injection.ts +466 -115
  512. package/src/memory/v2/migration.ts +117 -20
  513. package/src/memory/v2/page-index.ts +191 -0
  514. package/src/memory/v2/page-store.ts +42 -0
  515. package/src/memory/v2/prompts/consolidation.ts +14 -7
  516. package/src/memory/v2/prompts/router.ts +192 -0
  517. package/src/memory/v2/qdrant.ts +307 -133
  518. package/src/memory/v2/reranker.ts +14 -7
  519. package/src/memory/v2/router.ts +322 -0
  520. package/src/memory/v2/sim.ts +88 -34
  521. package/src/memory/v2/skill-store.ts +118 -29
  522. package/src/memory/v2/static-context.ts +20 -17
  523. package/src/memory/v2/sweep-job.ts +127 -102
  524. package/src/memory/v2/types.ts +16 -5
  525. package/src/memory/validation.ts +13 -0
  526. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  527. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  528. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  529. package/src/notifications/adapters/platform.ts +171 -0
  530. package/src/notifications/conversation-pairing.ts +2 -2
  531. package/src/notifications/copy-composer.ts +61 -12
  532. package/src/notifications/decision-engine.ts +46 -0
  533. package/src/notifications/destination-resolver.ts +21 -0
  534. package/src/notifications/emit-signal.ts +28 -1
  535. package/src/notifications/home-feed-side-effect.ts +111 -0
  536. package/src/notifications/signal.ts +5 -0
  537. package/src/permissions/checker.ts +12 -0
  538. package/src/permissions/gateway-threshold-reader.ts +116 -8
  539. package/src/permissions/ipc-risk-types.ts +2 -0
  540. package/src/permissions/prompter.ts +86 -96
  541. package/src/permissions/secret-prompter.ts +31 -31
  542. package/src/plugin-api/index.ts +13 -0
  543. package/src/plugin-api/package.json +12 -0
  544. package/src/plugin-api/types.ts +62 -0
  545. package/src/plugins/defaults/injectors.ts +20 -5
  546. package/src/plugins/external-plugin-loader.ts +294 -0
  547. package/src/plugins/types.ts +46 -30
  548. package/src/plugins/user-loader.ts +64 -41
  549. package/src/proactive-artifact/job.test.ts +63 -8
  550. package/src/proactive-artifact/job.ts +20 -2
  551. package/src/proactive-artifact/message-copy.ts +18 -1
  552. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  553. package/src/proactive-artifact/trigger-state.ts +4 -0
  554. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  555. package/src/prompts/system-prompt.ts +22 -1
  556. package/src/prompts/templates/SOUL.md +13 -28
  557. package/src/prompts/update-bulletin-job.ts +61 -73
  558. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  559. package/src/providers/__tests__/inference.test.ts +288 -0
  560. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  561. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  562. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  563. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  564. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  565. package/src/providers/anthropic/client.ts +95 -26
  566. package/src/providers/call-site-routing.ts +94 -16
  567. package/src/providers/connection-resolution.ts +163 -0
  568. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  569. package/src/providers/inference/adapter-factory.ts +173 -0
  570. package/src/providers/inference/auth.ts +112 -0
  571. package/src/providers/inference/backfill.ts +196 -0
  572. package/src/providers/inference/connections.ts +356 -0
  573. package/src/providers/inference/resolve-auth.ts +65 -0
  574. package/src/providers/model-catalog.ts +104 -6
  575. package/src/providers/openai/responses-provider.ts +4 -2
  576. package/src/providers/provider-env-vars.ts +17 -7
  577. package/src/providers/provider-secret-catalog.ts +49 -30
  578. package/src/providers/provider-send-message.ts +41 -20
  579. package/src/providers/registry.ts +143 -159
  580. package/src/providers/retry.ts +18 -10
  581. package/src/providers/search-provider-catalog.ts +121 -0
  582. package/src/runtime/AGENTS.md +18 -5
  583. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  584. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  585. package/src/runtime/actor-trust-resolver.ts +32 -10
  586. package/src/runtime/agent-wake.ts +35 -6
  587. package/src/runtime/assistant-event-hub.ts +3 -85
  588. package/src/runtime/auth/route-policy.ts +304 -8
  589. package/src/runtime/auth/same-actor.ts +2 -0
  590. package/src/runtime/background-job-runner.ts +339 -0
  591. package/src/runtime/btw-sidechain.ts +1 -0
  592. package/src/runtime/channel-approvals.ts +3 -2
  593. package/src/runtime/guardian-reply-router.ts +0 -10
  594. package/src/runtime/http-router.ts +36 -1
  595. package/src/runtime/http-server.ts +31 -5
  596. package/src/runtime/http-types.ts +2 -0
  597. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  598. package/src/runtime/middleware/request-logger.ts +62 -1
  599. package/src/runtime/pending-interactions.ts +19 -15
  600. package/src/runtime/pre-first-message-gate.ts +83 -0
  601. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  602. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  603. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  604. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  605. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  606. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  607. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  608. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  609. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  610. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  611. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  612. package/src/runtime/routes/acp-routes.ts +10 -8
  613. package/src/runtime/routes/app-management-routes.ts +228 -3
  614. package/src/runtime/routes/approval-routes.ts +7 -21
  615. package/src/runtime/routes/audit-routes.ts +43 -0
  616. package/src/runtime/routes/auth-routes.ts +72 -0
  617. package/src/runtime/routes/avatar-routes.ts +273 -20
  618. package/src/runtime/routes/backup-routes.ts +406 -2
  619. package/src/runtime/routes/bookmark-routes.ts +154 -0
  620. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  621. package/src/runtime/routes/consolidation-routes.ts +8 -9
  622. package/src/runtime/routes/contact-routes.ts +0 -160
  623. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  624. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  625. package/src/runtime/routes/conversation-query-routes.ts +373 -82
  626. package/src/runtime/routes/conversation-routes.ts +31 -10
  627. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  628. package/src/runtime/routes/credential-routes.ts +540 -0
  629. package/src/runtime/routes/debug-bash-routes.ts +2 -0
  630. package/src/runtime/routes/debug-routes.ts +2 -2
  631. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  632. package/src/runtime/routes/domain-routes.ts +167 -0
  633. package/src/runtime/routes/email-routes.ts +603 -0
  634. package/src/runtime/routes/errors.ts +2 -2
  635. package/src/runtime/routes/events-routes.ts +192 -0
  636. package/src/runtime/routes/filing-routes.ts +2 -3
  637. package/src/runtime/routes/home-feed-routes.ts +6 -78
  638. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  639. package/src/runtime/routes/host-browser-routes.ts +103 -22
  640. package/src/runtime/routes/http-adapter.ts +2 -0
  641. package/src/runtime/routes/identity-routes.ts +5 -0
  642. package/src/runtime/routes/image-generation-routes.ts +99 -0
  643. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  644. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  645. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  646. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
  647. package/src/runtime/routes/index.ts +36 -0
  648. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  649. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  650. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  651. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  652. package/src/runtime/routes/inference-send-routes.ts +115 -0
  653. package/src/runtime/routes/integrations/twilio.ts +1 -0
  654. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  655. package/src/runtime/routes/memory-item-routes.test.ts +3 -9
  656. package/src/runtime/routes/memory-item-routes.ts +5 -6
  657. package/src/runtime/routes/memory-v2-routes.ts +105 -404
  658. package/src/runtime/routes/notification-routes.ts +2 -0
  659. package/src/runtime/routes/oauth-apps.ts +112 -7
  660. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  661. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  662. package/src/runtime/routes/oauth-providers.ts +298 -8
  663. package/src/runtime/routes/platform-routes.ts +336 -0
  664. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  665. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  666. package/src/runtime/routes/playground/state.ts +2 -1
  667. package/src/runtime/routes/publish-routes.ts +221 -0
  668. package/src/runtime/routes/schedule-routes.ts +82 -0
  669. package/src/runtime/routes/sequence-routes.ts +291 -0
  670. package/src/runtime/routes/settings-routes.ts +2 -10
  671. package/src/runtime/routes/skills-routes.ts +31 -1
  672. package/src/runtime/routes/stt-routes.ts +240 -3
  673. package/src/runtime/routes/surface-action-routes.ts +43 -7
  674. package/src/runtime/routes/tts-routes.ts +67 -0
  675. package/src/runtime/routes/types.ts +32 -0
  676. package/src/runtime/routes/user-routes-cli.ts +243 -0
  677. package/src/runtime/routes/webhook-routes.ts +165 -0
  678. package/src/runtime/sync/resource-sync-events.ts +25 -0
  679. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  680. package/src/runtime/sync/sync-publisher.ts +21 -0
  681. package/src/schedule/scheduler.ts +200 -123
  682. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  683. package/src/security/secret-patterns.ts +3 -0
  684. package/src/sequence/engine.ts +38 -40
  685. package/src/skills/include-graph.ts +35 -13
  686. package/src/subagent/manager.ts +20 -15
  687. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  688. package/src/tools/browser/browser-execution.ts +15 -4
  689. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  690. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  691. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  692. package/src/tools/browser/cdp-client/factory.ts +66 -5
  693. package/src/tools/browser/runtime-check.ts +77 -0
  694. package/src/tools/document/document-tool.ts +20 -0
  695. package/src/tools/executor.ts +18 -2
  696. package/src/tools/memory/register.test.ts +10 -8
  697. package/src/tools/memory/register.ts +9 -1
  698. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  699. package/src/tools/network/web-search.ts +280 -37
  700. package/src/tools/permission-checker.ts +28 -5
  701. package/src/tools/skills/load.ts +24 -20
  702. package/src/tools/subagent/spawn.ts +3 -3
  703. package/src/tools/terminal/shell.ts +44 -0
  704. package/src/tools/tool-name-aliases.ts +19 -0
  705. package/src/tools/types.ts +19 -1
  706. package/src/usage/attribution.ts +3 -2
  707. package/src/util/pricing.ts +86 -160
  708. package/src/watcher/__tests__/engine.test.ts +301 -0
  709. package/src/watcher/constants.ts +7 -0
  710. package/src/watcher/engine.ts +90 -90
  711. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  712. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  713. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  714. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
  715. package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
  716. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  717. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  718. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  719. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  720. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  721. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  722. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  723. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  724. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  725. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  726. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  727. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  728. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  729. package/src/workspace/migrations/registry.ts +28 -0
  730. package/src/workspace/migrations/runner.ts +13 -2
  731. package/src/workspace/migrations/types.ts +13 -3
  732. package/src/workspace/provider-commit-message-generator.ts +3 -2
  733. package/src/__tests__/context-search-pkb-source.test.ts +0 -492
  734. package/src/__tests__/credentials-cli.test.ts +0 -1225
  735. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  736. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  737. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  738. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  739. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  740. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  741. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  742. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  743. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  744. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  745. package/src/cli/commands/autonomy.ts +0 -365
  746. package/src/cli/commands/memory.ts +0 -424
  747. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
  748. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  749. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  750. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  751. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  752. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  753. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  754. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  755. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  756. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  757. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  758. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  759. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  760. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  761. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  762. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  763. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  764. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  765. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  766. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  767. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  768. package/src/home/assistant-feed-authoring.ts +0 -135
  769. package/src/home/emit-feed-event.ts +0 -169
  770. package/src/home/feed-scheduler.ts +0 -281
  771. package/src/home/platform-gmail-digest.ts +0 -163
  772. package/src/home/rewrite-command-preview.ts +0 -66
  773. package/src/home/rewrite-feed-title.ts +0 -58
  774. package/src/home/rollup-producer.ts +0 -426
  775. package/src/memory/admin.ts +0 -326
  776. package/src/memory/context-search/sources/pkb.ts +0 -477
  777. package/src/memory/graph/compaction.ts +0 -299
  778. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -1,10 +1,5 @@
1
- import { v4 as uuid } from "uuid";
2
-
3
1
  import { getConfig } from "../config/loader.js";
4
- import {
5
- assistantEventHub,
6
- broadcastMessage,
7
- } from "../runtime/assistant-event-hub.js";
2
+ import { assistantEventHub } from "../runtime/assistant-event-hub.js";
8
3
  import {
9
4
  ambiguousSameUserError,
10
5
  enforceSameActorOrErrorResult,
@@ -13,14 +8,42 @@ import {
13
8
  import * as pendingInteractions from "../runtime/pending-interactions.js";
14
9
  import { formatShellOutput } from "../tools/shared/shell-output.js";
15
10
  import type { ToolExecutionResult } from "../tools/types.js";
16
- import { AssistantError, ErrorCode } from "../util/errors.js";
17
11
  import { getLogger } from "../util/logger.js";
12
+ import { HostProxyBase, HostProxyRequestError } from "./host-proxy-base.js";
18
13
 
19
14
  const log = getLogger("host-bash-proxy");
20
15
 
21
- export class HostBashProxy {
16
+ export type HostBashInput = {
17
+ command: string;
18
+ working_dir?: string;
19
+ timeout_seconds?: number;
20
+ env?: Record<string, string>;
21
+ targetClientId?: string;
22
+ };
23
+
24
+ type HostBashResultPayload = {
25
+ stdout: string;
26
+ stderr: string;
27
+ exitCode: number | null;
28
+ timedOut: boolean;
29
+ };
30
+
31
+ export class HostBashProxy extends HostProxyBase<
32
+ Record<string, unknown>,
33
+ HostBashResultPayload
34
+ > {
22
35
  private static _instance: HostBashProxy | null = null;
23
36
 
37
+ constructor() {
38
+ super({
39
+ capabilityName: "host_bash",
40
+ requestEventName: "host_bash_request",
41
+ cancelEventName: "host_bash_cancel",
42
+ resultPendingKind: "host_bash",
43
+ disposedMessage: "Host bash proxy disposed",
44
+ });
45
+ }
46
+
24
47
  /**
25
48
  * Lazily-initialized singleton. Availability of an actual desktop
26
49
  * connection is checked at send time via the assistant event hub,
@@ -47,31 +70,15 @@ export class HostBashProxy {
47
70
  HostBashProxy._instance = null;
48
71
  }
49
72
 
50
- /**
51
- * Whether a client with `host_bash` capability is connected.
52
- */
53
- isAvailable(): boolean {
54
- return (
55
- assistantEventHub.getMostRecentClientByCapability("host_bash") != null
56
- );
57
- }
58
-
59
- request(
60
- input: {
61
- command: string;
62
- working_dir?: string;
63
- timeout_seconds?: number;
64
- env?: Record<string, string>;
65
- targetClientId?: string;
66
- },
73
+ async request(
74
+ input: HostBashInput,
67
75
  conversationId: string,
68
76
  signal?: AbortSignal,
69
77
  // Principal ID of the actor on whose behalf this request is initiated.
70
78
  sourceActorPrincipalId?: string,
71
79
  ): Promise<ToolExecutionResult> {
72
80
  if (signal?.aborted) {
73
- const result = formatShellOutput("", "Aborted", null, false, 0);
74
- return Promise.resolve(result);
81
+ return formatShellOutput("", "Aborted", null, false, 0);
75
82
  }
76
83
 
77
84
  let resolvedTargetClientId: string | undefined;
@@ -79,10 +86,10 @@ export class HostBashProxy {
79
86
  if (input.targetClientId) {
80
87
  const target = assistantEventHub.getClientById(input.targetClientId);
81
88
  if (!target || !target.capabilities.includes("host_bash")) {
82
- return Promise.resolve({
89
+ return {
83
90
  content: `Error: client "${input.targetClientId}" is not connected or does not support host_bash. Run \`assistant clients list --capability host_bash\` to see available clients.`,
84
91
  isError: true,
85
- });
92
+ };
86
93
  }
87
94
  resolvedTargetClientId = input.targetClientId;
88
95
  } else {
@@ -97,7 +104,7 @@ export class HostBashProxy {
97
104
  sourceActorPrincipalId,
98
105
  });
99
106
  if (resolved.kind === "ambiguous") {
100
- return Promise.resolve(ambiguousSameUserError("host_bash"));
107
+ return ambiguousSameUserError("host_bash");
101
108
  }
102
109
  resolvedTargetClientId =
103
110
  resolved.kind === "match" ? resolved.clientId : undefined;
@@ -114,98 +121,56 @@ export class HostBashProxy {
114
121
  targetClientId: resolvedTargetClientId,
115
122
  op: "host_bash",
116
123
  });
117
- if (rejection) return Promise.resolve(rejection);
124
+ if (rejection) return rejection;
118
125
  }
119
126
 
120
- const requestId = uuid();
121
-
122
- return new Promise<ToolExecutionResult>((resolve, reject) => {
123
- const shellMaxTimeoutSec = getConfig().timeouts.shellMaxTimeoutSec;
124
- const timeoutSec = input.timeout_seconds ?? shellMaxTimeoutSec;
125
- const proxyTimeoutSec = timeoutSec + 3;
126
-
127
- let detachAbort: () => void = () => {};
128
-
129
- const timer = setTimeout(() => {
130
- pendingInteractions.resolve(requestId);
131
- log.warn(
132
- { requestId, command: input.command },
133
- "Host bash proxy request timed out",
134
- );
135
- const timeoutMessage = resolvedTargetClientId
136
- ? `Host bash proxy timed out waiting for response from client ${resolvedTargetClientId}`
137
- : "Host bash proxy timed out waiting for client response";
138
- resolve(formatShellOutput("", timeoutMessage, null, true, timeoutSec));
139
- }, proxyTimeoutSec * 1000);
140
-
141
- if (signal) {
142
- const onAbort = () => {
143
- if (pendingInteractions.get(requestId)) {
144
- pendingInteractions.resolve(requestId);
145
- try {
146
- broadcastMessage(
147
- {
148
- type: "host_bash_cancel",
149
- requestId,
150
- conversationId,
151
- targetClientId: resolvedTargetClientId,
152
- },
153
- conversationId,
154
- { targetClientId: resolvedTargetClientId },
155
- );
156
- } catch {
157
- // Best-effort cancel notification
158
- }
159
- resolve(formatShellOutput("", "Aborted", null, false, 0));
160
- }
161
- };
162
- signal.addEventListener("abort", onAbort, { once: true });
163
- detachAbort = () => signal.removeEventListener("abort", onAbort);
164
- }
165
-
166
- pendingInteractions.register(requestId, {
127
+ const shellMaxTimeoutSec = getConfig().timeouts.shellMaxTimeoutSec;
128
+ const timeoutSec = input.timeout_seconds ?? shellMaxTimeoutSec;
129
+ const proxyTimeoutMs = (timeoutSec + 3) * 1000;
130
+
131
+ // Spread command fields at the top level of the envelope so the desktop
132
+ // client receives the same flat message shape it has always expected.
133
+ const extraFields: Record<string, unknown> = { command: input.command };
134
+ if (input.working_dir !== undefined) extraFields.working_dir = input.working_dir;
135
+ if (input.timeout_seconds !== undefined)
136
+ extraFields.timeout_seconds = input.timeout_seconds;
137
+ if (input.env && Object.keys(input.env).length > 0) extraFields.env = input.env;
138
+
139
+ try {
140
+ const payload = await this.dispatchRequest(
141
+ "host_bash",
142
+ {},
167
143
  conversationId,
168
- kind: "host_bash",
169
- rpcResolve: resolve,
170
- rpcReject: reject,
171
- timer,
172
- detachAbort,
173
- targetClientId: resolvedTargetClientId,
174
- targetActorPrincipalId:
175
- resolvedTargetClientId != null
176
- ? assistantEventHub.getActorPrincipalIdForClient(
177
- resolvedTargetClientId,
178
- )
179
- : undefined,
180
- metadata: { timeoutSec },
181
- });
182
-
183
- try {
184
- broadcastMessage(
185
- {
186
- type: "host_bash_request",
187
- requestId,
188
- conversationId,
189
- command: input.command,
190
- working_dir: input.working_dir,
191
- timeout_seconds: input.timeout_seconds,
192
- targetClientId: resolvedTargetClientId,
193
- ...(input.env && Object.keys(input.env).length > 0
194
- ? { env: input.env }
195
- : {}),
196
- },
197
- conversationId,
198
- { targetClientId: resolvedTargetClientId },
199
- );
200
- } catch (err) {
201
- pendingInteractions.resolve(requestId);
202
- log.warn(
203
- { requestId, command: input.command, err },
204
- "Host bash proxy send failed",
205
- );
206
- reject(err instanceof Error ? err : new Error(String(err)));
144
+ signal,
145
+ extraFields,
146
+ resolvedTargetClientId,
147
+ proxyTimeoutMs,
148
+ );
149
+ return formatShellOutput(
150
+ payload.stdout,
151
+ payload.stderr,
152
+ payload.exitCode,
153
+ payload.timedOut,
154
+ timeoutSec,
155
+ );
156
+ } catch (err) {
157
+ if (err instanceof HostProxyRequestError) {
158
+ if (err.reason === "timeout") {
159
+ log.warn(
160
+ { command: input.command },
161
+ "Host bash proxy request timed out",
162
+ );
163
+ const msg = resolvedTargetClientId
164
+ ? `Host bash proxy timed out waiting for response from client ${resolvedTargetClientId}`
165
+ : "Host bash proxy timed out waiting for client response";
166
+ return formatShellOutput("", msg, null, true, timeoutSec);
167
+ }
168
+ if (err.reason === "aborted") {
169
+ return formatShellOutput("", "Aborted", null, false, 0);
170
+ }
207
171
  }
208
- });
172
+ throw err;
173
+ }
209
174
  }
210
175
 
211
176
  /**
@@ -220,45 +185,7 @@ export class HostBashProxy {
220
185
  timedOut: boolean;
221
186
  },
222
187
  ): void {
223
- const interaction = pendingInteractions.resolve(requestId);
224
- if (!interaction?.rpcResolve) {
225
- log.warn({ requestId }, "No pending host bash request for response");
226
- return;
227
- }
228
- const timeoutSec = (interaction.metadata?.timeoutSec as number) ?? 0;
229
- const result = formatShellOutput(
230
- response.stdout,
231
- response.stderr,
232
- response.exitCode,
233
- response.timedOut,
234
- timeoutSec,
235
- );
236
- interaction.rpcResolve(result);
237
- }
238
-
239
- dispose(): void {
240
- for (const entry of pendingInteractions.getByKind("host_bash")) {
241
- pendingInteractions.resolve(entry.requestId);
242
- try {
243
- broadcastMessage(
244
- {
245
- type: "host_bash_cancel",
246
- requestId: entry.requestId,
247
- conversationId: entry.conversationId,
248
- targetClientId: entry.targetClientId,
249
- },
250
- entry.conversationId,
251
- { targetClientId: entry.targetClientId },
252
- );
253
- } catch {
254
- // Best-effort cancel notification — connection may already be closed.
255
- }
256
- entry.rpcReject?.(
257
- new AssistantError(
258
- "Host bash proxy disposed",
259
- ErrorCode.INTERNAL_ERROR,
260
- ),
261
- );
262
- }
188
+ pendingInteractions.resolve(requestId);
189
+ this.resolve(requestId, response);
263
190
  }
264
191
  }
@@ -1,10 +1,10 @@
1
1
  import { v4 as uuid } from "uuid";
2
2
 
3
- import type { InterfaceId } from "../channels/types.js";
4
3
  import {
5
4
  assistantEventHub,
6
5
  broadcastMessage,
7
6
  } from "../runtime/assistant-event-hub.js";
7
+ import { enforceSameActorOrErrorResult } from "../runtime/auth/same-actor.js";
8
8
  import * as pendingInteractions from "../runtime/pending-interactions.js";
9
9
  import type { ToolExecutionResult } from "../tools/types.js";
10
10
  import { AssistantError, ErrorCode } from "../util/errors.js";
@@ -24,11 +24,49 @@ export type HostBrowserInput = DistributiveOmit<
24
24
 
25
25
  const log = getLogger("host-browser-proxy");
26
26
 
27
- /** Interface priority order for host_browser: Chrome Extension first, macOS SSE bridge second. */
28
- const HOST_BROWSER_INTERFACE_PREFERENCE: InterfaceId[] = [
29
- "chrome-extension",
30
- "macos",
31
- ];
27
+ /**
28
+ * Pick the host_browser-capable client to dispatch to.
29
+ *
30
+ * When `targetClientId` is supplied, the client with that id is looked
31
+ * up directly in the `host_browser`-capable roster. The same-actor check
32
+ * in `request()` still runs on the returned client when
33
+ * `sourceActorPrincipalId` is present.
34
+ *
35
+ * When `sourceActorPrincipalId` is supplied (and no explicit target),
36
+ * candidate clients are filtered down to those owned by the same actor.
37
+ * Returns `undefined` when no same-actor client is connected; the
38
+ * caller surfaces this as the existing "no active extension connection"
39
+ * rejection.
40
+ *
41
+ * When neither is supplied (legacy callers without a resolved actor
42
+ * identity), falls through to the most-recently-active host_browser
43
+ * client so the registry singleton continues to work for single-client
44
+ * setups.
45
+ *
46
+ * Within each branch, ties are broken by `lastActiveAt` descending —
47
+ * the natural order returned by `listClientsByCapability`. Callers that
48
+ * need a specific transport (e.g. Chrome Extension's `chrome.debugger`
49
+ * over the macOS CDP bridge) must pass `targetClientId` explicitly via
50
+ * the LLM-facing param added in #30066.
51
+ */
52
+ function resolveTargetClient(
53
+ sourceActorPrincipalId: string | undefined,
54
+ targetClientId?: string,
55
+ ) {
56
+ if (targetClientId != null) {
57
+ const clients = assistantEventHub.listClientsByCapability("host_browser");
58
+ return clients.find((c) => c.clientId === targetClientId);
59
+ }
60
+
61
+ const candidates =
62
+ assistantEventHub.listClientsByCapability("host_browser");
63
+ if (sourceActorPrincipalId == null) {
64
+ return candidates[0];
65
+ }
66
+ return candidates.find(
67
+ (c) => c.actorPrincipalId === sourceActorPrincipalId,
68
+ );
69
+ }
32
70
 
33
71
  export class HostBrowserProxy {
34
72
  private static _instance: HostBrowserProxy | null = null;
@@ -67,10 +105,7 @@ export class HostBrowserProxy {
67
105
  */
68
106
  isAvailable(): boolean {
69
107
  return (
70
- assistantEventHub.getPreferredClientByCapability(
71
- "host_browser",
72
- HOST_BROWSER_INTERFACE_PREFERENCE,
73
- ) != null
108
+ assistantEventHub.getMostRecentClientByCapability("host_browser") != null
74
109
  );
75
110
  }
76
111
 
@@ -84,15 +119,64 @@ export class HostBrowserProxy {
84
119
  return assistantEventHub.listClientsByInterface("chrome-extension").length > 0;
85
120
  }
86
121
 
122
+ /**
123
+ * Send a host_browser request to the connected extension/macOS bridge.
124
+ *
125
+ * When `targetClientId` is supplied, the proxy dispatches to that specific
126
+ * client (subject to the `host_browser` capability check and the same-actor
127
+ * gate below). This mirrors the `target_client_id` pattern on `host_bash`,
128
+ * `host_file_*`, and `host_cu`.
129
+ *
130
+ * When `sourceActorPrincipalId` is supplied, the proxy refuses to dispatch
131
+ * to a client owned by a different actor — same-user enforcement is the
132
+ * authoritative gate against routing one actor's CDP request onto another
133
+ * actor's connected extension. The resolved target's `clientId` and
134
+ * `actorPrincipalId` are then persisted alongside the pending interaction
135
+ * so that the result-route's same-actor check can verify the submitting
136
+ * client at result time.
137
+ *
138
+ * When `sourceActorPrincipalId` is undefined (legacy/internal flows
139
+ * with no resolved actor identity), falls back to the most-recently-
140
+ * active host_browser client without an actor filter so the registry
141
+ * singleton continues to work for single-client setups.
142
+ */
87
143
  request(
88
144
  input: HostBrowserInput,
89
145
  conversationId: string,
90
146
  signal?: AbortSignal,
147
+ sourceActorPrincipalId?: string,
148
+ targetClientId?: string,
91
149
  ): Promise<ToolExecutionResult> {
92
150
  if (signal?.aborted) {
93
151
  return Promise.resolve({ content: "Aborted", isError: true });
94
152
  }
95
153
 
154
+ // Resolve the target client up front so we can persist the actor binding
155
+ // alongside the pending interaction registration. Same shape as
156
+ // host-cu-proxy: the result-route same-actor check compares the
157
+ // submitting client's actor against this captured value.
158
+ const preferredClient = resolveTargetClient(sourceActorPrincipalId, targetClientId);
159
+
160
+ // Same-user enforcement: when the caller's actor is known, refuse to
161
+ // dispatch to a client owned by a different actor. This covers the
162
+ // cross-client exposure case where a web/iOS turn for actor A would
163
+ // otherwise auto-resolve to actor B's connected extension.
164
+ if (
165
+ sourceActorPrincipalId != null &&
166
+ preferredClient != null &&
167
+ preferredClient.actorPrincipalId !== sourceActorPrincipalId
168
+ ) {
169
+ const rejection = enforceSameActorOrErrorResult({
170
+ hub: assistantEventHub,
171
+ sourceActorPrincipalId,
172
+ targetClientId: preferredClient.clientId,
173
+ op: "host_browser",
174
+ });
175
+ if (rejection) return Promise.resolve(rejection);
176
+ }
177
+
178
+ const resolvedClientId = preferredClient?.clientId;
179
+ const targetActorPrincipalId = preferredClient?.actorPrincipalId;
96
180
  const requestId = uuid();
97
181
 
98
182
  return new Promise<ToolExecutionResult>((resolve, reject) => {
@@ -135,17 +219,15 @@ export class HostBrowserProxy {
135
219
  pendingInteractions.register(requestId, {
136
220
  conversationId,
137
221
  kind: "host_browser",
138
- rpcResolve: resolve,
222
+ targetClientId: resolvedClientId,
223
+ targetActorPrincipalId,
224
+ rpcResolve: resolve as (v: unknown) => void,
139
225
  rpcReject: reject,
140
226
  timer,
141
227
  detachAbort,
142
228
  });
143
229
 
144
230
  try {
145
- const preferredClient = assistantEventHub.getPreferredClientByCapability(
146
- "host_browser",
147
- HOST_BROWSER_INTERFACE_PREFERENCE,
148
- );
149
231
  if (!preferredClient) {
150
232
  pendingInteractions.resolve(requestId);
151
233
  reject(
@@ -172,27 +254,6 @@ export class HostBrowserProxy {
172
254
  });
173
255
  }
174
256
 
175
- /**
176
- * Process a client result and resolve the RPC. Called by route handlers.
177
- */
178
- resolveResult(
179
- requestId: string,
180
- response: { content: string; isError: boolean },
181
- ): void {
182
- const interaction = pendingInteractions.resolve(requestId);
183
- if (!interaction?.rpcResolve) {
184
- log.debug(
185
- { requestId },
186
- "Ignoring host_browser_result for unknown or already-resolved request",
187
- );
188
- return;
189
- }
190
- interaction.rpcResolve({
191
- content: response.content,
192
- isError: response.isError,
193
- });
194
- }
195
-
196
257
  dispose(): void {
197
258
  for (const entry of pendingInteractions.getByKind("host_browser")) {
198
259
  pendingInteractions.resolve(entry.requestId);
@@ -239,7 +239,7 @@ export class HostCuProxy {
239
239
  targetClientId != null
240
240
  ? assistantEventHub.getActorPrincipalIdForClient(targetClientId)
241
241
  : undefined,
242
- rpcResolve: resolve,
242
+ rpcResolve: resolve as (v: unknown) => void,
243
243
  rpcReject: reject,
244
244
  timer,
245
245
  detachAbort,
@@ -186,7 +186,7 @@ export class HostFileProxy {
186
186
  resolvedTargetClientId,
187
187
  )
188
188
  : undefined,
189
- rpcResolve: resolve,
189
+ rpcResolve: resolve as (v: unknown) => void,
190
190
  rpcReject: reject,
191
191
  timer,
192
192
  detachAbort,
@@ -141,8 +141,10 @@ export abstract class HostProxyBase<TRequest, TResultPayload> {
141
141
  signal?: AbortSignal,
142
142
  extraFields?: Record<string, unknown>,
143
143
  targetClientId?: string,
144
+ timeoutMsOverride?: number,
144
145
  ): Promise<TResultPayload> {
145
146
  const requestId = uuid();
147
+ const effectiveTimeoutMs = timeoutMsOverride ?? this.timeoutMs;
146
148
 
147
149
  return new Promise<TResultPayload>((resolve, reject) => {
148
150
  // Declared up-front so onAbort can close over a stable reference once
@@ -158,7 +160,7 @@ export abstract class HostProxyBase<TRequest, TResultPayload> {
158
160
  "Host proxy request timed out",
159
161
  );
160
162
  reject(new HostProxyRequestError("timeout", "timeout"));
161
- }, this.timeoutMs);
163
+ }, effectiveTimeoutMs);
162
164
 
163
165
  if (signal) {
164
166
  const onAbort = () => {
@@ -204,10 +206,20 @@ export abstract class HostProxyBase<TRequest, TResultPayload> {
204
206
  // (HostCuProxy bypasses dispatchRequest entirely with its own inline
205
207
  // request method that registers directly, which is why CU works
206
208
  // without this base-level fix.)
209
+ // Snapshot the target's actorPrincipalId at registration time so the
210
+ // result-route same-actor check has a stable value to compare against —
211
+ // the target client's SSE subscription may briefly disconnect between
212
+ // dispatch and result submission, which would make a live hub lookup
213
+ // falsely 403 a legitimate result.
214
+ const targetActorPrincipalId =
215
+ targetClientId != null
216
+ ? assistantEventHub.getActorPrincipalIdForClient(targetClientId)
217
+ : undefined;
207
218
  pendingInteractions.register(requestId, {
208
219
  conversationId,
209
220
  kind: this.resultPendingKind,
210
221
  ...(targetClientId != null ? { targetClientId } : {}),
222
+ ...(targetActorPrincipalId != null ? { targetActorPrincipalId } : {}),
211
223
  });
212
224
 
213
225
  try {
@@ -28,6 +28,7 @@
28
28
 
29
29
  import type { HostProxyCapability, InterfaceId } from "../channels/types.js";
30
30
  import { supportsHostProxy } from "../channels/types.js";
31
+ import { assistantEventHub } from "../runtime/assistant-event-hub.js";
31
32
 
32
33
  /**
33
34
  * Subset of Conversation/ProcessConversationContext that
@@ -60,6 +61,29 @@ export const HOST_PROXY_SKILL_PREACTIVATIONS: ReadonlyArray<{
60
61
  { capability: "host_app_control", skillId: "app-control" },
61
62
  ];
62
63
 
64
+ /**
65
+ * Returns true when a host-proxy for the given capability should be attached
66
+ * (instantiated and preactivated) for the current turn. Two cases qualify:
67
+ *
68
+ * 1. The source interface natively supports the capability (e.g. macOS → host_cu).
69
+ * 2. The source interface doesn't support the capability natively but at least
70
+ * one connected client does — cross-client routing. `chrome-extension` is
71
+ * excluded as a security boundary: it is its own executor context and cannot
72
+ * broker cross-client routing to a macOS client.
73
+ *
74
+ * This is the single source of truth for both preactivation and proxy
75
+ * instantiation, so the two decisions stay in sync.
76
+ */
77
+ export function shouldAttachHostProxyForCapability(
78
+ capability: HostProxyCapability,
79
+ sourceInterface: InterfaceId | undefined,
80
+ ): boolean {
81
+ if (!sourceInterface) return false;
82
+ if (supportsHostProxy(sourceInterface, capability)) return true;
83
+ if (sourceInterface === "chrome-extension") return false;
84
+ return assistantEventHub.listClientsByCapability(capability).length > 0;
85
+ }
86
+
63
87
  /**
64
88
  * Preactivate every host-proxy-backed skill that the given source interface
65
89
  * supports. No-op when `sourceInterface` is undefined.
@@ -75,7 +99,7 @@ export function preactivateHostProxySkills(
75
99
  ): void {
76
100
  if (!sourceInterface) return;
77
101
  for (const { capability, skillId } of HOST_PROXY_SKILL_PREACTIVATIONS) {
78
- if (supportsHostProxy(sourceInterface, capability)) {
102
+ if (shouldAttachHostProxyForCapability(capability, sourceInterface)) {
79
103
  conversation.addPreactivatedSkillId(skillId);
80
104
  }
81
105
  }
@@ -273,7 +273,7 @@ export class HostTransferProxy {
273
273
  resolvedTargetClientId,
274
274
  )
275
275
  : undefined,
276
- rpcResolve: resolve,
276
+ rpcResolve: resolve as (v: unknown) => void,
277
277
  rpcReject: reject,
278
278
  timer,
279
279
  detachAbort,
@@ -462,7 +462,7 @@ export class HostTransferProxy {
462
462
  resolvedTargetClientId,
463
463
  )
464
464
  : undefined,
465
- rpcResolve: resolve,
465
+ rpcResolve: resolve as (v: unknown) => void,
466
466
  rpcReject: reject,
467
467
  timer,
468
468
  detachAbort,
@@ -1,4 +1,5 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
2
3
 
3
4
  import { getWorkspacePromptPath } from "../util/platform.js";
4
5
 
@@ -14,3 +15,21 @@ export function getAssistantName(): string | null {
14
15
  return null;
15
16
  }
16
17
  }
18
+
19
+ /**
20
+ * Read the guardian's display name from `users/default.md`. We look for the
21
+ * markdown-bold "Name" label (matching the IDENTITY.md convention) and fall
22
+ * back to `null` on any miss; callers substitute a generic label.
23
+ */
24
+ export function resolveUserName(workspaceDir: string): string | null {
25
+ try {
26
+ const content = readFileSync(
27
+ join(workspaceDir, "users", "default.md"),
28
+ "utf-8",
29
+ );
30
+ const match = content.match(/\*\*Name:\*\*\s*(.+)/);
31
+ return match?.[1]?.trim() || null;
32
+ } catch {
33
+ return null;
34
+ }
35
+ }