@vellumai/assistant 0.6.1 → 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 (463) hide show
  1. package/bun.lock +40 -40
  2. package/bunfig.toml +3 -0
  3. package/docker-entrypoint.sh +12 -2
  4. package/docs/architecture/memory.md +1 -1
  5. package/node_modules/@vellumai/ces-contracts/src/handles.ts +7 -9
  6. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
  7. package/openapi.yaml +184 -69
  8. package/package.json +41 -41
  9. package/scripts/generate-openapi.ts +1 -2
  10. package/src/__tests__/acp-session.test.ts +43 -0
  11. package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
  12. package/src/__tests__/app-executors.test.ts +1 -0
  13. package/src/__tests__/app-source-watcher.test.ts +37 -11
  14. package/src/__tests__/approval-routes-http.test.ts +178 -1
  15. package/src/__tests__/assistant-event-hub.test.ts +30 -0
  16. package/src/__tests__/browser-fill-credential.test.ts +229 -94
  17. package/src/__tests__/browser-manager.test.ts +40 -27
  18. package/src/__tests__/catalog-files.test.ts +862 -0
  19. package/src/__tests__/channel-approvals.test.ts +53 -0
  20. package/src/__tests__/checker.test.ts +104 -170
  21. package/src/__tests__/cli-command-risk-guard.test.ts +1 -1
  22. package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
  23. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  24. package/src/__tests__/config-schema.test.ts +125 -48
  25. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
  26. package/src/__tests__/context-overflow-approval.test.ts +21 -6
  27. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
  28. package/src/__tests__/conversation-agent-loop.test.ts +1 -1
  29. package/src/__tests__/conversation-analysis-routes.test.ts +169 -0
  30. package/src/__tests__/conversation-attachments.test.ts +80 -4
  31. package/src/__tests__/conversation-confirmation-signals.test.ts +155 -0
  32. package/src/__tests__/conversation-directories-parse.test.ts +105 -0
  33. package/src/__tests__/conversation-fork-crud.test.ts +17 -0
  34. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  35. package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
  36. package/src/__tests__/conversation-inject-context.test.ts +103 -0
  37. package/src/__tests__/conversation-queue.test.ts +45 -2
  38. package/src/__tests__/conversation-routes-disk-view.test.ts +5 -0
  39. package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
  40. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  41. package/src/__tests__/conversation-runtime-assembly.test.ts +269 -46
  42. package/src/__tests__/conversation-starter-routes.test.ts +126 -0
  43. package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
  44. package/src/__tests__/conversation-store.test.ts +195 -0
  45. package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
  46. package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -3
  47. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  48. package/src/__tests__/credential-vault-unit.test.ts +4 -4
  49. package/src/__tests__/credential-vault.test.ts +152 -13
  50. package/src/__tests__/credentials-cli.test.ts +2 -2
  51. package/src/__tests__/date-context.test.ts +4 -4
  52. package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
  53. package/src/__tests__/extension-id-sync-guard.test.ts +155 -0
  54. package/src/__tests__/fixtures/mock-chrome-extension.ts +375 -0
  55. package/src/__tests__/gateway-only-guard.test.ts +3 -0
  56. package/src/__tests__/gemini-provider.test.ts +2 -2
  57. package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
  58. package/src/__tests__/headless-browser-interactions.test.ts +707 -371
  59. package/src/__tests__/headless-browser-navigate.test.ts +389 -47
  60. package/src/__tests__/headless-browser-read-tools.test.ts +266 -103
  61. package/src/__tests__/headless-browser-snapshot.test.ts +240 -77
  62. package/src/__tests__/host-bash-proxy.test.ts +150 -1
  63. package/src/__tests__/host-browser-e2e-cloud.test.ts +462 -0
  64. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
  65. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
  66. package/src/__tests__/host-browser-event-routes.test.ts +350 -0
  67. package/src/__tests__/host-browser-proxy.test.ts +444 -0
  68. package/src/__tests__/host-browser-routes.test.ts +198 -0
  69. package/src/__tests__/host-browser-ws-events-e2e.test.ts +320 -0
  70. package/src/__tests__/host-cu-proxy.test.ts +171 -1
  71. package/src/__tests__/host-file-proxy.test.ts +185 -1
  72. package/src/__tests__/host-file-read-tool.test.ts +52 -0
  73. package/src/__tests__/host-proxy-interface.test.ts +165 -0
  74. package/src/__tests__/host-shell-tool.test.ts +1 -11
  75. package/src/__tests__/http-user-message-parity.test.ts +1 -0
  76. package/src/__tests__/init-feature-flag-overrides.test.ts +167 -0
  77. package/src/__tests__/inline-command-runner.test.ts +7 -5
  78. package/src/__tests__/integration-status.test.ts +6 -7
  79. package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
  80. package/src/__tests__/log-export-workspace.test.ts +190 -0
  81. package/src/__tests__/managed-credential-catalog-cli.test.ts +12 -14
  82. package/src/__tests__/mcp-client-auth.test.ts +40 -4
  83. package/src/__tests__/mcp-health-check.test.ts +10 -3
  84. package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
  85. package/src/__tests__/migration-export-http.test.ts +61 -2
  86. package/src/__tests__/migration-export-streaming.test.ts +66 -0
  87. package/src/__tests__/migration-import-commit-http.test.ts +101 -1
  88. package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
  89. package/src/__tests__/navigate-settings-tab.test.ts +14 -1
  90. package/src/__tests__/notification-broadcaster.test.ts +65 -0
  91. package/src/__tests__/oauth-apps-routes.test.ts +17 -12
  92. package/src/__tests__/oauth-cli.test.ts +707 -60
  93. package/src/__tests__/oauth-connect-orchestrator.test.ts +116 -24
  94. package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
  95. package/src/__tests__/oauth-provider-serializer.test.ts +146 -10
  96. package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
  97. package/src/__tests__/oauth-providers-routes.test.ts +50 -14
  98. package/src/__tests__/oauth-store.test.ts +1386 -182
  99. package/src/__tests__/oauth2-gateway-transport.test.ts +211 -20
  100. package/src/__tests__/onboarding-template-contract.test.ts +74 -55
  101. package/src/__tests__/openai-provider.test.ts +2 -2
  102. package/src/__tests__/outlook-categories.test.ts +1 -1
  103. package/src/__tests__/outlook-client-automation.test.ts +1 -1
  104. package/src/__tests__/outlook-compose-tools.test.ts +1 -1
  105. package/src/__tests__/outlook-email-watcher.test.ts +1 -1
  106. package/src/__tests__/outlook-follow-up.test.ts +1 -1
  107. package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
  108. package/src/__tests__/outlook-trash.test.ts +1 -1
  109. package/src/__tests__/outlook-unsubscribe.test.ts +1 -1
  110. package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
  111. package/src/__tests__/permission-mode.test.ts +28 -56
  112. package/src/__tests__/pkb-autoinject.test.ts +96 -0
  113. package/src/__tests__/platform-callback-registration.test.ts +19 -0
  114. package/src/__tests__/post-turn-tool-result-truncation.test.ts +296 -0
  115. package/src/__tests__/proxy-approval-callback.test.ts +18 -0
  116. package/src/__tests__/require-fresh-approval.test.ts +40 -3
  117. package/src/__tests__/sandbox-diagnostics.test.ts +1 -32
  118. package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
  119. package/src/__tests__/schedule-routes.test.ts +162 -0
  120. package/src/__tests__/secret-detection-handler.test.ts +84 -0
  121. package/src/__tests__/secret-ingress-http.test.ts +1 -0
  122. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  123. package/src/__tests__/set-permission-mode.test.ts +13 -250
  124. package/src/__tests__/skills-file-content-endpoint.test.ts +670 -0
  125. package/src/__tests__/skills-files-catalog-fallback.test.ts +450 -0
  126. package/src/__tests__/slack-channel-config.test.ts +12 -15
  127. package/src/__tests__/subagent-detail.test.ts +44 -2
  128. package/src/__tests__/subagent-disposal.test.ts +1 -0
  129. package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
  130. package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
  131. package/src/__tests__/subagent-manager-notify.test.ts +1 -0
  132. package/src/__tests__/subagent-notify-parent.test.ts +1 -0
  133. package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
  134. package/src/__tests__/subagent-tools.test.ts +1 -0
  135. package/src/__tests__/subagent-types.test.ts +1 -0
  136. package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
  137. package/src/__tests__/system-prompt.test.ts +72 -1
  138. package/src/__tests__/task-scheduler.test.ts +32 -6
  139. package/src/__tests__/telegram-config.test.ts +10 -13
  140. package/src/__tests__/terminal-sandbox.test.ts +1 -1
  141. package/src/__tests__/terminal-tools.test.ts +11 -5
  142. package/src/__tests__/test-preload.ts +14 -0
  143. package/src/__tests__/tool-approval-handler.test.ts +73 -0
  144. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -1
  145. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -8
  146. package/src/__tests__/tool-executor.test.ts +0 -1
  147. package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
  148. package/src/__tests__/top-level-renderer.test.ts +73 -1
  149. package/src/__tests__/transport-hints-queue.test.ts +62 -0
  150. package/src/__tests__/trust-store.test.ts +4 -4
  151. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
  152. package/src/__tests__/v2-consent-policy.test.ts +103 -0
  153. package/src/__tests__/workspace-migration-030-seed-pkb-autoinject.test.ts +168 -0
  154. package/src/__tests__/workspace-policy.test.ts +2 -7
  155. package/src/acp/client-handler.ts +30 -4
  156. package/src/agent/loop.ts +12 -35
  157. package/src/approvals/guardian-request-resolvers.ts +21 -15
  158. package/src/browser-session/__tests__/manager.test.ts +297 -0
  159. package/src/browser-session/backends/cdp-inspect.ts +30 -0
  160. package/src/browser-session/backends/extension.ts +26 -0
  161. package/src/browser-session/backends/local.ts +24 -0
  162. package/src/browser-session/events.ts +164 -0
  163. package/src/browser-session/index.ts +27 -0
  164. package/src/browser-session/manager.ts +159 -0
  165. package/src/browser-session/types.ts +28 -0
  166. package/src/channels/__tests__/types.test.ts +134 -0
  167. package/src/channels/types.ts +55 -0
  168. package/src/cli/__tests__/run-assistant-command.ts +34 -7
  169. package/src/cli/__tests__/unknown-command.test.ts +33 -0
  170. package/src/cli/commands/browser-relay.ts +339 -409
  171. package/src/cli/commands/credentials.ts +3 -3
  172. package/src/cli/commands/default-action.ts +68 -1
  173. package/src/cli/commands/email.ts +18 -13
  174. package/src/cli/commands/mcp.ts +16 -4
  175. package/src/cli/commands/oauth/__tests__/connect.test.ts +68 -41
  176. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
  177. package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
  178. package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
  179. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +31 -33
  180. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +329 -0
  181. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +116 -12
  182. package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
  183. package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
  184. package/src/cli/commands/oauth/apps.ts +7 -4
  185. package/src/cli/commands/oauth/connect.ts +16 -2
  186. package/src/cli/commands/oauth/disconnect.ts +1 -1
  187. package/src/cli/commands/oauth/providers.ts +200 -36
  188. package/src/cli/commands/oauth/shared.ts +5 -5
  189. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +259 -0
  190. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  191. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  192. package/src/cli/commands/platform/__tests__/status.test.ts +1 -1
  193. package/src/cli/commands/platform/index.ts +107 -10
  194. package/src/cli/commands/usage.ts +10 -9
  195. package/src/cli/lib/daemon-credential-client.ts +4 -0
  196. package/src/cli/program.ts +10 -3
  197. package/src/config/assistant-feature-flags.ts +59 -55
  198. package/src/config/bundled-skills/app-builder/SKILL.md +33 -173
  199. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +105 -0
  200. package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
  201. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
  202. package/src/config/bundled-skills/contacts/SKILL.md +3 -0
  203. package/src/config/bundled-skills/document/SKILL.md +4 -0
  204. package/src/config/bundled-skills/gmail/SKILL.md +12 -7
  205. package/src/config/bundled-skills/gmail/TOOLS.json +1 -1
  206. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -1
  207. package/src/config/bundled-skills/outlook/SKILL.md +7 -0
  208. package/src/config/bundled-skills/settings/TOOLS.json +1 -1
  209. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +8 -3
  210. package/src/config/bundled-skills/subagent/SKILL.md +21 -0
  211. package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
  212. package/src/config/bundled-skills/tasks/SKILL.md +5 -0
  213. package/src/config/env-registry.ts +14 -0
  214. package/src/config/env.ts +21 -0
  215. package/src/config/feature-flag-registry.json +46 -7
  216. package/src/config/loader.ts +56 -1
  217. package/src/config/sanitize-for-transfer.ts +47 -0
  218. package/src/config/schema.ts +46 -5
  219. package/src/config/schemas/host-browser.ts +66 -0
  220. package/src/config/schemas/memory-lifecycle.ts +1 -1
  221. package/src/config/schemas/memory-retrieval.ts +103 -0
  222. package/src/config/schemas/security.ts +0 -6
  223. package/src/config/schemas/services.ts +16 -0
  224. package/src/config/types.ts +0 -1
  225. package/src/context/post-turn-tool-result-truncation.ts +176 -0
  226. package/src/context/window-manager.ts +19 -1
  227. package/src/credential-execution/approval-bridge.ts +49 -16
  228. package/src/credential-execution/managed-catalog.ts +3 -7
  229. package/src/daemon/__tests__/conversation-tool-setup.test.ts +186 -0
  230. package/src/daemon/app-source-watcher.ts +35 -0
  231. package/src/daemon/config-watcher.ts +6 -2
  232. package/src/daemon/context-overflow-approval.ts +5 -1
  233. package/src/daemon/conversation-agent-loop-handlers.ts +17 -2
  234. package/src/daemon/conversation-agent-loop.ts +74 -19
  235. package/src/daemon/conversation-attachments.ts +40 -1
  236. package/src/daemon/conversation-messaging.ts +3 -0
  237. package/src/daemon/conversation-process.ts +66 -3
  238. package/src/daemon/conversation-queue-manager.ts +8 -0
  239. package/src/daemon/conversation-runtime-assembly.ts +159 -20
  240. package/src/daemon/conversation-surfaces.ts +78 -12
  241. package/src/daemon/conversation-tool-setup.ts +74 -11
  242. package/src/daemon/conversation-workspace.ts +12 -0
  243. package/src/daemon/conversation.ts +227 -11
  244. package/src/daemon/date-context.ts +10 -10
  245. package/src/daemon/first-greeting.ts +3 -2
  246. package/src/daemon/handlers/conversations.ts +9 -139
  247. package/src/daemon/handlers/shared.ts +65 -0
  248. package/src/daemon/handlers/skills.ts +232 -37
  249. package/src/daemon/host-bash-proxy.ts +48 -13
  250. package/src/daemon/host-browser-proxy.ts +191 -0
  251. package/src/daemon/host-cu-proxy.ts +36 -11
  252. package/src/daemon/host-file-proxy.ts +57 -9
  253. package/src/daemon/lifecycle.ts +86 -12
  254. package/src/daemon/message-protocol.ts +7 -0
  255. package/src/daemon/message-types/conversations.ts +59 -13
  256. package/src/daemon/message-types/host-browser.ts +100 -0
  257. package/src/daemon/message-types/messages.ts +5 -6
  258. package/src/daemon/message-types/notifications.ts +12 -0
  259. package/src/daemon/message-types/settings.ts +12 -0
  260. package/src/daemon/message-types/skills.ts +10 -0
  261. package/src/daemon/message-types/subagents.ts +2 -0
  262. package/src/daemon/server.ts +112 -35
  263. package/src/daemon/tool-side-effects.ts +6 -0
  264. package/src/daemon/transport-hints.ts +14 -0
  265. package/src/inbound/platform-callback-registration.ts +18 -17
  266. package/src/index.ts +1 -1
  267. package/src/mcp/client.ts +59 -24
  268. package/src/memory/app-store.ts +31 -1
  269. package/src/memory/conversation-crud.ts +38 -10
  270. package/src/memory/conversation-directories.ts +39 -0
  271. package/src/memory/conversation-group-migration.ts +65 -5
  272. package/src/memory/conversation-starters-cadence.ts +76 -0
  273. package/src/memory/conversation-title-service.ts +5 -2
  274. package/src/memory/db-init.ts +12 -0
  275. package/src/memory/embedding-backend.test.ts +75 -0
  276. package/src/memory/embedding-backend.ts +131 -5
  277. package/src/memory/embedding-gemini.test.ts +54 -0
  278. package/src/memory/embedding-gemini.ts +20 -9
  279. package/src/memory/embedding-local.ts +177 -18
  280. package/src/memory/graph/capability-seed.ts +3 -5
  281. package/src/memory/graph/consolidation.ts +10 -23
  282. package/src/memory/graph/extraction-job.ts +15 -0
  283. package/src/memory/graph/retriever.ts +40 -22
  284. package/src/memory/graph/store.test.ts +7 -3
  285. package/src/memory/graph/store.ts +47 -12
  286. package/src/memory/group-crud.ts +25 -9
  287. package/src/memory/llm-usage-store.ts +45 -4
  288. package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
  289. package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
  290. package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
  291. package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
  292. package/src/memory/migrations/217-conversation-host-access.ts +40 -0
  293. package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
  294. package/src/memory/migrations/index.ts +6 -0
  295. package/src/memory/migrations/registry.ts +8 -0
  296. package/src/memory/schema/conversations.ts +1 -0
  297. package/src/memory/schema/oauth.ts +18 -13
  298. package/src/messaging/provider.ts +1 -1
  299. package/src/notifications/broadcaster.ts +6 -0
  300. package/src/notifications/conversation-pairing.ts +12 -4
  301. package/src/notifications/emit-signal.ts +14 -0
  302. package/src/notifications/signal.ts +11 -0
  303. package/src/oauth/AGENTS.md +76 -0
  304. package/src/oauth/__tests__/identity-verifier.test.ts +24 -19
  305. package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
  306. package/src/oauth/byo-connection.test.ts +8 -8
  307. package/src/oauth/byo-connection.ts +7 -7
  308. package/src/oauth/connect-orchestrator.ts +23 -21
  309. package/src/oauth/connect-types.ts +3 -3
  310. package/src/oauth/connection-resolver.test.ts +17 -4
  311. package/src/oauth/connection-resolver.ts +16 -16
  312. package/src/oauth/connection.ts +1 -1
  313. package/src/oauth/manual-token-connection.ts +13 -13
  314. package/src/oauth/oauth-store.ts +214 -100
  315. package/src/oauth/platform-connection.test.ts +5 -5
  316. package/src/oauth/platform-connection.ts +4 -4
  317. package/src/oauth/provider-serializer.ts +31 -5
  318. package/src/oauth/revoke.ts +76 -0
  319. package/src/oauth/seed-providers.ts +127 -87
  320. package/src/oauth/token-persistence.ts +1 -1
  321. package/src/permissions/checker.ts +3 -3
  322. package/src/permissions/defaults.ts +7 -8
  323. package/src/permissions/permission-mode.ts +4 -11
  324. package/src/permissions/prompter.ts +13 -3
  325. package/src/permissions/v2-consent-policy.ts +87 -0
  326. package/src/platform/client.ts +1 -1
  327. package/src/prompts/system-prompt.ts +18 -21
  328. package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
  329. package/src/prompts/templates/BOOTSTRAP.md +59 -96
  330. package/src/prompts/templates/SOUL.md +11 -11
  331. package/src/providers/anthropic/client.ts +1 -0
  332. package/src/providers/types.ts +1 -1
  333. package/src/runtime/AGENTS.md +23 -0
  334. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
  335. package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
  336. package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
  337. package/src/runtime/assistant-event-hub.ts +24 -2
  338. package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
  339. package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
  340. package/src/runtime/auth/__tests__/route-policy.test.ts +8 -0
  341. package/src/runtime/auth/middleware.ts +98 -0
  342. package/src/runtime/auth/route-policy.ts +6 -7
  343. package/src/runtime/auth/token-service.ts +8 -0
  344. package/src/runtime/capability-tokens.ts +414 -0
  345. package/src/runtime/channel-approvals.ts +18 -5
  346. package/src/runtime/chrome-extension-registry.ts +332 -0
  347. package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
  348. package/src/runtime/guardian-decision-types.ts +7 -0
  349. package/src/runtime/http-server.ts +425 -70
  350. package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
  351. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
  352. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +162 -0
  353. package/src/runtime/migrations/migration-transport.ts +6 -0
  354. package/src/runtime/migrations/migration-wizard.ts +22 -2
  355. package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
  356. package/src/runtime/migrations/vbundle-builder.ts +145 -38
  357. package/src/runtime/migrations/vbundle-import-analyzer.ts +19 -0
  358. package/src/runtime/migrations/vbundle-importer.ts +55 -5
  359. package/src/runtime/pending-interactions.ts +29 -13
  360. package/src/runtime/routes/approval-routes.ts +90 -16
  361. package/src/runtime/routes/browser-cdp-routes.ts +229 -0
  362. package/src/runtime/routes/browser-extension-pair-routes.ts +497 -0
  363. package/src/runtime/routes/conversation-analysis-routes.ts +18 -5
  364. package/src/runtime/routes/conversation-management-routes.ts +108 -0
  365. package/src/runtime/routes/conversation-routes.ts +308 -28
  366. package/src/runtime/routes/conversation-starter-routes.ts +78 -16
  367. package/src/runtime/routes/group-routes.ts +22 -8
  368. package/src/runtime/routes/guardian-action-routes.ts +24 -13
  369. package/src/runtime/routes/host-browser-routes.ts +279 -0
  370. package/src/runtime/routes/host-file-routes.ts +9 -1
  371. package/src/runtime/routes/identity-routes.ts +259 -16
  372. package/src/runtime/routes/log-export/AGENTS.md +104 -0
  373. package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +103 -0
  374. package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +716 -0
  375. package/src/runtime/routes/log-export/workspace-allowlist.ts +458 -0
  376. package/src/runtime/routes/log-export-routes.ts +60 -25
  377. package/src/runtime/routes/memory-item-routes.ts +1 -7
  378. package/src/runtime/routes/migration-routes.ts +87 -2
  379. package/src/runtime/routes/oauth-apps.ts +15 -17
  380. package/src/runtime/routes/oauth-providers.ts +4 -0
  381. package/src/runtime/routes/schedule-routes.ts +24 -11
  382. package/src/runtime/routes/settings-routes.ts +9 -97
  383. package/src/runtime/routes/skills-routes.ts +52 -2
  384. package/src/runtime/routes/subagents-routes.ts +14 -10
  385. package/src/runtime/routes/usage-routes.ts +8 -7
  386. package/src/runtime/routes/workspace-routes.test.ts +22 -0
  387. package/src/runtime/routes/workspace-routes.ts +8 -1
  388. package/src/runtime/routes/workspace-utils.ts +2 -0
  389. package/src/schedule/scheduler.ts +7 -5
  390. package/src/security/ces-credential-client.ts +20 -0
  391. package/src/security/ces-rpc-credential-backend.ts +17 -0
  392. package/src/security/credential-backend.ts +5 -0
  393. package/src/security/oauth2.ts +42 -25
  394. package/src/security/secure-keys.ts +118 -25
  395. package/src/security/token-manager.ts +23 -10
  396. package/src/skills/catalog-files.ts +492 -0
  397. package/src/skills/inline-command-runner.ts +12 -14
  398. package/src/subagent/manager.ts +131 -26
  399. package/src/subagent/types.ts +19 -0
  400. package/src/tools/apps/executors.ts +11 -2
  401. package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
  402. package/src/tools/browser/auth-detector.ts +43 -12
  403. package/src/tools/browser/browser-execution.ts +645 -340
  404. package/src/tools/browser/browser-manager.ts +36 -12
  405. package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
  406. package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
  407. package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +870 -0
  408. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +330 -0
  409. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +377 -0
  410. package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
  411. package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
  412. package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
  413. package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
  414. package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
  415. package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
  416. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +743 -0
  417. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
  418. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +578 -0
  419. package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
  420. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +635 -0
  421. package/src/tools/browser/cdp-client/errors.ts +34 -0
  422. package/src/tools/browser/cdp-client/extension-cdp-client.ts +125 -0
  423. package/src/tools/browser/cdp-client/factory.ts +204 -0
  424. package/src/tools/browser/cdp-client/index.ts +14 -0
  425. package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
  426. package/src/tools/browser/cdp-client/types.ts +52 -0
  427. package/src/tools/filesystem/edit.ts +1 -1
  428. package/src/tools/filesystem/list.ts +1 -1
  429. package/src/tools/filesystem/read.ts +1 -1
  430. package/src/tools/filesystem/write.ts +2 -1
  431. package/src/tools/host-filesystem/edit.ts +1 -1
  432. package/src/tools/host-filesystem/read.ts +12 -15
  433. package/src/tools/host-filesystem/write.ts +1 -1
  434. package/src/tools/host-terminal/host-shell.ts +21 -16
  435. package/src/tools/permission-checker.ts +77 -100
  436. package/src/tools/registry.ts +0 -2
  437. package/src/tools/secret-detection-handler.ts +34 -1
  438. package/src/tools/shared/filesystem/image-read.ts +61 -40
  439. package/src/tools/skills/sandbox-runner.ts +3 -6
  440. package/src/tools/subagent/spawn.ts +47 -3
  441. package/src/tools/subagent/status.ts +2 -0
  442. package/src/tools/system/register.ts +2 -16
  443. package/src/tools/terminal/safe-env.ts +7 -0
  444. package/src/tools/terminal/sandbox-diagnostics.ts +4 -4
  445. package/src/tools/terminal/sandbox.ts +4 -1
  446. package/src/tools/terminal/shell.ts +24 -21
  447. package/src/tools/tool-approval-handler.ts +48 -2
  448. package/src/tools/types.ts +2 -3
  449. package/src/util/platform.ts +14 -19
  450. package/src/watcher/provider-types.ts +1 -1
  451. package/src/workspace/migrations/029-seed-pkb.ts +1 -0
  452. package/src/workspace/migrations/030-seed-pkb-autoinject.ts +73 -0
  453. package/src/workspace/migrations/registry.ts +2 -0
  454. package/src/workspace/top-level-renderer.ts +19 -1
  455. package/src/__tests__/chrome-cdp.test.ts +0 -419
  456. package/src/__tests__/permission-mode-sse.test.ts +0 -418
  457. package/src/__tests__/permission-mode-store.test.ts +0 -277
  458. package/src/browser-extension-relay/protocol.ts +0 -63
  459. package/src/browser-extension-relay/server.ts +0 -203
  460. package/src/config/schemas/sandbox.ts +0 -14
  461. package/src/permissions/permission-mode-store.ts +0 -180
  462. package/src/tools/browser/chrome-cdp.ts +0 -239
  463. package/src/tools/system/set-permission-mode.ts +0 -103
@@ -336,6 +336,17 @@ Examples:
336
336
  // BYO PATH
337
337
  // =============================================================
338
338
 
339
+ // Manual-token providers (slack_channel, telegram) don't use
340
+ // OAuth2 browser flows — credentials are configured via
341
+ // `assistant credentials` or chat setup instead.
342
+ if (providerRow.authorizeUrl === "urn:manual-token") {
343
+ writeError(
344
+ `"${provider}" uses manual token configuration, not an OAuth browser flow. ` +
345
+ `Set the token with: assistant credentials set <token_value> --service ${provider} --field <field_name>`,
346
+ );
347
+ return;
348
+ }
349
+
339
350
  // a. Resolve client credentials from the DB
340
351
  const dbApp = opts.clientId
341
352
  ? getAppByProviderAndClientId(provider, opts.clientId)
@@ -403,12 +414,15 @@ Examples:
403
414
  writeOutput(cmd, {
404
415
  ok: true,
405
416
  deferred: true,
406
- authUrl: result.authUrl,
417
+ // Wire key stays `authUrl` for backward compatibility with
418
+ // existing CLI script consumers; the internal field on
419
+ // `result` is `authorizeUrl`.
420
+ authUrl: result.authorizeUrl,
407
421
  service: result.service,
408
422
  });
409
423
  } else {
410
424
  process.stdout.write(
411
- `\nAuthorize with ${provider}:\n\n${result.authUrl}\n\nThe connection will complete automatically once you authorize.\n`,
425
+ `\nAuthorize with ${provider}:\n\n${result.authorizeUrl}\n\nThe connection will complete automatically once you authorize.\n`,
412
426
  );
413
427
  }
414
428
  return;
@@ -212,7 +212,7 @@ Examples:
212
212
  accountLabel = conn.accountInfo ?? undefined;
213
213
  } else if (opts.connectionId) {
214
214
  const conn = getConnection(opts.connectionId);
215
- if (!conn || conn.providerKey !== provider) {
215
+ if (!conn || conn.provider !== provider) {
216
216
  writeError(
217
217
  `Connection "${opts.connectionId}" is not an active ${provider} connection.\n\n` +
218
218
  `Run 'assistant oauth status ${provider}' to see active connections.`,
@@ -23,6 +23,41 @@ const log = getCliLogger("cli");
23
23
 
24
24
  const LOOPBACK_CALLBACK_PATH = "/oauth/callback";
25
25
 
26
+ /**
27
+ * Resolve a logo URL from CLI flags, enforcing mutual exclusion between
28
+ * --logo-url and --logo-simpleicons-slug. Returns:
29
+ * - `undefined` when neither flag is set (caller should leave the field unchanged)
30
+ * - `null` when `--logo-url ""` is passed (clear the stored value)
31
+ * - a non-empty string URL otherwise
32
+ * Throws when both flags are set simultaneously.
33
+ */
34
+ function resolveLogoUrlFromFlags(opts: {
35
+ logoUrl?: string;
36
+ logoSimpleiconsSlug?: string;
37
+ }): string | null | undefined {
38
+ if (opts.logoUrl !== undefined && opts.logoSimpleiconsSlug !== undefined) {
39
+ throw new Error(
40
+ "--logo-url and --logo-simpleicons-slug are mutually exclusive. Provide at most one.",
41
+ );
42
+ }
43
+ if (opts.logoSimpleiconsSlug !== undefined) {
44
+ const slug = opts.logoSimpleiconsSlug.trim();
45
+ if (!slug) {
46
+ throw new Error("--logo-simpleicons-slug cannot be empty.");
47
+ }
48
+ return `https://cdn.simpleicons.org/${encodeURIComponent(slug)}`;
49
+ }
50
+ if (opts.logoUrl !== undefined) {
51
+ // Trim whitespace so copy-paste-padded URLs don't fail to parse on the
52
+ // client. Empty string (after trimming) clears the stored value
53
+ // (matches --revoke-url semantics documented in the `update` command
54
+ // help text).
55
+ const trimmed = opts.logoUrl.trim();
56
+ return trimmed === "" ? null : trimmed;
57
+ }
58
+ return undefined;
59
+ }
60
+
26
61
  /**
27
62
  * Resolve the redirect URI for a provider based on its loopback port.
28
63
  *
@@ -171,14 +206,14 @@ Examples:
171
206
  $ assistant oauth providers get google
172
207
  $ assistant oauth providers get twitter --json`,
173
208
  )
174
- .action((providerKey: string, _opts: unknown, cmd: Command) => {
209
+ .action((provider: string, _opts: unknown, cmd: Command) => {
175
210
  try {
176
- const row = getProvider(providerKey);
211
+ const row = getProvider(provider);
177
212
 
178
213
  if (!row) {
179
214
  writeOutput(cmd, {
180
215
  ok: false,
181
- error: `Provider not found: "${providerKey}". Run 'assistant oauth providers list' to see all registered providers. To register a custom provider, run 'assistant oauth providers register --help'.`,
216
+ error: `Provider not found: "${provider}". Run 'assistant oauth providers list' to see all registered providers. To register a custom provider, run 'assistant oauth providers register --help'.`,
182
217
  });
183
218
  process.exitCode = 1;
184
219
  return;
@@ -187,7 +222,7 @@ Examples:
187
222
  if (!isProviderVisible(row, loadConfig())) {
188
223
  writeOutput(cmd, {
189
224
  ok: false,
190
- error: `Provider not found: "${providerKey}". Run 'assistant oauth providers list' to see all registered providers. To register a custom provider, run 'assistant oauth providers register --help'.`,
225
+ error: `Provider not found: "${provider}". Run 'assistant oauth providers list' to see all registered providers. To register a custom provider, run 'assistant oauth providers register --help'.`,
191
226
  });
192
227
  process.exitCode = 1;
193
228
  return;
@@ -220,12 +255,20 @@ Examples:
220
255
  "--token-url <url>",
221
256
  "OAuth token endpoint URL (e.g. https://oauth2.example.com/token)",
222
257
  )
258
+ .option(
259
+ "--refresh-url <url>",
260
+ "OAuth token refresh endpoint URL. Defaults to --token-url when omitted. Set this when the provider uses a different endpoint for the refresh_token grant than for the authorization_code grant.",
261
+ )
223
262
  .option("--base-url <url>", "API base URL for the service")
224
263
  .option("--userinfo-url <url>", "OpenID Connect userinfo endpoint URL")
225
264
  .option(
226
265
  "--scopes <scopes>",
227
266
  'Comma-separated default scopes (e.g. "read,write,profile")',
228
267
  )
268
+ .option(
269
+ "--scope-separator <sep>",
270
+ 'Separator used to join scopes in the authorize URL (default: " "). Use "," for providers like Linear that expect comma-separated scopes.',
271
+ )
229
272
  .option(
230
273
  "--token-auth-method <method>",
231
274
  'How the client authenticates at the token endpoint: "client_secret_post" or "client_secret_basic"',
@@ -246,6 +289,14 @@ Examples:
246
289
  "--ping-body <json>",
247
290
  'JSON body to send with the ping request (e.g. \'{"query":"{ viewer { id } }"}\')',
248
291
  )
292
+ .option(
293
+ "--revoke-url <url>",
294
+ 'OAuth token revocation endpoint URL. Called best-effort during disconnect to invalidate the access token upstream (e.g. "https://oauth2.googleapis.com/revoke"). When omitted, disconnect is local-only — the upstream token is left valid until it naturally expires.',
295
+ )
296
+ .option(
297
+ "--revoke-body-template <json>",
298
+ 'JSON object body template for the revoke request, supporting {access_token} and {client_id} substitution (e.g. \'{"token":"{access_token}","client_id":"{client_id}"}\'). The body is form-encoded and POSTed to --revoke-url.',
299
+ )
249
300
  .option(
250
301
  "--display-name <name>",
251
302
  "Human-readable display name for the provider",
@@ -255,6 +306,14 @@ Examples:
255
306
  "--dashboard-url <url>",
256
307
  "URL to the provider's developer console / dashboard",
257
308
  )
309
+ .option(
310
+ "--logo-url <url>",
311
+ "URL to the provider's logo image (SVG or PNG). Mutually exclusive with --logo-simpleicons-slug.",
312
+ )
313
+ .option(
314
+ "--logo-simpleicons-slug <slug>",
315
+ 'Simple Icons slug (e.g. "notion", "linear"). Resolves to https://cdn.simpleicons.org/<slug>. Mutually exclusive with --logo-url.',
316
+ )
258
317
  .option(
259
318
  "--client-id-placeholder <text>",
260
319
  "Placeholder text shown in the client ID input field",
@@ -340,6 +399,17 @@ Examples:
340
399
  --ping-url https://example.com/graphql \\
341
400
  --ping-method POST \\
342
401
  --ping-body '{"query":"{ viewer { id } }"}'
402
+ $ assistant oauth providers register \\
403
+ --provider-key linear-custom \\
404
+ --auth-url https://linear.app/oauth/authorize \\
405
+ --token-url https://api.linear.app/oauth/token \\
406
+ --scopes read,write \\
407
+ --scope-separator ","
408
+ $ assistant oauth providers register \\
409
+ --provider-key split-grants \\
410
+ --auth-url https://example.com/oauth/authorize \\
411
+ --token-url https://example.com/oauth/token \\
412
+ --refresh-url https://example.com/oauth/refresh
343
413
  $ assistant oauth providers register \\
344
414
  --provider-key my-api \\
345
415
  --auth-url https://example.com/auth \\
@@ -347,7 +417,18 @@ Examples:
347
417
  --loopback-port 17400 \\
348
418
  --injection-templates '[{"hostPattern":"api.example.com","injectionType":"header","headerName":"Authorization","valuePrefix":"Bearer "}]' \\
349
419
  --identity-url https://api.example.com/me \\
350
- --identity-response-paths email,name`,
420
+ --identity-response-paths email,name
421
+ $ assistant oauth providers register \\
422
+ --provider-key custom-revokable \\
423
+ --auth-url https://example.com/oauth/authorize \\
424
+ --token-url https://example.com/oauth/token \\
425
+ --revoke-url https://example.com/oauth/revoke \\
426
+ --revoke-body-template '{"token":"{access_token}","client_id":"{client_id}"}'
427
+ $ assistant oauth providers register \\
428
+ --provider-key notion-custom \\
429
+ --auth-url https://api.notion.com/v1/oauth/authorize \\
430
+ --token-url https://api.notion.com/v1/oauth/token \\
431
+ --logo-simpleicons-slug notion`,
351
432
  )
352
433
  .action(
353
434
  (
@@ -355,17 +436,23 @@ Examples:
355
436
  providerKey: string;
356
437
  authUrl: string;
357
438
  tokenUrl: string;
439
+ refreshUrl?: string;
358
440
  baseUrl?: string;
359
441
  userinfoUrl?: string;
360
442
  scopes?: string;
443
+ scopeSeparator?: string;
361
444
  tokenAuthMethod?: string;
362
445
  pingUrl?: string;
363
446
  pingMethod?: string;
364
447
  pingHeaders?: string;
365
448
  pingBody?: string;
449
+ revokeUrl?: string;
450
+ revokeBodyTemplate?: string;
366
451
  displayName?: string;
367
452
  description?: string;
368
453
  dashboardUrl?: string;
454
+ logoUrl?: string;
455
+ logoSimpleiconsSlug?: string;
369
456
  clientIdPlaceholder?: string;
370
457
  clientSecret: boolean;
371
458
  loopbackPort?: string;
@@ -383,14 +470,23 @@ Examples:
383
470
  cmd: Command,
384
471
  ) => {
385
472
  try {
473
+ const resolvedLogoUrl = resolveLogoUrlFromFlags(opts);
474
+ if (resolvedLogoUrl === null) {
475
+ throw new Error(
476
+ "Cannot clear logo_url with empty --logo-url during registration. Omit the flag instead.",
477
+ );
478
+ }
479
+
386
480
  const row = registerProvider({
387
- providerKey: opts.providerKey,
388
- authUrl: opts.authUrl,
389
- tokenUrl: opts.tokenUrl,
481
+ provider: opts.providerKey,
482
+ authorizeUrl: opts.authUrl,
483
+ tokenExchangeUrl: opts.tokenUrl,
484
+ refreshUrl: opts.refreshUrl,
390
485
  baseUrl: opts.baseUrl,
391
486
  userinfoUrl: opts.userinfoUrl,
392
487
  defaultScopes: opts.scopes ? opts.scopes.split(",") : [],
393
488
  scopePolicy: {},
489
+ scopeSeparator: opts.scopeSeparator,
394
490
  tokenEndpointAuthMethod: opts.tokenAuthMethod,
395
491
  pingUrl: opts.pingUrl,
396
492
  pingMethod: opts.pingMethod,
@@ -398,9 +494,14 @@ Examples:
398
494
  ? JSON.parse(opts.pingHeaders)
399
495
  : undefined,
400
496
  pingBody: opts.pingBody ? JSON.parse(opts.pingBody) : undefined,
401
- displayName: opts.displayName,
497
+ revokeUrl: opts.revokeUrl,
498
+ revokeBodyTemplate: opts.revokeBodyTemplate
499
+ ? JSON.parse(opts.revokeBodyTemplate)
500
+ : undefined,
501
+ displayLabel: opts.displayName,
402
502
  description: opts.description,
403
503
  dashboardUrl: opts.dashboardUrl,
504
+ logoUrl: resolvedLogoUrl,
404
505
  clientIdPlaceholder: opts.clientIdPlaceholder,
405
506
  requiresClientSecret: opts.clientSecret ? 1 : 0,
406
507
  loopbackPort: opts.loopbackPort
@@ -455,12 +556,20 @@ Examples:
455
556
  "--token-url <url>",
456
557
  "OAuth token endpoint URL (e.g. https://oauth2.example.com/token)",
457
558
  )
559
+ .option(
560
+ "--refresh-url <url>",
561
+ "OAuth token refresh endpoint URL. Defaults to --token-url when omitted. Set this when the provider uses a different endpoint for the refresh_token grant than for the authorization_code grant.",
562
+ )
458
563
  .option("--base-url <url>", "API base URL for the service")
459
564
  .option("--userinfo-url <url>", "OpenID Connect userinfo endpoint URL")
460
565
  .option(
461
566
  "--scopes <scopes>",
462
567
  'Comma-separated default scopes (e.g. "read,write,profile")',
463
568
  )
569
+ .option(
570
+ "--scope-separator <sep>",
571
+ 'Separator used to join scopes in the authorize URL (default: " "). Use "," for providers like Linear that expect comma-separated scopes.',
572
+ )
464
573
  .option(
465
574
  "--token-auth-method <method>",
466
575
  'How the client authenticates at the token endpoint: "client_secret_post" or "client_secret_basic"',
@@ -481,6 +590,14 @@ Examples:
481
590
  "--ping-body <json>",
482
591
  'JSON body to send with the ping request (e.g. \'{"query":"{ viewer { id } }"}\')',
483
592
  )
593
+ .option(
594
+ "--revoke-url <url>",
595
+ "OAuth token revocation endpoint URL. Called best-effort during disconnect to invalidate the access token upstream. Pass an empty string to clear.",
596
+ )
597
+ .option(
598
+ "--revoke-body-template <json>",
599
+ "JSON object body template for the revoke request, supporting {access_token} and {client_id} substitution. Pass an empty string to clear.",
600
+ )
484
601
  .option(
485
602
  "--display-name <name>",
486
603
  "Human-readable display name for the provider",
@@ -490,6 +607,14 @@ Examples:
490
607
  "--dashboard-url <url>",
491
608
  "URL to the provider's developer console / dashboard",
492
609
  )
610
+ .option(
611
+ "--logo-url <url>",
612
+ "URL to the provider's logo image (SVG or PNG). Mutually exclusive with --logo-simpleicons-slug.",
613
+ )
614
+ .option(
615
+ "--logo-simpleicons-slug <slug>",
616
+ 'Simple Icons slug (e.g. "notion", "linear"). Resolves to https://cdn.simpleicons.org/<slug>. Mutually exclusive with --logo-url.',
617
+ )
493
618
  .option(
494
619
  "--client-id-placeholder <text>",
495
620
  "Placeholder text shown in the client ID input field",
@@ -562,29 +687,42 @@ Examples:
562
687
  $ assistant oauth providers update custom-api --display-name "My Custom API"
563
688
  $ assistant oauth providers update custom-api --scopes read,write --auth-url https://new.example.com/auth
564
689
  $ assistant oauth providers update custom-api --ping-url https://api.example.com/me --json
690
+ $ assistant oauth providers update custom-api --scope-separator ","
691
+ $ assistant oauth providers update custom-api --refresh-url https://example.com/oauth/refresh
565
692
  $ assistant oauth providers update custom-api \\
566
693
  --identity-url https://api.example.com/me \\
567
694
  --identity-response-paths email,name
568
695
  $ assistant oauth providers update custom-api \\
569
- --injection-templates '[{"hostPattern":"api.example.com","injectionType":"header","headerName":"Authorization","valuePrefix":"Bearer "}]'`,
696
+ --injection-templates '[{"hostPattern":"api.example.com","injectionType":"header","headerName":"Authorization","valuePrefix":"Bearer "}]'
697
+ $ assistant oauth providers update custom-api \\
698
+ --revoke-url https://api.example.com/oauth/revoke \\
699
+ --revoke-body-template '{"token":"{access_token}"}'
700
+ $ assistant oauth providers update custom-api --logo-simpleicons-slug notion
701
+ $ assistant oauth providers update custom-api --logo-url ""`,
570
702
  )
571
703
  .action(
572
704
  (
573
- providerKey: string,
705
+ provider: string,
574
706
  opts: {
575
707
  authUrl?: string;
576
708
  tokenUrl?: string;
709
+ refreshUrl?: string;
577
710
  baseUrl?: string;
578
711
  userinfoUrl?: string;
579
712
  scopes?: string;
713
+ scopeSeparator?: string;
580
714
  tokenAuthMethod?: string;
581
715
  pingUrl?: string;
582
716
  pingMethod?: string;
583
717
  pingHeaders?: string;
584
718
  pingBody?: string;
719
+ revokeUrl?: string;
720
+ revokeBodyTemplate?: string;
585
721
  displayName?: string;
586
722
  description?: string;
587
723
  dashboardUrl?: string;
724
+ logoUrl?: string;
725
+ logoSimpleiconsSlug?: string;
588
726
  clientIdPlaceholder?: string;
589
727
  clientSecret: boolean;
590
728
  loopbackPort?: string;
@@ -603,11 +741,11 @@ Examples:
603
741
  ) => {
604
742
  try {
605
743
  // Verify provider exists
606
- const existing = getProvider(providerKey);
744
+ const existing = getProvider(provider);
607
745
  if (!existing) {
608
746
  writeOutput(cmd, {
609
747
  ok: false,
610
- error: `Provider "${providerKey}" not found. Run 'assistant oauth providers list' to see all registered providers.`,
748
+ error: `Provider "${provider}" not found. Run 'assistant oauth providers list' to see all registered providers.`,
611
749
  });
612
750
  process.exitCode = 1;
613
751
  return;
@@ -616,17 +754,17 @@ Examples:
616
754
  if (!isProviderVisible(existing, loadConfig())) {
617
755
  writeOutput(cmd, {
618
756
  ok: false,
619
- error: `Provider "${providerKey}" not found. Run 'assistant oauth providers list' to see all registered providers.`,
757
+ error: `Provider "${provider}" not found. Run 'assistant oauth providers list' to see all registered providers.`,
620
758
  });
621
759
  process.exitCode = 1;
622
760
  return;
623
761
  }
624
762
 
625
763
  // Block updates to built-in providers
626
- if (SEEDED_PROVIDER_KEYS.has(providerKey)) {
764
+ if (SEEDED_PROVIDER_KEYS.has(provider)) {
627
765
  writeOutput(cmd, {
628
766
  ok: false,
629
- error: `Cannot update built-in provider "${providerKey}". Built-in providers are managed by the system and reset on startup. To create a custom provider with different settings, use 'assistant oauth providers register --provider-key <your-custom-key> ...'`,
767
+ error: `Cannot update built-in provider "${provider}". Built-in providers are managed by the system and reset on startup. To create a custom provider with different settings, use 'assistant oauth providers register --provider-key <your-custom-key> ...'`,
630
768
  });
631
769
  process.exitCode = 1;
632
770
  return;
@@ -635,13 +773,18 @@ Examples:
635
773
  // Build params object from provided options, omitting undefined values
636
774
  const params: Record<string, unknown> = {};
637
775
 
638
- if (opts.authUrl !== undefined) params.authUrl = opts.authUrl;
639
- if (opts.tokenUrl !== undefined) params.tokenUrl = opts.tokenUrl;
776
+ if (opts.authUrl !== undefined) params.authorizeUrl = opts.authUrl;
777
+ if (opts.tokenUrl !== undefined)
778
+ params.tokenExchangeUrl = opts.tokenUrl;
779
+ if (opts.refreshUrl !== undefined)
780
+ params.refreshUrl = opts.refreshUrl;
640
781
  if (opts.baseUrl !== undefined) params.baseUrl = opts.baseUrl;
641
782
  if (opts.userinfoUrl !== undefined)
642
783
  params.userinfoUrl = opts.userinfoUrl;
643
784
  if (opts.scopes !== undefined)
644
785
  params.defaultScopes = opts.scopes.split(",");
786
+ if (opts.scopeSeparator !== undefined)
787
+ params.scopeSeparator = opts.scopeSeparator;
645
788
  if (opts.tokenAuthMethod !== undefined)
646
789
  params.tokenEndpointAuthMethod = opts.tokenAuthMethod;
647
790
  if (opts.pingUrl !== undefined) params.pingUrl = opts.pingUrl;
@@ -651,8 +794,24 @@ Examples:
651
794
  params.pingHeaders = JSON.parse(opts.pingHeaders);
652
795
  if (opts.pingBody !== undefined)
653
796
  params.pingBody = JSON.parse(opts.pingBody);
797
+ if (opts.revokeUrl !== undefined) {
798
+ // Empty string means "clear" — normalize to null so the stored
799
+ // value matches the "disabled" semantics documented in the help
800
+ // text. `updateProvider`'s Partial type accepts `string | null`
801
+ // for this field so drizzle writes `null` to clear the column.
802
+ params.revokeUrl = opts.revokeUrl === "" ? null : opts.revokeUrl;
803
+ }
804
+ if (opts.revokeBodyTemplate !== undefined) {
805
+ // Empty string means "clear" — normalize to null to match --revoke-url's
806
+ // empty-string-clear semantics documented in the help text. The
807
+ // updateProvider type accepts `Record<string, string> | null` for this.
808
+ params.revokeBodyTemplate =
809
+ opts.revokeBodyTemplate === ""
810
+ ? null
811
+ : JSON.parse(opts.revokeBodyTemplate);
812
+ }
654
813
  if (opts.displayName !== undefined)
655
- params.displayName = opts.displayName;
814
+ params.displayLabel = opts.displayName;
656
815
  if (opts.description !== undefined)
657
816
  params.description = opts.description;
658
817
  if (opts.dashboardUrl !== undefined)
@@ -660,6 +819,11 @@ Examples:
660
819
  if (opts.clientIdPlaceholder !== undefined)
661
820
  params.clientIdPlaceholder = opts.clientIdPlaceholder;
662
821
 
822
+ const resolvedLogoUrl = resolveLogoUrlFromFlags(opts);
823
+ if (resolvedLogoUrl !== undefined) {
824
+ params.logoUrl = resolvedLogoUrl;
825
+ }
826
+
663
827
  // Handle the negated --no-client-* flag: Commander defaults
664
828
  // opts.clientSecret to true; the negated form sets it to false.
665
829
  // Use getOptionValueSource to detect explicit user intent.
@@ -701,7 +865,7 @@ Examples:
701
865
  return;
702
866
  }
703
867
 
704
- const row = updateProvider(providerKey, params);
868
+ const row = updateProvider(provider, params);
705
869
 
706
870
  writeOutput(cmd, parseProviderRow(row));
707
871
  } catch (err) {
@@ -747,53 +911,53 @@ Examples:
747
911
  $ assistant oauth providers delete custom-api --force --json`,
748
912
  )
749
913
  .action(
750
- async (providerKey: string, opts: { force?: boolean }, cmd: Command) => {
914
+ async (provider: string, opts: { force?: boolean }, cmd: Command) => {
751
915
  try {
752
- const provider = getProvider(providerKey);
753
- if (!provider) {
916
+ const providerRow = getProvider(provider);
917
+ if (!providerRow) {
754
918
  writeOutput(cmd, {
755
919
  ok: false,
756
- error: `Provider not found: "${providerKey}". Run 'assistant oauth providers list' to see all registered providers.`,
920
+ error: `Provider not found: "${provider}". Run 'assistant oauth providers list' to see all registered providers.`,
757
921
  });
758
922
  process.exitCode = 1;
759
923
  return;
760
924
  }
761
925
 
762
- if (!isProviderVisible(provider, loadConfig())) {
926
+ if (!isProviderVisible(providerRow, loadConfig())) {
763
927
  writeOutput(cmd, {
764
928
  ok: false,
765
- error: `Provider not found: "${providerKey}". Run 'assistant oauth providers list' to see all registered providers.`,
929
+ error: `Provider not found: "${provider}". Run 'assistant oauth providers list' to see all registered providers.`,
766
930
  });
767
931
  process.exitCode = 1;
768
932
  return;
769
933
  }
770
934
 
771
- if (SEEDED_PROVIDER_KEYS.has(providerKey) && !opts.force) {
935
+ if (SEEDED_PROVIDER_KEYS.has(provider) && !opts.force) {
772
936
  log.info(
773
- `Note: "${providerKey}" is a built-in provider and will be re-created on next startup.`,
937
+ `Note: "${provider}" is a built-in provider and will be re-created on next startup.`,
774
938
  );
775
939
  }
776
940
 
777
941
  const dependentApps = listApps().filter(
778
- (a) => a.providerKey === providerKey,
942
+ (a) => a.provider === provider,
779
943
  );
780
- const dependentConnections = listConnections(providerKey);
944
+ const dependentConnections = listConnections(provider);
781
945
  const appCount = dependentApps.length;
782
946
  const connCount = dependentConnections.length;
783
947
 
784
948
  if ((appCount > 0 || connCount > 0) && !opts.force) {
785
949
  writeOutput(cmd, {
786
950
  ok: false,
787
- error: `Cannot delete provider "${providerKey}": ${appCount} app(s) and ${connCount} connection(s) depend on it. Use --force to cascade-delete all dependent apps and connections, or remove them manually first with 'assistant oauth apps delete' and 'assistant oauth disconnect'.`,
951
+ error: `Cannot delete provider "${provider}": ${appCount} app(s) and ${connCount} connection(s) depend on it. Use --force to cascade-delete all dependent apps and connections, or remove them manually first with 'assistant oauth apps delete' and 'assistant oauth disconnect'.`,
788
952
  });
789
953
  process.exitCode = 1;
790
954
  return;
791
955
  }
792
956
 
793
957
  // Warn about built-in providers when --force is used
794
- if (SEEDED_PROVIDER_KEYS.has(providerKey) && opts.force) {
958
+ if (SEEDED_PROVIDER_KEYS.has(provider) && opts.force) {
795
959
  log.info(
796
- `Note: "${providerKey}" is a built-in provider and will be re-created on next startup.`,
960
+ `Note: "${provider}" is a built-in provider and will be re-created on next startup.`,
797
961
  );
798
962
  }
799
963
 
@@ -802,7 +966,7 @@ Examples:
802
966
  // storage in addition to deleting the connection DB row.
803
967
  for (const conn of dependentConnections) {
804
968
  const result = await disconnectOAuthProvider(
805
- providerKey,
969
+ provider,
806
970
  undefined,
807
971
  conn.id as string,
808
972
  );
@@ -816,10 +980,10 @@ Examples:
816
980
  for (const app of dependentApps) {
817
981
  await deleteApp(app.id);
818
982
  }
819
- deleteProvider(providerKey);
983
+ deleteProvider(provider);
820
984
 
821
985
  if (!shouldOutputJson(cmd)) {
822
- log.info(`Deleted provider: ${providerKey}`);
986
+ log.info(`Deleted provider: ${provider}`);
823
987
  }
824
988
 
825
989
  writeOutput(cmd, {
@@ -30,9 +30,9 @@ export interface PlatformConnectionEntry {
30
30
  * lookup so that callers (e.g. `isManagedMode`, `mode.ts`) don't duplicate the
31
31
  * validation.
32
32
  */
33
- export function getManagedServiceConfigKey(providerKey: string): string | null {
34
- const provider = getProvider(providerKey);
35
- const managedKey = provider?.managedServiceConfigKey;
33
+ export function getManagedServiceConfigKey(provider: string): string | null {
34
+ const providerRow = getProvider(provider);
35
+ const managedKey = providerRow?.managedServiceConfigKey;
36
36
  if (!managedKey || !(managedKey in ServicesSchema.shape)) return null;
37
37
  return managedKey;
38
38
  }
@@ -41,8 +41,8 @@ export function getManagedServiceConfigKey(providerKey: string): string | null {
41
41
  * Determine whether a provider is running in platform-managed mode.
42
42
  * Returns false if config is unavailable (e.g. in test environments).
43
43
  */
44
- export function isManagedMode(providerKey: string): boolean {
45
- const managedKey = getManagedServiceConfigKey(providerKey);
44
+ export function isManagedMode(provider: string): boolean {
45
+ const managedKey = getManagedServiceConfigKey(provider);
46
46
  if (!managedKey) return false;
47
47
  try {
48
48
  const services: Services = getConfig().services;