@vellumai/assistant 0.6.3 → 0.6.4

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 (667) hide show
  1. package/ARCHITECTURE.md +273 -10
  2. package/Dockerfile +2 -3
  3. package/bun.lock +5 -13
  4. package/docs/backup-troubleshooting.md +52 -0
  5. package/docs/browser-use-architecture-phase2.md +174 -0
  6. package/docs/stt-provider-onboarding.md +120 -0
  7. package/knip.json +12 -2
  8. package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
  9. package/node_modules/@vellumai/ces-contracts/package.json +3 -3
  10. package/openapi.yaml +982 -72
  11. package/package.json +4 -6
  12. package/scripts/generate-openapi.ts +0 -1
  13. package/scripts/test.sh +73 -18
  14. package/src/__tests__/agent-image-optimize.test.ts +28 -0
  15. package/src/__tests__/agent-loop.test.ts +123 -0
  16. package/src/__tests__/anthropic-provider.test.ts +263 -10
  17. package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
  18. package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
  19. package/src/__tests__/browser-fill-credential.test.ts +11 -0
  20. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
  21. package/src/__tests__/browser-skill-endstate.test.ts +31 -7
  22. package/src/__tests__/btw-routes.test.ts +7 -0
  23. package/src/__tests__/call-controller.test.ts +581 -20
  24. package/src/__tests__/catalog-files.test.ts +138 -0
  25. package/src/__tests__/channel-invite-transport.test.ts +2 -2
  26. package/src/__tests__/channel-readiness-routes.test.ts +16 -20
  27. package/src/__tests__/channel-readiness-service.test.ts +12 -7
  28. package/src/__tests__/checker.test.ts +157 -10
  29. package/src/__tests__/clawhub-files.test.ts +347 -0
  30. package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
  31. package/src/__tests__/config-analysis.test.ts +100 -0
  32. package/src/__tests__/config-schema.test.ts +1013 -66
  33. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
  34. package/src/__tests__/config-watcher.test.ts +43 -8
  35. package/src/__tests__/contact-store-user-file.test.ts +512 -0
  36. package/src/__tests__/contacts-write.test.ts +197 -0
  37. package/src/__tests__/context-window-manager.test.ts +88 -0
  38. package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
  39. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  40. package/src/__tests__/conversation-agent-loop.test.ts +98 -2
  41. package/src/__tests__/conversation-confirmation-signals.test.ts +135 -0
  42. package/src/__tests__/conversation-error.test.ts +70 -0
  43. package/src/__tests__/conversation-history-web-search.test.ts +11 -4
  44. package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
  45. package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
  46. package/src/__tests__/conversation-list-source.test.ts +145 -0
  47. package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
  48. package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
  49. package/src/__tests__/conversation-queue.test.ts +901 -60
  50. package/src/__tests__/conversation-routes-disk-view.test.ts +270 -0
  51. package/src/__tests__/conversation-runtime-assembly.test.ts +55 -0
  52. package/src/__tests__/conversation-skill-tools.test.ts +7 -4
  53. package/src/__tests__/conversation-slash-commands.test.ts +33 -0
  54. package/src/__tests__/conversation-slash-queue.test.ts +89 -18
  55. package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
  56. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
  57. package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
  58. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
  59. package/src/__tests__/credential-health-service.test.ts +352 -0
  60. package/src/__tests__/credential-security-invariants.test.ts +5 -3
  61. package/src/__tests__/credential-vault-unit.test.ts +379 -3
  62. package/src/__tests__/credentials-cli.test.ts +40 -16
  63. package/src/__tests__/cross-provider-web-search.test.ts +146 -35
  64. package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
  65. package/src/__tests__/device-id.test.ts +112 -0
  66. package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
  67. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
  68. package/src/__tests__/email-html-renderer.test.ts +71 -0
  69. package/src/__tests__/email-invite-adapter.test.ts +36 -32
  70. package/src/__tests__/emit-event-signal.test.ts +71 -0
  71. package/src/__tests__/extension-id-sync-guard.test.ts +75 -8
  72. package/src/__tests__/fixtures/mock-chrome-extension.ts +11 -0
  73. package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
  74. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  75. package/src/__tests__/gemini-provider.test.ts +64 -0
  76. package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
  77. package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
  78. package/src/__tests__/gmail-archive-gate.test.ts +246 -0
  79. package/src/__tests__/gmail-preferences.test.ts +117 -0
  80. package/src/__tests__/headless-browser-interactions.test.ts +43 -0
  81. package/src/__tests__/headless-browser-mode.test.ts +614 -0
  82. package/src/__tests__/headless-browser-navigate.test.ts +142 -5
  83. package/src/__tests__/headless-browser-read-tools.test.ts +11 -0
  84. package/src/__tests__/headless-browser-snapshot.test.ts +10 -0
  85. package/src/__tests__/heartbeat-service.test.ts +70 -17
  86. package/src/__tests__/home-state-routes.test.ts +162 -0
  87. package/src/__tests__/host-bash-proxy.test.ts +0 -5
  88. package/src/__tests__/host-browser-e2e-cloud.test.ts +138 -4
  89. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +4 -4
  90. package/src/__tests__/host-browser-ws-events-e2e.test.ts +103 -0
  91. package/src/__tests__/host-cu-proxy.test.ts +0 -5
  92. package/src/__tests__/identity-intro-cache.test.ts +40 -10
  93. package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
  94. package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
  95. package/src/__tests__/llm-context-normalization.test.ts +488 -0
  96. package/src/__tests__/llm-context-route-provider.test.ts +86 -5
  97. package/src/__tests__/llm-usage-store.test.ts +363 -0
  98. package/src/__tests__/media-stream-output.test.ts +555 -0
  99. package/src/__tests__/media-stream-parser.test.ts +374 -0
  100. package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
  101. package/src/__tests__/media-stream-stt-session.test.ts +588 -0
  102. package/src/__tests__/media-turn-detector.test.ts +440 -0
  103. package/src/__tests__/message-queue.test.ts +125 -0
  104. package/src/__tests__/migration-export-http.test.ts +6 -6
  105. package/src/__tests__/migration-import-commit-http.test.ts +8 -6
  106. package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
  107. package/src/__tests__/migration-validate-http.test.ts +3 -3
  108. package/src/__tests__/mock-gateway-ipc.ts +151 -0
  109. package/src/__tests__/model-intents.test.ts +2 -2
  110. package/src/__tests__/oauth-apps-routes.test.ts +1 -0
  111. package/src/__tests__/oauth-cli.test.ts +2 -0
  112. package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
  113. package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
  114. package/src/__tests__/oauth-providers-routes.test.ts +2 -0
  115. package/src/__tests__/oauth-store.test.ts +85 -0
  116. package/src/__tests__/oauth2-gateway-transport.test.ts +249 -6
  117. package/src/__tests__/onboarding-template-contract.test.ts +6 -13
  118. package/src/__tests__/openai-provider.test.ts +176 -0
  119. package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
  120. package/src/__tests__/openai-responses-provider.test.ts +1105 -0
  121. package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
  122. package/src/__tests__/outlook-unsubscribe.test.ts +31 -2
  123. package/src/__tests__/persona-resolver.test.ts +251 -0
  124. package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
  125. package/src/__tests__/platform.test.ts +92 -1
  126. package/src/__tests__/post-turn-tool-result-truncation.test.ts +47 -0
  127. package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
  128. package/src/__tests__/pricing.test.ts +174 -0
  129. package/src/__tests__/qdrant-manager.test.ts +29 -8
  130. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
  131. package/src/__tests__/relationship-state-contract.test.ts +175 -0
  132. package/src/__tests__/relay-server.test.ts +423 -5
  133. package/src/__tests__/search-skills-unified.test.ts +118 -0
  134. package/src/__tests__/secret-scanner-executor.test.ts +4 -0
  135. package/src/__tests__/secure-keys.test.ts +107 -0
  136. package/src/__tests__/send-endpoint-busy.test.ts +5 -1
  137. package/src/__tests__/sequence-store.test.ts +1 -1
  138. package/src/__tests__/server-history-render.test.ts +49 -0
  139. package/src/__tests__/settings-routes.test.ts +201 -0
  140. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  141. package/src/__tests__/skills-file-content-endpoint.test.ts +276 -145
  142. package/src/__tests__/skills-files-catalog-fallback.test.ts +381 -93
  143. package/src/__tests__/skills.test.ts +5 -2
  144. package/src/__tests__/skillssh-files.test.ts +446 -0
  145. package/src/__tests__/slack-block-formatting.test.ts +110 -0
  146. package/src/__tests__/slack-channel-config.test.ts +564 -1
  147. package/src/__tests__/stt-catalog-parity.test.ts +282 -0
  148. package/src/__tests__/stt-stream-session.test.ts +535 -0
  149. package/src/__tests__/system-prompt.test.ts +112 -26
  150. package/src/__tests__/telephony-stt-routing.test.ts +329 -0
  151. package/src/__tests__/terminal-tools.test.ts +18 -7
  152. package/src/__tests__/test-preload.ts +18 -0
  153. package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
  154. package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
  155. package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
  156. package/src/__tests__/tool-executor.test.ts +33 -24
  157. package/src/__tests__/tool-result-truncation.test.ts +36 -0
  158. package/src/__tests__/trust-store.test.ts +7 -1
  159. package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
  160. package/src/__tests__/tts-catalog-parity.test.ts +345 -0
  161. package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
  162. package/src/__tests__/twilio-routes.test.ts +376 -0
  163. package/src/__tests__/unicode.test.ts +293 -0
  164. package/src/__tests__/update-bulletin-format.test.ts +59 -0
  165. package/src/__tests__/update-bulletin.test.ts +206 -5
  166. package/src/__tests__/usage-routes.test.ts +25 -4
  167. package/src/__tests__/user-reference.test.ts +46 -61
  168. package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
  169. package/src/__tests__/voice-config-update.test.ts +403 -0
  170. package/src/__tests__/voice-quality.test.ts +434 -19
  171. package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
  172. package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
  173. package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
  174. package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
  175. package/src/__tests__/workspace-migration-meets.test.ts +244 -0
  176. package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
  177. package/src/__tests__/workspace-policy.test.ts +2 -0
  178. package/src/agent/image-optimize.ts +24 -12
  179. package/src/agent/loop.ts +43 -3
  180. package/src/backup/__tests__/backup-key.test.ts +152 -0
  181. package/src/backup/__tests__/backup-worker.test.ts +767 -0
  182. package/src/backup/__tests__/list-snapshots.test.ts +87 -0
  183. package/src/backup/__tests__/local-writer.test.ts +218 -0
  184. package/src/backup/__tests__/offsite-writer.test.ts +641 -0
  185. package/src/backup/__tests__/paths.test.ts +300 -0
  186. package/src/backup/__tests__/restore.test.ts +498 -0
  187. package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
  188. package/src/backup/__tests__/stream-crypt.test.ts +228 -0
  189. package/src/backup/backup-key.ts +137 -0
  190. package/src/backup/backup-worker.ts +459 -0
  191. package/src/backup/list-snapshots.ts +147 -0
  192. package/src/backup/local-writer.ts +133 -0
  193. package/src/backup/offsite-writer.ts +222 -0
  194. package/src/backup/paths.ts +226 -0
  195. package/src/backup/restore.ts +322 -0
  196. package/src/backup/snapshot-lock.ts +431 -0
  197. package/src/backup/stream-crypt.ts +263 -0
  198. package/src/bundler/package-resolver.ts +4 -0
  199. package/src/calls/audio-store.ts +11 -5
  200. package/src/calls/call-controller.ts +226 -71
  201. package/src/calls/call-domain.ts +9 -0
  202. package/src/calls/call-speech-output.ts +190 -0
  203. package/src/calls/call-transport.ts +77 -0
  204. package/src/calls/media-stream-audio-transcode.ts +173 -0
  205. package/src/calls/media-stream-output.ts +660 -0
  206. package/src/calls/media-stream-parser.ts +300 -0
  207. package/src/calls/media-stream-protocol.ts +166 -0
  208. package/src/calls/media-stream-server.ts +592 -0
  209. package/src/calls/media-stream-stt-session.ts +460 -0
  210. package/src/calls/media-turn-detector.ts +230 -0
  211. package/src/calls/relay-server.ts +90 -75
  212. package/src/calls/resolve-call-tts-provider.ts +136 -0
  213. package/src/calls/telephony-stt-routing.ts +145 -0
  214. package/src/calls/tts-call-strategy.ts +161 -0
  215. package/src/calls/tts-text-sanitizer.ts +32 -16
  216. package/src/calls/twilio-routes.ts +281 -17
  217. package/src/calls/voice-quality.ts +78 -35
  218. package/src/calls/voice-session-bridge.ts +8 -1
  219. package/src/channels/types.ts +16 -0
  220. package/src/cli/__tests__/run-assistant-command.ts +11 -1
  221. package/src/cli/commands/__tests__/backup.test.ts +1165 -0
  222. package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
  223. package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
  224. package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
  225. package/src/cli/commands/__tests__/email-download.test.ts +16 -1
  226. package/src/cli/commands/__tests__/email-list.test.ts +22 -4
  227. package/src/cli/commands/__tests__/email-register.test.ts +4 -4
  228. package/src/cli/commands/__tests__/email-send.test.ts +37 -4
  229. package/src/cli/commands/__tests__/email-status.test.ts +5 -1
  230. package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
  231. package/src/cli/commands/backup.ts +993 -0
  232. package/src/cli/commands/conversations.ts +77 -0
  233. package/src/cli/commands/credentials.ts +0 -1
  234. package/src/cli/commands/domain.ts +210 -0
  235. package/src/cli/commands/email.ts +255 -3
  236. package/src/cli/commands/oauth/__tests__/connect.test.ts +12 -0
  237. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +1 -0
  238. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -0
  239. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -0
  240. package/src/cli/commands/oauth/mode.ts +12 -3
  241. package/src/cli/commands/oauth/providers.ts +15 -0
  242. package/src/cli/commands/oauth/shared.ts +2 -1
  243. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +4 -9
  244. package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
  245. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  246. package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
  247. package/src/cli/program.ts +30 -4
  248. package/src/config/__tests__/backup-schema.test.ts +134 -0
  249. package/src/config/assistant-feature-flags.ts +61 -62
  250. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +37 -1
  251. package/src/config/bundled-skills/browser/SKILL.md +30 -5
  252. package/src/config/bundled-skills/browser/TOOLS.json +123 -0
  253. package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
  254. package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
  255. package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
  256. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +2 -2
  258. package/src/config/bundled-skills/gmail/SKILL.md +53 -7
  259. package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
  260. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
  261. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
  262. package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
  263. package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
  264. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
  265. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
  266. package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
  267. package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
  268. package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
  269. package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
  270. package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
  271. package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
  272. package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
  273. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
  274. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  275. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
  276. package/src/config/bundled-skills/outlook/SKILL.md +2 -2
  277. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
  278. package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
  279. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
  280. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
  281. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  282. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
  283. package/src/config/bundled-skills/slack/SKILL.md +1 -0
  284. package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
  285. package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
  286. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
  287. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
  288. package/src/config/bundled-tool-registry.ts +8 -0
  289. package/src/config/env-registry.ts +24 -0
  290. package/src/config/env.ts +34 -10
  291. package/src/config/feature-flag-registry.json +46 -14
  292. package/src/config/loader.ts +26 -12
  293. package/src/config/schema.ts +35 -10
  294. package/src/config/schemas/__tests__/stt.test.ts +43 -0
  295. package/src/config/schemas/analysis.ts +51 -0
  296. package/src/config/schemas/backup.ts +72 -0
  297. package/src/config/schemas/calls.ts +1 -26
  298. package/src/config/schemas/elevenlabs.ts +0 -59
  299. package/src/config/schemas/filing.ts +47 -7
  300. package/src/config/schemas/heartbeat.ts +27 -5
  301. package/src/config/schemas/host-browser.ts +47 -1
  302. package/src/config/schemas/inference.ts +1 -1
  303. package/src/config/schemas/memory-lifecycle.ts +14 -2
  304. package/src/config/schemas/services.ts +44 -0
  305. package/src/config/schemas/stt.ts +59 -0
  306. package/src/config/schemas/tts.ts +230 -0
  307. package/src/config/schemas/updates.ts +14 -0
  308. package/src/config/skills.ts +4 -0
  309. package/src/config/types.ts +4 -0
  310. package/src/contacts/contact-store.ts +56 -11
  311. package/src/contacts/contacts-write.ts +38 -1
  312. package/src/context/post-turn-tool-result-truncation.ts +3 -2
  313. package/src/context/tool-result-truncation.ts +2 -1
  314. package/src/context/window-manager.ts +45 -12
  315. package/src/credential-execution/executable-discovery.ts +12 -2
  316. package/src/credential-execution/process-manager.ts +33 -2
  317. package/src/credential-health/credential-health-service.ts +366 -0
  318. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
  319. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
  320. package/src/daemon/__tests__/conversation-tool-setup.test.ts +17 -8
  321. package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
  322. package/src/daemon/config-watcher.ts +99 -5
  323. package/src/daemon/conversation-agent-loop-handlers.ts +6 -0
  324. package/src/daemon/conversation-agent-loop.ts +101 -24
  325. package/src/daemon/conversation-error.ts +11 -0
  326. package/src/daemon/conversation-history.ts +40 -6
  327. package/src/daemon/conversation-launch.ts +220 -0
  328. package/src/daemon/conversation-lifecycle.ts +59 -9
  329. package/src/daemon/conversation-messaging.ts +37 -3
  330. package/src/daemon/conversation-notifiers.ts +5 -0
  331. package/src/daemon/conversation-process.ts +581 -19
  332. package/src/daemon/conversation-queue-manager.ts +24 -0
  333. package/src/daemon/conversation-runtime-assembly.ts +11 -1
  334. package/src/daemon/conversation-slash.ts +36 -0
  335. package/src/daemon/conversation-surfaces.ts +94 -4
  336. package/src/daemon/conversation-tool-setup.ts +25 -0
  337. package/src/daemon/conversation-usage.ts +7 -4
  338. package/src/daemon/conversation.ts +86 -28
  339. package/src/daemon/handlers/config-slack-channel.ts +269 -94
  340. package/src/daemon/handlers/conversations.ts +4 -1
  341. package/src/daemon/handlers/shared.ts +22 -0
  342. package/src/daemon/handlers/skills.ts +321 -77
  343. package/src/daemon/host-browser-proxy.ts +2 -1
  344. package/src/daemon/lifecycle.ts +122 -25
  345. package/src/daemon/message-protocol.ts +6 -0
  346. package/src/daemon/message-types/conversations.ts +34 -1
  347. package/src/daemon/message-types/home.ts +40 -0
  348. package/src/daemon/message-types/meet.ts +143 -0
  349. package/src/daemon/message-types/messages.ts +14 -0
  350. package/src/daemon/message-types/schedules.ts +34 -2
  351. package/src/daemon/message-types/skills.ts +16 -0
  352. package/src/daemon/message-types/surfaces.ts +2 -0
  353. package/src/daemon/server.ts +347 -2
  354. package/src/daemon/shutdown-handlers.ts +32 -4
  355. package/src/daemon/shutdown-registry.ts +40 -0
  356. package/src/daemon/tool-side-effects.ts +9 -0
  357. package/src/email/html-renderer.ts +76 -0
  358. package/src/heartbeat/heartbeat-service.ts +93 -7
  359. package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
  360. package/src/home/__tests__/emit-feed-event.test.ts +169 -0
  361. package/src/home/__tests__/feed-scheduler.test.ts +194 -0
  362. package/src/home/__tests__/feed-types.test.ts +275 -0
  363. package/src/home/__tests__/feed-writer.test.ts +688 -0
  364. package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
  365. package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
  366. package/src/home/__tests__/progress-formula.test.ts +213 -0
  367. package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
  368. package/src/home/__tests__/rollup-producer.test.ts +398 -0
  369. package/src/home/assistant-feed-authoring.ts +124 -0
  370. package/src/home/emit-feed-event.ts +158 -0
  371. package/src/home/feed-scheduler.ts +247 -0
  372. package/src/home/feed-types.ts +181 -0
  373. package/src/home/feed-writer.ts +469 -0
  374. package/src/home/platform-gmail-digest.ts +163 -0
  375. package/src/home/progress-formula.ts +86 -0
  376. package/src/home/relationship-state-writer.ts +824 -0
  377. package/src/home/relationship-state.ts +143 -0
  378. package/src/home/rollup-producer.ts +384 -0
  379. package/src/hooks/runner.ts +7 -0
  380. package/src/inbound/platform-callback-registration.ts +12 -3
  381. package/src/inbound/public-ingress-urls.ts +12 -0
  382. package/src/instrument.ts +1 -1
  383. package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
  384. package/src/ipc/cli-client.ts +151 -0
  385. package/src/ipc/cli-server.ts +234 -0
  386. package/src/ipc/gateway-client.ts +180 -0
  387. package/src/ipc/routes/index.ts +5 -0
  388. package/src/ipc/routes/wake-conversation.ts +19 -0
  389. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
  390. package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
  391. package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
  392. package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
  393. package/src/memory/app-store.ts +1 -1
  394. package/src/memory/attachments-store.ts +70 -0
  395. package/src/memory/auto-analysis-enqueue.ts +127 -0
  396. package/src/memory/auto-analysis-guard.ts +27 -0
  397. package/src/memory/cleanup-schedule-state.ts +37 -0
  398. package/src/memory/conversation-analyze-job.ts +73 -0
  399. package/src/memory/conversation-crud.ts +99 -0
  400. package/src/memory/conversation-disk-view.ts +7 -0
  401. package/src/memory/conversation-group-migration.ts +34 -2
  402. package/src/memory/conversation-queries.ts +6 -5
  403. package/src/memory/db-init.ts +6 -0
  404. package/src/memory/db-maintenance.ts +108 -0
  405. package/src/memory/db.ts +1 -0
  406. package/src/memory/graph/conversation-graph-memory.ts +15 -0
  407. package/src/memory/graph/extraction.test.ts +23 -0
  408. package/src/memory/graph/extraction.ts +8 -0
  409. package/src/memory/graph/retriever.ts +27 -18
  410. package/src/memory/graph/scoring.test.ts +186 -0
  411. package/src/memory/graph/scoring.ts +31 -1
  412. package/src/memory/graph/tools.ts +1 -1
  413. package/src/memory/group-crud.ts +6 -1
  414. package/src/memory/indexer.ts +95 -16
  415. package/src/memory/job-handlers/cleanup.ts +11 -8
  416. package/src/memory/job-handlers/conversation-starters.ts +16 -10
  417. package/src/memory/jobs-store.ts +64 -4
  418. package/src/memory/jobs-worker.ts +22 -9
  419. package/src/memory/llm-usage-store.ts +92 -56
  420. package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
  421. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
  422. package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
  423. package/src/memory/migrations/index.ts +6 -0
  424. package/src/memory/migrations/registry.ts +8 -0
  425. package/src/memory/qdrant-manager.ts +43 -16
  426. package/src/memory/schema/conversations.ts +2 -0
  427. package/src/memory/schema/oauth.ts +3 -0
  428. package/src/memory/usage-buckets.ts +396 -0
  429. package/src/messaging/providers/gmail/client.ts +57 -6
  430. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
  431. package/src/messaging/providers/slack/adapter.ts +143 -38
  432. package/src/messaging/providers/slack/client.ts +16 -0
  433. package/src/messaging/providers/slack/types.ts +4 -0
  434. package/src/notifications/decision-engine.ts +3 -3
  435. package/src/notifications/signal.ts +5 -0
  436. package/src/oauth/__tests__/identity-verifier.test.ts +1 -0
  437. package/src/oauth/byo-connection.test.ts +18 -1
  438. package/src/oauth/byo-connection.ts +3 -1
  439. package/src/oauth/connect-orchestrator.ts +2 -0
  440. package/src/oauth/connection-resolver.ts +6 -2
  441. package/src/oauth/connection.ts +2 -0
  442. package/src/oauth/oauth-store.ts +9 -0
  443. package/src/oauth/platform-connection.test.ts +98 -0
  444. package/src/oauth/platform-connection.ts +52 -31
  445. package/src/oauth/seed-providers.ts +7 -0
  446. package/src/permissions/checker.ts +16 -6
  447. package/src/permissions/defaults.ts +49 -1
  448. package/src/permissions/trust-store.ts +3 -3
  449. package/src/permissions/workspace-policy.ts +3 -0
  450. package/src/platform/client.test.ts +10 -0
  451. package/src/platform/sync-identity.ts +129 -0
  452. package/src/prompts/persona-resolver.ts +126 -2
  453. package/src/prompts/system-prompt.ts +59 -18
  454. package/src/prompts/templates/BOOTSTRAP.md +5 -5
  455. package/src/prompts/templates/SOUL.md +3 -1
  456. package/src/prompts/templates/UPDATES.md +12 -0
  457. package/src/prompts/templates/channels/slack.md +20 -0
  458. package/src/prompts/update-bulletin-format.ts +26 -9
  459. package/src/prompts/update-bulletin.ts +34 -23
  460. package/src/prompts/user-reference.ts +20 -17
  461. package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
  462. package/src/providers/anthropic/client.ts +157 -61
  463. package/src/providers/fireworks/client.ts +2 -2
  464. package/src/providers/gemini/client.ts +9 -1
  465. package/src/providers/model-catalog.ts +6 -0
  466. package/src/providers/model-intents.ts +4 -4
  467. package/src/providers/ollama/client.ts +2 -2
  468. package/src/providers/openai/chat-completions-provider.ts +474 -0
  469. package/src/providers/openai/client.ts +25 -440
  470. package/src/providers/openai/responses-provider.ts +502 -0
  471. package/src/providers/openrouter/client.ts +101 -4
  472. package/src/providers/provider-secret-catalog.ts +139 -0
  473. package/src/providers/registry.ts +2 -2
  474. package/src/providers/retry.ts +14 -3
  475. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
  476. package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
  477. package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
  478. package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
  479. package/src/providers/speech-to-text/deepgram.test.ts +332 -0
  480. package/src/providers/speech-to-text/deepgram.ts +115 -0
  481. package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
  482. package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
  483. package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
  484. package/src/providers/speech-to-text/google-gemini.ts +101 -0
  485. package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
  486. package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
  487. package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
  488. package/src/providers/speech-to-text/openai-whisper.ts +63 -33
  489. package/src/providers/speech-to-text/provider-catalog.ts +306 -0
  490. package/src/providers/speech-to-text/resolve.ts +386 -6
  491. package/src/providers/types.ts +9 -0
  492. package/src/runtime/AGENTS.md +43 -1
  493. package/src/runtime/__tests__/agent-wake.test.ts +831 -0
  494. package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
  495. package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
  496. package/src/runtime/agent-wake.ts +512 -0
  497. package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
  498. package/src/runtime/auth/route-policy.ts +30 -5
  499. package/src/runtime/auth/token-service.ts +56 -1
  500. package/src/runtime/btw-sidechain.ts +2 -0
  501. package/src/runtime/capability-tokens.ts +10 -10
  502. package/src/runtime/channel-invite-transport.ts +1 -1
  503. package/src/runtime/channel-invite-transports/email.ts +14 -6
  504. package/src/runtime/channel-readiness-service.ts +12 -22
  505. package/src/runtime/chrome-extension-registry.ts +38 -2
  506. package/src/runtime/http-server.ts +395 -10
  507. package/src/runtime/http-types.ts +6 -2
  508. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +36 -0
  509. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
  510. package/src/runtime/migrations/migration-transport.ts +1 -0
  511. package/src/runtime/migrations/migration-wizard.ts +1 -0
  512. package/src/runtime/migrations/vbundle-import-analyzer.ts +77 -1
  513. package/src/runtime/migrations/vbundle-importer.ts +34 -0
  514. package/src/runtime/pending-interactions.ts +0 -11
  515. package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
  516. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
  517. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
  518. package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
  519. package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
  520. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
  521. package/src/runtime/routes/app-management-routes.ts +12 -18
  522. package/src/runtime/routes/attachment-routes.test.ts +9 -3
  523. package/src/runtime/routes/attachment-routes.ts +216 -17
  524. package/src/runtime/routes/backup-routes.ts +519 -0
  525. package/src/runtime/routes/browser-extension-pair-routes.ts +82 -23
  526. package/src/runtime/routes/btw-routes.ts +8 -6
  527. package/src/runtime/routes/contact-routes.test.ts +298 -0
  528. package/src/runtime/routes/contact-routes.ts +132 -5
  529. package/src/runtime/routes/conversation-analysis-routes.ts +22 -142
  530. package/src/runtime/routes/conversation-management-routes.ts +115 -0
  531. package/src/runtime/routes/conversation-routes.ts +367 -146
  532. package/src/runtime/routes/filing-routes.ts +93 -0
  533. package/src/runtime/routes/home-feed-routes.ts +334 -0
  534. package/src/runtime/routes/home-state-routes.ts +138 -0
  535. package/src/runtime/routes/host-browser-routes.ts +3 -14
  536. package/src/runtime/routes/identity-intro-cache.ts +7 -3
  537. package/src/runtime/routes/identity-routes.ts +3 -17
  538. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
  539. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
  540. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
  541. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
  542. package/src/runtime/routes/integrations/slack/channel.ts +11 -3
  543. package/src/runtime/routes/integrations/slack/share.ts +45 -7
  544. package/src/runtime/routes/llm-context-normalization.ts +303 -0
  545. package/src/runtime/routes/memory-item-routes.test.ts +3 -2
  546. package/src/runtime/routes/migration-routes.ts +40 -5
  547. package/src/runtime/routes/settings-routes.ts +22 -5
  548. package/src/runtime/routes/skills-routes.ts +76 -7
  549. package/src/runtime/routes/stt-routes.ts +233 -0
  550. package/src/runtime/routes/surface-action-routes.ts +41 -2
  551. package/src/runtime/routes/tts-routes.ts +108 -24
  552. package/src/runtime/routes/usage-routes.ts +30 -2
  553. package/src/runtime/routes/user-route-dispatcher.ts +50 -5
  554. package/src/runtime/routes/user-routes.ts +13 -1
  555. package/src/runtime/routes/work-items-routes.ts +8 -1
  556. package/src/runtime/runtime-mode.ts +33 -0
  557. package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
  558. package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
  559. package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
  560. package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
  561. package/src/runtime/services/analyze-conversation.ts +344 -0
  562. package/src/runtime/services/analyze-deps-singleton.ts +32 -0
  563. package/src/runtime/services/auto-analysis-prompt.ts +55 -0
  564. package/src/runtime/skill-route-registry.ts +49 -0
  565. package/src/runtime/slack-block-formatting.ts +437 -10
  566. package/src/schedule/scheduler.ts +50 -0
  567. package/src/security/oauth2.ts +26 -4
  568. package/src/security/secure-keys.ts +25 -2
  569. package/src/security/token-manager.ts +8 -0
  570. package/src/sequence/engine.ts +23 -0
  571. package/src/sequence/types.ts +1 -1
  572. package/src/skills/catalog-files.ts +64 -2
  573. package/src/skills/category-inference.ts +122 -0
  574. package/src/skills/clawhub-files.ts +213 -0
  575. package/src/skills/clawhub.ts +84 -23
  576. package/src/skills/skill-file-provider.ts +40 -0
  577. package/src/skills/skillssh-files.ts +395 -0
  578. package/src/skills/skillssh-registry.ts +4 -4
  579. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
  580. package/src/stt/__tests__/types.test.ts +89 -0
  581. package/src/stt/daemon-batch-transcriber.ts +195 -0
  582. package/src/stt/stt-stream-session.ts +499 -0
  583. package/src/stt/types.ts +330 -0
  584. package/src/stt/wav-encoder.test.ts +373 -0
  585. package/src/stt/wav-encoder.ts +175 -0
  586. package/src/subagent/manager.ts +38 -14
  587. package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
  588. package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
  589. package/src/tools/browser/browser-execution.ts +1163 -23
  590. package/src/tools/browser/browser-manager.ts +45 -0
  591. package/src/tools/browser/browser-mode-constants.ts +12 -0
  592. package/src/tools/browser/browser-mode.ts +92 -0
  593. package/src/tools/browser/browser-status-constants.ts +33 -0
  594. package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +393 -0
  595. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +29 -0
  596. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1648 -32
  597. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +264 -0
  598. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +183 -17
  599. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +254 -21
  600. package/src/tools/browser/cdp-client/errors.ts +15 -0
  601. package/src/tools/browser/cdp-client/extension-cdp-client.ts +39 -16
  602. package/src/tools/browser/cdp-client/factory.ts +797 -87
  603. package/src/tools/browser/cdp-client/index.ts +16 -2
  604. package/src/tools/browser/cdp-client/types.ts +68 -0
  605. package/src/tools/credentials/vault.ts +35 -6
  606. package/src/tools/network/web-fetch.ts +5 -2
  607. package/src/tools/network/web-search.ts +5 -2
  608. package/src/tools/shared/shell-output.ts +3 -1
  609. package/src/tools/side-effects.ts +2 -0
  610. package/src/tools/skills/sandbox-runner.ts +3 -2
  611. package/src/tools/terminal/safe-env.ts +10 -2
  612. package/src/tools/terminal/shell.ts +15 -4
  613. package/src/tools/tool-manifest.ts +21 -0
  614. package/src/tools/types.ts +17 -0
  615. package/src/tools/ui-surface/definitions.ts +6 -1
  616. package/src/tts/__tests__/provider-adapters.test.ts +834 -0
  617. package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
  618. package/src/tts/__tests__/provider-catalog.test.ts +183 -0
  619. package/src/tts/__tests__/provider-registry.test.ts +90 -0
  620. package/src/tts/provider-catalog.ts +201 -0
  621. package/src/tts/provider-registry.ts +73 -0
  622. package/src/tts/providers/deepgram-provider.ts +219 -0
  623. package/src/tts/providers/elevenlabs-provider.ts +211 -0
  624. package/src/tts/providers/fish-audio-provider.ts +183 -0
  625. package/src/tts/providers/index.ts +42 -0
  626. package/src/tts/providers/register-builtins.ts +130 -0
  627. package/src/tts/synthesize-text.ts +110 -0
  628. package/src/tts/tts-config-resolver.ts +78 -0
  629. package/src/tts/types.ts +153 -0
  630. package/src/types/onboarding-context.ts +7 -0
  631. package/src/util/abort-reasons.ts +58 -0
  632. package/src/util/device-id.ts +32 -16
  633. package/src/util/errors.ts +9 -1
  634. package/src/util/platform.ts +54 -10
  635. package/src/util/pricing.ts +66 -3
  636. package/src/util/spawn.ts +1 -1
  637. package/src/util/truncate.ts +4 -2
  638. package/src/util/unicode.ts +201 -0
  639. package/src/version.ts +19 -24
  640. package/src/watcher/engine.ts +23 -0
  641. package/src/watcher/watcher-store.ts +31 -0
  642. package/src/workspace/migrations/003-seed-device-id.ts +9 -3
  643. package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
  644. package/src/workspace/migrations/029-seed-pkb.ts +1 -1
  645. package/src/workspace/migrations/031-drop-user-md.ts +317 -0
  646. package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
  647. package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
  648. package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
  649. package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
  650. package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
  651. package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
  652. package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
  653. package/src/workspace/migrations/registry.ts +16 -0
  654. package/src/workspace/top-level-renderer.ts +13 -1
  655. package/src/workspace/turn-commit.ts +31 -0
  656. package/src/__tests__/email-cli.test.ts +0 -297
  657. package/src/__tests__/email-service-config-fallback.test.ts +0 -102
  658. package/src/cli/commands/browser-relay.ts +0 -466
  659. package/src/email/guardrails.ts +0 -221
  660. package/src/email/provider.ts +0 -117
  661. package/src/email/providers/agentmail.ts +0 -361
  662. package/src/email/providers/index.ts +0 -65
  663. package/src/email/service.ts +0 -384
  664. package/src/email/types.ts +0 -126
  665. package/src/prompts/templates/USER.md +0 -13
  666. package/src/providers/speech-to-text/types.ts +0 -17
  667. package/src/runtime/routes/browser-cdp-routes.ts +0 -229
@@ -1,466 +0,0 @@
1
- /**
2
- * `assistant browser chrome relay <action>` CLI shim.
3
- *
4
- * Translates the legacy relay actions (find_tab, new_tab, navigate,
5
- * evaluate, get_cookies, set_cookie, screenshot) into Chrome DevTools
6
- * Protocol commands and forwards them to the daemon's
7
- * `/v1/browser-cdp` HTTP endpoint, which routes the command through
8
- * the connected chrome-extension WebSocket.
9
- *
10
- * Why this exists: PR #24329 deleted the in-process extension relay
11
- * server and the original CLI surface. Two in-tree skills (amazon and
12
- * influencer) still spawn `assistant browser chrome relay <action>` as
13
- * a subprocess and parse the JSON output. Until those skills migrate
14
- * onto the new CDP-based skill API, this shim keeps them working by
15
- * preserving the legacy stdout contract:
16
- *
17
- * { "ok": true, "tabId"?: <id>, "result"?: <unknown> }
18
- * { "ok": false, "error": <string> }
19
- *
20
- * The CLI mints a short-lived daemon delivery JWT (same audience and
21
- * scope profile as the daemon's internal callbacks) and POSTs directly
22
- * to the runtime's loopback HTTP port — no gateway involvement
23
- * required.
24
- */
25
-
26
- import { existsSync, readFileSync } from "node:fs";
27
-
28
- import type { Command } from "commander";
29
-
30
- import { getRuntimeHttpPort } from "../../config/env.js";
31
- import { CURRENT_POLICY_EPOCH } from "../../runtime/auth/policy.js";
32
- import { mintToken } from "../../runtime/auth/token-service.js";
33
- import {
34
- initAuthSigningKey,
35
- isSigningKeyInitialized,
36
- loadOrCreateSigningKey,
37
- } from "../../runtime/auth/token-service.js";
38
- import { getRuntimePortFilePath } from "../../util/platform.js";
39
-
40
- // ---------------------------------------------------------------------------
41
- // Daemon HTTP client
42
- // ---------------------------------------------------------------------------
43
-
44
- interface BrowserCdpResponse {
45
- result?: unknown;
46
- error?: { code: string; message: string };
47
- }
48
-
49
- /**
50
- * Resolve the daemon's runtime HTTP port. Prefers the runtime-port
51
- * file written by the daemon at startup so non-default ports
52
- * (RUNTIME_HTTP_PORT) are picked up automatically without an env var
53
- * roundtrip. Falls back to the env-var-derived default.
54
- */
55
- function resolveRuntimePort(): number {
56
- try {
57
- const portFile = getRuntimePortFilePath();
58
- if (existsSync(portFile)) {
59
- const raw = readFileSync(portFile, "utf-8").trim();
60
- const parsed = Number(raw);
61
- if (Number.isFinite(parsed) && parsed > 0 && parsed < 65536) {
62
- return parsed;
63
- }
64
- }
65
- } catch {
66
- // Fall through to env-var default
67
- }
68
- return getRuntimeHttpPort();
69
- }
70
-
71
- /**
72
- * Mint a short-lived JWT acceptable to the runtime auth middleware.
73
- * Mirrors `mintDaemonDeliveryToken` (sub=svc:daemon:self,
74
- * scope_profile=gateway_service_v1, aud=vellum-daemon) but is minted
75
- * out-of-process by the CLI using the on-disk signing key.
76
- */
77
- function mintCliToken(): string {
78
- if (!isSigningKeyInitialized()) {
79
- initAuthSigningKey(loadOrCreateSigningKey());
80
- }
81
- return mintToken({
82
- aud: "vellum-daemon",
83
- sub: "svc:daemon:self",
84
- scope_profile: "gateway_service_v1",
85
- policy_epoch: CURRENT_POLICY_EPOCH,
86
- ttlSeconds: 60,
87
- });
88
- }
89
-
90
- /**
91
- * Send a single CDP command to the daemon's /v1/browser-cdp route and
92
- * return the parsed response. Throws on transport-level errors; the
93
- * caller wraps the throw into a `{ ok: false, error }` envelope.
94
- */
95
- async function postBrowserCdp(payload: {
96
- cdpMethod: string;
97
- cdpParams?: Record<string, unknown>;
98
- cdpSessionId?: string;
99
- timeoutMs?: number;
100
- }): Promise<BrowserCdpResponse> {
101
- const port = resolveRuntimePort();
102
- const token = mintCliToken();
103
- const url = `http://127.0.0.1:${port}/v1/browser-cdp`;
104
-
105
- const resp = await fetch(url, {
106
- method: "POST",
107
- headers: {
108
- "Content-Type": "application/json",
109
- Authorization: `Bearer ${token}`,
110
- },
111
- body: JSON.stringify(payload),
112
- });
113
-
114
- const bodyText = await resp.text();
115
- let parsed: BrowserCdpResponse;
116
- try {
117
- parsed = JSON.parse(bodyText) as BrowserCdpResponse;
118
- } catch {
119
- throw new Error(
120
- `Daemon returned non-JSON response (HTTP ${resp.status}): ${bodyText.slice(0, 200)}`,
121
- );
122
- }
123
-
124
- if (!resp.ok) {
125
- const message = parsed.error?.message ?? `HTTP ${resp.status}`;
126
- throw new Error(message);
127
- }
128
-
129
- return parsed;
130
- }
131
-
132
- // ---------------------------------------------------------------------------
133
- // Stdout helpers
134
- // ---------------------------------------------------------------------------
135
-
136
- interface RelayResultOk {
137
- ok: true;
138
- tabId?: number | string;
139
- result?: unknown;
140
- }
141
-
142
- interface RelayResultErr {
143
- ok: false;
144
- error: string;
145
- }
146
-
147
- function emitOk(payload: Omit<RelayResultOk, "ok">): void {
148
- const out: RelayResultOk = { ok: true, ...payload };
149
- process.stdout.write(JSON.stringify(out) + "\n");
150
- }
151
-
152
- function emitError(message: string): void {
153
- const out: RelayResultErr = { ok: false, error: message };
154
- process.stdout.write(JSON.stringify(out) + "\n");
155
- process.exitCode = 1;
156
- }
157
-
158
- async function readStdin(): Promise<string> {
159
- const chunks: Buffer[] = [];
160
- for await (const chunk of process.stdin) {
161
- chunks.push(chunk as Buffer);
162
- }
163
- return Buffer.concat(chunks).toString("utf-8");
164
- }
165
-
166
- // ---------------------------------------------------------------------------
167
- // URL glob matching for find-tab
168
- // ---------------------------------------------------------------------------
169
-
170
- /**
171
- * Convert a Chrome match-pattern style glob (e.g. `*://*.amazon.com/*`)
172
- * into a regular expression. Matches the chrome.tabs.query semantics
173
- * the legacy relay CLI exposed:
174
- *
175
- * - `*` is a wildcard that matches any sequence (including `/` in
176
- * the path component, mirroring the legacy minimatch behaviour).
177
- * - All other regex metacharacters are escaped.
178
- */
179
- function globToRegex(glob: string): RegExp {
180
- const escaped = glob.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
181
- const pattern = "^" + escaped.replace(/\*/g, ".*") + "$";
182
- return new RegExp(pattern);
183
- }
184
-
185
- // ---------------------------------------------------------------------------
186
- // Action handlers — translate legacy actions into CDP commands
187
- // ---------------------------------------------------------------------------
188
-
189
- interface CdpTarget {
190
- targetId: string;
191
- type: string;
192
- url: string;
193
- title?: string;
194
- attached?: boolean;
195
- }
196
-
197
- interface CdpTargetsResult {
198
- targetInfos: CdpTarget[];
199
- }
200
-
201
- async function actionFindTab(urlPattern: string): Promise<void> {
202
- try {
203
- const resp = await postBrowserCdp({ cdpMethod: "Target.getTargets" });
204
- const targets =
205
- (resp.result as CdpTargetsResult | undefined)?.targetInfos ?? [];
206
- const re = globToRegex(urlPattern);
207
- const match = targets.find((t) => t.type === "page" && re.test(t.url));
208
- if (!match) {
209
- emitError(`No tab matched URL pattern: ${urlPattern}`);
210
- return;
211
- }
212
- emitOk({ tabId: match.targetId });
213
- } catch (err) {
214
- emitError(err instanceof Error ? err.message : String(err));
215
- }
216
- }
217
-
218
- async function actionNewTab(url: string): Promise<void> {
219
- try {
220
- const resp = await postBrowserCdp({
221
- cdpMethod: "Target.createTarget",
222
- cdpParams: { url },
223
- });
224
- const targetId = (resp.result as { targetId?: string } | undefined)
225
- ?.targetId;
226
- if (!targetId) {
227
- emitError("Target.createTarget did not return a targetId");
228
- return;
229
- }
230
- emitOk({ tabId: targetId });
231
- } catch (err) {
232
- emitError(err instanceof Error ? err.message : String(err));
233
- }
234
- }
235
-
236
- async function actionNavigate(tabId: string, url: string): Promise<void> {
237
- try {
238
- await postBrowserCdp({
239
- cdpMethod: "Page.navigate",
240
- cdpParams: { url },
241
- cdpSessionId: tabId,
242
- });
243
- emitOk({});
244
- } catch (err) {
245
- emitError(err instanceof Error ? err.message : String(err));
246
- }
247
- }
248
-
249
- async function actionEvaluate(tabId: string, code: string): Promise<void> {
250
- try {
251
- const resp = await postBrowserCdp({
252
- cdpMethod: "Runtime.evaluate",
253
- cdpParams: {
254
- expression: code,
255
- returnByValue: true,
256
- awaitPromise: true,
257
- },
258
- cdpSessionId: tabId,
259
- });
260
- // CDP Runtime.evaluate returns { result: { type, value }, exceptionDetails? }.
261
- // Surface exceptions as relay errors so callers don't silently get undefined.
262
- const result = resp.result as
263
- | {
264
- result?: { value?: unknown };
265
- exceptionDetails?: {
266
- text?: string;
267
- exception?: { description?: string };
268
- };
269
- }
270
- | undefined;
271
- if (result?.exceptionDetails) {
272
- const desc =
273
- result.exceptionDetails.exception?.description ??
274
- result.exceptionDetails.text ??
275
- "Runtime exception during evaluate";
276
- emitError(desc);
277
- return;
278
- }
279
- emitOk({ result: result?.result?.value });
280
- } catch (err) {
281
- emitError(err instanceof Error ? err.message : String(err));
282
- }
283
- }
284
-
285
- async function actionGetCookies(domain: string): Promise<void> {
286
- try {
287
- const resp = await postBrowserCdp({ cdpMethod: "Network.getCookies" });
288
- const cookies =
289
- (resp.result as { cookies?: Array<Record<string, unknown>> } | undefined)
290
- ?.cookies ?? [];
291
- // Filter by domain (Chrome stores cookies with leading-dot or bare-host
292
- // domains depending on the Set-Cookie source). Match either form so the
293
- // legacy "amazon.com" / ".amazon.com" callers both succeed.
294
- const trimmed = domain.startsWith(".") ? domain.slice(1) : domain;
295
- const filtered = cookies.filter((c) => {
296
- const d = String(c.domain ?? "");
297
- const dTrim = d.startsWith(".") ? d.slice(1) : d;
298
- return dTrim === trimmed || dTrim.endsWith("." + trimmed);
299
- });
300
- emitOk({ result: filtered });
301
- } catch (err) {
302
- emitError(err instanceof Error ? err.message : String(err));
303
- }
304
- }
305
-
306
- async function actionSetCookie(cookie: Record<string, unknown>): Promise<void> {
307
- try {
308
- await postBrowserCdp({
309
- cdpMethod: "Network.setCookie",
310
- cdpParams: cookie,
311
- });
312
- emitOk({});
313
- } catch (err) {
314
- emitError(err instanceof Error ? err.message : String(err));
315
- }
316
- }
317
-
318
- async function actionScreenshot(tabId?: string): Promise<void> {
319
- try {
320
- const resp = await postBrowserCdp({
321
- cdpMethod: "Page.captureScreenshot",
322
- cdpParams: { format: "png" },
323
- ...(tabId !== undefined ? { cdpSessionId: tabId } : {}),
324
- });
325
- const data = (resp.result as { data?: string } | undefined)?.data;
326
- if (data === undefined) {
327
- emitError("Page.captureScreenshot returned no data");
328
- return;
329
- }
330
- emitOk({ result: data });
331
- } catch (err) {
332
- emitError(err instanceof Error ? err.message : String(err));
333
- }
334
- }
335
-
336
- // ---------------------------------------------------------------------------
337
- // Command registration
338
- // ---------------------------------------------------------------------------
339
-
340
- export function registerBrowserRelayCommand(program: Command): void {
341
- const browser = program
342
- .command("browser")
343
- .description(
344
- "Browser automation surface (`chrome relay <action>` CDP shim)",
345
- );
346
-
347
- browser.addHelpText(
348
- "after",
349
- `
350
- Provides a thin CDP-over-HTTP shim used by in-tree skills that have not
351
- yet migrated onto the new CDP-based skill API. Each command translates
352
- the legacy action into a Chrome DevTools Protocol call and forwards it
353
- to the daemon's /v1/browser-cdp route, which routes through the
354
- connected chrome-extension WebSocket.
355
-
356
- Examples:
357
- $ assistant browser chrome relay find-tab --url "*://*.amazon.com/*"
358
- $ assistant browser chrome relay new-tab --url "https://example.com"
359
- $ assistant browser chrome relay evaluate --tab-id <id> --code "document.title"
360
- $ assistant browser chrome relay screenshot --tab-id <id>`,
361
- );
362
-
363
- const chrome = browser
364
- .command("chrome")
365
- .description("Chrome browser automation via the chrome-extension proxy");
366
-
367
- const relay = chrome
368
- .command("relay")
369
- .description(
370
- "Send a single CDP command to a Chrome tab via the chrome extension",
371
- );
372
-
373
- // -- find-tab --
374
-
375
- relay
376
- .command("find-tab")
377
- .description("Find a tab matching a URL glob pattern")
378
- .requiredOption(
379
- "--url <pattern>",
380
- "URL glob pattern to match (e.g. *://*.instagram.com/*)",
381
- )
382
- .action(async (opts: { url: string }) => {
383
- await actionFindTab(opts.url);
384
- });
385
-
386
- // -- new-tab --
387
-
388
- relay
389
- .command("new-tab")
390
- .description("Open a new tab with the given URL")
391
- .requiredOption("--url <url>", "URL to open in a new tab")
392
- .action(async (opts: { url: string }) => {
393
- await actionNewTab(opts.url);
394
- });
395
-
396
- // -- navigate --
397
-
398
- relay
399
- .command("navigate")
400
- .description("Navigate an existing tab to a new URL")
401
- .requiredOption("--tab-id <id>", "Target tab ID")
402
- .requiredOption("--url <url>", "URL to navigate to")
403
- .action(async (opts: { tabId: string; url: string }) => {
404
- await actionNavigate(opts.tabId, opts.url);
405
- });
406
-
407
- // -- evaluate --
408
-
409
- relay
410
- .command("evaluate")
411
- .description("Execute JavaScript in a Chrome tab")
412
- .requiredOption("--tab-id <id>", "Target tab ID")
413
- .option(
414
- "--code <script>",
415
- "JavaScript code to evaluate (or read from stdin)",
416
- )
417
- .action(async (opts: { tabId: string; code?: string }) => {
418
- let code: string;
419
- if (opts.code) {
420
- code = opts.code;
421
- } else if (process.stdin.isTTY) {
422
- emitError("No code provided. Use --code or pipe JavaScript via stdin.");
423
- return;
424
- } else {
425
- code = await readStdin();
426
- }
427
- await actionEvaluate(opts.tabId, code);
428
- });
429
-
430
- // -- get-cookies --
431
-
432
- relay
433
- .command("get-cookies")
434
- .description("Fetch cookies for a domain")
435
- .requiredOption("--domain <domain>", "Cookie domain to fetch")
436
- .action(async (opts: { domain: string }) => {
437
- await actionGetCookies(opts.domain);
438
- });
439
-
440
- // -- set-cookie --
441
-
442
- relay
443
- .command("set-cookie")
444
- .description("Set a cookie in the browser")
445
- .requiredOption("--cookie <json>", "Cookie specification as JSON")
446
- .action(async (opts: { cookie: string }) => {
447
- let parsed: Record<string, unknown>;
448
- try {
449
- parsed = JSON.parse(opts.cookie) as Record<string, unknown>;
450
- } catch {
451
- emitError("Invalid JSON in --cookie argument");
452
- return;
453
- }
454
- await actionSetCookie(parsed);
455
- });
456
-
457
- // -- screenshot --
458
-
459
- relay
460
- .command("screenshot")
461
- .description("Capture a base64-encoded PNG screenshot of a Chrome tab")
462
- .option("--tab-id <id>", "Target tab ID (defaults to active tab)")
463
- .action(async (opts: { tabId?: string }) => {
464
- await actionScreenshot(opts.tabId);
465
- });
466
- }
@@ -1,221 +0,0 @@
1
- /**
2
- * Local guardrails state for email operations.
3
- * Stores state in ~/.vellum/email-guardrails.json.
4
- */
5
-
6
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
- import { join } from "node:path";
8
-
9
- import { minimatch } from "minimatch";
10
-
11
- import { getWorkspaceDir } from "../util/platform.js";
12
-
13
- export interface AddressRule {
14
- id: string;
15
- type: "block" | "allow";
16
- pattern: string;
17
- createdAt: string;
18
- }
19
-
20
- interface DailyCount {
21
- [date: string]: number;
22
- }
23
-
24
- interface GuardrailsState {
25
- paused: boolean;
26
- dailyCap: number;
27
- dailyCounts: DailyCount;
28
- addressRules: AddressRule[];
29
- }
30
-
31
- const DEFAULT_STATE: GuardrailsState = {
32
- paused: false,
33
- dailyCap: 25,
34
- dailyCounts: {},
35
- addressRules: [],
36
- };
37
-
38
- function getGuardrailsPath(): string {
39
- return join(getWorkspaceDir(), "email-guardrails.json");
40
- }
41
-
42
- function loadState(): GuardrailsState {
43
- const path = getGuardrailsPath();
44
- if (!existsSync(path))
45
- return { ...DEFAULT_STATE, dailyCounts: {}, addressRules: [] };
46
- try {
47
- const raw = readFileSync(path, "utf-8");
48
- const parsed = JSON.parse(raw) as Partial<GuardrailsState>;
49
- return {
50
- paused: parsed.paused ?? DEFAULT_STATE.paused,
51
- dailyCap: parsed.dailyCap ?? DEFAULT_STATE.dailyCap,
52
- dailyCounts: parsed.dailyCounts ?? {},
53
- addressRules: parsed.addressRules ?? [],
54
- };
55
- } catch {
56
- return { ...DEFAULT_STATE, dailyCounts: {}, addressRules: [] };
57
- }
58
- }
59
-
60
- function saveState(state: GuardrailsState): void {
61
- const path = getGuardrailsPath();
62
- const dir = getWorkspaceDir();
63
- if (!existsSync(dir)) {
64
- mkdirSync(dir, { recursive: true });
65
- }
66
- writeFileSync(path, JSON.stringify(state, null, 2));
67
- }
68
-
69
- function todayKey(): string {
70
- return new Date().toISOString().slice(0, 10);
71
- }
72
-
73
- export function getDailySendCount(): number {
74
- const state = loadState();
75
- return state.dailyCounts[todayKey()] ?? 0;
76
- }
77
-
78
- export function incrementDailySendCount(): number {
79
- const state = loadState();
80
- const key = todayKey();
81
- const newCount = (state.dailyCounts[key] ?? 0) + 1;
82
- state.dailyCounts[key] = newCount;
83
- saveState(state);
84
- return newCount;
85
- }
86
-
87
- export function isOutboundPaused(): boolean {
88
- return loadState().paused;
89
- }
90
-
91
- export function setOutboundPaused(paused: boolean): void {
92
- const state = loadState();
93
- state.paused = paused;
94
- saveState(state);
95
- }
96
-
97
- export function getDailySendCap(): number {
98
- return loadState().dailyCap;
99
- }
100
-
101
- export function setDailySendCap(cap: number): void {
102
- const state = loadState();
103
- state.dailyCap = cap;
104
- saveState(state);
105
- }
106
-
107
- function isAddressAllowed(email: string): {
108
- allowed: boolean;
109
- reason?: string;
110
- rule?: AddressRule;
111
- } {
112
- const state = loadState();
113
- const normalized = email.toLowerCase().trim();
114
-
115
- // Check block rules first
116
- for (const rule of state.addressRules) {
117
- if (
118
- rule.type === "block" &&
119
- minimatch(normalized, rule.pattern, { nocase: true })
120
- ) {
121
- return {
122
- allowed: false,
123
- reason: `blocked by rule: ${rule.pattern}`,
124
- rule,
125
- };
126
- }
127
- }
128
-
129
- // If there are allow rules, address must match at least one
130
- const allowRules = state.addressRules.filter((r) => r.type === "allow");
131
- if (allowRules.length > 0) {
132
- const matched = allowRules.some((r) =>
133
- minimatch(normalized, r.pattern, { nocase: true }),
134
- );
135
- if (!matched) {
136
- return { allowed: false, reason: "not in allowlist" };
137
- }
138
- }
139
-
140
- return { allowed: true };
141
- }
142
-
143
- export function addAddressRule(
144
- type: "block" | "allow",
145
- pattern: string,
146
- ): AddressRule {
147
- const state = loadState();
148
- const rule: AddressRule = {
149
- id: crypto.randomUUID(),
150
- type,
151
- pattern: pattern.toLowerCase(),
152
- createdAt: new Date().toISOString(),
153
- };
154
- state.addressRules.push(rule);
155
- saveState(state);
156
- return rule;
157
- }
158
-
159
- export function removeAddressRule(ruleId: string): boolean {
160
- const state = loadState();
161
- const idx = state.addressRules.findIndex(
162
- (r) => r.id === ruleId || r.id.startsWith(ruleId),
163
- );
164
- if (idx === -1) return false;
165
- state.addressRules.splice(idx, 1);
166
- saveState(state);
167
- return true;
168
- }
169
-
170
- export function listRules(): AddressRule[] {
171
- return loadState().addressRules;
172
- }
173
-
174
- export function getGuardrailsStatus(): {
175
- paused: boolean;
176
- dailyCap: number;
177
- dailyCount: number;
178
- rules: AddressRule[];
179
- } {
180
- const state = loadState();
181
- return {
182
- paused: state.paused,
183
- dailyCap: state.dailyCap,
184
- dailyCount: state.dailyCounts[todayKey()] ?? 0,
185
- rules: state.addressRules,
186
- };
187
- }
188
-
189
- /**
190
- * Check all guardrails before sending. Returns null if all clear,
191
- * or an error object describing what blocked the send.
192
- */
193
- export function checkSendGuardrails(recipients: string[]): {
194
- error: string;
195
- address?: string;
196
- reason?: string;
197
- count?: number;
198
- cap?: number;
199
- } | null {
200
- if (isOutboundPaused()) {
201
- return { error: "outbound_paused" };
202
- }
203
-
204
- const count = getDailySendCount();
205
- const cap = getDailySendCap();
206
- if (count >= cap) {
207
- return { error: "daily_cap_reached", count, cap };
208
- }
209
-
210
- for (const addr of recipients) {
211
- const check = isAddressAllowed(addr);
212
- if (!check.allowed) {
213
- return { error: "address_blocked", address: addr, reason: check.reason };
214
- }
215
- }
216
-
217
- return null;
218
- }
219
-
220
- /** @internal Test-only: reset state file path override. */
221
- export { getGuardrailsPath as _getGuardrailsPath };