@vellumai/assistant 0.6.5 → 0.6.6

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 (443) hide show
  1. package/AGENTS.md +9 -1
  2. package/ARCHITECTURE.md +15 -17
  3. package/Dockerfile +6 -4
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
  5. package/docs/architecture/integrations.md +32 -39
  6. package/docs/architecture/memory.md +25 -30
  7. package/docs/architecture/security.md +7 -6
  8. package/docs/browser-use-architecture-phase2.md +63 -20
  9. package/docs/plugins.md +761 -0
  10. package/examples/plugins/echo/README.md +132 -0
  11. package/examples/plugins/echo/package.json +17 -0
  12. package/examples/plugins/echo/register.ts +187 -0
  13. package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
  14. package/openapi.yaml +212 -68
  15. package/package.json +1 -1
  16. package/src/__tests__/app-compiler.test.ts +57 -0
  17. package/src/__tests__/approval-cascade.test.ts +7 -2
  18. package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
  19. package/src/__tests__/avatar-generator.test.ts +4 -2
  20. package/src/__tests__/bundled-asset.test.ts +6 -6
  21. package/src/__tests__/catalog-cache.test.ts +69 -0
  22. package/src/__tests__/checker.test.ts +459 -171
  23. package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
  24. package/src/__tests__/compaction-events.test.ts +501 -0
  25. package/src/__tests__/compaction-pipeline.test.ts +210 -0
  26. package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
  27. package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
  28. package/src/__tests__/config-model-image-provider.test.ts +110 -0
  29. package/src/__tests__/config-schema.test.ts +22 -9
  30. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
  31. package/src/__tests__/contacts-tools.test.ts +26 -0
  32. package/src/__tests__/context-overflow-policy.test.ts +7 -7
  33. package/src/__tests__/context-window-manager.test.ts +355 -4
  34. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
  35. package/src/__tests__/conversation-agent-loop-overflow.test.ts +26 -30
  36. package/src/__tests__/conversation-agent-loop.test.ts +30 -141
  37. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -1
  38. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  39. package/src/__tests__/conversation-init.benchmark.test.ts +2 -16
  40. package/src/__tests__/conversation-pairing.test.ts +174 -10
  41. package/src/__tests__/conversation-pre-run-repair.test.ts +4 -1
  42. package/src/__tests__/conversation-process-callsite.test.ts +3 -0
  43. package/src/__tests__/conversation-provider-retry-repair.test.ts +16 -7
  44. package/src/__tests__/conversation-queue.test.ts +29 -14
  45. package/src/__tests__/conversation-routes-disk-view.test.ts +7 -6
  46. package/src/__tests__/conversation-runtime-assembly.test.ts +155 -110
  47. package/src/__tests__/conversation-runtime-workspace.test.ts +23 -38
  48. package/src/__tests__/conversation-seed-composer.test.ts +2 -2
  49. package/src/__tests__/conversation-slash-queue.test.ts +7 -2
  50. package/src/__tests__/conversation-slash-unknown.test.ts +25 -2
  51. package/src/__tests__/conversation-speed-override.test.ts +6 -1
  52. package/src/__tests__/conversation-title-service.test.ts +116 -0
  53. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
  54. package/src/__tests__/conversation-usage.test.ts +1 -1
  55. package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
  56. package/src/__tests__/conversation-workspace-injection.test.ts +3 -0
  57. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -1
  58. package/src/__tests__/credential-health-service.test.ts +78 -9
  59. package/src/__tests__/credential-security-invariants.test.ts +2 -2
  60. package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
  61. package/src/__tests__/empty-response-pipeline.test.ts +305 -0
  62. package/src/__tests__/extension-id-sync-guard.test.ts +3 -3
  63. package/src/__tests__/first-greeting.test.ts +247 -5
  64. package/src/__tests__/headless-browser-mode.test.ts +57 -0
  65. package/src/__tests__/history-repair-pipeline.test.ts +399 -0
  66. package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
  67. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
  68. package/src/__tests__/host-proxy-interface.test.ts +36 -2
  69. package/src/__tests__/image-credentials.test.ts +137 -0
  70. package/src/__tests__/image-service-dispatcher.test.ts +186 -0
  71. package/src/__tests__/injector-chain.test.ts +526 -0
  72. package/src/__tests__/intent-routing.test.ts +0 -26
  73. package/src/__tests__/llm-call-pipeline.test.ts +285 -0
  74. package/src/__tests__/llm-schema.test.ts +1 -1
  75. package/src/__tests__/media-generate-image.test.ts +119 -13
  76. package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
  77. package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
  78. package/src/__tests__/migration-import-from-url.test.ts +5 -68
  79. package/src/__tests__/model-intents.test.ts +4 -2
  80. package/src/__tests__/notification-broadcaster.test.ts +3 -3
  81. package/src/__tests__/notification-decision-strategy.test.ts +0 -11
  82. package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
  83. package/src/__tests__/oauth-apps-routes.test.ts +1 -1
  84. package/src/__tests__/oauth-cli.test.ts +14 -12
  85. package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
  86. package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
  87. package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
  88. package/src/__tests__/oauth-providers-routes.test.ts +3 -2
  89. package/src/__tests__/oauth-store.test.ts +41 -76
  90. package/src/__tests__/onboarding-template-contract.test.ts +16 -64
  91. package/src/__tests__/openai-image-service.test.ts +368 -0
  92. package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
  93. package/src/__tests__/permission-checker-host-gate.test.ts +0 -24
  94. package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
  95. package/src/__tests__/persistence-pipeline.test.ts +377 -0
  96. package/src/__tests__/pipeline-runner.test.ts +565 -0
  97. package/src/__tests__/platform.test.ts +5 -2
  98. package/src/__tests__/plugin-bootstrap.test.ts +483 -0
  99. package/src/__tests__/plugin-registry.test.ts +273 -0
  100. package/src/__tests__/plugin-route-contribution.test.ts +288 -0
  101. package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
  102. package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
  103. package/src/__tests__/plugin-types.test.ts +320 -0
  104. package/src/__tests__/pricing.test.ts +44 -12
  105. package/src/__tests__/proxy-approval-callback.test.ts +69 -8
  106. package/src/__tests__/reaction-persistence.test.ts +1 -0
  107. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  108. package/src/__tests__/registry.test.ts +0 -2
  109. package/src/__tests__/schedule-routes.test.ts +131 -1
  110. package/src/__tests__/scheduler-recurrence.test.ts +14 -70
  111. package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
  112. package/src/__tests__/secret-detection-handler.test.ts +0 -10
  113. package/src/__tests__/shell-identity.test.ts +0 -134
  114. package/src/__tests__/suggestion-routes.test.ts +103 -4
  115. package/src/__tests__/task-memory-cleanup.test.ts +1 -0
  116. package/src/__tests__/task-scheduler.test.ts +3 -15
  117. package/src/__tests__/test-preload.ts +11 -0
  118. package/src/__tests__/title-generate-pipeline.test.ts +224 -0
  119. package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
  120. package/src/__tests__/tool-error-pipeline.test.ts +244 -0
  121. package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
  122. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -6
  123. package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
  124. package/src/__tests__/tool-executor.test.ts +141 -0
  125. package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
  126. package/src/__tests__/tool-result-truncation.test.ts +0 -110
  127. package/src/__tests__/user-plugin-loader.test.ts +191 -0
  128. package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
  129. package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
  130. package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
  131. package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
  132. package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
  133. package/src/__tests__/workspace-policy.test.ts +21 -3
  134. package/src/agent/loop.ts +340 -102
  135. package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
  136. package/src/approvals/guardian-request-resolvers.ts +80 -0
  137. package/src/backup/__tests__/backup-worker.test.ts +2 -13
  138. package/src/backup/backup-worker.ts +3 -15
  139. package/src/bundler/app-compiler.ts +84 -1
  140. package/src/calls/call-state.ts +2 -2
  141. package/src/channels/__tests__/types.test.ts +3 -3
  142. package/src/channels/types.ts +6 -4
  143. package/src/cli/__tests__/notifications.test.ts +87 -211
  144. package/src/cli/commands/__tests__/backup.test.ts +1 -1
  145. package/src/cli/commands/__tests__/image-generation.test.ts +255 -35
  146. package/src/cli/commands/__tests__/inference-send.test.ts +12 -0
  147. package/src/cli/commands/__tests__/tts-synthesize.test.ts +12 -0
  148. package/src/cli/commands/backup.ts +2 -2
  149. package/src/cli/commands/clients.ts +138 -0
  150. package/src/cli/commands/completions.ts +2 -9
  151. package/src/cli/commands/conversations.ts +55 -7
  152. package/src/cli/commands/image-generation.ts +33 -34
  153. package/src/cli/commands/notifications.ts +68 -103
  154. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
  155. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
  156. package/src/cli/commands/oauth/connect.ts +2 -2
  157. package/src/cli/commands/oauth/providers.ts +176 -8
  158. package/src/cli/commands/oauth/status.ts +46 -36
  159. package/src/cli/commands/skills.ts +3 -4
  160. package/src/cli/program.ts +25 -29
  161. package/src/config/__tests__/backup-schema.test.ts +7 -2
  162. package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
  163. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
  164. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
  165. package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
  166. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
  167. package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
  168. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
  169. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
  170. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  171. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
  172. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +12 -0
  173. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +58 -0
  174. package/src/config/bundled-skills/schedule/SKILL.md +8 -3
  175. package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
  176. package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
  177. package/src/config/bundled-tool-registry.ts +0 -15
  178. package/src/config/feature-flag-registry.json +17 -1
  179. package/src/config/schema.ts +19 -0
  180. package/src/config/schemas/backup.ts +1 -1
  181. package/src/config/schemas/conversations.ts +16 -0
  182. package/src/config/schemas/llm.ts +2 -3
  183. package/src/config/schemas/security.ts +6 -6
  184. package/src/config/schemas/tts.ts +11 -0
  185. package/src/config/skill-state.ts +6 -2
  186. package/src/config/skills.ts +94 -5
  187. package/src/context/__tests__/compact-prompt.test.ts +27 -9
  188. package/src/context/prompts/compact.md +26 -12
  189. package/src/context/tool-result-truncation.ts +3 -63
  190. package/src/context/window-manager.ts +190 -16
  191. package/src/credential-health/credential-health-service.ts +19 -6
  192. package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
  193. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
  194. package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
  195. package/src/daemon/config-watcher.ts +0 -2
  196. package/src/daemon/context-overflow-policy.ts +4 -13
  197. package/src/daemon/conversation-agent-loop-handlers.ts +83 -22
  198. package/src/daemon/conversation-agent-loop.ts +984 -683
  199. package/src/daemon/conversation-history.ts +10 -19
  200. package/src/daemon/conversation-lifecycle.ts +37 -19
  201. package/src/daemon/conversation-notifiers.ts +2 -110
  202. package/src/daemon/conversation-process.ts +14 -7
  203. package/src/daemon/conversation-runtime-assembly.ts +532 -411
  204. package/src/daemon/conversation-tool-setup.ts +41 -4
  205. package/src/daemon/conversation.ts +80 -35
  206. package/src/daemon/external-plugins-bootstrap.ts +478 -0
  207. package/src/daemon/first-greeting.ts +191 -14
  208. package/src/daemon/handlers/config-model.ts +11 -0
  209. package/src/daemon/handlers/skills.ts +5 -1
  210. package/src/daemon/lifecycle.ts +33 -68
  211. package/src/daemon/message-types/computer-use.ts +2 -34
  212. package/src/daemon/message-types/conversations.ts +49 -0
  213. package/src/daemon/message-types/messages.ts +12 -0
  214. package/src/daemon/server.ts +5 -3
  215. package/src/daemon/shutdown-handlers.ts +2 -12
  216. package/src/daemon/tool-side-effects.ts +14 -56
  217. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
  218. package/src/heartbeat/heartbeat-service.ts +24 -1
  219. package/src/home/__tests__/feed-population-integration.test.ts +312 -0
  220. package/src/home/emit-feed-event.ts +7 -0
  221. package/src/home/feed-types.ts +41 -2
  222. package/src/home/rewrite-command-preview.ts +66 -0
  223. package/src/ipc/__tests__/socket-path.test.ts +11 -50
  224. package/src/ipc/cli-client.ts +1 -1
  225. package/src/ipc/cli-server.ts +3 -3
  226. package/src/ipc/gateway-client.ts +4 -1
  227. package/src/ipc/routes/browser-context.ts +2 -0
  228. package/src/ipc/routes/browser.ts +1 -0
  229. package/src/ipc/routes/get-contact.ts +16 -0
  230. package/src/ipc/routes/index.ts +14 -0
  231. package/src/ipc/routes/list-clients.ts +31 -0
  232. package/src/ipc/routes/merge-contacts.ts +17 -0
  233. package/src/ipc/routes/notification.ts +133 -0
  234. package/src/ipc/routes/rename-conversation.ts +59 -0
  235. package/src/ipc/routes/search-contacts.ts +19 -0
  236. package/src/ipc/routes/upsert-contact.ts +25 -0
  237. package/src/ipc/socket-path.ts +14 -38
  238. package/src/media/app-icon-generator.ts +23 -46
  239. package/src/media/avatar-router.ts +26 -41
  240. package/src/media/gemini-image-service.ts +8 -41
  241. package/src/media/image-credentials.ts +73 -0
  242. package/src/media/image-service.ts +85 -0
  243. package/src/media/openai-image-service.ts +131 -0
  244. package/src/media/types.ts +46 -0
  245. package/src/memory/conversation-crud.ts +48 -18
  246. package/src/memory/conversation-queries.ts +57 -4
  247. package/src/memory/conversation-title-service.ts +25 -0
  248. package/src/memory/db-init.ts +8 -0
  249. package/src/memory/embedding-gemini.test.ts +41 -2
  250. package/src/memory/embedding-gemini.ts +6 -1
  251. package/src/memory/graph/bootstrap.test.ts +282 -0
  252. package/src/memory/graph/bootstrap.ts +8 -5
  253. package/src/memory/graph/extraction.ts +10 -2
  254. package/src/memory/graph/graph-search.test.ts +1 -0
  255. package/src/memory/graph/inspect.ts +2 -2
  256. package/src/memory/graph/retriever.ts +10 -3
  257. package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
  258. package/src/memory/migrations/149-oauth-tables.ts +1 -0
  259. package/src/memory/migrations/223-schedule-script-column.ts +11 -0
  260. package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
  261. package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
  262. package/src/memory/migrations/index.ts +4 -0
  263. package/src/memory/pkb/pkb-index.test.ts +1 -0
  264. package/src/memory/pkb/pkb-reconcile.test.ts +1 -0
  265. package/src/memory/pkb/pkb-search.test.ts +65 -4
  266. package/src/memory/pkb/pkb-search.ts +40 -18
  267. package/src/memory/qdrant-client.test.ts +60 -0
  268. package/src/memory/qdrant-client.ts +25 -0
  269. package/src/memory/schema/infrastructure.ts +1 -0
  270. package/src/memory/schema/oauth.ts +4 -1
  271. package/src/messaging/providers/slack/render-transcript.test.ts +77 -29
  272. package/src/messaging/providers/slack/render-transcript.ts +58 -0
  273. package/src/notifications/conversation-pairing.ts +78 -19
  274. package/src/notifications/copy-composer.ts +0 -5
  275. package/src/notifications/emit-signal.ts +1 -1
  276. package/src/notifications/signal.ts +1 -2
  277. package/src/oauth/AGENTS.md +1 -1
  278. package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
  279. package/src/oauth/connect-orchestrator.ts +8 -34
  280. package/src/oauth/connect-types.ts +6 -10
  281. package/src/oauth/manual-token-connection.ts +23 -0
  282. package/src/oauth/oauth-store.ts +30 -14
  283. package/src/oauth/provider-serializer.ts +6 -1
  284. package/src/oauth/seed-providers.ts +56 -108
  285. package/src/outbound-proxy/http-forwarder.ts +9 -0
  286. package/src/permissions/approval-policy.test.ts +293 -18
  287. package/src/permissions/approval-policy.ts +110 -58
  288. package/src/permissions/arg-parser.test.ts +161 -0
  289. package/src/permissions/arg-parser.ts +141 -0
  290. package/src/permissions/bash-risk-classifier.test.ts +414 -2
  291. package/src/permissions/bash-risk-classifier.ts +303 -60
  292. package/src/permissions/checker.ts +157 -29
  293. package/src/permissions/command-registry.test.ts +239 -0
  294. package/src/permissions/command-registry.ts +234 -54
  295. package/src/permissions/defaults.ts +5 -4
  296. package/src/permissions/gateway-threshold-reader.ts +196 -0
  297. package/src/permissions/prompter.ts +4 -0
  298. package/src/permissions/risk-types.ts +61 -4
  299. package/src/permissions/schedule-risk-classifier.test.ts +129 -0
  300. package/src/permissions/schedule-risk-classifier.ts +85 -0
  301. package/src/permissions/shell-identity.ts +2 -42
  302. package/src/permissions/types.ts +2 -0
  303. package/src/permissions/workspace-policy.ts +8 -3
  304. package/src/plugins/defaults/circuit-breaker.ts +146 -0
  305. package/src/plugins/defaults/compaction.ts +145 -0
  306. package/src/plugins/defaults/empty-response.ts +126 -0
  307. package/src/plugins/defaults/history-repair.ts +85 -0
  308. package/src/plugins/defaults/index.ts +116 -0
  309. package/src/plugins/defaults/injectors.ts +491 -0
  310. package/src/plugins/defaults/llm-call.ts +82 -0
  311. package/src/plugins/defaults/memory-retrieval.ts +226 -0
  312. package/src/plugins/defaults/overflow-reduce.ts +181 -0
  313. package/src/plugins/defaults/persistence.ts +129 -0
  314. package/src/plugins/defaults/title-generate.ts +95 -0
  315. package/src/plugins/defaults/token-estimate.ts +104 -0
  316. package/src/plugins/defaults/tool-error.ts +126 -0
  317. package/src/plugins/defaults/tool-execute.ts +89 -0
  318. package/src/plugins/defaults/tool-result-truncate.ts +88 -0
  319. package/src/plugins/pipeline.ts +316 -0
  320. package/src/plugins/plugin-skill-contributions.ts +292 -0
  321. package/src/plugins/registry.ts +241 -0
  322. package/src/plugins/types.ts +1134 -0
  323. package/src/plugins/user-loader.ts +177 -0
  324. package/src/prompts/templates/BOOTSTRAP.md +27 -77
  325. package/src/providers/model-catalog.ts +52 -29
  326. package/src/providers/model-intents.ts +1 -1
  327. package/src/providers/openrouter/client.ts +5 -1
  328. package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
  329. package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
  330. package/src/providers/speech-to-text/xai-realtime.test.ts +72 -4
  331. package/src/providers/speech-to-text/xai-realtime.ts +39 -14
  332. package/src/runtime/AGENTS.md +25 -16
  333. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
  334. package/src/runtime/__tests__/client-registry.test.ts +293 -0
  335. package/src/runtime/client-registry.ts +261 -0
  336. package/src/runtime/http-server.ts +77 -8
  337. package/src/runtime/http-types.ts +0 -2
  338. package/src/runtime/migrations/vbundle-builder.ts +1 -22
  339. package/src/runtime/routes/approval-prompt-ts-tracker.ts +51 -31
  340. package/src/runtime/routes/approval-routes.ts +17 -0
  341. package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
  342. package/src/runtime/routes/conversation-routes.ts +223 -116
  343. package/src/runtime/routes/inbound-message-handler.ts +88 -13
  344. package/src/runtime/routes/memory-item-routes.test.ts +1 -0
  345. package/src/runtime/routes/migration-routes.ts +0 -3
  346. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
  347. package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
  348. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
  349. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
  350. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
  351. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
  352. package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
  353. package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
  354. package/src/runtime/routes/playground/deps.ts +56 -0
  355. package/src/runtime/routes/playground/force-compact.ts +73 -0
  356. package/src/runtime/routes/playground/guard.ts +37 -0
  357. package/src/runtime/routes/playground/index.ts +28 -0
  358. package/src/runtime/routes/playground/inject-failures.ts +159 -0
  359. package/src/runtime/routes/playground/reset-circuit.ts +115 -0
  360. package/src/runtime/routes/playground/seed-conversation.ts +139 -0
  361. package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
  362. package/src/runtime/routes/playground/state.ts +78 -0
  363. package/src/runtime/routes/schedule-routes.ts +89 -8
  364. package/src/runtime/skill-route-registry.ts +75 -15
  365. package/src/schedule/run-script.ts +68 -0
  366. package/src/schedule/schedule-store.ts +7 -1
  367. package/src/schedule/scheduler.ts +48 -8
  368. package/src/skills/catalog-cache.ts +12 -5
  369. package/src/tools/browser/__tests__/browser-status.test.ts +189 -0
  370. package/src/tools/browser/browser-execution.ts +88 -19
  371. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
  372. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
  373. package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
  374. package/src/tools/browser/cdp-client/factory.ts +15 -4
  375. package/src/tools/executor.ts +126 -74
  376. package/src/tools/network/script-proxy/session-manager.ts +37 -1
  377. package/src/tools/permission-checker.ts +98 -49
  378. package/src/tools/policy-context.ts +4 -0
  379. package/src/tools/registry.ts +140 -3
  380. package/src/tools/schedule/create.ts +23 -8
  381. package/src/tools/schedule/update.ts +3 -1
  382. package/src/tools/secret-detection-handler.ts +0 -51
  383. package/src/tools/system/avatar-generator.ts +6 -2
  384. package/src/tools/types.ts +28 -2
  385. package/src/util/platform.ts +7 -2
  386. package/src/util/pricing.ts +26 -3
  387. package/src/workspace/migrations/006-services-config.ts +2 -4
  388. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
  389. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +3 -4
  390. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
  391. package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
  392. package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
  393. package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
  394. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
  395. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
  396. package/src/workspace/migrations/registry.ts +12 -0
  397. package/tsconfig.json +1 -1
  398. package/hook-templates/debug-prompt-logger/hook.json +0 -7
  399. package/hook-templates/debug-prompt-logger/run.sh +0 -66
  400. package/src/__tests__/compaction-circuit-breaker.test.ts +0 -336
  401. package/src/__tests__/context-overflow-approval.test.ts +0 -156
  402. package/src/__tests__/hooks-blocking.test.ts +0 -178
  403. package/src/__tests__/hooks-cli.test.ts +0 -182
  404. package/src/__tests__/hooks-config.test.ts +0 -108
  405. package/src/__tests__/hooks-discovery.test.ts +0 -211
  406. package/src/__tests__/hooks-integration.test.ts +0 -196
  407. package/src/__tests__/hooks-manager.test.ts +0 -226
  408. package/src/__tests__/hooks-runner.test.ts +0 -175
  409. package/src/__tests__/hooks-settings.test.ts +0 -160
  410. package/src/__tests__/hooks-templates.test.ts +0 -169
  411. package/src/__tests__/hooks-ts-runner.test.ts +0 -170
  412. package/src/__tests__/hooks-watch.test.ts +0 -112
  413. package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
  414. package/src/__tests__/oauth-scope-policy.test.ts +0 -180
  415. package/src/__tests__/send-notification-tool.test.ts +0 -83
  416. package/src/cli/commands/shotgun.ts +0 -266
  417. package/src/config/bundled-skills/conversations/SKILL.md +0 -20
  418. package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
  419. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -88
  420. package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
  421. package/src/config/bundled-skills/notifications/SKILL.md +0 -40
  422. package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
  423. package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
  424. package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
  425. package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
  426. package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
  427. package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
  428. package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
  429. package/src/daemon/context-overflow-approval.ts +0 -52
  430. package/src/daemon/watch-handler.ts +0 -399
  431. package/src/hooks/cli.ts +0 -253
  432. package/src/hooks/config.ts +0 -100
  433. package/src/hooks/discovery.ts +0 -135
  434. package/src/hooks/manager.ts +0 -179
  435. package/src/hooks/runner.ts +0 -117
  436. package/src/hooks/templates.ts +0 -77
  437. package/src/hooks/types.ts +0 -75
  438. package/src/oauth/scope-policy.ts +0 -89
  439. package/src/runtime/gateway-internal-client.ts +0 -94
  440. package/src/runtime/routes/watch-routes.ts +0 -156
  441. package/src/signals/shotgun.ts +0 -203
  442. package/src/tools/watch/screen-watch.ts +0 -144
  443. package/src/tools/watch/watch-state.ts +0 -142
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * CRUD store for OAuth providers, apps, and connections.
3
3
  *
4
- * Backed by Drizzle + SQLite. All JSON fields (default_scopes, scope_policy,
4
+ * Backed by Drizzle + SQLite. All JSON fields (default_scopes, available_scopes,
5
5
  * extra_params, granted_scopes, metadata) are stored as serialized JSON strings.
6
6
  *
7
7
  * Note: TS field names use camelCase from the platform's naming
@@ -31,6 +31,7 @@ import {
31
31
  setSecureKeyAsync,
32
32
  } from "../security/secure-keys.js";
33
33
  import { getLogger } from "../util/logger.js";
34
+ import type { AvailableScopes } from "./connect-types.js";
34
35
  import { tryRevokeOAuthToken } from "./revoke.js";
35
36
 
36
37
  const log = getLogger("oauth-store");
@@ -56,12 +57,10 @@ export type OAuthConnectionRow = typeof oauthConnections.$inferSelect;
56
57
  * loopbackPort, injectionTemplates, appType, setupNotes,
57
58
  * identityUrl, identityMethod, identityHeaders, identityBody,
58
59
  * identityResponsePaths, identityFormat, identityOkField, featureFlag,
59
- * scopeSeparator)
60
+ * scopeSeparator, defaultScopes, availableScopes)
60
61
  * and display metadata (displayLabel, description, dashboardUrl,
61
62
  * clientIdPlaceholder, logoUrl, requiresClientSecret) propagate to existing
62
- * installations on every startup, while user-customizable fields
63
- * (defaultScopes, scopePolicy) are only written on the
64
- * initial insert. baseUrl is backfilled from seed data when null
63
+ * installations on every startup. baseUrl is backfilled from seed data when null
65
64
  * (e.g. legacy rows created before the column existed) but preserved
66
65
  * if the user has set a custom value.
67
66
  */
@@ -82,10 +81,11 @@ export function seedProviders(
82
81
  revokeBodyTemplate?: Record<string, string>;
83
82
  baseUrl?: string;
84
83
  defaultScopes: string[];
85
- scopePolicy: Record<string, unknown>;
84
+ availableScopes?: AvailableScopes;
86
85
  scopeSeparator?: string;
87
86
  authorizeParams?: Record<string, string>;
88
87
  managedServiceConfigKey?: string;
88
+ managedServiceIsPaid?: boolean;
89
89
  displayLabel?: string;
90
90
  description?: string;
91
91
  dashboardUrl?: string | null;
@@ -136,7 +136,9 @@ export function seedProviders(
136
136
  : null;
137
137
  const baseUrl = p.baseUrl ?? null;
138
138
  const defaultScopes = JSON.stringify(p.defaultScopes);
139
- const scopePolicy = JSON.stringify(p.scopePolicy);
139
+ const availableScopes = p.availableScopes
140
+ ? JSON.stringify(p.availableScopes)
141
+ : null;
140
142
  // Coerce empty string to the default space separator. An empty separator
141
143
  // would join scopes into a single concatenated token (e.g. "readwrite"),
142
144
  // which is never a valid OAuth authorize URL value.
@@ -145,6 +147,7 @@ export function seedProviders(
145
147
  ? JSON.stringify(p.authorizeParams)
146
148
  : null;
147
149
  const managedServiceConfigKey = p.managedServiceConfigKey ?? null;
150
+ const managedServiceIsPaid = p.managedServiceIsPaid === true;
148
151
  const displayLabel = p.displayLabel ?? null;
149
152
  const description = p.description ?? null;
150
153
  const dashboardUrl = p.dashboardUrl ?? null;
@@ -182,7 +185,7 @@ export function seedProviders(
182
185
  userinfoUrl,
183
186
  baseUrl,
184
187
  defaultScopes,
185
- scopePolicy,
188
+ availableScopes,
186
189
  scopeSeparator,
187
190
  authorizeParams,
188
191
  pingUrl,
@@ -192,6 +195,7 @@ export function seedProviders(
192
195
  revokeUrl,
193
196
  revokeBodyTemplate,
194
197
  managedServiceConfigKey,
198
+ managedServiceIsPaid,
195
199
  displayLabel,
196
200
  description,
197
201
  dashboardUrl,
@@ -224,6 +228,7 @@ export function seedProviders(
224
228
  userinfoUrl,
225
229
  baseUrl: sql`COALESCE(${oauthProviders.baseUrl}, ${baseUrl})`,
226
230
  defaultScopes,
231
+ availableScopes,
227
232
  scopeSeparator,
228
233
  authorizeParams,
229
234
  pingUrl,
@@ -233,6 +238,7 @@ export function seedProviders(
233
238
  revokeUrl,
234
239
  revokeBodyTemplate,
235
240
  managedServiceConfigKey,
241
+ managedServiceIsPaid,
236
242
  displayLabel,
237
243
  description,
238
244
  dashboardUrl,
@@ -294,10 +300,11 @@ export function registerProvider(params: {
294
300
  revokeBodyTemplate?: Record<string, string>;
295
301
  baseUrl?: string;
296
302
  defaultScopes: string[];
297
- scopePolicy: Record<string, unknown>;
303
+ availableScopes?: AvailableScopes;
298
304
  scopeSeparator?: string;
299
305
  authorizeParams?: Record<string, string>;
300
306
  managedServiceConfigKey?: string;
307
+ managedServiceIsPaid?: boolean;
301
308
  displayLabel?: string;
302
309
  description?: string;
303
310
  dashboardUrl?: string;
@@ -341,7 +348,9 @@ export function registerProvider(params: {
341
348
  userinfoUrl: params.userinfoUrl ?? null,
342
349
  baseUrl: params.baseUrl ?? null,
343
350
  defaultScopes: JSON.stringify(params.defaultScopes),
344
- scopePolicy: JSON.stringify(params.scopePolicy),
351
+ availableScopes: params.availableScopes
352
+ ? JSON.stringify(params.availableScopes)
353
+ : null,
345
354
  // Coerce empty string to the default space separator (see seedProviders).
346
355
  scopeSeparator: params.scopeSeparator || " ",
347
356
  authorizeParams: params.authorizeParams
@@ -357,6 +366,7 @@ export function registerProvider(params: {
357
366
  ? JSON.stringify(params.revokeBodyTemplate)
358
367
  : null,
359
368
  managedServiceConfigKey: params.managedServiceConfigKey ?? null,
369
+ managedServiceIsPaid: params.managedServiceIsPaid === true,
360
370
  displayLabel: params.displayLabel ?? null,
361
371
  description: params.description ?? null,
362
372
  dashboardUrl: params.dashboardUrl ?? null,
@@ -396,7 +406,7 @@ export function registerProvider(params: {
396
406
  /**
397
407
  * Update mutable fields on an existing provider. Only the fields explicitly
398
408
  * provided (not `undefined`) are written; everything else is left unchanged.
399
- * JSON fields (defaultScopes, scopePolicy, authorizeParams, pingHeaders, pingBody)
409
+ * JSON fields (defaultScopes, availableScopes, authorizeParams, pingHeaders, pingBody)
400
410
  * are serialized with JSON.stringify before storage.
401
411
  *
402
412
  * Returns the updated provider row, or `undefined` if no provider with the
@@ -419,7 +429,7 @@ export function updateProvider(
419
429
  revokeBodyTemplate: Record<string, string> | null;
420
430
  baseUrl: string;
421
431
  defaultScopes: string[];
422
- scopePolicy: Record<string, unknown>;
432
+ availableScopes: AvailableScopes | null;
423
433
  scopeSeparator: string;
424
434
  authorizeParams: Record<string, string>;
425
435
  displayLabel: string;
@@ -445,6 +455,7 @@ export function updateProvider(
445
455
  identityFormat: string;
446
456
  identityOkField: string;
447
457
  featureFlag: string;
458
+ managedServiceIsPaid: boolean;
448
459
  }>,
449
460
  ): OAuthProviderRow | undefined {
450
461
  const existing = getProvider(provider);
@@ -478,8 +489,11 @@ export function updateProvider(
478
489
  if (params.baseUrl !== undefined) set.baseUrl = params.baseUrl;
479
490
  if (params.defaultScopes !== undefined)
480
491
  set.defaultScopes = JSON.stringify(params.defaultScopes);
481
- if (params.scopePolicy !== undefined)
482
- set.scopePolicy = JSON.stringify(params.scopePolicy);
492
+ if (params.availableScopes !== undefined)
493
+ set.availableScopes =
494
+ params.availableScopes === null
495
+ ? null
496
+ : JSON.stringify(params.availableScopes);
483
497
  if (params.scopeSeparator !== undefined)
484
498
  // Coerce empty string to the default space separator (see seedProviders).
485
499
  set.scopeSeparator = params.scopeSeparator || " ";
@@ -513,6 +527,8 @@ export function updateProvider(
513
527
  if (params.identityOkField !== undefined)
514
528
  set.identityOkField = params.identityOkField;
515
529
  if (params.featureFlag !== undefined) set.featureFlag = params.featureFlag;
530
+ if (params.managedServiceIsPaid !== undefined)
531
+ set.managedServiceIsPaid = params.managedServiceIsPaid;
516
532
 
517
533
  db.update(oauthProviders)
518
534
  .set(set)
@@ -32,6 +32,7 @@ export interface SerializedProviderSummary {
32
32
  requires_client_secret: boolean;
33
33
  logo_url: string | null;
34
34
  supports_managed_mode: boolean;
35
+ managed_service_is_paid: boolean;
35
36
  feature_flag: string | null;
36
37
  }
37
38
 
@@ -86,8 +87,11 @@ function _serializeProvider(
86
87
  clientIdPlaceholder: row.clientIdPlaceholder ?? null,
87
88
  requiresClientSecret: !!(row.requiresClientSecret ?? 1),
88
89
  supportsManagedMode: !!row.managedServiceConfigKey,
90
+ managedServiceIsPaid: !!row.managedServiceIsPaid,
89
91
  defaultScopes: row.defaultScopes ? JSON.parse(row.defaultScopes) : [],
90
- scopePolicy: row.scopePolicy ? JSON.parse(row.scopePolicy) : {},
92
+ availableScopes: row.availableScopes
93
+ ? JSON.parse(row.availableScopes)
94
+ : null,
91
95
  scopeSeparator: row.scopeSeparator,
92
96
  extraParams: authorizeParams ? JSON.parse(authorizeParams) : null,
93
97
  pingHeaders: row.pingHeaders ? JSON.parse(row.pingHeaders) : null,
@@ -140,6 +144,7 @@ export function serializeProviderSummary(
140
144
  requires_client_secret: !!(row.requiresClientSecret ?? 1),
141
145
  logo_url: row.logoUrl ?? null,
142
146
  supports_managed_mode: !!row.managedServiceConfigKey,
147
+ managed_service_is_paid: !!row.managedServiceIsPaid,
143
148
  feature_flag: row.featureFlag ?? null,
144
149
  };
145
150
  }
@@ -1,3 +1,4 @@
1
+ import type { AvailableScopes } from "./connect-types.js";
1
2
  import { seedProviders } from "./oauth-store.js";
2
3
 
3
4
  /**
@@ -7,7 +8,7 @@ import { seedProviders } from "./oauth-store.js";
7
8
  * every startup. Only Vellum implementation fields (authorizeUrl, tokenExchangeUrl,
8
9
  * refreshUrl, tokenEndpointAuthMethod, userinfoUrl, authorizeParams,
9
10
  * pingUrl, pingMethod, pingHeaders, pingBody, revokeUrl, revokeBodyTemplate,
10
- * managedServiceConfigKey,
11
+ * managedServiceConfigKey, managedServiceIsPaid,
11
12
  * loopbackPort, injectionTemplates, appType, setupNotes,
12
13
  * identityUrl, identityMethod, identityHeaders, identityBody,
13
14
  * identityResponsePaths, identityFormat, identityOkField, featureFlag,
@@ -15,12 +16,10 @@ import { seedProviders } from "./oauth-store.js";
15
16
  * and display metadata (displayLabel,
16
17
  * description, dashboardUrl, clientIdPlaceholder, requiresClientSecret,
17
18
  * logoUrl)
18
- * are overwritten on subsequent startups — user-customizable
19
- * fields (scopePolicy) are only
20
- * written on initial insert and preserved across restarts.
21
- * defaultScopes are also overwritten on subsequent startups so that
22
- * upstream scope additions (e.g. new Gmail API scopes) propagate to
23
- * existing installations.
19
+ * are overwritten on subsequent startups.
20
+ * defaultScopes and availableScopes are also overwritten on subsequent
21
+ * startups so that upstream scope additions (e.g. new Gmail API scopes)
22
+ * propagate to existing installations.
24
23
  */
25
24
  export const PROVIDER_SEED_DATA: Record<
26
25
  string,
@@ -40,14 +39,11 @@ export const PROVIDER_SEED_DATA: Record<
40
39
  revokeBodyTemplate?: Record<string, string>;
41
40
  baseUrl?: string;
42
41
  defaultScopes: string[];
43
- scopePolicy: {
44
- allowAdditionalScopes: boolean;
45
- allowedOptionalScopes: string[];
46
- forbiddenScopes: string[];
47
- };
42
+ availableScopes?: AvailableScopes;
48
43
  scopeSeparator?: string;
49
44
  authorizeParams?: Record<string, string>;
50
45
  managedServiceConfigKey?: string;
46
+ managedServiceIsPaid?: boolean;
51
47
  displayLabel: string;
52
48
  description: string;
53
49
  dashboardUrl: string | null;
@@ -95,14 +91,8 @@ export const PROVIDER_SEED_DATA: Record<
95
91
  "https://www.googleapis.com/auth/userinfo.email",
96
92
  "https://www.googleapis.com/auth/contacts.readonly",
97
93
  ],
98
- scopePolicy: {
99
- allowAdditionalScopes: true,
100
- allowedOptionalScopes: [
101
- "https://www.googleapis.com/auth/drive.readonly",
102
- "https://www.googleapis.com/auth/drive.file",
103
- ],
104
- forbiddenScopes: [],
105
- },
94
+ availableScopes:
95
+ "https://developers.google.com/identity/protocols/oauth2/scopes",
106
96
  authorizeParams: { access_type: "offline", prompt: "consent" },
107
97
  loopbackPort: 17321,
108
98
  managedServiceConfigKey: "google-oauth",
@@ -160,11 +150,7 @@ export const PROVIDER_SEED_DATA: Record<
160
150
  "search:read",
161
151
  "reactions:write",
162
152
  ],
163
- scopePolicy: {
164
- allowAdditionalScopes: false,
165
- allowedOptionalScopes: [],
166
- forbiddenScopes: [],
167
- },
153
+ availableScopes: "https://api.slack.com/scopes",
168
154
  authorizeParams: {
169
155
  user_scope:
170
156
  "channels:read,channels:history,groups:read,groups:history,im:read,im:history,im:write,mpim:read,mpim:history,users:read,chat:write,search:read,reactions:write",
@@ -198,11 +184,6 @@ export const PROVIDER_SEED_DATA: Record<
198
184
  clientIdPlaceholder: null,
199
185
  logoUrl: "https://cdn.simpleicons.org/notion",
200
186
  defaultScopes: [],
201
- scopePolicy: {
202
- allowAdditionalScopes: false,
203
- allowedOptionalScopes: [],
204
- forbiddenScopes: [],
205
- },
206
187
  authorizeParams: { owner: "user" },
207
188
  tokenEndpointAuthMethod: "client_secret_basic",
208
189
  tokenExchangeBodyFormat: "json",
@@ -237,16 +218,16 @@ export const PROVIDER_SEED_DATA: Record<
237
218
  "tweet.read",
238
219
  "tweet.write",
239
220
  "users.read",
221
+ "like.read",
222
+ "bookmark.read",
240
223
  "offline.access",
241
224
  ],
242
- scopePolicy: {
243
- allowAdditionalScopes: false,
244
- allowedOptionalScopes: [],
245
- forbiddenScopes: [],
246
- },
225
+ availableScopes:
226
+ "https://developer.x.com/en/docs/authentication/oauth-2-0/authorization-code",
247
227
  tokenEndpointAuthMethod: "client_secret_basic",
248
228
  loopbackPort: 17335,
249
229
  managedServiceConfigKey: "twitter-oauth",
230
+ managedServiceIsPaid: true,
250
231
  injectionTemplates: [
251
232
  {
252
233
  hostPattern: "api.x.com",
@@ -279,16 +260,8 @@ export const PROVIDER_SEED_DATA: Record<
279
260
  clientIdPlaceholder: null,
280
261
  logoUrl: "https://cdn.simpleicons.org/github",
281
262
  defaultScopes: ["repo", "read:user", "notifications"],
282
- scopePolicy: {
283
- allowAdditionalScopes: true,
284
- allowedOptionalScopes: [
285
- "read:org",
286
- "write:discussion",
287
- "gist",
288
- "project",
289
- ],
290
- forbiddenScopes: ["delete_repo", "admin:org"],
291
- },
263
+ availableScopes:
264
+ "https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps",
292
265
  managedServiceConfigKey: "github-oauth",
293
266
  loopbackPort: 17332,
294
267
  injectionTemplates: [
@@ -320,11 +293,20 @@ export const PROVIDER_SEED_DATA: Record<
320
293
  clientIdPlaceholder: null,
321
294
  logoUrl: "https://cdn.simpleicons.org/linear",
322
295
  defaultScopes: ["read", "write", "issues:create"],
323
- scopePolicy: {
324
- allowAdditionalScopes: false,
325
- allowedOptionalScopes: [],
326
- forbiddenScopes: [],
327
- },
296
+ availableScopes: [
297
+ { scope: "read", description: "Read access for the user's account" },
298
+ { scope: "write", description: "Write access for the user's account" },
299
+ {
300
+ scope: "issues:create",
301
+ description: "Create new issues and attachments",
302
+ },
303
+ { scope: "comments:create", description: "Create new issue comments" },
304
+ {
305
+ scope: "timeSchedule:write",
306
+ description: "Create and modify time schedules",
307
+ },
308
+ { scope: "admin", description: "Full access to admin-level endpoints" },
309
+ ],
328
310
  scopeSeparator: ",",
329
311
  authorizeParams: { prompt: "consent" },
330
312
  loopbackPort: 17324,
@@ -369,11 +351,8 @@ export const PROVIDER_SEED_DATA: Record<
369
351
  "user-library-read",
370
352
  "user-library-modify",
371
353
  ],
372
- scopePolicy: {
373
- allowAdditionalScopes: false,
374
- allowedOptionalScopes: [],
375
- forbiddenScopes: [],
376
- },
354
+ availableScopes:
355
+ "https://developer.spotify.com/documentation/web-api/concepts/scopes",
377
356
  tokenEndpointAuthMethod: "client_secret_basic",
378
357
  loopbackPort: 17333,
379
358
  injectionTemplates: [
@@ -401,11 +380,18 @@ export const PROVIDER_SEED_DATA: Record<
401
380
  clientIdPlaceholder: null,
402
381
  logoUrl: "https://cdn.simpleicons.org/todoist",
403
382
  defaultScopes: ["data:read_write"],
404
- scopePolicy: {
405
- allowAdditionalScopes: false,
406
- allowedOptionalScopes: [],
407
- forbiddenScopes: ["data:delete"],
408
- },
383
+ availableScopes: [
384
+ {
385
+ scope: "data:read",
386
+ description: "Read-only access to tasks and projects",
387
+ },
388
+ {
389
+ scope: "data:read_write",
390
+ description: "Read and write access to tasks and projects",
391
+ },
392
+ { scope: "data:delete", description: "Delete tasks and projects" },
393
+ { scope: "project:delete", description: "Delete entire projects" },
394
+ ],
409
395
  loopbackPort: 17325,
410
396
  injectionTemplates: [
411
397
  {
@@ -440,11 +426,8 @@ export const PROVIDER_SEED_DATA: Record<
440
426
  "guilds.members.read",
441
427
  "messages.read",
442
428
  ],
443
- scopePolicy: {
444
- allowAdditionalScopes: false,
445
- allowedOptionalScopes: ["bot"],
446
- forbiddenScopes: [],
447
- },
429
+ availableScopes:
430
+ "https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes",
448
431
  loopbackPort: 17326,
449
432
  injectionTemplates: [
450
433
  {
@@ -477,11 +460,7 @@ export const PROVIDER_SEED_DATA: Record<
477
460
  "files.content.write",
478
461
  "sharing.read",
479
462
  ],
480
- scopePolicy: {
481
- allowAdditionalScopes: false,
482
- allowedOptionalScopes: [],
483
- forbiddenScopes: [],
484
- },
463
+ availableScopes: "https://developers.dropbox.com/oauth-guide",
485
464
  authorizeParams: { token_access_type: "offline" },
486
465
  loopbackPort: 17327,
487
466
  injectionTemplates: [
@@ -516,11 +495,7 @@ export const PROVIDER_SEED_DATA: Record<
516
495
  clientIdPlaceholder: null,
517
496
  logoUrl: "https://cdn.simpleicons.org/asana",
518
497
  defaultScopes: ["default"],
519
- scopePolicy: {
520
- allowAdditionalScopes: false,
521
- allowedOptionalScopes: [],
522
- forbiddenScopes: [],
523
- },
498
+ availableScopes: "https://developers.asana.com/docs/oauth-scopes",
524
499
  loopbackPort: 17328,
525
500
  injectionTemplates: [
526
501
  {
@@ -551,11 +526,7 @@ export const PROVIDER_SEED_DATA: Record<
551
526
  "data.records:write",
552
527
  "schema.bases:read",
553
528
  ],
554
- scopePolicy: {
555
- allowAdditionalScopes: false,
556
- allowedOptionalScopes: [],
557
- forbiddenScopes: [],
558
- },
529
+ availableScopes: "https://airtable.com/developers/web/api/scopes",
559
530
  tokenEndpointAuthMethod: "client_secret_basic",
560
531
  loopbackPort: 17329,
561
532
  injectionTemplates: [
@@ -589,14 +560,8 @@ export const PROVIDER_SEED_DATA: Record<
589
560
  "crm.objects.deals.write",
590
561
  "crm.objects.companies.read",
591
562
  ],
592
- scopePolicy: {
593
- allowAdditionalScopes: true,
594
- allowedOptionalScopes: [
595
- "crm.objects.companies.write",
596
- "crm.objects.owners.read",
597
- ],
598
- forbiddenScopes: [],
599
- },
563
+ availableScopes:
564
+ "https://developers.hubspot.com/docs/guides/apps/authentication/scopes",
600
565
  loopbackPort: 17330,
601
566
  injectionTemplates: [
602
567
  {
@@ -623,11 +588,7 @@ export const PROVIDER_SEED_DATA: Record<
623
588
  clientIdPlaceholder: null,
624
589
  logoUrl: "https://cdn.simpleicons.org/figma",
625
590
  defaultScopes: ["files:read", "file_comments:write"],
626
- scopePolicy: {
627
- allowAdditionalScopes: false,
628
- allowedOptionalScopes: [],
629
- forbiddenScopes: [],
630
- },
591
+ availableScopes: "https://developers.figma.com/docs/rest-api/scopes/",
631
592
  tokenEndpointAuthMethod: "client_secret_basic",
632
593
  loopbackPort: 17331,
633
594
  injectionTemplates: [
@@ -669,11 +630,8 @@ export const PROVIDER_SEED_DATA: Record<
669
630
  "Calendars.ReadWrite",
670
631
  "MailboxSettings.ReadWrite",
671
632
  ],
672
- scopePolicy: {
673
- allowAdditionalScopes: true,
674
- allowedOptionalScopes: ["Contacts.Read", "Files.Read", "Tasks.ReadWrite"],
675
- forbiddenScopes: [],
676
- },
633
+ availableScopes:
634
+ "https://learn.microsoft.com/en-us/graph/permissions-reference",
677
635
  authorizeParams: { prompt: "consent" },
678
636
  tokenEndpointAuthMethod: "client_secret_post",
679
637
  loopbackPort: 17334,
@@ -707,11 +665,6 @@ export const PROVIDER_SEED_DATA: Record<
707
665
  requiresClientSecret: false,
708
666
  logoUrl: "https://cdn.simpleicons.org/slack",
709
667
  defaultScopes: [],
710
- scopePolicy: {
711
- allowAdditionalScopes: false,
712
- allowedOptionalScopes: [],
713
- forbiddenScopes: [],
714
- },
715
668
  },
716
669
 
717
670
  telegram: {
@@ -726,11 +679,6 @@ export const PROVIDER_SEED_DATA: Record<
726
679
  requiresClientSecret: false,
727
680
  logoUrl: "https://cdn.simpleicons.org/telegram",
728
681
  defaultScopes: [],
729
- scopePolicy: {
730
- allowAdditionalScopes: false,
731
- allowedOptionalScopes: [],
732
- forbiddenScopes: [],
733
- },
734
682
  },
735
683
  };
736
684
 
@@ -27,12 +27,19 @@ const HOP_BY_HOP = new Set([
27
27
  * Optional callback for credential injection or policy gating.
28
28
  * Called before the upstream request is sent. Returns extra headers
29
29
  * to merge, or null to reject the request.
30
+ *
31
+ * `method` and `requestHeaders` are populated for plain-HTTP proxied
32
+ * requests (absolute-URL form). For HTTPS CONNECT tunnels the proxy has
33
+ * not yet terminated TLS and cannot see HTTP-level details, so these are
34
+ * left undefined.
30
35
  */
31
36
  export type PolicyCallback = (
32
37
  hostname: string,
33
38
  port: number | null,
34
39
  path: string,
35
40
  scheme: "http" | "https",
41
+ method?: string,
42
+ requestHeaders?: IncomingMessage["headers"],
36
43
  ) => Promise<Record<string, string> | null>;
37
44
 
38
45
  /**
@@ -141,6 +148,8 @@ export function forwardHttpRequest(
141
148
  parsed.port ? Number(parsed.port) : null,
142
149
  path,
143
150
  "http",
151
+ clientReq.method,
152
+ clientReq.headers,
144
153
  )
145
154
  .then((extraHeaders) => {
146
155
  if (extraHeaders == null) {