@vellumai/assistant 0.6.2 → 0.6.3

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 (396) hide show
  1. package/bun.lock +40 -40
  2. package/bunfig.toml +3 -0
  3. package/docs/architecture/memory.md +1 -1
  4. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
  5. package/openapi.yaml +184 -69
  6. package/package.json +41 -41
  7. package/scripts/generate-openapi.ts +1 -2
  8. package/src/__tests__/acp-session.test.ts +43 -0
  9. package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
  10. package/src/__tests__/app-executors.test.ts +1 -0
  11. package/src/__tests__/app-source-watcher.test.ts +37 -11
  12. package/src/__tests__/approval-routes-http.test.ts +178 -1
  13. package/src/__tests__/browser-fill-credential.test.ts +229 -94
  14. package/src/__tests__/browser-manager.test.ts +40 -27
  15. package/src/__tests__/catalog-files.test.ts +862 -0
  16. package/src/__tests__/channel-approvals.test.ts +53 -0
  17. package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
  18. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  19. package/src/__tests__/config-schema.test.ts +125 -48
  20. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
  21. package/src/__tests__/context-overflow-approval.test.ts +16 -1
  22. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
  23. package/src/__tests__/conversation-agent-loop.test.ts +1 -1
  24. package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
  25. package/src/__tests__/conversation-attachments.test.ts +80 -4
  26. package/src/__tests__/conversation-confirmation-signals.test.ts +155 -0
  27. package/src/__tests__/conversation-fork-crud.test.ts +17 -0
  28. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  29. package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
  30. package/src/__tests__/conversation-inject-context.test.ts +103 -0
  31. package/src/__tests__/conversation-queue.test.ts +45 -2
  32. package/src/__tests__/conversation-routes-disk-view.test.ts +5 -0
  33. package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
  34. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  35. package/src/__tests__/conversation-runtime-assembly.test.ts +269 -46
  36. package/src/__tests__/conversation-starter-routes.test.ts +126 -0
  37. package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
  38. package/src/__tests__/conversation-store.test.ts +195 -0
  39. package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
  40. package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
  41. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  42. package/src/__tests__/credential-vault-unit.test.ts +4 -4
  43. package/src/__tests__/credential-vault.test.ts +152 -13
  44. package/src/__tests__/credentials-cli.test.ts +2 -2
  45. package/src/__tests__/date-context.test.ts +4 -4
  46. package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
  47. package/src/__tests__/extension-id-sync-guard.test.ts +155 -0
  48. package/src/__tests__/fixtures/mock-chrome-extension.ts +375 -0
  49. package/src/__tests__/gateway-only-guard.test.ts +3 -0
  50. package/src/__tests__/gemini-provider.test.ts +2 -2
  51. package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
  52. package/src/__tests__/headless-browser-interactions.test.ts +707 -371
  53. package/src/__tests__/headless-browser-navigate.test.ts +389 -47
  54. package/src/__tests__/headless-browser-read-tools.test.ts +266 -103
  55. package/src/__tests__/headless-browser-snapshot.test.ts +240 -77
  56. package/src/__tests__/host-bash-proxy.test.ts +150 -1
  57. package/src/__tests__/host-browser-e2e-cloud.test.ts +462 -0
  58. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
  59. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
  60. package/src/__tests__/host-browser-event-routes.test.ts +350 -0
  61. package/src/__tests__/host-browser-proxy.test.ts +444 -0
  62. package/src/__tests__/host-browser-routes.test.ts +198 -0
  63. package/src/__tests__/host-browser-ws-events-e2e.test.ts +320 -0
  64. package/src/__tests__/host-cu-proxy.test.ts +171 -1
  65. package/src/__tests__/host-file-proxy.test.ts +185 -1
  66. package/src/__tests__/host-file-read-tool.test.ts +52 -0
  67. package/src/__tests__/host-proxy-interface.test.ts +165 -0
  68. package/src/__tests__/host-shell-tool.test.ts +1 -11
  69. package/src/__tests__/http-user-message-parity.test.ts +1 -0
  70. package/src/__tests__/integration-status.test.ts +6 -7
  71. package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
  72. package/src/__tests__/mcp-client-auth.test.ts +40 -4
  73. package/src/__tests__/mcp-health-check.test.ts +10 -3
  74. package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
  75. package/src/__tests__/migration-export-http.test.ts +61 -2
  76. package/src/__tests__/migration-export-streaming.test.ts +66 -0
  77. package/src/__tests__/migration-import-commit-http.test.ts +101 -1
  78. package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
  79. package/src/__tests__/oauth-apps-routes.test.ts +17 -12
  80. package/src/__tests__/oauth-cli.test.ts +707 -60
  81. package/src/__tests__/oauth-connect-orchestrator.test.ts +116 -24
  82. package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
  83. package/src/__tests__/oauth-provider-serializer.test.ts +146 -10
  84. package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
  85. package/src/__tests__/oauth-providers-routes.test.ts +50 -14
  86. package/src/__tests__/oauth-store.test.ts +1386 -182
  87. package/src/__tests__/oauth2-gateway-transport.test.ts +211 -20
  88. package/src/__tests__/onboarding-template-contract.test.ts +75 -57
  89. package/src/__tests__/openai-provider.test.ts +2 -2
  90. package/src/__tests__/outlook-categories.test.ts +1 -1
  91. package/src/__tests__/outlook-client-automation.test.ts +1 -1
  92. package/src/__tests__/outlook-compose-tools.test.ts +1 -1
  93. package/src/__tests__/outlook-email-watcher.test.ts +1 -1
  94. package/src/__tests__/outlook-follow-up.test.ts +1 -1
  95. package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
  96. package/src/__tests__/outlook-trash.test.ts +1 -1
  97. package/src/__tests__/outlook-unsubscribe.test.ts +1 -1
  98. package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
  99. package/src/__tests__/permission-mode.test.ts +28 -56
  100. package/src/__tests__/platform-callback-registration.test.ts +19 -0
  101. package/src/__tests__/post-turn-tool-result-truncation.test.ts +296 -0
  102. package/src/__tests__/proxy-approval-callback.test.ts +18 -0
  103. package/src/__tests__/require-fresh-approval.test.ts +40 -1
  104. package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
  105. package/src/__tests__/schedule-routes.test.ts +162 -0
  106. package/src/__tests__/secret-detection-handler.test.ts +84 -0
  107. package/src/__tests__/secret-ingress-http.test.ts +1 -0
  108. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  109. package/src/__tests__/set-permission-mode.test.ts +13 -250
  110. package/src/__tests__/skills-file-content-endpoint.test.ts +670 -0
  111. package/src/__tests__/skills-files-catalog-fallback.test.ts +450 -0
  112. package/src/__tests__/slack-channel-config.test.ts +12 -15
  113. package/src/__tests__/subagent-detail.test.ts +44 -2
  114. package/src/__tests__/subagent-disposal.test.ts +1 -0
  115. package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
  116. package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
  117. package/src/__tests__/subagent-manager-notify.test.ts +1 -0
  118. package/src/__tests__/subagent-notify-parent.test.ts +1 -0
  119. package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
  120. package/src/__tests__/subagent-tools.test.ts +1 -0
  121. package/src/__tests__/subagent-types.test.ts +1 -0
  122. package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
  123. package/src/__tests__/system-prompt.test.ts +72 -1
  124. package/src/__tests__/task-scheduler.test.ts +32 -6
  125. package/src/__tests__/telegram-config.test.ts +10 -13
  126. package/src/__tests__/terminal-tools.test.ts +9 -0
  127. package/src/__tests__/tool-approval-handler.test.ts +73 -0
  128. package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
  129. package/src/__tests__/top-level-renderer.test.ts +73 -1
  130. package/src/__tests__/transport-hints-queue.test.ts +14 -29
  131. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
  132. package/src/__tests__/v2-consent-policy.test.ts +103 -0
  133. package/src/acp/client-handler.ts +30 -4
  134. package/src/agent/loop.ts +12 -6
  135. package/src/approvals/guardian-request-resolvers.ts +21 -15
  136. package/src/browser-session/__tests__/manager.test.ts +297 -0
  137. package/src/browser-session/backends/cdp-inspect.ts +30 -0
  138. package/src/browser-session/backends/extension.ts +26 -0
  139. package/src/browser-session/backends/local.ts +24 -0
  140. package/src/browser-session/events.ts +164 -0
  141. package/src/browser-session/index.ts +27 -0
  142. package/src/browser-session/manager.ts +159 -0
  143. package/src/browser-session/types.ts +28 -0
  144. package/src/channels/__tests__/types.test.ts +134 -0
  145. package/src/channels/types.ts +53 -3
  146. package/src/cli/commands/browser-relay.ts +339 -409
  147. package/src/cli/commands/credentials.ts +3 -3
  148. package/src/cli/commands/email.ts +18 -13
  149. package/src/cli/commands/mcp.ts +16 -4
  150. package/src/cli/commands/oauth/__tests__/connect.test.ts +44 -44
  151. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
  152. package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
  153. package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
  154. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +31 -33
  155. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +329 -0
  156. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +116 -12
  157. package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
  158. package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
  159. package/src/cli/commands/oauth/apps.ts +7 -4
  160. package/src/cli/commands/oauth/connect.ts +6 -3
  161. package/src/cli/commands/oauth/disconnect.ts +1 -1
  162. package/src/cli/commands/oauth/providers.ts +200 -36
  163. package/src/cli/commands/oauth/shared.ts +5 -5
  164. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +259 -0
  165. package/src/cli/commands/platform/index.ts +107 -10
  166. package/src/cli/commands/usage.ts +10 -9
  167. package/src/cli/lib/daemon-credential-client.ts +4 -0
  168. package/src/cli/program.ts +1 -1
  169. package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
  170. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +105 -0
  171. package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
  172. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
  173. package/src/config/bundled-skills/contacts/SKILL.md +3 -0
  174. package/src/config/bundled-skills/document/SKILL.md +4 -0
  175. package/src/config/bundled-skills/gmail/SKILL.md +1 -1
  176. package/src/config/bundled-skills/outlook/SKILL.md +7 -0
  177. package/src/config/bundled-skills/subagent/SKILL.md +21 -0
  178. package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
  179. package/src/config/bundled-skills/tasks/SKILL.md +5 -0
  180. package/src/config/env-registry.ts +14 -0
  181. package/src/config/env.ts +21 -0
  182. package/src/config/feature-flag-registry.json +44 -5
  183. package/src/config/loader.ts +56 -1
  184. package/src/config/sanitize-for-transfer.ts +47 -0
  185. package/src/config/schema.ts +46 -5
  186. package/src/config/schemas/host-browser.ts +66 -0
  187. package/src/config/schemas/memory-lifecycle.ts +1 -1
  188. package/src/config/schemas/memory-retrieval.ts +103 -0
  189. package/src/config/schemas/security.ts +0 -6
  190. package/src/config/schemas/services.ts +8 -0
  191. package/src/config/types.ts +0 -1
  192. package/src/context/post-turn-tool-result-truncation.ts +176 -0
  193. package/src/context/window-manager.ts +19 -1
  194. package/src/credential-execution/approval-bridge.ts +49 -15
  195. package/src/daemon/__tests__/conversation-tool-setup.test.ts +186 -0
  196. package/src/daemon/app-source-watcher.ts +35 -0
  197. package/src/daemon/context-overflow-approval.ts +5 -0
  198. package/src/daemon/conversation-agent-loop-handlers.ts +17 -2
  199. package/src/daemon/conversation-agent-loop.ts +58 -24
  200. package/src/daemon/conversation-attachments.ts +40 -0
  201. package/src/daemon/conversation-process.ts +48 -1
  202. package/src/daemon/conversation-runtime-assembly.ts +118 -36
  203. package/src/daemon/conversation-surfaces.ts +37 -36
  204. package/src/daemon/conversation-tool-setup.ts +74 -8
  205. package/src/daemon/conversation-workspace.ts +12 -0
  206. package/src/daemon/conversation.ts +226 -8
  207. package/src/daemon/date-context.ts +10 -10
  208. package/src/daemon/first-greeting.ts +3 -2
  209. package/src/daemon/handlers/conversations.ts +9 -140
  210. package/src/daemon/handlers/shared.ts +58 -0
  211. package/src/daemon/handlers/skills.ts +232 -37
  212. package/src/daemon/host-bash-proxy.ts +48 -13
  213. package/src/daemon/host-browser-proxy.ts +191 -0
  214. package/src/daemon/host-cu-proxy.ts +36 -11
  215. package/src/daemon/host-file-proxy.ts +57 -9
  216. package/src/daemon/lifecycle.ts +65 -11
  217. package/src/daemon/message-protocol.ts +7 -0
  218. package/src/daemon/message-types/conversations.ts +55 -13
  219. package/src/daemon/message-types/host-browser.ts +100 -0
  220. package/src/daemon/message-types/messages.ts +5 -5
  221. package/src/daemon/message-types/skills.ts +10 -0
  222. package/src/daemon/message-types/subagents.ts +2 -0
  223. package/src/daemon/server.ts +92 -12
  224. package/src/daemon/tool-side-effects.ts +6 -0
  225. package/src/daemon/transport-hints.ts +5 -24
  226. package/src/inbound/platform-callback-registration.ts +18 -17
  227. package/src/mcp/client.ts +59 -24
  228. package/src/memory/app-store.ts +31 -1
  229. package/src/memory/conversation-crud.ts +23 -0
  230. package/src/memory/conversation-starters-cadence.ts +76 -0
  231. package/src/memory/conversation-title-service.ts +5 -2
  232. package/src/memory/db-init.ts +12 -0
  233. package/src/memory/embedding-backend.test.ts +75 -0
  234. package/src/memory/embedding-backend.ts +131 -5
  235. package/src/memory/embedding-gemini.test.ts +54 -0
  236. package/src/memory/embedding-gemini.ts +20 -9
  237. package/src/memory/embedding-local.ts +176 -17
  238. package/src/memory/graph/consolidation.ts +10 -23
  239. package/src/memory/graph/extraction-job.ts +15 -0
  240. package/src/memory/graph/retriever.ts +40 -22
  241. package/src/memory/graph/store.test.ts +7 -3
  242. package/src/memory/graph/store.ts +47 -12
  243. package/src/memory/llm-usage-store.ts +45 -4
  244. package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
  245. package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
  246. package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
  247. package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
  248. package/src/memory/migrations/217-conversation-host-access.ts +40 -0
  249. package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
  250. package/src/memory/migrations/index.ts +6 -0
  251. package/src/memory/migrations/registry.ts +8 -0
  252. package/src/memory/schema/conversations.ts +1 -0
  253. package/src/memory/schema/oauth.ts +18 -13
  254. package/src/oauth/AGENTS.md +76 -0
  255. package/src/oauth/__tests__/identity-verifier.test.ts +24 -19
  256. package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
  257. package/src/oauth/byo-connection.test.ts +8 -8
  258. package/src/oauth/byo-connection.ts +7 -7
  259. package/src/oauth/connect-orchestrator.ts +23 -21
  260. package/src/oauth/connect-types.ts +3 -3
  261. package/src/oauth/connection-resolver.test.ts +17 -4
  262. package/src/oauth/connection-resolver.ts +16 -16
  263. package/src/oauth/connection.ts +1 -1
  264. package/src/oauth/manual-token-connection.ts +13 -13
  265. package/src/oauth/oauth-store.ts +214 -100
  266. package/src/oauth/platform-connection.test.ts +3 -3
  267. package/src/oauth/platform-connection.ts +4 -4
  268. package/src/oauth/provider-serializer.ts +31 -5
  269. package/src/oauth/revoke.ts +76 -0
  270. package/src/oauth/seed-providers.ts +126 -87
  271. package/src/oauth/token-persistence.ts +1 -1
  272. package/src/permissions/permission-mode.ts +4 -11
  273. package/src/permissions/prompter.ts +13 -1
  274. package/src/permissions/v2-consent-policy.ts +87 -0
  275. package/src/prompts/system-prompt.ts +18 -21
  276. package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
  277. package/src/prompts/templates/BOOTSTRAP.md +59 -105
  278. package/src/providers/anthropic/client.ts +1 -0
  279. package/src/providers/types.ts +1 -1
  280. package/src/runtime/AGENTS.md +23 -0
  281. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
  282. package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
  283. package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
  284. package/src/runtime/assistant-event-hub.ts +2 -2
  285. package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
  286. package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
  287. package/src/runtime/auth/__tests__/route-policy.test.ts +8 -0
  288. package/src/runtime/auth/middleware.ts +98 -0
  289. package/src/runtime/auth/route-policy.ts +6 -7
  290. package/src/runtime/capability-tokens.ts +414 -0
  291. package/src/runtime/channel-approvals.ts +18 -5
  292. package/src/runtime/chrome-extension-registry.ts +332 -0
  293. package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
  294. package/src/runtime/guardian-decision-types.ts +7 -0
  295. package/src/runtime/http-server.ts +425 -70
  296. package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
  297. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
  298. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +162 -0
  299. package/src/runtime/migrations/migration-transport.ts +6 -0
  300. package/src/runtime/migrations/migration-wizard.ts +22 -2
  301. package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
  302. package/src/runtime/migrations/vbundle-builder.ts +145 -38
  303. package/src/runtime/migrations/vbundle-import-analyzer.ts +19 -0
  304. package/src/runtime/migrations/vbundle-importer.ts +55 -5
  305. package/src/runtime/pending-interactions.ts +29 -13
  306. package/src/runtime/routes/approval-routes.ts +90 -16
  307. package/src/runtime/routes/browser-cdp-routes.ts +229 -0
  308. package/src/runtime/routes/browser-extension-pair-routes.ts +497 -0
  309. package/src/runtime/routes/conversation-analysis-routes.ts +2 -1
  310. package/src/runtime/routes/conversation-management-routes.ts +108 -0
  311. package/src/runtime/routes/conversation-routes.ts +301 -27
  312. package/src/runtime/routes/conversation-starter-routes.ts +78 -16
  313. package/src/runtime/routes/guardian-action-routes.ts +24 -13
  314. package/src/runtime/routes/host-browser-routes.ts +279 -0
  315. package/src/runtime/routes/host-file-routes.ts +9 -1
  316. package/src/runtime/routes/identity-routes.ts +259 -16
  317. package/src/runtime/routes/log-export-routes.ts +42 -22
  318. package/src/runtime/routes/memory-item-routes.ts +1 -7
  319. package/src/runtime/routes/migration-routes.ts +87 -2
  320. package/src/runtime/routes/oauth-apps.ts +15 -17
  321. package/src/runtime/routes/oauth-providers.ts +4 -0
  322. package/src/runtime/routes/schedule-routes.ts +24 -11
  323. package/src/runtime/routes/settings-routes.ts +9 -97
  324. package/src/runtime/routes/skills-routes.ts +52 -2
  325. package/src/runtime/routes/subagents-routes.ts +14 -10
  326. package/src/runtime/routes/usage-routes.ts +8 -7
  327. package/src/runtime/routes/workspace-routes.test.ts +22 -0
  328. package/src/runtime/routes/workspace-routes.ts +8 -1
  329. package/src/runtime/routes/workspace-utils.ts +2 -0
  330. package/src/schedule/scheduler.ts +7 -5
  331. package/src/security/ces-credential-client.ts +20 -0
  332. package/src/security/ces-rpc-credential-backend.ts +17 -0
  333. package/src/security/credential-backend.ts +5 -0
  334. package/src/security/oauth2.ts +42 -25
  335. package/src/security/secure-keys.ts +118 -25
  336. package/src/security/token-manager.ts +23 -10
  337. package/src/skills/catalog-files.ts +492 -0
  338. package/src/subagent/manager.ts +131 -26
  339. package/src/subagent/types.ts +19 -0
  340. package/src/tools/apps/executors.ts +11 -2
  341. package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
  342. package/src/tools/browser/auth-detector.ts +43 -12
  343. package/src/tools/browser/browser-execution.ts +645 -340
  344. package/src/tools/browser/browser-manager.ts +36 -12
  345. package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
  346. package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
  347. package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +870 -0
  348. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +330 -0
  349. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +377 -0
  350. package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
  351. package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
  352. package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
  353. package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
  354. package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
  355. package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
  356. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +743 -0
  357. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
  358. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +578 -0
  359. package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
  360. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +635 -0
  361. package/src/tools/browser/cdp-client/errors.ts +34 -0
  362. package/src/tools/browser/cdp-client/extension-cdp-client.ts +125 -0
  363. package/src/tools/browser/cdp-client/factory.ts +204 -0
  364. package/src/tools/browser/cdp-client/index.ts +14 -0
  365. package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
  366. package/src/tools/browser/cdp-client/types.ts +52 -0
  367. package/src/tools/filesystem/edit.ts +1 -1
  368. package/src/tools/filesystem/list.ts +1 -1
  369. package/src/tools/filesystem/read.ts +1 -1
  370. package/src/tools/filesystem/write.ts +2 -1
  371. package/src/tools/host-filesystem/edit.ts +1 -1
  372. package/src/tools/host-filesystem/read.ts +12 -15
  373. package/src/tools/host-filesystem/write.ts +1 -1
  374. package/src/tools/host-terminal/host-shell.ts +21 -16
  375. package/src/tools/permission-checker.ts +77 -82
  376. package/src/tools/registry.ts +0 -2
  377. package/src/tools/secret-detection-handler.ts +34 -0
  378. package/src/tools/shared/filesystem/image-read.ts +61 -40
  379. package/src/tools/subagent/spawn.ts +47 -3
  380. package/src/tools/subagent/status.ts +2 -0
  381. package/src/tools/system/register.ts +2 -16
  382. package/src/tools/terminal/safe-env.ts +7 -0
  383. package/src/tools/terminal/shell.ts +21 -16
  384. package/src/tools/tool-approval-handler.ts +48 -2
  385. package/src/tools/types.ts +2 -0
  386. package/src/util/platform.ts +14 -19
  387. package/src/workspace/top-level-renderer.ts +19 -1
  388. package/src/__tests__/chrome-cdp.test.ts +0 -419
  389. package/src/__tests__/permission-mode-sse.test.ts +0 -418
  390. package/src/__tests__/permission-mode-store.test.ts +0 -277
  391. package/src/browser-extension-relay/protocol.ts +0 -63
  392. package/src/browser-extension-relay/server.ts +0 -203
  393. package/src/config/schemas/sandbox.ts +0 -14
  394. package/src/permissions/permission-mode-store.ts +0 -180
  395. package/src/tools/browser/chrome-cdp.ts +0 -239
  396. package/src/tools/system/set-permission-mode.ts +0 -103
@@ -138,10 +138,11 @@ globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => {
138
138
  import { type OAuth2Config, startOAuth2Flow } from "../security/oauth2.js";
139
139
 
140
140
  const BASE_OAUTH_CONFIG: OAuth2Config = {
141
- authUrl: "https://provider.example.com/authorize",
142
- tokenUrl: "https://provider.example.com/token",
141
+ authorizeUrl: "https://provider.example.com/authorize",
142
+ tokenExchangeUrl: "https://provider.example.com/token",
143
143
  scopes: ["read", "write"],
144
144
  clientId: "test-client-id",
145
+ scopeSeparator: " ",
145
146
  };
146
147
 
147
148
  beforeEach(() => {
@@ -219,9 +220,9 @@ describe("OAuth2 gateway transport", () => {
219
220
  expect(capturedAuthUrl).toContain(encodeURIComponent("/oauth/callback"));
220
221
 
221
222
  // Extract the redirect_uri and simulate the callback
222
- const authUrl = new URL(capturedAuthUrl);
223
- const redirectUri = authUrl.searchParams.get("redirect_uri")!;
224
- const state = authUrl.searchParams.get("state")!;
223
+ const authorizeUrl = new URL(capturedAuthUrl);
224
+ const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
225
+ const state = authorizeUrl.searchParams.get("state")!;
225
226
 
226
227
  // Make a request to the loopback server with the auth code
227
228
  const callbackUrl = `${redirectUri}?code=loopback-auth-code&state=${state}`;
@@ -282,9 +283,9 @@ describe("OAuth2 gateway transport", () => {
282
283
  expect(capturedAuthUrl).not.toContain("gw.example.com");
283
284
 
284
285
  // Simulate callback to loopback server
285
- const authUrl = new URL(capturedAuthUrl);
286
- const redirectUri = authUrl.searchParams.get("redirect_uri")!;
287
- const state = authUrl.searchParams.get("state")!;
286
+ const authorizeUrl = new URL(capturedAuthUrl);
287
+ const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
288
+ const state = authorizeUrl.searchParams.get("state")!;
288
289
  await fetch(`${redirectUri}?code=explicit-loopback-code&state=${state}`);
289
290
 
290
291
  const result = await flowPromise;
@@ -405,9 +406,9 @@ describe("OAuth2 gateway transport", () => {
405
406
  expect(capturedAuthUrl).toContain("code_challenge=");
406
407
  expect(capturedAuthUrl).toContain("code_challenge_method=S256");
407
408
 
408
- const authUrl = new URL(capturedAuthUrl);
409
- const redirectUri = authUrl.searchParams.get("redirect_uri")!;
410
- const state = authUrl.searchParams.get("state")!;
409
+ const authorizeUrl = new URL(capturedAuthUrl);
410
+ const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
411
+ const state = authorizeUrl.searchParams.get("state")!;
411
412
 
412
413
  const resp = await fetch(
413
414
  `${redirectUri}?code=loopback-code&state=${state}`,
@@ -440,9 +441,9 @@ describe("OAuth2 gateway transport", () => {
440
441
 
441
442
  await urlReadyPromise;
442
443
 
443
- const authUrl = new URL(capturedAuthUrl);
444
- const redirectUri = authUrl.searchParams.get("redirect_uri")!;
445
- const state = authUrl.searchParams.get("state")!;
444
+ const authorizeUrl = new URL(capturedAuthUrl);
445
+ const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
446
+ const state = authorizeUrl.searchParams.get("state")!;
446
447
 
447
448
  // Fire callback without awaiting — immediately check flowPromise rejection
448
449
  fetch(`${redirectUri}?error=access_denied&state=${state}`).catch(
@@ -473,8 +474,8 @@ describe("OAuth2 gateway transport", () => {
473
474
 
474
475
  await urlReadyPromise;
475
476
 
476
- const authUrl = new URL(capturedAuthUrl);
477
- const redirectUri = authUrl.searchParams.get("redirect_uri")!;
477
+ const authorizeUrl = new URL(capturedAuthUrl);
478
+ const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
478
479
 
479
480
  // Send callback with wrong state
480
481
  const resp = await fetch(
@@ -484,7 +485,7 @@ describe("OAuth2 gateway transport", () => {
484
485
 
485
486
  // The flow should still be waiting (not resolved)
486
487
  // Send the correct callback to clean up
487
- const state = authUrl.searchParams.get("state")!;
488
+ const state = authorizeUrl.searchParams.get("state")!;
488
489
  await fetch(`${redirectUri}?code=correct-code&state=${state}`);
489
490
 
490
491
  const result = await flowPromise;
@@ -516,9 +517,9 @@ describe("OAuth2 gateway transport", () => {
516
517
 
517
518
  await urlReadyPromise;
518
519
 
519
- const authUrl = new URL(capturedAuthUrl);
520
- const redirectUri = authUrl.searchParams.get("redirect_uri")!;
521
- const state = authUrl.searchParams.get("state")!;
520
+ const authorizeUrl = new URL(capturedAuthUrl);
521
+ const redirectUri = authorizeUrl.searchParams.get("redirect_uri")!;
522
+ const state = authorizeUrl.searchParams.get("state")!;
522
523
 
523
524
  // Fire callback without awaiting — immediately check flowPromise rejection
524
525
  fetch(`${redirectUri}?code=code-that-fails&state=${state}`).catch(
@@ -653,4 +654,194 @@ describe("OAuth2 gateway transport", () => {
653
654
  expect(lastTokenRequestBody!.has("client_secret")).toBe(false);
654
655
  });
655
656
  });
657
+
658
+ describe("scope separator", () => {
659
+ test("authorize URL joins scopes with space when scopeSeparator is ' '", async () => {
660
+ mockPublicBaseUrl = "https://gw.example.com";
661
+
662
+ let capturedAuthUrl = "";
663
+ const flowPromise = startOAuth2Flow(
664
+ BASE_OAUTH_CONFIG,
665
+ {
666
+ openUrl: (url) => {
667
+ capturedAuthUrl = url;
668
+ },
669
+ },
670
+ { callbackTransport: "gateway" },
671
+ );
672
+
673
+ await new Promise((r) => setTimeout(r, 10));
674
+
675
+ // URLSearchParams encodes spaces as '+' in query strings (application/x-www-form-urlencoded)
676
+ expect(capturedAuthUrl).toContain("scope=read+write");
677
+
678
+ const entries = Array.from(pendingCallbacks.entries());
679
+ entries[0][1].resolve("space-separator-code");
680
+ await flowPromise;
681
+ });
682
+
683
+ test("authorize URL joins scopes with comma when scopeSeparator is ','", async () => {
684
+ mockPublicBaseUrl = "https://gw.example.com";
685
+
686
+ const commaConfig: OAuth2Config = {
687
+ ...BASE_OAUTH_CONFIG,
688
+ scopeSeparator: ",",
689
+ };
690
+
691
+ let capturedAuthUrl = "";
692
+ const flowPromise = startOAuth2Flow(
693
+ commaConfig,
694
+ {
695
+ openUrl: (url) => {
696
+ capturedAuthUrl = url;
697
+ },
698
+ },
699
+ { callbackTransport: "gateway" },
700
+ );
701
+
702
+ await new Promise((r) => setTimeout(r, 10));
703
+
704
+ // Comma-encoded scopes
705
+ expect(capturedAuthUrl).toContain("scope=read%2Cwrite");
706
+
707
+ const entries = Array.from(pendingCallbacks.entries());
708
+ entries[0][1].resolve("comma-separator-code");
709
+ await flowPromise;
710
+ });
711
+
712
+ test("token response with comma-separated scope splits into individual scopes when scopeSeparator is ','", async () => {
713
+ mockPublicBaseUrl = "https://gw.example.com";
714
+ mockTokenResponse = {
715
+ ok: true,
716
+ status: 200,
717
+ body: {
718
+ access_token: "test-access-token",
719
+ refresh_token: "test-refresh-token",
720
+ expires_in: 3600,
721
+ scope: "read,write,issues:create",
722
+ token_type: "Bearer",
723
+ },
724
+ };
725
+
726
+ const commaConfig: OAuth2Config = {
727
+ ...BASE_OAUTH_CONFIG,
728
+ scopeSeparator: ",",
729
+ };
730
+
731
+ const flowPromise = startOAuth2Flow(
732
+ commaConfig,
733
+ { openUrl: () => {} },
734
+ { callbackTransport: "gateway" },
735
+ );
736
+
737
+ await new Promise((r) => setTimeout(r, 10));
738
+
739
+ const entries = Array.from(pendingCallbacks.entries());
740
+ entries[0][1].resolve("comma-token-code");
741
+
742
+ const result = await flowPromise;
743
+ expect(result.grantedScopes).toEqual(["read", "write", "issues:create"]);
744
+ });
745
+
746
+ test("token response with whitespace around comma separators is trimmed", async () => {
747
+ mockPublicBaseUrl = "https://gw.example.com";
748
+ mockTokenResponse = {
749
+ ok: true,
750
+ status: 200,
751
+ body: {
752
+ access_token: "test-access-token",
753
+ refresh_token: "test-refresh-token",
754
+ expires_in: 3600,
755
+ scope: " read , write ",
756
+ token_type: "Bearer",
757
+ },
758
+ };
759
+
760
+ const commaConfig: OAuth2Config = {
761
+ ...BASE_OAUTH_CONFIG,
762
+ scopeSeparator: ",",
763
+ };
764
+
765
+ const flowPromise = startOAuth2Flow(
766
+ commaConfig,
767
+ { openUrl: () => {} },
768
+ { callbackTransport: "gateway" },
769
+ );
770
+
771
+ await new Promise((r) => setTimeout(r, 10));
772
+
773
+ const entries = Array.from(pendingCallbacks.entries());
774
+ entries[0][1].resolve("comma-whitespace-code");
775
+
776
+ const result = await flowPromise;
777
+ expect(result.grantedScopes).toEqual(["read", "write"]);
778
+ });
779
+
780
+ test("default-space provider still parses comma-separated token response scopes (GitHub/Slack compat)", async () => {
781
+ // Providers like GitHub and Slack use space as their authorize-URL
782
+ // separator but return comma-separated scopes in token responses.
783
+ // The defensive split MUST tolerate that without requiring providers
784
+ // to opt into scopeSeparator: ",".
785
+ mockPublicBaseUrl = "https://gw.example.com";
786
+ mockTokenResponse = {
787
+ ok: true,
788
+ status: 200,
789
+ body: {
790
+ access_token: "test-access-token",
791
+ refresh_token: "test-refresh-token",
792
+ expires_in: 3600,
793
+ scope: "repo,read:user,notifications",
794
+ token_type: "Bearer",
795
+ },
796
+ };
797
+
798
+ // BASE_OAUTH_CONFIG uses the default " " separator.
799
+ const flowPromise = startOAuth2Flow(
800
+ BASE_OAUTH_CONFIG,
801
+ { openUrl: () => {} },
802
+ { callbackTransport: "gateway" },
803
+ );
804
+
805
+ await new Promise((r) => setTimeout(r, 10));
806
+
807
+ const entries = Array.from(pendingCallbacks.entries());
808
+ entries[0][1].resolve("github-style-code");
809
+
810
+ const result = await flowPromise;
811
+ expect(result.grantedScopes).toEqual([
812
+ "repo",
813
+ "read:user",
814
+ "notifications",
815
+ ]);
816
+ });
817
+
818
+ test("default-space provider parses space-separated token response scopes", async () => {
819
+ mockPublicBaseUrl = "https://gw.example.com";
820
+ mockTokenResponse = {
821
+ ok: true,
822
+ status: 200,
823
+ body: {
824
+ access_token: "test-access-token",
825
+ refresh_token: "test-refresh-token",
826
+ expires_in: 3600,
827
+ scope: "read write admin",
828
+ token_type: "Bearer",
829
+ },
830
+ };
831
+
832
+ const flowPromise = startOAuth2Flow(
833
+ BASE_OAUTH_CONFIG,
834
+ { openUrl: () => {} },
835
+ { callbackTransport: "gateway" },
836
+ );
837
+
838
+ await new Promise((r) => setTimeout(r, 10));
839
+
840
+ const entries = Array.from(pendingCallbacks.entries());
841
+ entries[0][1].resolve("space-token-code");
842
+
843
+ const result = await flowPromise;
844
+ expect(result.grantedScopes).toEqual(["read", "write", "admin"]);
845
+ });
846
+ });
656
847
  });
@@ -19,48 +19,17 @@ describe("onboarding template contracts", () => {
19
19
 
20
20
  test("contains identity discovery prompts", () => {
21
21
  const lower = bootstrap.toLowerCase();
22
- expect(lower).toContain("your name");
23
- expect(lower).toContain("personality");
22
+ expect(lower).toContain("identity");
23
+ expect(lower).toContain("infer");
24
24
  });
25
25
 
26
- test("leads with personality-first emotional arc", () => {
27
- const lower = bootstrap.toLowerCase();
28
- expect(lower).toContain("personality");
29
- expect(lower).toContain("vibe");
30
- // Personality arc should come before usefulness arc
31
- const personalityIdx = lower.indexOf("oh, this has personality");
32
- const usefulIdx = lower.indexOf("oh, this is useful");
33
- expect(personalityIdx).toBeGreaterThan(-1);
34
- expect(usefulIdx).toBeGreaterThan(-1);
35
- expect(personalityIdx).toBeLessThan(usefulIdx);
36
- });
37
-
38
- test("contains name selection with change-later instruction", () => {
39
- const lower = bootstrap.toLowerCase();
40
- expect(lower).toContain("what they want to call you");
41
- expect(lower).toContain("change it later");
42
- });
43
-
44
- test("name exchange happens before personality quiz", () => {
45
- const nameIdx = bootstrap.indexOf("Step 1: Name Exchange");
46
- const quizIdx = bootstrap.indexOf("Step 2: Personality Quiz");
47
- expect(nameIdx).toBeGreaterThan(-1);
48
- expect(quizIdx).toBeGreaterThan(-1);
49
- expect(nameIdx).toBeLessThan(quizIdx);
50
- });
51
-
52
- test("gathers user context: work role, hobbies, daily tools", () => {
26
+ test("gathers user context", () => {
53
27
  const lower = bootstrap.toLowerCase();
54
28
  expect(lower).toContain("work role");
55
- expect(lower).toContain("hobbies");
29
+ expect(lower).toContain("goals");
56
30
  expect(lower).toContain("tools");
57
31
  });
58
32
 
59
- test("references ui_show payloads from BOOTSTRAP-REFERENCE.md", () => {
60
- expect(bootstrap).toContain("ui_show");
61
- expect(bootstrap).toContain("BOOTSTRAP-REFERENCE.md");
62
- });
63
-
64
33
  test("contains wrapping-up criteria with deletion instructions", () => {
65
34
  const lower = bootstrap.toLowerCase();
66
35
  expect(lower).toContain("wrapping up");
@@ -70,15 +39,12 @@ describe("onboarding template contracts", () => {
70
39
 
71
40
  test("contains refusal policy", () => {
72
41
  const lower = bootstrap.toLowerCase();
73
- expect(lower).toContain("hard-required");
74
- expect(lower).toContain("best-effort");
75
42
  expect(lower).toContain("declined");
76
- expect(lower).toContain("not interrogation");
43
+ expect(lower).toContain("constraints");
77
44
  });
78
45
 
79
- test("defines resolved as provided, inferred, or declined", () => {
46
+ test("defines field states as inferred or declined", () => {
80
47
  const lower = bootstrap.toLowerCase();
81
- expect(lower).toContain("resolved");
82
48
  expect(lower).toContain("inferred");
83
49
  expect(lower).toContain("declined");
84
50
  });
@@ -91,6 +57,7 @@ describe("onboarding template contracts", () => {
91
57
  });
92
58
 
93
59
  test("includes budget constraint", () => {
60
+ expect(bootstrap).toContain("$2");
94
61
  expect(bootstrap).toContain("$5");
95
62
  });
96
63
 
@@ -98,30 +65,73 @@ describe("onboarding template contracts", () => {
98
65
  expect(bootstrap).toContain("new colleague");
99
66
  });
100
67
 
101
- test("instructs checking Connected Services for email task variant", () => {
102
- expect(bootstrap).toContain("Connected Services");
103
- expect(bootstrap).toContain("Connect my email");
104
- expect(bootstrap).toContain("Check my email");
68
+ test("contains numbered goals", () => {
69
+ const lower = bootstrap.toLowerCase();
70
+ expect(lower).toContain("establish mutual identity");
71
+ expect(lower).toContain("prove value fast");
72
+ expect(lower).toContain("infer, don't interrogate");
73
+ expect(lower).toContain("surface what you learned");
74
+ expect(lower).toContain("offer the next level");
75
+ expect(lower).toContain("write everything immediately");
76
+ expect(lower).toContain("clean up");
77
+ });
78
+
79
+ test("contains constraints section", () => {
80
+ expect(bootstrap).toContain("## Constraints");
81
+ expect(bootstrap).toContain("$2");
82
+ expect(bootstrap).toContain("2 questions");
83
+ expect(bootstrap.toLowerCase()).toContain("don't block on setup");
84
+ expect(bootstrap).toContain("One-shot");
105
85
  });
106
86
 
107
- test("keeps momentum by chaining off the first task", () => {
87
+ test("contains 'what you own' section", () => {
108
88
  const lower = bootstrap.toLowerCase();
109
- expect(lower).toContain("keep the momentum");
110
- expect(lower).toContain("don't pivot to setup");
111
- expect(lower).toContain("chain off the task");
112
- expect(lower).toContain("while we're at it");
89
+ expect(lower).toContain("sequencing");
90
+ expect(lower).toContain("pacing");
113
91
  });
114
- });
115
92
 
116
- describe("BOOTSTRAP-REFERENCE.md", () => {
117
- test("contains personality form with 4 dropdowns", () => {
118
- expect(bootstrapRef).toContain('surface_type: "form"');
119
- expect(bootstrapRef).toContain("communication_style");
120
- expect(bootstrapRef).toContain("task_style");
121
- expect(bootstrapRef).toContain("humor");
122
- expect(bootstrapRef).toContain("depth");
93
+ test("contains technical contract", () => {
94
+ expect(bootstrap).toContain("Technical Contract");
95
+ expect(bootstrap).toContain("prescribed");
123
96
  });
124
97
 
98
+ test("contains capability unlock pattern", () => {
99
+ const lower = bootstrap.toLowerCase();
100
+ expect(lower).toContain("email");
101
+ expect(lower).toContain("voice");
102
+ expect(lower).toContain("slack");
103
+ });
104
+
105
+ test("contains tone guidance", () => {
106
+ expect(bootstrap).toContain("Not servile");
107
+ expect(bootstrap.toLowerCase()).toContain("match");
108
+ expect(bootstrap.toLowerCase()).toContain("energy");
109
+ });
110
+
111
+ test("contains pre-chat onboarding context section", () => {
112
+ const lower = bootstrap.toLowerCase();
113
+ expect(lower).toContain("onboarding");
114
+ expect(lower).toContain("json");
115
+ expect(lower).toContain("context");
116
+ });
117
+
118
+ test("does not contain personality quiz references", () => {
119
+ // BOOTSTRAP.md says "No personality quiz" as part of goal 3,
120
+ // but should NOT contain instructions TO USE or SHOW a personality quiz
121
+ expect(bootstrap).not.toMatch(/show.*personality quiz/i);
122
+ expect(bootstrap).not.toMatch(/present.*personality quiz/i);
123
+ // "dropdown" only appears in "No dropdown forms" — that's a prohibition, not an instruction
124
+ expect(bootstrap).not.toMatch(/show.*dropdown/i);
125
+ });
126
+
127
+ test("does not contain rigid step sequence", () => {
128
+ expect(bootstrap).not.toMatch(/Step 1:/);
129
+ expect(bootstrap).not.toMatch(/Step 2:/);
130
+ expect(bootstrap).not.toMatch(/Step 3:/);
131
+ });
132
+ });
133
+
134
+ describe("BOOTSTRAP-REFERENCE.md", () => {
125
135
  test("contains email-not-connected task card variant", () => {
126
136
  expect(bootstrapRef).toContain("Email Not Connected");
127
137
  expect(bootstrapRef).toContain("Connect my email");
@@ -132,6 +142,14 @@ describe("onboarding template contracts", () => {
132
142
  expect(bootstrapRef).toContain("Email Already Connected");
133
143
  expect(bootstrapRef).toContain("Check my email");
134
144
  });
145
+
146
+ test("does not contain personality form", () => {
147
+ expect(bootstrapRef).not.toContain('surface_type: "form"');
148
+ expect(bootstrapRef).not.toContain("communication_style");
149
+ expect(bootstrapRef).not.toContain("task_style");
150
+ expect(bootstrapRef).not.toContain("humor");
151
+ expect(bootstrapRef).not.toContain("depth");
152
+ });
135
153
  });
136
154
 
137
155
  describe("IDENTITY.md", () => {
@@ -653,10 +653,10 @@ describe("OpenAIProvider", () => {
653
653
  [{ role: "user", content: [{ type: "text", text: "Hi" }] }],
654
654
  undefined,
655
655
  undefined,
656
- { config: { max_tokens: 32000 } },
656
+ { config: { max_tokens: 64000 } },
657
657
  );
658
658
 
659
- expect(lastCreateParams!.max_completion_tokens).toBe(32000);
659
+ expect(lastCreateParams!.max_completion_tokens).toBe(64000);
660
660
  });
661
661
 
662
662
  // -----------------------------------------------------------------------
@@ -15,7 +15,7 @@ const mockListMasterCategories = mock(() =>
15
15
  }),
16
16
  );
17
17
  const mockResolveOAuthConnection = mock(() =>
18
- Promise.resolve({ id: "conn-1", providerKey: "outlook" }),
18
+ Promise.resolve({ id: "conn-1", provider: "outlook" }),
19
19
  );
20
20
 
21
21
  mock.module("../messaging/providers/outlook/client.js", () => ({
@@ -25,7 +25,7 @@ function createMockConnection(
25
25
  ): OAuthConnection {
26
26
  return {
27
27
  id: "outlook-conn-1",
28
- providerKey: "outlook",
28
+ provider: "outlook",
29
29
  accountInfo: "test@outlook.com",
30
30
  request: mock(() =>
31
31
  Promise.resolve({ status, headers: {}, body: responseBody }),
@@ -56,7 +56,7 @@ const createForwardDraftMock = mock(
56
56
 
57
57
  const fakeConnection = {
58
58
  id: "conn-1",
59
- providerKey: "microsoft",
59
+ provider: "microsoft",
60
60
  accountInfo: "user@outlook.com",
61
61
  } as unknown as OAuthConnection;
62
62
 
@@ -40,7 +40,7 @@ mock.module("../messaging/providers/outlook/client.js", () => ({
40
40
  }));
41
41
 
42
42
  const mockResolveOAuthConnection =
43
- mock<(providerKey: string) => Promise<unknown>>();
43
+ mock<(provider: string) => Promise<unknown>>();
44
44
 
45
45
  mock.module("../oauth/connection-resolver.js", () => ({
46
46
  resolveOAuthConnection: mockResolveOAuthConnection,
@@ -24,7 +24,7 @@ const mockListMessages = mock(() =>
24
24
  }),
25
25
  );
26
26
  const mockResolveOAuthConnection = mock(() =>
27
- Promise.resolve({ id: "conn-1", providerKey: "outlook" }),
27
+ Promise.resolve({ id: "conn-1", provider: "outlook" }),
28
28
  );
29
29
 
30
30
  mock.module("../messaging/providers/outlook/client.js", () => ({
@@ -164,7 +164,7 @@ import {
164
164
  function createMockConnection(): OAuthConnection {
165
165
  return {
166
166
  id: "outlook-conn-1",
167
- providerKey: "outlook",
167
+ provider: "outlook",
168
168
  accountInfo: "test@outlook.com",
169
169
  request: mock(() =>
170
170
  Promise.resolve({ status: 200, headers: {}, body: {} }),
@@ -884,7 +884,7 @@ describe("Outlook client functions", () => {
884
884
  ): OAuthConnection {
885
885
  return {
886
886
  id: "outlook-conn-1",
887
- providerKey: "outlook",
887
+ provider: "outlook",
888
888
  accountInfo: "test@outlook.com",
889
889
  request: mock(() =>
890
890
  Promise.resolve({ status, headers: {}, body: responseBody }),
@@ -4,7 +4,7 @@ import { describe, expect, mock, test } from "bun:test";
4
4
 
5
5
  const mockTrashMessage = mock(() => Promise.resolve({}));
6
6
  const mockResolveOAuthConnection = mock(() =>
7
- Promise.resolve({ id: "conn-1", providerKey: "outlook" }),
7
+ Promise.resolve({ id: "conn-1", provider: "outlook" }),
8
8
  );
9
9
 
10
10
  mock.module("../messaging/providers/outlook/client.js", () => ({
@@ -57,7 +57,7 @@ const { run } =
57
57
 
58
58
  // ── Helpers ──────────────────────────────────────────────────────────────────
59
59
 
60
- const fakeConnection = { id: "outlook-conn-1", providerKey: "outlook" };
60
+ const fakeConnection = { id: "outlook-conn-1", provider: "outlook" };
61
61
 
62
62
  function makeContext(overrides: Partial<ToolContext> = {}): ToolContext {
63
63
  return {