@vellumai/assistant 0.6.4 → 0.6.5

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 (717) hide show
  1. package/.prettierignore +5 -0
  2. package/ARCHITECTURE.md +32 -36
  3. package/Dockerfile +12 -0
  4. package/README.md +3 -4
  5. package/bun.lock +8 -3
  6. package/docs/architecture/integrations.md +1 -20
  7. package/docs/architecture/security.md +16 -16
  8. package/docs/error-handling.md +111 -0
  9. package/docs/skills.md +10 -10
  10. package/docs/stt-provider-onboarding.md +2 -1
  11. package/knip.json +9 -2
  12. package/node_modules/@vellumai/ces-contracts/package.json +2 -1
  13. package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
  14. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
  15. package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
  16. package/node_modules/@vellumai/credential-storage/package.json +2 -2
  17. package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
  18. package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
  19. package/node_modules/@vellumai/egress-proxy/package.json +2 -2
  20. package/openapi.yaml +123 -11
  21. package/package.json +6 -3
  22. package/scripts/generate-openapi.ts +50 -11
  23. package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
  24. package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
  25. package/src/__tests__/agent-loop.test.ts +112 -1
  26. package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
  27. package/src/__tests__/anthropic-provider.test.ts +171 -2
  28. package/src/__tests__/approval-cascade.test.ts +31 -10
  29. package/src/__tests__/approval-routes-http.test.ts +134 -10
  30. package/src/__tests__/assistant-attachments.test.ts +44 -0
  31. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
  32. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  33. package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
  34. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
  35. package/src/__tests__/browser-skill-endstate.test.ts +51 -182
  36. package/src/__tests__/btw-routes.test.ts +47 -1
  37. package/src/__tests__/call-controller.test.ts +1 -2
  38. package/src/__tests__/call-site-routing-provider.test.ts +214 -0
  39. package/src/__tests__/catalog-cache.test.ts +27 -4
  40. package/src/__tests__/channel-approval-routes.test.ts +4 -4
  41. package/src/__tests__/channel-reply-delivery.test.ts +300 -2
  42. package/src/__tests__/checker.test.ts +428 -501
  43. package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
  44. package/src/__tests__/compaction-circuit-breaker.test.ts +336 -0
  45. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  46. package/src/__tests__/config-analysis.test.ts +11 -28
  47. package/src/__tests__/config-loader-backfill.test.ts +174 -0
  48. package/src/__tests__/config-loader-corrupt.test.ts +183 -0
  49. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
  50. package/src/__tests__/config-schema-cmd.test.ts +11 -5
  51. package/src/__tests__/config-schema.test.ts +427 -114
  52. package/src/__tests__/config-watcher.test.ts +2 -2
  53. package/src/__tests__/contact-store-user-file.test.ts +72 -73
  54. package/src/__tests__/contacts-write.test.ts +4 -4
  55. package/src/__tests__/context-token-estimator.test.ts +191 -1
  56. package/src/__tests__/context-window-manager.test.ts +530 -2
  57. package/src/__tests__/conversation-abort-tool-results.test.ts +30 -16
  58. package/src/__tests__/conversation-agent-loop-overflow.test.ts +61 -17
  59. package/src/__tests__/conversation-agent-loop.test.ts +412 -82
  60. package/src/__tests__/conversation-attachments.test.ts +1 -1
  61. package/src/__tests__/conversation-confirmation-signals.test.ts +30 -9
  62. package/src/__tests__/conversation-error.test.ts +37 -6
  63. package/src/__tests__/conversation-history-web-search.test.ts +6 -0
  64. package/src/__tests__/conversation-init.benchmark.test.ts +36 -0
  65. package/src/__tests__/conversation-lifecycle.test.ts +336 -0
  66. package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
  67. package/src/__tests__/conversation-pre-run-repair.test.ts +30 -16
  68. package/src/__tests__/conversation-process-callsite.test.ts +306 -0
  69. package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -16
  70. package/src/__tests__/conversation-queue.test.ts +41 -26
  71. package/src/__tests__/conversation-routes-disk-view.test.ts +29 -1
  72. package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
  73. package/src/__tests__/conversation-runtime-assembly.test.ts +2735 -55
  74. package/src/__tests__/conversation-runtime-workspace.test.ts +12 -12
  75. package/src/__tests__/conversation-skill-tools.test.ts +12 -146
  76. package/src/__tests__/conversation-slash-queue.test.ts +34 -19
  77. package/src/__tests__/conversation-slash-unknown.test.ts +30 -16
  78. package/src/__tests__/conversation-speed-override.test.ts +30 -11
  79. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
  80. package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
  81. package/src/__tests__/conversation-title-service.test.ts +2 -2
  82. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
  83. package/src/__tests__/conversation-unread-route.test.ts +2 -2
  84. package/src/__tests__/conversation-usage.test.ts +3 -1
  85. package/src/__tests__/conversation-workspace-cache-state.test.ts +31 -10
  86. package/src/__tests__/conversation-workspace-injection.test.ts +43 -15
  87. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +44 -16
  88. package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
  89. package/src/__tests__/credential-security-invariants.test.ts +3 -0
  90. package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
  91. package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
  92. package/src/__tests__/credential-vault-unit.test.ts +135 -19
  93. package/src/__tests__/credentials-cli.test.ts +1 -9
  94. package/src/__tests__/cross-provider-web-search.test.ts +84 -0
  95. package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
  96. package/src/__tests__/delete-propagation.test.ts +437 -0
  97. package/src/__tests__/dm-backfill.test.ts +417 -0
  98. package/src/__tests__/dm-persistence.test.ts +227 -0
  99. package/src/__tests__/edit-propagation.test.ts +280 -0
  100. package/src/__tests__/ephemeral-permissions.test.ts +93 -3
  101. package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
  102. package/src/__tests__/estimator-calibration.test.ts +213 -0
  103. package/src/__tests__/extension-id-sync-guard.test.ts +26 -7
  104. package/src/__tests__/file-write-tool.test.ts +151 -1
  105. package/src/__tests__/filing-service.test.ts +255 -0
  106. package/src/__tests__/gemini-provider.test.ts +0 -3
  107. package/src/__tests__/guardian-grant-minting.test.ts +8 -0
  108. package/src/__tests__/headless-browser-interactions.test.ts +1 -1
  109. package/src/__tests__/heartbeat-service.test.ts +96 -15
  110. package/src/__tests__/host-shell-tool.test.ts +124 -18
  111. package/src/__tests__/http-user-message-parity.test.ts +29 -1
  112. package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
  113. package/src/__tests__/intent-routing.test.ts +1 -40
  114. package/src/__tests__/llm-catalog-parity.test.ts +174 -0
  115. package/src/__tests__/llm-context-normalization.test.ts +121 -0
  116. package/src/__tests__/llm-resolver.test.ts +214 -0
  117. package/src/__tests__/llm-schema.test.ts +223 -0
  118. package/src/__tests__/managed-proxy-context.test.ts +6 -2
  119. package/src/__tests__/messaging-skill-split.test.ts +3 -34
  120. package/src/__tests__/migration-import-from-url.test.ts +684 -0
  121. package/src/__tests__/model-intents.test.ts +9 -83
  122. package/src/__tests__/notification-decision-fallback.test.ts +0 -10
  123. package/src/__tests__/notification-decision-identity.test.ts +0 -9
  124. package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
  125. package/src/__tests__/oauth-store.test.ts +10 -7
  126. package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
  127. package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
  128. package/src/__tests__/openai-provider.test.ts +7 -0
  129. package/src/__tests__/openai-responses-provider.test.ts +396 -0
  130. package/src/__tests__/openrouter-provider-only.test.ts +135 -0
  131. package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
  132. package/src/__tests__/permission-checker-host-gate.test.ts +1 -1
  133. package/src/__tests__/permission-mode.test.ts +16 -0
  134. package/src/__tests__/permission-types.test.ts +0 -1
  135. package/src/__tests__/persona-resolver.test.ts +13 -13
  136. package/src/__tests__/pkb-autoinject.test.ts +37 -1
  137. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
  138. package/src/__tests__/pricing.test.ts +50 -3
  139. package/src/__tests__/profiler-routes.test.ts +1 -1
  140. package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
  141. package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
  142. package/src/__tests__/provider-error-scenarios.test.ts +135 -6
  143. package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
  144. package/src/__tests__/provider-registry-ollama.test.ts +1 -2
  145. package/src/__tests__/proxy-approval-callback.test.ts +0 -1
  146. package/src/__tests__/reaction-persistence.test.ts +560 -0
  147. package/src/__tests__/relay-server.test.ts +1 -1
  148. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  149. package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
  150. package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
  151. package/src/__tests__/risk-classifier-parity.test.ts +230 -0
  152. package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
  153. package/src/__tests__/secret-ingress-http.test.ts +28 -0
  154. package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
  156. package/src/__tests__/secret-scanner-executor.test.ts +1 -1
  157. package/src/__tests__/send-endpoint-busy.test.ts +29 -1
  158. package/src/__tests__/server-history-render.test.ts +31 -0
  159. package/src/__tests__/shell-parser-property.test.ts +13 -13
  160. package/src/__tests__/skill-cache-store.test.ts +182 -0
  161. package/src/__tests__/skills.test.ts +19 -33
  162. package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
  163. package/src/__tests__/slack-skill.test.ts +3 -8
  164. package/src/__tests__/starter-bundle.test.ts +35 -0
  165. package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
  166. package/src/__tests__/suggestion-routes.test.ts +160 -3
  167. package/src/__tests__/system-prompt.test.ts +22 -35
  168. package/src/__tests__/task-runner.test.ts +3 -1
  169. package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
  170. package/src/__tests__/terminal-tools.test.ts +8 -0
  171. package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
  172. package/src/__tests__/thread-backfill.test.ts +941 -0
  173. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -2
  174. package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
  175. package/src/__tests__/tool-executor.test.ts +60 -94
  176. package/src/__tests__/trust-store.test.ts +442 -109
  177. package/src/__tests__/update-bulletin-job.test.ts +389 -0
  178. package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
  179. package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
  180. package/src/__tests__/voice-session-bridge.test.ts +39 -0
  181. package/src/__tests__/volume-security-guard.test.ts +3 -2
  182. package/src/__tests__/web-search-history.test.ts +337 -0
  183. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
  184. package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
  185. package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
  186. package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
  187. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
  188. package/src/__tests__/workspace-policy.test.ts +1 -13
  189. package/src/acp/client-handler.ts +1 -2
  190. package/src/agent/loop.ts +209 -17
  191. package/src/avatar/resvg-lazy.test.ts +136 -0
  192. package/src/avatar/resvg-lazy.ts +82 -9
  193. package/src/avatar/traits-png-sync.ts +21 -1
  194. package/src/browser/__tests__/operations.test.ts +163 -0
  195. package/src/browser/identifiers.ts +51 -0
  196. package/src/browser/operations.ts +660 -0
  197. package/src/browser/types.ts +81 -0
  198. package/src/calls/guardian-question-copy.ts +2 -2
  199. package/src/calls/telephony-stt-routing.ts +1 -1
  200. package/src/calls/voice-session-bridge.ts +1 -0
  201. package/src/cli/AGENTS.md +1 -1
  202. package/src/cli/commands/__tests__/attachment.test.ts +438 -0
  203. package/src/cli/commands/__tests__/browser.test.ts +554 -0
  204. package/src/cli/commands/__tests__/cache.test.ts +623 -0
  205. package/src/cli/commands/__tests__/email-list.test.ts +6 -0
  206. package/src/cli/commands/__tests__/email-send.test.ts +93 -1
  207. package/src/cli/commands/__tests__/image-generation.test.ts +666 -0
  208. package/src/cli/commands/__tests__/inference-send.test.ts +451 -0
  209. package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
  210. package/src/cli/commands/__tests__/task.test.ts +913 -0
  211. package/src/cli/commands/__tests__/tts-synthesize.test.ts +594 -0
  212. package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
  213. package/src/cli/commands/__tests__/ui.test.ts +1215 -0
  214. package/src/cli/commands/__tests__/watchers.test.ts +716 -0
  215. package/src/cli/commands/attachment.ts +182 -0
  216. package/src/cli/commands/browser.ts +350 -0
  217. package/src/cli/commands/cache.ts +341 -0
  218. package/src/cli/commands/completions.ts +0 -3
  219. package/src/cli/commands/config.ts +6 -6
  220. package/src/cli/commands/conversations-import.ts +347 -0
  221. package/src/cli/commands/conversations.ts +14 -1
  222. package/src/cli/commands/email.ts +234 -194
  223. package/src/cli/commands/image-generation.ts +300 -0
  224. package/src/cli/commands/inference.ts +200 -0
  225. package/src/cli/commands/memory.ts +127 -17
  226. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
  227. package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
  228. package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
  229. package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
  230. package/src/cli/commands/stt.ts +339 -0
  231. package/src/cli/commands/task.ts +795 -0
  232. package/src/cli/commands/trust.ts +50 -19
  233. package/src/cli/commands/tts.ts +273 -0
  234. package/src/cli/commands/ui.ts +670 -0
  235. package/src/cli/commands/watchers.ts +509 -0
  236. package/src/cli/lib/daemon-credential-client.ts +0 -19
  237. package/src/cli/program.ts +23 -4
  238. package/src/cli.ts +0 -37
  239. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +23 -1
  240. package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
  241. package/src/config/bundled-skills/messaging/SKILL.md +2 -2
  242. package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
  243. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +8 -1
  244. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
  245. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
  246. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +11 -12
  247. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
  248. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  249. package/src/config/bundled-tool-registry.ts +0 -175
  250. package/src/config/env.ts +7 -2
  251. package/src/config/feature-flag-registry.json +25 -9
  252. package/src/config/llm-resolver.ts +128 -0
  253. package/src/config/loader.ts +194 -10
  254. package/src/config/raw-config-utils.ts +30 -2
  255. package/src/config/sanitize-for-transfer.ts +35 -0
  256. package/src/config/schema.ts +30 -41
  257. package/src/config/schemas/analysis.ts +3 -22
  258. package/src/config/schemas/calls.ts +0 -4
  259. package/src/config/schemas/filing.ts +2 -7
  260. package/src/config/schemas/heartbeat.ts +0 -5
  261. package/src/config/schemas/inference.ts +3 -23
  262. package/src/config/schemas/llm.ts +318 -0
  263. package/src/config/schemas/memory-processing.ts +1 -9
  264. package/src/config/schemas/notifications.ts +4 -11
  265. package/src/config/schemas/platform.ts +3 -9
  266. package/src/config/schemas/security.ts +33 -0
  267. package/src/config/schemas/services.ts +9 -4
  268. package/src/config/schemas/stt.ts +1 -0
  269. package/src/config/schemas/tts.ts +53 -0
  270. package/src/config/schemas/updates.ts +1 -1
  271. package/src/config/schemas/workspace-git.ts +3 -40
  272. package/src/config/skills.ts +2 -2
  273. package/src/context/__tests__/compact-prompt.test.ts +45 -0
  274. package/src/context/__tests__/microcompact.test.ts +805 -0
  275. package/src/context/estimator-calibration.ts +136 -0
  276. package/src/context/microcompact.ts +443 -0
  277. package/src/context/prompts/compact.md +12 -0
  278. package/src/context/token-estimator.ts +61 -3
  279. package/src/context/window-manager.ts +229 -25
  280. package/src/credential-execution/approval-bridge.ts +0 -1
  281. package/src/credential-execution/executable-discovery.ts +19 -8
  282. package/src/credential-execution/process-manager.test.ts +109 -0
  283. package/src/credential-execution/process-manager.ts +65 -2
  284. package/src/daemon/approval-generators.ts +29 -4
  285. package/src/daemon/assistant-attachments.ts +24 -13
  286. package/src/daemon/classifier.ts +2 -2
  287. package/src/daemon/config-watcher.ts +0 -1
  288. package/src/daemon/context-overflow-reducer.ts +4 -1
  289. package/src/daemon/conversation-agent-loop-handlers.ts +79 -12
  290. package/src/daemon/conversation-agent-loop.ts +462 -80
  291. package/src/daemon/conversation-attachments.ts +2 -6
  292. package/src/daemon/conversation-error.ts +36 -1
  293. package/src/daemon/conversation-lifecycle.ts +30 -6
  294. package/src/daemon/conversation-messaging.ts +73 -4
  295. package/src/daemon/conversation-process.ts +10 -4
  296. package/src/daemon/conversation-queue-manager.ts +3 -0
  297. package/src/daemon/conversation-runtime-assembly.ts +760 -29
  298. package/src/daemon/conversation-slash.ts +2 -2
  299. package/src/daemon/conversation-surfaces.ts +389 -1
  300. package/src/daemon/conversation-tool-setup.ts +10 -5
  301. package/src/daemon/conversation-usage.ts +1 -1
  302. package/src/daemon/conversation.ts +118 -30
  303. package/src/daemon/external-skills-bootstrap.ts +41 -0
  304. package/src/daemon/guardian-action-generators.ts +34 -14
  305. package/src/daemon/handlers/config-model.test.ts +86 -0
  306. package/src/daemon/handlers/config-model.ts +54 -12
  307. package/src/daemon/handlers/conversations.ts +9 -2
  308. package/src/daemon/handlers/shared.ts +39 -11
  309. package/src/daemon/handlers/skills.ts +2 -2
  310. package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
  311. package/src/daemon/lifecycle.ts +76 -14
  312. package/src/daemon/message-types/conversations.ts +14 -0
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/trust.ts +0 -2
  315. package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
  316. package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
  317. package/src/daemon/pkb-context-tracker.test.ts +169 -0
  318. package/src/daemon/pkb-context-tracker.ts +125 -0
  319. package/src/daemon/pkb-reminder-builder.test.ts +70 -0
  320. package/src/daemon/pkb-reminder-builder.ts +31 -0
  321. package/src/daemon/providers-setup.ts +6 -0
  322. package/src/daemon/server.ts +117 -9
  323. package/src/daemon/tool-side-effects.ts +0 -9
  324. package/src/daemon/watch-handler.ts +4 -4
  325. package/src/daemon/web-search-history.ts +126 -0
  326. package/src/events/domain-events.ts +0 -1
  327. package/src/filing/filing-service.ts +9 -10
  328. package/src/heartbeat/heartbeat-service.ts +76 -28
  329. package/src/home/__tests__/feed-scheduler.test.ts +39 -11
  330. package/src/home/__tests__/rollup-producer.test.ts +44 -0
  331. package/src/home/assistant-feed-authoring.ts +4 -0
  332. package/src/home/emit-feed-event.ts +4 -0
  333. package/src/home/feed-scheduler.ts +20 -4
  334. package/src/home/feed-types.ts +56 -2
  335. package/src/home/relationship-state-writer.ts +2 -2
  336. package/src/home/rollup-producer.ts +34 -5
  337. package/src/home/suggested-prompts.ts +101 -0
  338. package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
  339. package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
  340. package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
  341. package/src/ipc/__tests__/socket-path.test.ts +73 -0
  342. package/src/ipc/__tests__/task-ipc.test.ts +577 -0
  343. package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
  344. package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
  345. package/src/ipc/cli-client.ts +2 -1
  346. package/src/ipc/cli-server.ts +26 -8
  347. package/src/ipc/gateway-client.ts +4 -4
  348. package/src/ipc/routes/attachment.ts +114 -0
  349. package/src/ipc/routes/browser-context.ts +61 -0
  350. package/src/ipc/routes/browser.ts +96 -0
  351. package/src/ipc/routes/cache.ts +96 -0
  352. package/src/ipc/routes/index.ts +17 -1
  353. package/src/ipc/routes/task-queue.ts +226 -0
  354. package/src/ipc/routes/task.ts +173 -0
  355. package/src/ipc/routes/ui-request.ts +50 -0
  356. package/src/ipc/routes/watcher.ts +203 -0
  357. package/src/ipc/socket-path.ts +100 -0
  358. package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
  359. package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
  360. package/src/memory/admin.ts +18 -0
  361. package/src/memory/conversation-analyze-job.ts +14 -13
  362. package/src/memory/conversation-attention-store.ts +13 -6
  363. package/src/memory/conversation-crud.ts +103 -3
  364. package/src/memory/conversation-group-migration.ts +38 -6
  365. package/src/memory/conversation-title-service.ts +7 -4
  366. package/src/memory/db-init.ts +2 -0
  367. package/src/memory/embedding-backend.ts +1 -1
  368. package/src/memory/graph/compaction.ts +299 -0
  369. package/src/memory/graph/consolidation.ts +4 -4
  370. package/src/memory/graph/conversation-graph-memory.ts +89 -29
  371. package/src/memory/graph/extraction.test.ts +272 -2
  372. package/src/memory/graph/extraction.ts +173 -51
  373. package/src/memory/graph/graph-search.test.ts +92 -0
  374. package/src/memory/graph/graph-search.ts +4 -1
  375. package/src/memory/graph/narrative.ts +2 -2
  376. package/src/memory/graph/pattern-scan.ts +2 -2
  377. package/src/memory/graph/retriever.test.ts +459 -0
  378. package/src/memory/graph/retriever.ts +230 -48
  379. package/src/memory/graph/store.ts +41 -0
  380. package/src/memory/graph/tool-handlers.ts +27 -0
  381. package/src/memory/graph/tools.ts +6 -1
  382. package/src/memory/indexer.ts +5 -5
  383. package/src/memory/job-handlers/conversation-starters.ts +23 -20
  384. package/src/memory/job-handlers/summarization.ts +2 -2
  385. package/src/memory/job-utils.ts +7 -1
  386. package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
  387. package/src/memory/jobs/embed-pkb-file.ts +54 -0
  388. package/src/memory/jobs-store.ts +44 -3
  389. package/src/memory/jobs-worker.ts +4 -0
  390. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
  391. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
  392. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
  393. package/src/memory/migrations/index.ts +1 -0
  394. package/src/memory/pkb/pkb-index.test.ts +368 -0
  395. package/src/memory/pkb/pkb-index.ts +255 -0
  396. package/src/memory/pkb/pkb-reconcile.test.ts +251 -0
  397. package/src/memory/pkb/pkb-reconcile.ts +148 -0
  398. package/src/memory/pkb/pkb-search.test.ts +438 -0
  399. package/src/memory/pkb/pkb-search.ts +137 -0
  400. package/src/memory/pkb/types.ts +53 -0
  401. package/src/memory/qdrant-client.ts +122 -1
  402. package/src/memory/slack-thread-store.ts +37 -0
  403. package/src/messaging/providers/gmail/adapter.ts +6 -16
  404. package/src/messaging/providers/gmail/client.ts +22 -0
  405. package/src/messaging/providers/gmail/types.ts +7 -0
  406. package/src/messaging/providers/slack/adapter.ts +14 -2
  407. package/src/messaging/providers/slack/backfill.test.ts +257 -0
  408. package/src/messaging/providers/slack/backfill.ts +101 -0
  409. package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
  410. package/src/messaging/providers/slack/message-metadata.ts +123 -0
  411. package/src/messaging/providers/slack/render-transcript.test.ts +1373 -0
  412. package/src/messaging/providers/slack/render-transcript.ts +443 -0
  413. package/src/messaging/style-analyzer.ts +5 -2
  414. package/src/notifications/README.md +9 -5
  415. package/src/notifications/decision-engine.ts +3 -9
  416. package/src/notifications/preference-extractor.ts +2 -6
  417. package/src/oauth/oauth-store.ts +1 -0
  418. package/src/oauth/platform-connection.test.ts +47 -0
  419. package/src/oauth/platform-connection.ts +15 -5
  420. package/src/oauth/seed-providers.ts +4 -2
  421. package/src/permissions/approval-policy.test.ts +948 -0
  422. package/src/permissions/approval-policy.ts +257 -0
  423. package/src/permissions/bash-risk-classifier.test.ts +1208 -0
  424. package/src/permissions/bash-risk-classifier.ts +707 -0
  425. package/src/permissions/checker.ts +217 -708
  426. package/src/permissions/command-registry.test.ts +535 -0
  427. package/src/permissions/command-registry.ts +825 -0
  428. package/src/permissions/defaults.ts +26 -78
  429. package/src/permissions/file-risk-classifier.test.ts +535 -0
  430. package/src/permissions/file-risk-classifier.ts +274 -0
  431. package/src/permissions/risk-types.ts +205 -0
  432. package/src/permissions/secret-prompter.ts +53 -2
  433. package/src/permissions/skill-risk-classifier.test.ts +311 -0
  434. package/src/permissions/skill-risk-classifier.ts +214 -0
  435. package/src/permissions/trust-client.ts +52 -25
  436. package/src/permissions/trust-store-interface.ts +1 -6
  437. package/src/permissions/trust-store.ts +161 -62
  438. package/src/permissions/types.ts +23 -14
  439. package/src/permissions/web-risk-classifier.test.ts +170 -0
  440. package/src/permissions/web-risk-classifier.ts +89 -0
  441. package/src/permissions/workspace-policy.ts +1 -16
  442. package/src/platform/client.ts +19 -1
  443. package/src/prompts/persona-resolver.ts +3 -3
  444. package/src/prompts/system-prompt.ts +19 -20
  445. package/src/prompts/templates/SOUL.md +2 -2
  446. package/src/prompts/update-bulletin-job.ts +190 -0
  447. package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
  448. package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
  449. package/src/providers/__tests__/retry-callsite.test.ts +424 -0
  450. package/src/providers/anthropic/client.ts +183 -14
  451. package/src/providers/call-site-routing.ts +71 -0
  452. package/src/providers/gemini/client.ts +65 -2
  453. package/src/providers/managed-proxy/constants.ts +2 -1
  454. package/src/providers/model-catalog.ts +501 -33
  455. package/src/providers/model-intents.ts +4 -4
  456. package/src/providers/openai/chat-completions-provider.ts +57 -1
  457. package/src/providers/openai/responses-provider.ts +86 -9
  458. package/src/providers/openrouter/client.ts +76 -9
  459. package/src/providers/provider-env-vars.ts +56 -0
  460. package/src/providers/provider-send-message.ts +22 -5
  461. package/src/providers/ratelimit.ts +4 -0
  462. package/src/providers/registry.ts +19 -8
  463. package/src/providers/retry.ts +174 -39
  464. package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
  465. package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
  466. package/src/providers/speech-to-text/provider-catalog.ts +17 -0
  467. package/src/providers/speech-to-text/resolve.ts +7 -0
  468. package/src/providers/speech-to-text/xai-realtime.test.ts +578 -0
  469. package/src/providers/speech-to-text/xai-realtime.ts +796 -0
  470. package/src/providers/speech-to-text/xai.test.ts +155 -0
  471. package/src/providers/speech-to-text/xai.ts +97 -0
  472. package/src/providers/types.ts +93 -3
  473. package/src/runtime/AGENTS.md +2 -2
  474. package/src/runtime/__tests__/agent-wake.test.ts +43 -2
  475. package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
  476. package/src/runtime/agent-wake.ts +63 -22
  477. package/src/runtime/auth/route-policy.ts +4 -0
  478. package/src/runtime/btw-sidechain.ts +13 -3
  479. package/src/runtime/channel-reply-delivery.ts +106 -2
  480. package/src/runtime/decision-token.ts +116 -0
  481. package/src/runtime/gateway-client.ts +2 -2
  482. package/src/runtime/http-router.ts +32 -0
  483. package/src/runtime/http-server.ts +52 -1
  484. package/src/runtime/http-types.ts +23 -1
  485. package/src/runtime/interactive-ui.ts +362 -0
  486. package/src/runtime/invite-instruction-generator.ts +2 -2
  487. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
  488. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
  489. package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
  490. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
  491. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
  492. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
  493. package/src/runtime/migrations/gcs-signed-url.ts +162 -0
  494. package/src/runtime/migrations/vbundle-importer.ts +154 -9
  495. package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
  496. package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
  497. package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
  498. package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
  499. package/src/runtime/migrations/vbundle-validator.ts +15 -6
  500. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
  501. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
  502. package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
  503. package/src/runtime/routes/approval-prompt-ts-tracker.ts +58 -0
  504. package/src/runtime/routes/approval-routes.ts +12 -17
  505. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
  506. package/src/runtime/routes/avatar-routes.ts +20 -4
  507. package/src/runtime/routes/btw-routes.ts +1 -4
  508. package/src/runtime/routes/conversation-management-routes.ts +20 -2
  509. package/src/runtime/routes/conversation-routes.ts +133 -27
  510. package/src/runtime/routes/debug-routes.ts +1 -1
  511. package/src/runtime/routes/diagnostics-routes.ts +6 -4
  512. package/src/runtime/routes/events-routes.ts +16 -0
  513. package/src/runtime/routes/guardian-approval-interception.ts +33 -3
  514. package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
  515. package/src/runtime/routes/home-feed-routes.ts +120 -2
  516. package/src/runtime/routes/inbound-message-handler.ts +912 -2
  517. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
  518. package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
  519. package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
  520. package/src/runtime/routes/integrations/slack/channel.ts +25 -3
  521. package/src/runtime/routes/llm-context-normalization.ts +23 -1
  522. package/src/runtime/routes/migration-routes.ts +720 -124
  523. package/src/runtime/routes/settings-routes.ts +4 -2
  524. package/src/runtime/routes/trust-rules-routes.ts +30 -14
  525. package/src/runtime/routes/work-items-routes.test.ts +1 -1
  526. package/src/runtime/routes/work-items-routes.ts +3 -2
  527. package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
  528. package/src/runtime/services/analyze-conversation.ts +12 -16
  529. package/src/runtime/skill-route-registry.ts +28 -6
  530. package/src/schedule/scheduler.ts +8 -0
  531. package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
  532. package/src/security/__tests__/untrusted-content.test.ts +109 -0
  533. package/src/security/oauth2.ts +98 -35
  534. package/src/security/secure-keys.ts +7 -8
  535. package/src/security/token-manager.ts +27 -13
  536. package/src/security/untrusted-content.ts +102 -0
  537. package/src/skills/catalog-cache.ts +26 -7
  538. package/src/skills/catalog-install.ts +31 -3
  539. package/src/skills/skill-cache-store.ts +97 -0
  540. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
  541. package/src/stt/daemon-batch-transcriber.ts +33 -0
  542. package/src/stt/stt-stream-session.ts +8 -1
  543. package/src/stt/types.ts +5 -1
  544. package/src/subagent/manager.ts +41 -13
  545. package/src/tasks/ephemeral-permissions.ts +9 -4
  546. package/src/telemetry/usage-telemetry-reporter.ts +27 -5
  547. package/src/tools/browser/__tests__/browser-status.test.ts +45 -2
  548. package/src/tools/browser/browser-execution.ts +65 -38
  549. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
  550. package/src/tools/credentials/tool-policy.ts +39 -5
  551. package/src/tools/credentials/vault.ts +9 -4
  552. package/src/tools/executor.ts +4 -0
  553. package/src/tools/filesystem/write.ts +52 -0
  554. package/src/tools/host-terminal/host-shell.ts +45 -5
  555. package/src/tools/memory/register.test.ts +185 -0
  556. package/src/tools/memory/register.ts +3 -1
  557. package/src/tools/network/web-fetch.ts +20 -10
  558. package/src/tools/network/web-search.ts +19 -4
  559. package/src/tools/permission-checker.ts +36 -15
  560. package/src/tools/policy-context.ts +25 -8
  561. package/src/tools/registry.ts +55 -3
  562. package/src/tools/side-effects.ts +0 -11
  563. package/src/tools/skills/execute.ts +2 -2
  564. package/src/tools/skills/sandbox-runner.ts +5 -2
  565. package/src/tools/terminal/backends/native.ts +51 -2
  566. package/src/tools/terminal/safe-env.ts +3 -2
  567. package/src/tools/terminal/shell.ts +1 -0
  568. package/src/tools/tool-manifest.ts +6 -21
  569. package/src/tools/types.ts +12 -3
  570. package/src/tools/verification-control-plane-policy.ts +1 -1
  571. package/src/tts/__tests__/provider-adapters.test.ts +240 -13
  572. package/src/tts/provider-catalog.ts +18 -0
  573. package/src/tts/providers/index.ts +2 -0
  574. package/src/tts/providers/xai-provider.ts +224 -0
  575. package/src/tts/types.ts +46 -0
  576. package/src/types/tar-stream.d.ts +66 -0
  577. package/src/util/json.ts +17 -0
  578. package/src/util/platform.ts +2 -2
  579. package/src/util/pricing.ts +15 -5
  580. package/src/watcher/engine.ts +1 -1
  581. package/src/watcher/providers/google-calendar.ts +134 -8
  582. package/src/watcher/providers/outlook-calendar.ts +42 -2
  583. package/src/workspace/git-service.ts +23 -4
  584. package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
  585. package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
  586. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
  587. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +57 -0
  588. package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
  589. package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
  590. package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
  591. package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
  592. package/src/workspace/migrations/AGENTS.md +1 -1
  593. package/src/workspace/migrations/registry.ts +16 -0
  594. package/src/workspace/provider-commit-message-generator.ts +19 -38
  595. package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
  596. package/src/__tests__/gmail-archive-gate.test.ts +0 -246
  597. package/src/__tests__/gmail-preferences.test.ts +0 -117
  598. package/src/__tests__/outlook-attachments.test.ts +0 -301
  599. package/src/__tests__/outlook-automation-tools.test.ts +0 -425
  600. package/src/__tests__/outlook-categories.test.ts +0 -212
  601. package/src/__tests__/outlook-compose-tools.test.ts +0 -325
  602. package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
  603. package/src/__tests__/outlook-follow-up.test.ts +0 -196
  604. package/src/__tests__/outlook-trash.test.ts +0 -77
  605. package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
  606. package/src/__tests__/update-bulletin-format.test.ts +0 -181
  607. package/src/__tests__/update-bulletin-state.test.ts +0 -135
  608. package/src/__tests__/update-bulletin.test.ts +0 -478
  609. package/src/__tests__/update-template-contract.test.ts +0 -29
  610. package/src/cli/commands/doctor.ts +0 -341
  611. package/src/config/bundled-skills/browser/SKILL.md +0 -88
  612. package/src/config/bundled-skills/browser/TOOLS.json +0 -516
  613. package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
  614. package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
  615. package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
  616. package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
  617. package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
  618. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
  619. package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
  620. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
  621. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
  622. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
  623. package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
  624. package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
  625. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
  626. package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
  627. package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
  628. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
  629. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
  630. package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
  631. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
  632. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
  633. package/src/config/bundled-skills/gmail/SKILL.md +0 -221
  634. package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
  635. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
  636. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
  637. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
  638. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
  639. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
  640. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
  641. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
  642. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
  643. package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
  644. package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
  645. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
  646. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
  647. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
  648. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
  649. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
  650. package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
  651. package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
  652. package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
  653. package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
  654. package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
  655. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
  656. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
  657. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
  658. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
  659. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
  660. package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
  661. package/src/config/bundled-skills/google-calendar/types.ts +0 -97
  662. package/src/config/bundled-skills/outlook/SKILL.md +0 -196
  663. package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
  664. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
  665. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
  666. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
  667. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
  668. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
  669. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
  670. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
  671. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
  672. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
  673. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
  674. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
  675. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
  676. package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
  677. package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
  678. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
  679. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
  680. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
  681. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
  682. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
  683. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
  684. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
  685. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
  686. package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
  687. package/src/config/bundled-skills/slack/SKILL.md +0 -108
  688. package/src/config/bundled-skills/tasks/SKILL.md +0 -37
  689. package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
  690. package/src/config/bundled-skills/tasks/icon.svg +0 -34
  691. package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
  692. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
  693. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
  694. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
  695. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
  696. package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
  697. package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
  698. package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
  699. package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
  700. package/src/config/bundled-skills/watcher/SKILL.md +0 -31
  701. package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
  702. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
  703. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
  704. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
  705. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
  706. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
  707. package/src/prompts/templates/UPDATES.md +0 -50
  708. package/src/prompts/update-bulletin-format.ts +0 -85
  709. package/src/prompts/update-bulletin-state.ts +0 -58
  710. package/src/prompts/update-bulletin-template-path.ts +0 -13
  711. package/src/prompts/update-bulletin.ts +0 -139
  712. package/src/shared/provider-env-vars.ts +0 -19
  713. package/src/tools/watcher/create.ts +0 -86
  714. package/src/tools/watcher/delete.ts +0 -36
  715. package/src/tools/watcher/digest.ts +0 -54
  716. package/src/tools/watcher/list.ts +0 -83
  717. package/src/tools/watcher/update.ts +0 -71
@@ -0,0 +1,295 @@
1
+ /**
2
+ * Integration tests for the watcher IPC routes.
3
+ *
4
+ * Exercises the full IPC round-trip: CliIpcServer + cliIpcCall over
5
+ * the Unix domain socket, with the real SQLite watcher store backing
6
+ * the route handlers.
7
+ */
8
+
9
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
10
+
11
+ import { initializeDb } from "../../memory/db.js";
12
+ import { registerWatcherProvider } from "../../watcher/provider-registry.js";
13
+ import type { WatcherProvider } from "../../watcher/provider-types.js";
14
+ import type { Watcher, WatcherEvent } from "../../watcher/watcher-store.js";
15
+ import { cliIpcCall } from "../cli-client.js";
16
+ import { CliIpcServer } from "../cli-server.js";
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // DB + provider setup
20
+ // ---------------------------------------------------------------------------
21
+
22
+ initializeDb();
23
+
24
+ const mockProvider: WatcherProvider = {
25
+ id: "test-provider",
26
+ displayName: "Test Provider",
27
+ requiredCredentialService: "test-cred",
28
+ async fetchNew() {
29
+ return { items: [], watermark: "w1" };
30
+ },
31
+ async getInitialWatermark() {
32
+ return "initial";
33
+ },
34
+ cleanup() {},
35
+ };
36
+
37
+ registerWatcherProvider(mockProvider);
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // Helpers
41
+ // ---------------------------------------------------------------------------
42
+
43
+ let server: CliIpcServer | null = null;
44
+
45
+ /** IDs of watchers created during a test, cleaned up in afterEach. */
46
+ const createdWatcherIds: string[] = [];
47
+
48
+ beforeEach(async () => {
49
+ server = new CliIpcServer();
50
+ server.start();
51
+ // Allow the server socket to bind.
52
+ await new Promise((resolve) => setTimeout(resolve, 50));
53
+ });
54
+
55
+ afterEach(async () => {
56
+ // Clean up watchers created during the test.
57
+ for (const id of createdWatcherIds) {
58
+ await cliIpcCall("watcher/delete", { watcher_id: id });
59
+ }
60
+ createdWatcherIds.length = 0;
61
+
62
+ server?.stop();
63
+ server = null;
64
+ });
65
+
66
+ /** Helper to create a watcher and track it for cleanup. */
67
+ async function createTestWatcher(
68
+ overrides?: Record<string, unknown>,
69
+ ): Promise<Watcher> {
70
+ const result = await cliIpcCall<Watcher>("watcher/create", {
71
+ name: "Test Watcher",
72
+ provider: "test-provider",
73
+ action_prompt: "Handle events",
74
+ ...overrides,
75
+ });
76
+ expect(result.ok).toBe(true);
77
+ expect(result.result).toBeDefined();
78
+ createdWatcherIds.push(result.result!.id);
79
+ return result.result!;
80
+ }
81
+
82
+ // ---------------------------------------------------------------------------
83
+ // Tests
84
+ // ---------------------------------------------------------------------------
85
+
86
+ describe("watcher IPC routes", () => {
87
+ // -- CRUD round-trip --------------------------------------------------------
88
+
89
+ test("create -> list -> update -> delete round-trip", async () => {
90
+ // Create
91
+ const watcher = await createTestWatcher();
92
+ expect(watcher.name).toBe("Test Watcher");
93
+ expect(watcher.providerId).toBe("test-provider");
94
+ expect(watcher.actionPrompt).toBe("Handle events");
95
+ expect(watcher.enabled).toBe(true);
96
+ expect(watcher.status).toBe("idle");
97
+
98
+ // List all
99
+ const listResult = await cliIpcCall<Watcher[]>("watcher/list", {});
100
+ expect(listResult.ok).toBe(true);
101
+ expect(Array.isArray(listResult.result)).toBe(true);
102
+ const found = listResult.result!.find((w) => w.id === watcher.id);
103
+ expect(found).toBeDefined();
104
+
105
+ // List single
106
+ const detailResult = await cliIpcCall<{
107
+ watcher: Watcher;
108
+ events: WatcherEvent[];
109
+ }>("watcher/list", { watcher_id: watcher.id });
110
+ expect(detailResult.ok).toBe(true);
111
+ expect(detailResult.result!.watcher.id).toBe(watcher.id);
112
+ expect(Array.isArray(detailResult.result!.events)).toBe(true);
113
+
114
+ // Update
115
+ const updateResult = await cliIpcCall<Watcher>("watcher/update", {
116
+ watcher_id: watcher.id,
117
+ name: "Updated Watcher",
118
+ });
119
+ expect(updateResult.ok).toBe(true);
120
+ expect(updateResult.result!.name).toBe("Updated Watcher");
121
+
122
+ // Delete
123
+ const deleteResult = await cliIpcCall<{ deleted: boolean; name: string }>(
124
+ "watcher/delete",
125
+ { watcher_id: watcher.id },
126
+ );
127
+ expect(deleteResult.ok).toBe(true);
128
+ expect(deleteResult.result!.deleted).toBe(true);
129
+ expect(deleteResult.result!.name).toBe("Updated Watcher");
130
+
131
+ // Remove from cleanup tracking since we already deleted it.
132
+ const idx = createdWatcherIds.indexOf(watcher.id);
133
+ if (idx >= 0) createdWatcherIds.splice(idx, 1);
134
+
135
+ // Confirm gone
136
+ const afterDelete = await cliIpcCall<Watcher[]>("watcher/list", {});
137
+ expect(afterDelete.ok).toBe(true);
138
+ const gone = afterDelete.result!.find((w) => w.id === watcher.id);
139
+ expect(gone).toBeUndefined();
140
+ });
141
+
142
+ // -- Create: unknown provider -----------------------------------------------
143
+
144
+ test("watcher/create rejects unknown provider", async () => {
145
+ const result = await cliIpcCall("watcher/create", {
146
+ name: "Bad Watcher",
147
+ provider: "nonexistent",
148
+ action_prompt: "Do stuff",
149
+ });
150
+ expect(result.ok).toBe(false);
151
+ expect(result.error).toContain('Unknown provider "nonexistent"');
152
+ expect(result.error).toContain("test-provider");
153
+ });
154
+
155
+ // -- Create: poll interval too low ------------------------------------------
156
+
157
+ test("watcher/create rejects poll_interval_ms < 15000", async () => {
158
+ const result = await cliIpcCall("watcher/create", {
159
+ name: "Fast Watcher",
160
+ provider: "test-provider",
161
+ action_prompt: "Handle events",
162
+ poll_interval_ms: 5000,
163
+ });
164
+ expect(result.ok).toBe(false);
165
+ expect(result.error).toBeDefined();
166
+ });
167
+
168
+ // -- List: empty state ------------------------------------------------------
169
+
170
+ test("watcher/list returns empty array when no watchers exist", async () => {
171
+ const result = await cliIpcCall<Watcher[]>("watcher/list", {});
172
+ expect(result.ok).toBe(true);
173
+ expect(Array.isArray(result.result)).toBe(true);
174
+ // There might be leftover watchers from other tests, but the important
175
+ // thing is that the call succeeds and returns an array.
176
+ });
177
+
178
+ // -- Update: no fields provided ---------------------------------------------
179
+
180
+ test("watcher/update rejects when no update fields provided", async () => {
181
+ const watcher = await createTestWatcher();
182
+ const result = await cliIpcCall("watcher/update", {
183
+ watcher_id: watcher.id,
184
+ });
185
+ expect(result.ok).toBe(false);
186
+ expect(result.error).toContain("No updates provided");
187
+ });
188
+
189
+ // -- Delete: non-existent watcher -------------------------------------------
190
+
191
+ test("watcher/delete returns error for non-existent watcher", async () => {
192
+ const result = await cliIpcCall("watcher/delete", {
193
+ watcher_id: "does-not-exist",
194
+ });
195
+ expect(result.ok).toBe(false);
196
+ expect(result.error).toContain("Watcher not found");
197
+ });
198
+
199
+ // -- Digest: empty events ---------------------------------------------------
200
+
201
+ test("watcher/digest returns empty events when no events exist", async () => {
202
+ const result = await cliIpcCall<{
203
+ events: WatcherEvent[];
204
+ watcherNames: Record<string, string>;
205
+ }>("watcher/digest", {});
206
+ expect(result.ok).toBe(true);
207
+ expect(Array.isArray(result.result!.events)).toBe(true);
208
+ expect(typeof result.result!.watcherNames).toBe("object");
209
+ });
210
+
211
+ // -- Underscore aliases -----------------------------------------------------
212
+
213
+ test("watcher_create alias works identically to watcher/create", async () => {
214
+ const result = await cliIpcCall<Watcher>("watcher_create", {
215
+ name: "Alias Watcher",
216
+ provider: "test-provider",
217
+ action_prompt: "Handle events",
218
+ });
219
+ expect(result.ok).toBe(true);
220
+ expect(result.result!.name).toBe("Alias Watcher");
221
+ createdWatcherIds.push(result.result!.id);
222
+ });
223
+
224
+ test("watcher_list alias works identically to watcher/list", async () => {
225
+ const watcher = await createTestWatcher();
226
+ const result = await cliIpcCall<Watcher[]>("watcher_list", {});
227
+ expect(result.ok).toBe(true);
228
+ expect(Array.isArray(result.result)).toBe(true);
229
+ const found = result.result!.find((w) => w.id === watcher.id);
230
+ expect(found).toBeDefined();
231
+ });
232
+
233
+ test("watcher_update alias works identically to watcher/update", async () => {
234
+ const watcher = await createTestWatcher();
235
+ const result = await cliIpcCall<Watcher>("watcher_update", {
236
+ watcher_id: watcher.id,
237
+ name: "Alias Updated",
238
+ });
239
+ expect(result.ok).toBe(true);
240
+ expect(result.result!.name).toBe("Alias Updated");
241
+ });
242
+
243
+ test("watcher_delete alias works identically to watcher/delete", async () => {
244
+ const watcher = await createTestWatcher();
245
+ const result = await cliIpcCall<{ deleted: boolean; name: string }>(
246
+ "watcher_delete",
247
+ { watcher_id: watcher.id },
248
+ );
249
+ expect(result.ok).toBe(true);
250
+ expect(result.result!.deleted).toBe(true);
251
+
252
+ // Remove from cleanup tracking.
253
+ const idx = createdWatcherIds.indexOf(watcher.id);
254
+ if (idx >= 0) createdWatcherIds.splice(idx, 1);
255
+ });
256
+
257
+ test("watcher_digest alias works identically to watcher/digest", async () => {
258
+ const result = await cliIpcCall<{
259
+ events: WatcherEvent[];
260
+ watcherNames: Record<string, string>;
261
+ }>("watcher_digest", {});
262
+ expect(result.ok).toBe(true);
263
+ expect(Array.isArray(result.result!.events)).toBe(true);
264
+ });
265
+
266
+ // -- Create: credential_service override ------------------------------------
267
+
268
+ test("watcher/create uses provider default credential_service when not overridden", async () => {
269
+ const watcher = await createTestWatcher();
270
+ expect(watcher.credentialService).toBe("test-cred");
271
+ });
272
+
273
+ test("watcher/create accepts credential_service override", async () => {
274
+ const watcher = await createTestWatcher({
275
+ credential_service: "custom-cred",
276
+ });
277
+ expect(watcher.credentialService).toBe("custom-cred");
278
+ });
279
+
280
+ // -- Create: config passthrough ---------------------------------------------
281
+
282
+ test("watcher/create passes config as configJson", async () => {
283
+ const watcher = await createTestWatcher({
284
+ config: { filter: "important" },
285
+ });
286
+ expect(watcher.configJson).toBe(JSON.stringify({ filter: "important" }));
287
+ });
288
+
289
+ // -- Create: custom poll interval -------------------------------------------
290
+
291
+ test("watcher/create accepts valid poll_interval_ms", async () => {
292
+ const watcher = await createTestWatcher({ poll_interval_ms: 30000 });
293
+ expect(watcher.pollIntervalMs).toBe(30000);
294
+ });
295
+ });
@@ -5,7 +5,8 @@
5
5
  * Returns a typed result object so callers can distinguish success
6
6
  * from connection failures and method errors.
7
7
  *
8
- * The socket lives at `{workspaceDir}/assistant-cli.sock`.
8
+ * The preferred socket path is `{workspaceDir}/assistant-cli.sock`, with a
9
+ * deterministic fallback for long AF_UNIX paths.
9
10
  */
10
11
 
11
12
  import { connect, type Socket } from "node:net";
@@ -10,17 +10,18 @@
10
10
  * - Request: { "id": string, "method": string, "params"?: Record<string, unknown> }
11
11
  * - Response: { "id": string, "result"?: unknown, "error"?: string }
12
12
  *
13
- * The socket lives at `{workspaceDir}/assistant-cli.sock` on the workspace
14
- * volume so CLI commands running in the same container can connect to it.
13
+ * The preferred socket path is `{workspaceDir}/assistant-cli.sock`. On
14
+ * platforms with strict AF_UNIX path limits (notably macOS), the server falls
15
+ * back to a shorter deterministic path so CLI commands can still connect.
15
16
  */
16
17
 
17
- import { existsSync, unlinkSync } from "node:fs";
18
+ import { existsSync, mkdirSync, unlinkSync } from "node:fs";
18
19
  import { createServer, type Server, type Socket } from "node:net";
19
- import { join } from "node:path";
20
+ import { dirname } from "node:path";
20
21
 
21
22
  import { getLogger } from "../util/logger.js";
22
- import { getWorkspaceDir } from "../util/platform.js";
23
23
  import { cliIpcRoutes } from "./routes/index.js";
24
+ import { resolveIpcSocketPath } from "./socket-path.js";
24
25
 
25
26
  const log = getLogger("cli-ipc-server");
26
27
 
@@ -61,7 +62,19 @@ export class CliIpcServer {
61
62
  private socketPath: string;
62
63
 
63
64
  constructor() {
64
- this.socketPath = getCliSocketPath();
65
+ const socketResolution = resolveIpcSocketPath("assistant-cli.sock");
66
+ this.socketPath = socketResolution.path;
67
+ if (socketResolution.source !== "workspace") {
68
+ log.warn(
69
+ {
70
+ source: socketResolution.source,
71
+ workspacePath: socketResolution.workspacePath,
72
+ resolvedPath: socketResolution.path,
73
+ maxPathBytes: socketResolution.maxPathBytes,
74
+ },
75
+ "CLI IPC socket path exceeded platform limit; using fallback path",
76
+ );
77
+ }
65
78
  for (const route of cliIpcRoutes) {
66
79
  this.methods.set(route.method, route.handler);
67
80
  }
@@ -74,6 +87,12 @@ export class CliIpcServer {
74
87
 
75
88
  /** Start listening on the Unix domain socket. */
76
89
  start(): void {
90
+ // Ensure the parent directory exists before listening.
91
+ const socketDir = dirname(this.socketPath);
92
+ if (!existsSync(socketDir)) {
93
+ mkdirSync(socketDir, { recursive: true, mode: 0o700 });
94
+ }
95
+
77
96
  // Clean up stale socket file from a previous run
78
97
  if (existsSync(this.socketPath)) {
79
98
  try {
@@ -229,6 +248,5 @@ export class CliIpcServer {
229
248
  // ---------------------------------------------------------------------------
230
249
 
231
250
  export function getCliSocketPath(): string {
232
- return join(getWorkspaceDir(), "assistant-cli.sock");
251
+ return resolveIpcSocketPath("assistant-cli.sock").path;
233
252
  }
234
-
@@ -5,14 +5,14 @@
5
5
  * for reading gateway-owned data. Protocol: newline-delimited JSON
6
6
  * (same as gateway/src/ipc/server.ts).
7
7
  *
8
- * The socket lives at `{workspaceDir}/gateway.sock` on the shared volume.
8
+ * The preferred socket path is `{workspaceDir}/gateway.sock`, with a
9
+ * deterministic fallback for long AF_UNIX paths.
9
10
  */
10
11
 
11
12
  import { connect, type Socket } from "node:net";
12
- import { join } from "node:path";
13
13
 
14
14
  import { getLogger } from "../util/logger.js";
15
- import { getWorkspaceDir } from "../util/platform.js";
15
+ import { resolveIpcSocketPath } from "./socket-path.js";
16
16
 
17
17
  const log = getLogger("gateway-ipc-client");
18
18
 
@@ -176,5 +176,5 @@ export async function ipcGetFeatureFlags(): Promise<Record<string, boolean>> {
176
176
  // ---------------------------------------------------------------------------
177
177
 
178
178
  function getGatewaySocketPath(): string {
179
- return join(getWorkspaceDir(), "gateway.sock");
179
+ return resolveIpcSocketPath("gateway.sock").path;
180
180
  }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * IPC routes for attachment operations.
3
+ *
4
+ * Exposes register and lookup operations so CLI commands and external
5
+ * processes can interact with the attachment store.
6
+ *
7
+ * Each operation is registered under both a slash-style method name
8
+ * (e.g. `attachment/register`) and an underscore alias (`attachment_register`)
9
+ * for ergonomics.
10
+ */
11
+
12
+ import { statSync } from "node:fs";
13
+ import { basename } from "node:path";
14
+
15
+ import { z } from "zod";
16
+
17
+ import {
18
+ getFilePathBySourcePath,
19
+ uploadFileBackedAttachment,
20
+ validateAttachmentUpload,
21
+ } from "../../memory/attachments-store.js";
22
+ import type { IpcRoute } from "../cli-server.js";
23
+
24
+ // -- Param schemas --------------------------------------------------------
25
+
26
+ const AttachmentRegisterParams = z.object({
27
+ path: z.string().min(1),
28
+ mimeType: z.string().min(1),
29
+ filename: z.string().optional(),
30
+ });
31
+
32
+ const AttachmentLookupParams = z.object({
33
+ sourcePath: z.string().min(1),
34
+ conversationId: z.string().min(1),
35
+ });
36
+
37
+ // -- Handlers -------------------------------------------------------------
38
+
39
+ function handleAttachmentRegister(params?: Record<string, unknown>) {
40
+ const { path, mimeType, filename } = AttachmentRegisterParams.parse(params);
41
+
42
+ let sizeBytes: number;
43
+ try {
44
+ const stat = statSync(path);
45
+ if (!stat.isFile()) {
46
+ throw new Error(
47
+ `Path is not a regular file: ${path}. Provide a path to a file, not a directory.`,
48
+ );
49
+ }
50
+ sizeBytes = stat.size;
51
+ } catch (err) {
52
+ if (err instanceof Error && err.message.startsWith("Path is not")) {
53
+ throw err;
54
+ }
55
+ throw new Error(`File not found: ${path}`);
56
+ }
57
+
58
+ const resolvedFilename = filename ?? basename(path);
59
+
60
+ const validation = validateAttachmentUpload(resolvedFilename, mimeType);
61
+ if (!validation.ok) {
62
+ throw new Error(validation.error);
63
+ }
64
+
65
+ return uploadFileBackedAttachment(
66
+ resolvedFilename,
67
+ mimeType,
68
+ path,
69
+ sizeBytes,
70
+ );
71
+ }
72
+
73
+ function handleAttachmentLookup(params?: Record<string, unknown>) {
74
+ const { sourcePath, conversationId } = AttachmentLookupParams.parse(params);
75
+
76
+ const result = getFilePathBySourcePath(sourcePath, conversationId);
77
+ if (result === null) {
78
+ throw new Error(
79
+ `No attachment found for source path: ${sourcePath} in conversation ${conversationId}. Run 'assistant attachment register' to register a file first.`,
80
+ );
81
+ }
82
+
83
+ return { filePath: result };
84
+ }
85
+
86
+ // -- Route definitions ----------------------------------------------------
87
+
88
+ export const attachmentRegisterRoute: IpcRoute = {
89
+ method: "attachment/register",
90
+ handler: handleAttachmentRegister,
91
+ };
92
+
93
+ const attachmentRegisterAliasRoute: IpcRoute = {
94
+ method: "attachment_register",
95
+ handler: handleAttachmentRegister,
96
+ };
97
+
98
+ export const attachmentLookupRoute: IpcRoute = {
99
+ method: "attachment/lookup",
100
+ handler: handleAttachmentLookup,
101
+ };
102
+
103
+ const attachmentLookupAliasRoute: IpcRoute = {
104
+ method: "attachment_lookup",
105
+ handler: handleAttachmentLookup,
106
+ };
107
+
108
+ /** All attachment IPC routes (canonical + aliases). */
109
+ export const attachmentRoutes: IpcRoute[] = [
110
+ attachmentRegisterRoute,
111
+ attachmentRegisterAliasRoute,
112
+ attachmentLookupRoute,
113
+ attachmentLookupAliasRoute,
114
+ ];
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared context resolver for `browser_execute` IPC calls.
3
+ *
4
+ * The browser CLI can optionally pass a live conversation ID (for example
5
+ * from `__CONVERSATION_ID` in a nested `bash` tool invocation). When that
6
+ * conversation is currently active in daemon memory, we can reuse its
7
+ * host-browser proxy wiring so browser operations (including `status`) see
8
+ * extension connectivity exactly as the parent turn does.
9
+ *
10
+ * If no resolver is registered, or the requested conversation isn't active,
11
+ * callers fall back to the deterministic `browser-cli:<sessionId>` context.
12
+ */
13
+
14
+ import type { InterfaceId } from "../../channels/types.js";
15
+ import type { HostBrowserProxy } from "../../daemon/host-browser-proxy.js";
16
+ import type { TrustClass } from "../../runtime/actor-trust-resolver.js";
17
+
18
+ export interface BrowserIpcContextResolution {
19
+ conversationId: string;
20
+ trustClass: TrustClass;
21
+ hostBrowserProxy?: HostBrowserProxy;
22
+ transportInterface?: InterfaceId;
23
+ }
24
+
25
+ export type BrowserIpcContextResolver = (
26
+ conversationId: string,
27
+ ) => BrowserIpcContextResolution | null;
28
+
29
+ let resolver: BrowserIpcContextResolver | null = null;
30
+
31
+ export function registerBrowserIpcContextResolver(
32
+ nextResolver: BrowserIpcContextResolver,
33
+ ): void {
34
+ resolver = nextResolver;
35
+ }
36
+
37
+ /**
38
+ * Test-only helper to clear the module-level resolver.
39
+ *
40
+ * @internal
41
+ */
42
+ export function resetBrowserIpcContextResolverForTests(): void {
43
+ resolver = null;
44
+ }
45
+
46
+ export function resolveBrowserIpcContext(params: {
47
+ requestedConversationId?: string;
48
+ fallbackConversationId: string;
49
+ }): BrowserIpcContextResolution {
50
+ const { requestedConversationId, fallbackConversationId } = params;
51
+
52
+ if (requestedConversationId && resolver) {
53
+ const resolved = resolver(requestedConversationId);
54
+ if (resolved) return resolved;
55
+ }
56
+
57
+ return {
58
+ conversationId: fallbackConversationId,
59
+ trustClass: "guardian",
60
+ };
61
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * IPC route for browser operations.
3
+ *
4
+ * Exposes `browser_execute` so CLI commands and external processes can
5
+ * invoke browser operations without going through skill tool wrappers.
6
+ *
7
+ * The `sessionId` parameter (default `"default"`) is mapped to a
8
+ * deterministic conversation key `browser-cli:<sessionId>` so that
9
+ * sequential IPC calls with the same session reuse browser state.
10
+ */
11
+
12
+ import { z } from "zod";
13
+
14
+ import { executeBrowserOperation } from "../../browser/operations.js";
15
+ import {
16
+ BROWSER_OPERATIONS,
17
+ type BrowserOperation,
18
+ } from "../../browser/types.js";
19
+ import type { ContentBlock } from "../../providers/types.js";
20
+ import type { IpcRoute } from "../cli-server.js";
21
+ import { resolveBrowserIpcContext } from "./browser-context.js";
22
+
23
+ // ── Param validation ─────────────────────────────────────────────────
24
+
25
+ const BrowserExecuteParams = z.object({
26
+ operation: z.enum(BROWSER_OPERATIONS as unknown as [string, ...string[]]),
27
+ input: z.record(z.string(), z.unknown()).default({}),
28
+ sessionId: z.string().min(1).default("default"),
29
+ conversationId: z.string().min(1).optional(),
30
+ });
31
+
32
+ // ── Conversation key ─────────────────────────────────────────────────
33
+
34
+ /**
35
+ * Build a deterministic conversation key from a session ID.
36
+ * All CLI browser calls with the same session share browser state.
37
+ */
38
+ export function browserCliConversationKey(sessionId: string): string {
39
+ return `browser-cli:${sessionId}`;
40
+ }
41
+
42
+ // ── Screenshot extraction ────────────────────────────────────────────
43
+
44
+ /**
45
+ * Extract base64 screenshot payloads from tool execution content blocks.
46
+ * Returns an array of `{ mediaType, data }` objects for each image found.
47
+ */
48
+ function extractScreenshots(
49
+ contentBlocks?: ContentBlock[],
50
+ ): Array<{ mediaType: string; data: string }> {
51
+ if (!contentBlocks) return [];
52
+ const screenshots: Array<{ mediaType: string; data: string }> = [];
53
+ for (const block of contentBlocks) {
54
+ if (block.type === "image" && block.source.type === "base64") {
55
+ screenshots.push({
56
+ mediaType: block.source.media_type,
57
+ data: block.source.data,
58
+ });
59
+ }
60
+ }
61
+ return screenshots;
62
+ }
63
+
64
+ // ── Route definition ─────────────────────────────────────────────────
65
+
66
+ export const browserExecuteRoute: IpcRoute = {
67
+ method: "browser_execute",
68
+ handler: async (params) => {
69
+ const { operation, input, sessionId, conversationId } =
70
+ BrowserExecuteParams.parse(params);
71
+ const resolvedContext = resolveBrowserIpcContext({
72
+ requestedConversationId: conversationId,
73
+ fallbackConversationId: browserCliConversationKey(sessionId),
74
+ });
75
+
76
+ const result = await executeBrowserOperation(
77
+ operation as BrowserOperation,
78
+ input,
79
+ {
80
+ workingDir: process.cwd(),
81
+ conversationId: resolvedContext.conversationId,
82
+ trustClass: resolvedContext.trustClass,
83
+ hostBrowserProxy: resolvedContext.hostBrowserProxy,
84
+ transportInterface: resolvedContext.transportInterface,
85
+ },
86
+ );
87
+
88
+ const screenshots = extractScreenshots(result.contentBlocks);
89
+
90
+ return {
91
+ content: result.content,
92
+ isError: result.isError,
93
+ ...(screenshots.length > 0 ? { screenshots } : {}),
94
+ };
95
+ },
96
+ };