@vellumai/assistant 0.4.46 → 0.4.49

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 (382) hide show
  1. package/ARCHITECTURE.md +7 -7
  2. package/README.md +2 -23
  3. package/docs/architecture/integrations.md +45 -41
  4. package/docs/architecture/keychain-broker.md +3 -3
  5. package/docs/architecture/security.md +5 -5
  6. package/docs/runbook-trusted-contacts.md +3 -8
  7. package/hook-templates/debug-prompt-logger/hook.json +1 -1
  8. package/hook-templates/debug-prompt-logger/run.sh +1 -3
  9. package/package.json +1 -1
  10. package/src/__tests__/actor-token-service.test.ts +0 -1
  11. package/src/__tests__/anthropic-provider.test.ts +156 -0
  12. package/src/__tests__/approval-cascade.test.ts +810 -0
  13. package/src/__tests__/approval-primitive.test.ts +0 -1
  14. package/src/__tests__/approval-routes-http.test.ts +2 -0
  15. package/src/__tests__/assistant-attachments.test.ts +12 -34
  16. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
  17. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
  18. package/src/__tests__/browser-fill-credential.test.ts +5 -2
  19. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
  20. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -1
  21. package/src/__tests__/channel-guardian.test.ts +0 -2
  22. package/src/__tests__/channel-readiness-routes.test.ts +35 -25
  23. package/src/__tests__/channel-readiness-service.test.ts +10 -9
  24. package/src/__tests__/checker.test.ts +9 -29
  25. package/src/__tests__/cli.test.ts +23 -0
  26. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
  27. package/src/__tests__/computer-use-tools.test.ts +2 -19
  28. package/src/__tests__/config-watcher.test.ts +0 -1
  29. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  30. package/src/__tests__/context-image-dimensions.test.ts +332 -0
  31. package/src/__tests__/context-token-estimator.test.ts +196 -13
  32. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  33. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  34. package/src/__tests__/conversation-routes-guardian-reply.test.ts +144 -0
  35. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  36. package/src/__tests__/credential-broker-browser-fill.test.ts +23 -22
  37. package/src/__tests__/credential-broker-server-use.test.ts +22 -21
  38. package/src/__tests__/credential-broker.test.ts +2 -1
  39. package/src/__tests__/credential-metadata-store.test.ts +239 -26
  40. package/src/__tests__/credential-resolve.test.ts +5 -4
  41. package/src/__tests__/credential-security-e2e.test.ts +8 -8
  42. package/src/__tests__/credential-security-invariants.test.ts +111 -7
  43. package/src/__tests__/credential-vault-unit.test.ts +287 -54
  44. package/src/__tests__/credential-vault.test.ts +406 -12
  45. package/src/__tests__/credentials-cli.test.ts +82 -6
  46. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  47. package/src/__tests__/ephemeral-permissions.test.ts +3 -3
  48. package/src/__tests__/gateway-only-enforcement.test.ts +4 -2
  49. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  50. package/src/__tests__/gemini-image-service.test.ts +75 -45
  51. package/src/__tests__/gemini-provider.test.ts +9 -6
  52. package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -33
  53. package/src/__tests__/guardian-action-copy-generator.test.ts +0 -20
  54. package/src/__tests__/guardian-action-followup-executor.test.ts +1 -28
  55. package/src/__tests__/guardian-action-followup-store.test.ts +1 -1
  56. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  57. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  58. package/src/__tests__/guardian-grant-minting.test.ts +35 -0
  59. package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
  60. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  61. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
  62. package/src/__tests__/heartbeat-service.test.ts +0 -1
  63. package/src/__tests__/host-cu-proxy.test.ts +629 -0
  64. package/src/__tests__/host-shell-tool.test.ts +27 -15
  65. package/src/__tests__/http-user-message-parity.test.ts +1 -0
  66. package/src/__tests__/ingress-url-consistency.test.ts +14 -21
  67. package/src/__tests__/integration-status.test.ts +38 -25
  68. package/src/__tests__/intent-routing.test.ts +0 -1
  69. package/src/__tests__/invite-routes-http.test.ts +10 -9
  70. package/src/__tests__/keychain-broker-client.test.ts +11 -43
  71. package/src/__tests__/managed-proxy-context.test.ts +5 -3
  72. package/src/__tests__/media-generate-image.test.ts +63 -2
  73. package/src/__tests__/media-reuse-story.e2e.test.ts +7 -3
  74. package/src/__tests__/messaging-send-tool.test.ts +4 -6
  75. package/src/__tests__/notification-routing-intent.test.ts +0 -1
  76. package/src/__tests__/oauth-cli.test.ts +373 -14
  77. package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
  78. package/src/__tests__/oauth-scope-policy.test.ts +4 -6
  79. package/src/__tests__/oauth-store.test.ts +756 -0
  80. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  81. package/src/__tests__/provider-error-scenarios.test.ts +0 -1
  82. package/src/__tests__/provider-fail-open-selection.test.ts +3 -1
  83. package/src/__tests__/provider-managed-proxy-integration.test.ts +70 -6
  84. package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
  85. package/src/__tests__/public-ingress-urls.test.ts +15 -21
  86. package/src/__tests__/recording-handler.test.ts +3 -4
  87. package/src/__tests__/registry.test.ts +2 -2
  88. package/src/__tests__/runtime-events-sse.test.ts +55 -7
  89. package/src/__tests__/schedule-store.test.ts +0 -1
  90. package/src/__tests__/scheduler-recurrence.test.ts +0 -1
  91. package/src/__tests__/schema-transforms.test.ts +226 -0
  92. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  93. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  94. package/src/__tests__/script-proxy-injection-runtime.test.ts +23 -13
  95. package/src/__tests__/script-proxy-policy-runtime.test.ts +1 -1
  96. package/src/__tests__/script-proxy-session-manager.test.ts +1 -1
  97. package/src/__tests__/secret-ingress-handler.test.ts +0 -1
  98. package/src/__tests__/secret-onetime-send.test.ts +5 -3
  99. package/src/__tests__/send-endpoint-busy.test.ts +21 -6
  100. package/src/__tests__/sequence-store.test.ts +0 -1
  101. package/src/__tests__/session-init.benchmark.test.ts +4 -5
  102. package/src/__tests__/session-messaging-secret-redirect.test.ts +5 -4
  103. package/src/__tests__/skill-include-graph.test.ts +66 -0
  104. package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
  105. package/src/__tests__/skill-load-tool.test.ts +149 -1
  106. package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
  107. package/src/__tests__/skills-uninstall.test.ts +3 -3
  108. package/src/__tests__/skills.test.ts +3 -12
  109. package/src/__tests__/slack-channel-config.test.ts +76 -11
  110. package/src/__tests__/slack-share-routes.test.ts +17 -14
  111. package/src/__tests__/system-prompt.test.ts +0 -1
  112. package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -0
  113. package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
  114. package/src/__tests__/terminal-tools.test.ts +4 -3
  115. package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
  116. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  117. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  118. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  119. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
  120. package/src/__tests__/tool-executor.test.ts +0 -1
  121. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  122. package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
  123. package/src/__tests__/trust-store.test.ts +1 -22
  124. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  125. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  126. package/src/__tests__/twilio-config.test.ts +2 -1
  127. package/src/__tests__/twilio-provider.test.ts +4 -2
  128. package/src/__tests__/twilio-routes.test.ts +5 -20
  129. package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
  130. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  131. package/src/agent/ax-tree-compaction.test.ts +235 -0
  132. package/src/agent/loop.ts +76 -130
  133. package/src/calls/call-domain.ts +8 -10
  134. package/src/calls/relay-server.ts +9 -13
  135. package/src/calls/twilio-config.ts +4 -8
  136. package/src/calls/twilio-provider.ts +2 -1
  137. package/src/calls/twilio-rest.ts +2 -1
  138. package/src/calls/twilio-routes.ts +1 -2
  139. package/src/calls/voice-ingress-preflight.ts +1 -1
  140. package/src/cli/commands/browser-relay.ts +46 -15
  141. package/src/cli/commands/completions.ts +0 -3
  142. package/src/cli/commands/credentials.ts +110 -23
  143. package/src/cli/commands/oauth/apps.ts +255 -0
  144. package/src/cli/commands/oauth/connections.ts +299 -0
  145. package/src/cli/commands/oauth/index.ts +52 -0
  146. package/src/cli/commands/oauth/providers.ts +242 -0
  147. package/src/cli/commands/skills.ts +4 -338
  148. package/src/cli/program.ts +1 -5
  149. package/src/cli/reference.ts +1 -3
  150. package/src/cli.ts +3 -2
  151. package/src/config/assistant-feature-flags.ts +0 -3
  152. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  153. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -4
  154. package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
  155. package/src/config/bundled-skills/computer-use/TOOLS.json +22 -4
  156. package/src/config/bundled-skills/contacts/tools/google-contacts.ts +29 -32
  157. package/src/config/bundled-skills/gmail/SKILL.md +4 -4
  158. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +54 -61
  159. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +25 -28
  160. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +14 -17
  161. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +39 -44
  162. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +61 -58
  163. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +50 -49
  164. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +11 -13
  165. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +148 -146
  166. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +4 -7
  167. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +175 -173
  168. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +4 -7
  169. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +71 -76
  170. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +32 -38
  171. package/src/config/bundled-skills/google-calendar/SKILL.md +2 -2
  172. package/src/config/bundled-skills/google-calendar/calendar-client.ts +90 -44
  173. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +9 -10
  174. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +5 -6
  175. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +4 -5
  176. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +14 -15
  177. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +37 -37
  178. package/src/config/bundled-skills/google-calendar/tools/shared.ts +4 -9
  179. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +24 -3
  180. package/src/config/bundled-skills/messaging/SKILL.md +6 -6
  181. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +62 -63
  182. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +15 -16
  183. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +4 -5
  184. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +6 -7
  185. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +4 -5
  186. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +14 -15
  187. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +4 -5
  188. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +128 -128
  189. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +33 -34
  190. package/src/config/bundled-skills/messaging/tools/shared.ts +12 -15
  191. package/src/config/bundled-skills/settings/SKILL.md +1 -1
  192. package/src/config/bundled-skills/settings/TOOLS.json +2 -8
  193. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
  194. package/src/config/bundled-skills/slack/tools/shared.ts +4 -10
  195. package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +4 -5
  196. package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +15 -16
  197. package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +4 -5
  198. package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +4 -5
  199. package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +4 -5
  200. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +95 -92
  201. package/src/config/env-registry.ts +14 -83
  202. package/src/config/env.ts +11 -50
  203. package/src/config/feature-flag-registry.json +16 -16
  204. package/src/config/schema.ts +3 -1
  205. package/src/config/skills.ts +21 -2
  206. package/src/context/image-dimensions.ts +229 -0
  207. package/src/context/token-estimator.ts +75 -12
  208. package/src/context/window-manager.ts +49 -10
  209. package/src/daemon/assistant-attachments.ts +1 -13
  210. package/src/daemon/guardian-action-generators.ts +4 -5
  211. package/src/daemon/handlers/config-ingress.ts +8 -33
  212. package/src/daemon/handlers/config-slack-channel.ts +76 -56
  213. package/src/daemon/handlers/config-telegram.ts +53 -24
  214. package/src/daemon/handlers/sessions.ts +10 -24
  215. package/src/daemon/handlers/shared.ts +0 -130
  216. package/src/daemon/host-cu-proxy.ts +401 -0
  217. package/src/daemon/lifecycle.ts +39 -63
  218. package/src/daemon/message-protocol.ts +3 -0
  219. package/src/daemon/message-types/computer-use.ts +2 -119
  220. package/src/daemon/message-types/host-cu.ts +19 -0
  221. package/src/daemon/message-types/integrations.ts +1 -0
  222. package/src/daemon/message-types/messages.ts +3 -0
  223. package/src/daemon/server.ts +14 -21
  224. package/src/daemon/session-agent-loop-handlers.ts +2 -0
  225. package/src/daemon/session-attachments.ts +1 -2
  226. package/src/daemon/session-messaging.ts +3 -1
  227. package/src/daemon/session-slash.ts +1 -1
  228. package/src/daemon/session-surfaces.ts +40 -28
  229. package/src/daemon/session-tool-setup.ts +20 -11
  230. package/src/daemon/session.ts +139 -16
  231. package/src/daemon/tool-side-effects.ts +2 -8
  232. package/src/daemon/watch-handler.ts +2 -2
  233. package/src/email/providers/index.ts +2 -1
  234. package/src/events/tool-metrics-listener.ts +2 -2
  235. package/src/hooks/manager.ts +1 -4
  236. package/src/inbound/public-ingress-urls.ts +7 -7
  237. package/src/instrument.ts +15 -1
  238. package/src/logfire.ts +16 -5
  239. package/src/media/app-icon-generator.ts +30 -4
  240. package/src/media/avatar-router.ts +26 -3
  241. package/src/media/gemini-image-service.ts +28 -2
  242. package/src/memory/conversation-key-store.ts +21 -0
  243. package/src/memory/db-init.ts +4 -0
  244. package/src/memory/guardian-action-store.ts +1 -1
  245. package/src/memory/migrations/149-oauth-tables.ts +60 -0
  246. package/src/memory/migrations/index.ts +1 -0
  247. package/src/memory/schema/guardian.ts +1 -1
  248. package/src/memory/schema/index.ts +1 -0
  249. package/src/memory/schema/oauth.ts +65 -0
  250. package/src/messaging/provider.ts +19 -13
  251. package/src/messaging/providers/gmail/adapter.ts +40 -23
  252. package/src/messaging/providers/gmail/client.ts +283 -122
  253. package/src/messaging/providers/gmail/people-client.ts +32 -24
  254. package/src/messaging/providers/slack/adapter.ts +29 -19
  255. package/src/messaging/providers/slack/client.ts +265 -78
  256. package/src/messaging/providers/telegram-bot/adapter.ts +19 -18
  257. package/src/messaging/providers/whatsapp/adapter.ts +17 -11
  258. package/src/messaging/registry.ts +2 -31
  259. package/src/notifications/copy-composer.ts +0 -5
  260. package/src/notifications/signal.ts +4 -5
  261. package/src/oauth/byo-connection.test.ts +537 -0
  262. package/src/oauth/byo-connection.ts +128 -0
  263. package/src/oauth/connect-orchestrator.ts +139 -56
  264. package/src/oauth/connect-types.ts +17 -23
  265. package/src/oauth/connection-resolver.ts +58 -0
  266. package/src/oauth/connection.ts +38 -0
  267. package/src/oauth/manual-token-connection.ts +104 -0
  268. package/src/oauth/oauth-store.ts +496 -0
  269. package/src/oauth/platform-connection.test.ts +192 -0
  270. package/src/oauth/platform-connection.ts +111 -0
  271. package/src/oauth/provider-behaviors.ts +124 -0
  272. package/src/oauth/scope-policy.ts +9 -2
  273. package/src/oauth/seed-providers.ts +161 -0
  274. package/src/oauth/token-persistence.ts +74 -78
  275. package/src/permissions/checker.ts +8 -4
  276. package/src/permissions/defaults.ts +0 -1
  277. package/src/permissions/prompter.ts +10 -1
  278. package/src/permissions/trust-store.ts +13 -0
  279. package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
  280. package/src/prompts/system-prompt.ts +70 -45
  281. package/src/providers/anthropic/client.ts +133 -24
  282. package/src/providers/gemini/client.ts +15 -6
  283. package/src/providers/managed-proxy/constants.ts +2 -2
  284. package/src/providers/managed-proxy/context.ts +5 -1
  285. package/src/providers/ratelimit.ts +17 -0
  286. package/src/providers/registry.ts +2 -2
  287. package/src/providers/retry.ts +1 -27
  288. package/src/runtime/AGENTS.md +17 -0
  289. package/src/runtime/auth/route-policy.ts +0 -3
  290. package/src/runtime/channel-invite-transports/telegram.ts +2 -1
  291. package/src/runtime/channel-readiness-service.ts +168 -195
  292. package/src/runtime/channel-readiness-types.ts +4 -0
  293. package/src/runtime/channel-reply-delivery.ts +0 -40
  294. package/src/runtime/gateway-client.ts +0 -7
  295. package/src/runtime/guardian-action-conversation-turn.ts +1 -3
  296. package/src/runtime/guardian-action-followup-executor.ts +1 -1
  297. package/src/runtime/guardian-action-message-composer.ts +3 -23
  298. package/src/runtime/http-server.ts +17 -10
  299. package/src/runtime/http-types.ts +2 -3
  300. package/src/runtime/middleware/rate-limiter.ts +74 -20
  301. package/src/runtime/middleware/twilio-validation.ts +1 -11
  302. package/src/runtime/pending-interactions.ts +14 -12
  303. package/src/runtime/routes/channel-delivery-routes.ts +0 -1
  304. package/src/runtime/routes/channel-readiness-routes.ts +2 -0
  305. package/src/runtime/routes/conversation-routes.ts +73 -19
  306. package/src/runtime/routes/diagnostics-routes.ts +11 -9
  307. package/src/runtime/routes/events-routes.ts +21 -11
  308. package/src/runtime/routes/guardian-approval-interception.ts +20 -5
  309. package/src/runtime/routes/host-cu-routes.ts +97 -0
  310. package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
  311. package/src/runtime/routes/integrations/slack/share.ts +6 -6
  312. package/src/runtime/routes/integrations/twilio.ts +6 -5
  313. package/src/runtime/routes/log-export-routes.ts +126 -8
  314. package/src/runtime/routes/secret-routes.ts +3 -2
  315. package/src/runtime/routes/settings-routes.ts +113 -48
  316. package/src/runtime/routes/surface-action-routes.ts +1 -1
  317. package/src/runtime/routes/watch-routes.ts +128 -0
  318. package/src/schedule/integration-status.ts +10 -8
  319. package/src/security/credential-key.ts +14 -0
  320. package/src/security/keychain-broker-client.ts +5 -6
  321. package/src/security/oauth2.ts +1 -1
  322. package/src/security/token-manager.ts +145 -43
  323. package/src/skills/catalog-install.ts +358 -0
  324. package/src/skills/include-graph.ts +32 -0
  325. package/src/telegram/bot-username.ts +2 -3
  326. package/src/tools/apps/definitions.ts +0 -5
  327. package/src/tools/assets/materialize.ts +0 -5
  328. package/src/tools/assets/search.ts +0 -5
  329. package/src/tools/browser/headless-browser.ts +1 -67
  330. package/src/tools/browser/network-recorder.ts +1 -1
  331. package/src/tools/browser/network-recording-types.ts +1 -1
  332. package/src/tools/claude-code/claude-code.ts +0 -5
  333. package/src/tools/computer-use/definitions.ts +46 -11
  334. package/src/tools/computer-use/registry.ts +4 -5
  335. package/src/tools/credentials/broker.ts +5 -4
  336. package/src/tools/credentials/metadata-store.ts +22 -74
  337. package/src/tools/credentials/resolve.ts +2 -1
  338. package/src/tools/credentials/vault.ts +139 -151
  339. package/src/tools/filesystem/edit.ts +1 -6
  340. package/src/tools/filesystem/read.ts +0 -5
  341. package/src/tools/filesystem/write.ts +1 -6
  342. package/src/tools/host-filesystem/edit.ts +1 -6
  343. package/src/tools/host-filesystem/read.ts +1 -6
  344. package/src/tools/host-filesystem/write.ts +1 -6
  345. package/src/tools/mcp/mcp-tool-factory.ts +18 -1
  346. package/src/tools/memory/definitions.ts +0 -5
  347. package/src/tools/network/web-fetch.ts +0 -5
  348. package/src/tools/network/web-search.ts +0 -5
  349. package/src/tools/registry.ts +2 -7
  350. package/src/tools/schema-transforms.ts +99 -0
  351. package/src/tools/skills/load.ts +62 -8
  352. package/src/tools/swarm/delegate.ts +0 -5
  353. package/src/tools/system/avatar-generator.ts +0 -5
  354. package/src/tools/ui-surface/definitions.ts +0 -15
  355. package/src/tools/watch/screen-watch.ts +0 -5
  356. package/src/tools/watch/watch-state.ts +0 -12
  357. package/src/util/logger.ts +7 -41
  358. package/src/util/platform.ts +9 -28
  359. package/src/version.ts +10 -0
  360. package/src/watcher/providers/github.ts +51 -52
  361. package/src/watcher/providers/gmail.ts +88 -80
  362. package/src/watcher/providers/google-calendar.ts +94 -86
  363. package/src/watcher/providers/linear.ts +87 -93
  364. package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
  365. package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
  366. package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
  367. package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
  368. package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
  369. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
  370. package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
  371. package/src/cli/commands/dev.ts +0 -129
  372. package/src/cli/commands/map.ts +0 -391
  373. package/src/cli/commands/oauth.ts +0 -77
  374. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -16
  375. package/src/daemon/computer-use-session.ts +0 -1020
  376. package/src/daemon/ride-shotgun-handler.ts +0 -567
  377. package/src/oauth/provider-profiles.ts +0 -192
  378. package/src/prompts/computer-use-prompt.ts +0 -98
  379. package/src/runtime/routes/computer-use-routes.ts +0 -641
  380. package/src/runtime/telegram-streaming-delivery.test.ts +0 -597
  381. package/src/runtime/telegram-streaming-delivery.ts +0 -383
  382. package/src/tools/computer-use/request-computer-control.ts +0 -61
@@ -744,24 +744,20 @@ export class RelayConnection {
744
744
  }
745
745
 
746
746
  /**
747
- * Start normal call flow — fire the controller greeting unless a
748
- * static welcome greeting is configured.
747
+ * Start normal call flow — fire the controller greeting.
749
748
  */
750
749
  private startNormalCallFlow(
751
750
  controller: CallController,
752
751
  isInbound: boolean,
753
752
  ): void {
754
- const hasStaticGreeting = !!process.env.CALL_WELCOME_GREETING?.trim();
755
- if (!hasStaticGreeting) {
756
- controller
757
- .startInitialGreeting()
758
- .catch((err) =>
759
- log.error(
760
- { err, callSessionId: this.callSessionId },
761
- `Failed to start initial ${isInbound ? "inbound" : "outbound"} greeting`,
762
- ),
763
- );
764
- }
753
+ controller
754
+ .startInitialGreeting()
755
+ .catch((err) =>
756
+ log.error(
757
+ { err, callSessionId: this.callSessionId },
758
+ `Failed to start initial ${isInbound ? "inbound" : "outbound"} greeting`,
759
+ ),
760
+ );
765
761
  }
766
762
 
767
763
  /**
@@ -1,9 +1,9 @@
1
- import { getTwilioPhoneNumberEnv } from "../config/env.js";
2
1
  import { loadConfig } from "../config/loader.js";
3
2
  import {
4
3
  getPublicBaseUrl,
5
4
  getTwilioRelayUrl,
6
5
  } from "../inbound/public-ingress-urls.js";
6
+ import { credentialKey } from "../security/credential-key.js";
7
7
  import { getSecureKey } from "../security/secure-keys.js";
8
8
  import { ConfigError } from "../util/errors.js";
9
9
  import { getLogger } from "../util/logger.js";
@@ -24,14 +24,10 @@ export interface TwilioConfig {
24
24
  * agree on the same number.
25
25
  *
26
26
  * Resolution order:
27
- * 1. TWILIO_PHONE_NUMBER env var
28
- * 2. config.twilio?.phoneNumber
29
- * 3. ""
27
+ * 1. config.twilio?.phoneNumber
28
+ * 2. ""
30
29
  */
31
30
  export function resolveTwilioPhoneNumber(): string {
32
- const fromEnv = getTwilioPhoneNumberEnv();
33
- if (fromEnv) return fromEnv;
34
-
35
31
  try {
36
32
  const config = loadConfig();
37
33
  if (config.twilio?.phoneNumber) return config.twilio.phoneNumber;
@@ -45,7 +41,7 @@ export function resolveTwilioPhoneNumber(): string {
45
41
  export function getTwilioConfig(): TwilioConfig {
46
42
  const config = loadConfig();
47
43
  const accountSid = config.twilio?.accountSid || "";
48
- const authToken = getSecureKey("credential:twilio:auth_token") || "";
44
+ const authToken = getSecureKey(credentialKey("twilio", "auth_token")) || "";
49
45
  const phoneNumber = resolveTwilioPhoneNumber();
50
46
  const webhookBaseUrl = getPublicBaseUrl(config);
51
47
 
@@ -1,5 +1,6 @@
1
1
  import { createHmac, timingSafeEqual } from "node:crypto";
2
2
 
3
+ import { credentialKey } from "../security/credential-key.js";
3
4
  import { getSecureKey } from "../security/secure-keys.js";
4
5
  import { ProviderError } from "../util/errors.js";
5
6
  import { getLogger } from "../util/logger.js";
@@ -280,7 +281,7 @@ export class TwilioConversationRelayProvider implements VoiceProvider {
280
281
  * middleware) can check availability independently.
281
282
  */
282
283
  static getAuthToken(): string | null {
283
- return getSecureKey("credential:twilio:auth_token") || null;
284
+ return getSecureKey(credentialKey("twilio", "auth_token")) || null;
284
285
  }
285
286
 
286
287
  /**
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import { loadConfig } from "../config/loader.js";
10
+ import { credentialKey } from "../security/credential-key.js";
10
11
  import { getSecureKey } from "../security/secure-keys.js";
11
12
  import { ConfigError, ProviderError } from "../util/errors.js";
12
13
 
@@ -28,7 +29,7 @@ function resolveAccountSid(): string | undefined {
28
29
 
29
30
  /** Resolve the Twilio Auth Token from the credential store. */
30
31
  function resolveAuthToken(): string | undefined {
31
- return getSecureKey("credential:twilio:auth_token") || undefined;
32
+ return getSecureKey(credentialKey("twilio", "auth_token")) || undefined;
32
33
  }
33
34
 
34
35
  /** Resolve Twilio credentials from config (SID) and credential store (token). Throws if not configured. */
@@ -6,7 +6,6 @@
6
6
  * - handleConnectAction: called when the ConversationRelay connection ends
7
7
  */
8
8
 
9
- import { getCallWelcomeGreeting } from "../config/env.js";
10
9
  import { loadConfig } from "../config/loader.js";
11
10
  import { getTwilioRelayUrl } from "../inbound/public-ingress-urls.js";
12
11
  import { mintEdgeRelayToken } from "../runtime/auth/token-service.js";
@@ -236,7 +235,7 @@ function buildVoiceWebhookTwiml(
236
235
  );
237
236
 
238
237
  const relayUrl = getTwilioRelayUrl(loadConfig());
239
- const welcomeGreeting = buildWelcomeGreeting(task, getCallWelcomeGreeting());
238
+ const welcomeGreeting = buildWelcomeGreeting(task);
240
239
 
241
240
  const relayToken = mintEdgeRelayToken();
242
241
 
@@ -61,7 +61,7 @@ export async function preflightVoiceIngress(): Promise<VoiceIngressPreflightResu
61
61
  const msg = err instanceof Error ? err.message : String(err);
62
62
  return fail(
63
63
  msg ||
64
- "Outbound voice calls require public ingress to be enabled and a public base URL (ingress.publicBaseUrl or INGRESS_PUBLIC_BASE_URL).",
64
+ "Outbound voice calls require public ingress to be enabled and a public base URL (ingress.publicBaseUrl).",
65
65
  );
66
66
  }
67
67
 
@@ -1,5 +1,7 @@
1
1
  import type { Command } from "commander";
2
2
 
3
+ import type { ExtensionCommand } from "../../browser-extension-relay/protocol.js";
4
+ import { extensionRelayServer } from "../../browser-extension-relay/server.js";
3
5
  import {
4
6
  initAuthSigningKey,
5
7
  isSigningKeyInitialized,
@@ -16,22 +18,38 @@ import {
16
18
  } from "../../tools/browser/chrome-cdp.js";
17
19
 
18
20
  // ---------------------------------------------------------------------------
19
- // Shared relay helper
21
+ // Shared relay helper — in-process when connected, gateway HTTP otherwise
20
22
  // ---------------------------------------------------------------------------
21
23
 
22
24
  async function relayCommand(command: Record<string, unknown>): Promise<void> {
23
25
  try {
24
- if (!isSigningKeyInitialized()) {
25
- initAuthSigningKey(loadOrCreateSigningKey());
26
- }
27
-
28
- const { data } = await gatewayPost<{
29
- id: string;
26
+ // Dual-path: use in-process relay when connected (daemon context),
27
+ // otherwise fall back to gateway HTTP (out-of-process CLI context).
28
+ // We check connection status upfront rather than try/catch to avoid
29
+ // double-execution of side-effectful commands (navigate, new_tab, etc.)
30
+ // when sendCommand fails after the command was already dispatched.
31
+ let data: {
32
+ id?: string;
30
33
  success: boolean;
31
34
  result?: unknown;
32
35
  error?: string;
33
36
  tabId?: number;
34
- }>("/v1/browser-relay/command", command);
37
+ };
38
+
39
+ if (extensionRelayServer.getStatus().connected) {
40
+ data = await extensionRelayServer.sendCommand(
41
+ command as Omit<ExtensionCommand, "id">,
42
+ );
43
+ } else {
44
+ // In-process relay not connected — fall back to gateway HTTP
45
+ if (!isSigningKeyInitialized()) {
46
+ initAuthSigningKey(loadOrCreateSigningKey());
47
+ }
48
+ ({ data } = await gatewayPost<typeof data>(
49
+ "/v1/browser-relay/command",
50
+ command,
51
+ ));
52
+ }
35
53
 
36
54
  if (data.success) {
37
55
  process.stdout.write(
@@ -367,15 +385,28 @@ Examples:
367
385
  )
368
386
  .action(async () => {
369
387
  try {
370
- if (!isSigningKeyInitialized()) {
371
- initAuthSigningKey(loadOrCreateSigningKey());
372
- }
373
- const data = await gatewayGet<{
388
+ // Dual-path: use in-process status when connected (daemon context),
389
+ // otherwise query gateway HTTP (out-of-process CLI context).
390
+ // getStatus() is a synchronous getter that never throws — we check
391
+ // .connected to decide whether the local status is meaningful.
392
+ let data: {
374
393
  connected: boolean;
375
- connectionId?: string;
376
- lastHeartbeatAt?: number;
394
+ connectionId?: string | null;
395
+ lastHeartbeatAt?: number | null;
377
396
  pendingCommandCount: number;
378
- }>("/v1/browser-relay/status");
397
+ };
398
+
399
+ const localStatus = extensionRelayServer.getStatus();
400
+ if (localStatus.connected) {
401
+ data = localStatus;
402
+ } else {
403
+ // In-process relay not connected — fall back to gateway HTTP
404
+ if (!isSigningKeyInitialized()) {
405
+ initAuthSigningKey(loadOrCreateSigningKey());
406
+ }
407
+ data = await gatewayGet<typeof data>("/v1/browser-relay/status");
408
+ }
409
+
379
410
  process.stdout.write(
380
411
  JSON.stringify({
381
412
  ok: true,
@@ -45,7 +45,6 @@ Examples:
45
45
  autonomy: ["get", "set"],
46
46
  };
47
47
  const topLevel = [
48
- "dev",
49
48
  "sessions",
50
49
  "config",
51
50
  "keys",
@@ -129,7 +128,6 @@ function generateZshCompletion(
129
128
  _assistant() {
130
129
  local -a commands
131
130
  commands=(
132
- 'dev:Run assistant in dev mode with auto-restart'
133
131
  'sessions:Manage sessions'
134
132
  'config:Manage configuration'
135
133
  'keys:Manage API keys in secure storage'
@@ -171,7 +169,6 @@ function generateFishCompletion(
171
169
  script += `complete -c assistant -f\n`;
172
170
 
173
171
  const descriptions: Record<string, string> = {
174
- dev: "Run assistant in dev mode with auto-restart",
175
172
  sessions: "Manage sessions",
176
173
  config: "Manage configuration",
177
174
  keys: "Manage API keys in secure storage",
@@ -1,5 +1,12 @@
1
1
  import type { Command } from "commander";
2
2
 
3
+ import {
4
+ disconnectOAuthProvider,
5
+ getConnectionByProvider,
6
+ listConnections,
7
+ type OAuthConnectionRow,
8
+ } from "../../oauth/oauth-store.js";
9
+ import { credentialKey } from "../../security/credential-key.js";
3
10
  import {
4
11
  deleteSecureKeyAsync,
5
12
  getSecureKey,
@@ -47,15 +54,45 @@ function scrubSecret(secret: string | undefined): string {
47
54
  return "****" + secret.slice(-4);
48
55
  }
49
56
 
57
+ /**
58
+ * Safely look up an OAuth connection for a credential service.
59
+ * Returns undefined when the oauth-store has no data or the tables
60
+ * haven't been created yet (pre-migration).
61
+ */
62
+ function safeGetConnectionByProvider(
63
+ service: string,
64
+ ): OAuthConnectionRow | undefined {
65
+ try {
66
+ return getConnectionByProvider(service);
67
+ } catch {
68
+ return undefined;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Safely list all OAuth connections. Returns an empty array when the
74
+ * oauth-store has no data or the tables haven't been created yet.
75
+ */
76
+ function safeListConnections(): OAuthConnectionRow[] {
77
+ try {
78
+ return listConnections();
79
+ } catch {
80
+ return [];
81
+ }
82
+ }
83
+
50
84
  /**
51
85
  * Build a structured credential output object suitable for both `inspect`
52
86
  * and `list` responses. Produces an identical shape for every credential.
87
+ * Optionally enriches with data from the oauth-store when a matching
88
+ * connection exists.
53
89
  */
54
90
  function buildCredentialOutput(
55
91
  metadata: CredentialMetadata,
56
92
  secret: string | undefined,
93
+ connection?: OAuthConnectionRow,
57
94
  ): Record<string, unknown> {
58
- return {
95
+ const output: Record<string, unknown> = {
59
96
  ok: true,
60
97
  service: metadata.service,
61
98
  field: metadata.field,
@@ -66,14 +103,24 @@ function buildCredentialOutput(
66
103
  usageDescription: metadata.usageDescription ?? null,
67
104
  allowedTools: metadata.allowedTools,
68
105
  allowedDomains: metadata.allowedDomains,
69
- grantedScopes: metadata.grantedScopes ?? null,
70
- expiresAt: metadata.expiresAt
71
- ? new Date(metadata.expiresAt).toISOString()
72
- : null,
73
106
  createdAt: new Date(metadata.createdAt).toISOString(),
74
107
  updatedAt: new Date(metadata.updatedAt).toISOString(),
75
108
  injectionTemplateCount: metadata.injectionTemplates?.length ?? 0,
109
+ grantedScopes: connection ? JSON.parse(connection.grantedScopes) : null,
110
+ expiresAt: connection?.expiresAt
111
+ ? new Date(connection.expiresAt).toISOString()
112
+ : null,
76
113
  };
114
+
115
+ if (connection) {
116
+ output.oauthConnectionId = connection.id;
117
+ output.oauthAccountInfo = connection.accountInfo ?? null;
118
+ output.oauthStatus = connection.status;
119
+ output.oauthHasRefreshToken = connection.hasRefreshToken === 1;
120
+ output.oauthLabel = connection.label ?? null;
121
+ }
122
+
123
+ return output;
77
124
  }
78
125
 
79
126
  /**
@@ -100,15 +147,19 @@ function printCredentialHuman(output: Record<string, unknown>): void {
100
147
  log.info(
101
148
  ` Domains: ${(output.allowedDomains as string[]).join(", ")}`,
102
149
  );
103
- if (output.grantedScopes)
104
- log.info(
105
- ` Scopes: ${(output.grantedScopes as string[]).join(", ")}`,
106
- );
107
- if (output.expiresAt) log.info(` Expires: ${output.expiresAt}`);
108
150
  log.info(` Created: ${output.createdAt}`);
109
151
  log.info(` Updated: ${output.updatedAt}`);
110
152
  if ((output.injectionTemplateCount as number) > 0)
111
153
  log.info(` Templates: ${output.injectionTemplateCount}`);
154
+
155
+ // OAuth connection enrichment
156
+ if (output.oauthStatus) {
157
+ log.info(` OAuth: ${output.oauthStatus}`);
158
+ if (output.oauthAccountInfo)
159
+ log.info(` Account: ${output.oauthAccountInfo}`);
160
+ if (output.oauthLabel) log.info(` OAuth Label: ${output.oauthLabel}`);
161
+ log.info(` Refresh: ${output.oauthHasRefreshToken ? "yes" : "no"}`);
162
+ }
112
163
  }
113
164
 
114
165
  // ---------------------------------------------------------------------------
@@ -127,7 +178,7 @@ export function registerCredentialsCommand(program: Command): void {
127
178
  "after",
128
179
  `
129
180
  Credentials are identified by name in service:field format, matching the
130
- storage convention used internally (credential:{service}:{field}):
181
+ storage convention used internally (credential/{service}/{field}):
131
182
 
132
183
  twilio:account_sid Twilio account SID
133
184
  twilio:auth_token Twilio auth token
@@ -197,9 +248,24 @@ Examples:
197
248
  });
198
249
  }
199
250
 
251
+ // Build a lookup of oauth connections keyed by providerKey for enrichment.
252
+ // listConnections() returns rows in no guaranteed order, so we compare
253
+ // createdAt to keep the most recent active connection per provider —
254
+ // matching the behaviour of getConnectionByProvider() used by inspect.
255
+ const allConnections = safeListConnections();
256
+ const connectionsByProvider = new Map<string, OAuthConnectionRow>();
257
+ for (const conn of allConnections) {
258
+ if (conn.status !== "active") continue;
259
+ const existing = connectionsByProvider.get(conn.providerKey);
260
+ if (!existing || conn.createdAt > existing.createdAt) {
261
+ connectionsByProvider.set(conn.providerKey, conn);
262
+ }
263
+ }
264
+
200
265
  const credentials = allMetadata.map((m) => {
201
- const secret = getSecureKey(`credential:${m.service}:${m.field}`);
202
- return buildCredentialOutput(m, secret);
266
+ const secret = getSecureKey(credentialKey(m.service, m.field));
267
+ const connection = connectionsByProvider.get(m.service);
268
+ return buildCredentialOutput(m, secret, connection);
203
269
  });
204
270
 
205
271
  writeOutput(cmd, { ok: true, credentials });
@@ -273,7 +339,7 @@ Examples:
273
339
  }
274
340
 
275
341
  const { service, field } = parsed;
276
- const storageKey = `credential:${service}:${field}`;
342
+ const storageKey = credentialKey(service, field);
277
343
 
278
344
  assertMetadataWritable();
279
345
 
@@ -350,7 +416,7 @@ Examples:
350
416
  }
351
417
 
352
418
  const { service, field } = parsed;
353
- const storageKey = `credential:${service}:${field}`;
419
+ const storageKey = credentialKey(service, field);
354
420
 
355
421
  assertMetadataWritable();
356
422
 
@@ -366,7 +432,29 @@ Examples:
366
432
 
367
433
  const metadataDeleted = deleteCredentialMetadata(service, field);
368
434
 
369
- if (secretResult !== "deleted" && !metadataDeleted) {
435
+ // Also clean up the OAuth connection and new-format secure keys.
436
+ // disconnectOAuthProvider is a no-op when no connection exists.
437
+ let oauthResult: "disconnected" | "not-found" | "error" = "not-found";
438
+ try {
439
+ oauthResult = await disconnectOAuthProvider(service);
440
+ } catch {
441
+ // Best-effort — OAuth tables may not exist yet
442
+ }
443
+
444
+ if (oauthResult === "error") {
445
+ writeOutput(cmd, {
446
+ ok: false,
447
+ error: "Failed to disconnect OAuth provider — please try again",
448
+ });
449
+ process.exitCode = 1;
450
+ return;
451
+ }
452
+
453
+ if (
454
+ secretResult !== "deleted" &&
455
+ !metadataDeleted &&
456
+ oauthResult !== "disconnected"
457
+ ) {
370
458
  writeOutput(cmd, { ok: false, error: "Credential not found" });
371
459
  process.exitCode = 1;
372
460
  return;
@@ -424,11 +512,11 @@ Examples:
424
512
  return;
425
513
  }
426
514
  metadata = getCredentialMetadata(parsed.service, parsed.field);
427
- storageKey = `credential:${parsed.service}:${parsed.field}`;
515
+ storageKey = credentialKey(parsed.service, parsed.field);
428
516
  } else {
429
517
  metadata = getCredentialMetadataById(name);
430
518
  if (metadata) {
431
- storageKey = `credential:${metadata.service}:${metadata.field}`;
519
+ storageKey = credentialKey(metadata.service, metadata.field);
432
520
  } else {
433
521
  // No metadata found by UUID, and we can't determine the storage key
434
522
  writeOutput(cmd, { ok: false, error: "Credential not found" });
@@ -463,8 +551,6 @@ Examples:
463
551
  usageDescription: null,
464
552
  allowedTools: [],
465
553
  allowedDomains: [],
466
- grantedScopes: null,
467
- expiresAt: null,
468
554
  createdAt: null,
469
555
  updatedAt: null,
470
556
  injectionTemplateCount: 0,
@@ -478,7 +564,8 @@ Examples:
478
564
  return;
479
565
  }
480
566
 
481
- const output = buildCredentialOutput(metadata, secret);
567
+ const connection = safeGetConnectionByProvider(metadata.service);
568
+ const output = buildCredentialOutput(metadata, secret, connection);
482
569
  writeOutput(cmd, output);
483
570
 
484
571
  if (!shouldOutputJson(cmd)) {
@@ -529,11 +616,11 @@ Examples:
529
616
  process.exitCode = 1;
530
617
  return;
531
618
  }
532
- storageKey = `credential:${parsed.service}:${parsed.field}`;
619
+ storageKey = credentialKey(parsed.service, parsed.field);
533
620
  } else {
534
621
  const metadata = getCredentialMetadataById(name);
535
622
  if (metadata) {
536
- storageKey = `credential:${metadata.service}:${metadata.field}`;
623
+ storageKey = credentialKey(metadata.service, metadata.field);
537
624
  } else {
538
625
  writeOutput(cmd, { ok: false, error: "Credential not found" });
539
626
  process.exitCode = 1;