@zackbart/connecta 0.34.0 → 0.35.0

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 (428) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +62 -105
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2051 -1160
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +663 -271
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +15 -7
  53. package/dist/connectors/api-connector.js +147 -57
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/option-shapes.js +1 -1
  58. package/dist/connectors/remote-mcp.d.ts +12 -30
  59. package/dist/connectors/remote-mcp.js +960 -564
  60. package/dist/d1.js +10 -243
  61. package/dist/derived-context.js +5 -0
  62. package/dist/describe-config.d.ts +5 -1
  63. package/dist/describe-config.js +3 -0
  64. package/dist/downstream-input.js +347 -260
  65. package/dist/errors.d.ts +87 -6
  66. package/dist/errors.js +114 -4
  67. package/dist/execute.js +87 -50
  68. package/dist/executor-admission.js +3 -0
  69. package/dist/executors/quickjs.js +163 -112
  70. package/dist/guarded-transport.js +50 -0
  71. package/dist/guest-runtime.js +1 -1
  72. package/dist/http/client.js +439 -0
  73. package/dist/http/errors.js +558 -0
  74. package/dist/http/fields.js +49 -0
  75. package/dist/http/hatch-paging.js +318 -0
  76. package/dist/http/hatch.js +1279 -0
  77. package/dist/http/json-schema.js +267 -0
  78. package/dist/http/node-transport.js +241 -0
  79. package/dist/http/oauth.js +162 -0
  80. package/dist/http/paging.js +228 -0
  81. package/dist/http/provider.js +221 -0
  82. package/dist/http/safety.js +82 -0
  83. package/dist/http/services.js +79 -0
  84. package/dist/http/tools.js +383 -0
  85. package/dist/http/vendor-index.js +138 -0
  86. package/dist/http/vendor.js +448 -0
  87. package/dist/http/write-request.js +66 -0
  88. package/dist/http-policy.d.ts +11 -0
  89. package/dist/http-policy.js +45 -0
  90. package/dist/inbound-credential.js +1 -1
  91. package/dist/index.d.ts +2 -2
  92. package/dist/index.js +4 -0
  93. package/dist/invocation-auth.js +30 -19
  94. package/dist/invocation.js +221 -87
  95. package/dist/mcp-result.js +0 -4
  96. package/dist/membership.d.ts +4 -0
  97. package/dist/meta-output.js +1 -1
  98. package/dist/meta-tools.js +534 -408
  99. package/dist/native-recovery.js +52 -0
  100. package/dist/native-tools.js +382 -0
  101. package/dist/node.d.ts +4 -3
  102. package/dist/node.js +45 -8
  103. package/dist/oauth-handoff.js +177 -104
  104. package/dist/oauth-partition.js +6 -20
  105. package/dist/oauth-sealing.js +6 -7
  106. package/dist/operation-vocabulary.js +101 -0
  107. package/dist/operator-record.d.ts +2 -2
  108. package/dist/operator-record.js +17 -4
  109. package/dist/operator-ui/agents.d.ts +5 -4
  110. package/dist/operator-ui/agents.js +17 -7
  111. package/dist/operator-ui/config-summary.js +8 -4
  112. package/dist/operator-ui/connection-map.js +9 -6
  113. package/dist/operator-ui/contract.d.ts +7 -3
  114. package/dist/operator-ui/endpoints.js +5 -14
  115. package/dist/operator-ui/fix-prompts.d.ts +1 -1
  116. package/dist/operator-ui/fix-prompts.js +0 -8
  117. package/dist/operator-ui/generated.js +3 -3
  118. package/dist/operator-ui/health.js +52 -0
  119. package/dist/operator-ui/model.d.ts +2 -3
  120. package/dist/operator-ui/overview.js +11 -19
  121. package/dist/operator-ui/setup-commands.js +0 -4
  122. package/dist/operator-ui/view.d.ts +5 -29
  123. package/dist/operator-ui/view.js +3 -59
  124. package/dist/program-writes.js +47 -26
  125. package/dist/provider-call-facts.d.ts +115 -0
  126. package/dist/provider-call-facts.js +182 -0
  127. package/dist/provider-call.d.ts +112 -0
  128. package/dist/provider-call.js +271 -0
  129. package/dist/provider.d.ts +71 -32
  130. package/dist/provider.js +134 -40
  131. package/dist/providers/_shared/google/hatch.js +91 -0
  132. package/dist/providers/_shared/google/kit.js +537 -0
  133. package/dist/providers/_shared/google/result-size.js +15 -2
  134. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  135. package/dist/providers/_shared/google/service-account.js +8 -4
  136. package/dist/providers/_shared/google/workspace.d.ts +8 -209
  137. package/dist/providers/_shared/google/workspace.js +7 -426
  138. package/dist/providers/_shared/rest/compact-index.js +86 -0
  139. package/dist/providers/_shared/rest/dispatch.js +3 -23
  140. package/dist/providers/_shared/rest/kit.js +546 -0
  141. package/dist/providers/_shared/rest/operation-index.js +230 -14
  142. package/dist/providers/_shared/rest/response-media.js +11 -0
  143. package/dist/providers/_shared/rest/tools.js +101 -78
  144. package/dist/providers/_shared/rest/value-safety.js +353 -195
  145. package/dist/providers/_shared/sensitive-fields.js +27 -0
  146. package/dist/providers/breeze/api.js +584 -0
  147. package/dist/providers/breeze/index.d.ts +3 -3
  148. package/dist/providers/breeze/index.js +67 -1420
  149. package/dist/providers/breeze/openapi.generated.js +60 -0
  150. package/dist/providers/breeze/skill.generated.js +2 -6
  151. package/dist/providers/breeze/tools.js +696 -0
  152. package/dist/providers/ccb/api.js +496 -0
  153. package/dist/providers/ccb/index.d.ts +17 -37
  154. package/dist/providers/ccb/index.js +77 -1702
  155. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  156. package/dist/providers/ccb/lib/constants.js +74 -0
  157. package/dist/providers/ccb/lib/guide.js +9 -0
  158. package/dist/providers/ccb/lib/verdicts.js +387 -0
  159. package/dist/providers/ccb/openapi.generated.js +397 -0
  160. package/dist/providers/ccb/safety.js +295 -0
  161. package/dist/providers/ccb/skill.generated.js +2 -6
  162. package/dist/providers/ccb/tools.js +853 -0
  163. package/dist/providers/cloudflare/api.js +1066 -0
  164. package/dist/providers/cloudflare/index.d.ts +7 -22
  165. package/dist/providers/cloudflare/index.js +80 -194
  166. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  167. package/dist/providers/cloudflare/lib/config.js +2 -0
  168. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  169. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  170. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  171. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  172. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  173. package/dist/providers/cloudflare/openapi.generated.js +3299 -3208
  174. package/dist/providers/cloudflare/{value-safety.js → safety.js} +538 -18
  175. package/dist/providers/cloudflare/skill.generated.js +2 -10
  176. package/dist/providers/cloudflare/tools.js +360 -0
  177. package/dist/providers/docs/api.js +51 -0
  178. package/dist/providers/docs/index.d.ts +1 -12
  179. package/dist/providers/docs/index.js +53 -1165
  180. package/dist/providers/docs/lib/constants.d.ts +18 -0
  181. package/dist/providers/docs/lib/constants.js +18 -0
  182. package/dist/providers/docs/lib/discovery.js +26 -0
  183. package/dist/providers/docs/lib/requests.js +48 -0
  184. package/dist/providers/docs/lib/schemas.js +168 -0
  185. package/dist/providers/docs/openapi.generated.js +16 -0
  186. package/dist/providers/docs/safety.js +54 -0
  187. package/dist/providers/docs/skill.generated.js +2 -6
  188. package/dist/providers/docs/tools.js +802 -0
  189. package/dist/providers/drive/api.js +177 -0
  190. package/dist/providers/drive/index.d.ts +1 -12
  191. package/dist/providers/drive/index.js +38 -1448
  192. package/dist/providers/drive/lib/constants.d.ts +6 -0
  193. package/dist/providers/drive/lib/constants.js +6 -0
  194. package/dist/providers/drive/lib/contracts.js +532 -0
  195. package/dist/providers/drive/lib/hatch.js +197 -0
  196. package/dist/providers/drive/openapi.generated.js +77 -0
  197. package/dist/providers/drive/safety.js +90 -0
  198. package/dist/providers/drive/skill.generated.js +2 -6
  199. package/dist/providers/drive/tools.js +1290 -0
  200. package/dist/providers/forms/api.js +71 -0
  201. package/dist/providers/forms/index.d.ts +1 -12
  202. package/dist/providers/forms/index.js +49 -1145
  203. package/dist/providers/forms/lib/constants.d.ts +14 -0
  204. package/dist/providers/forms/lib/constants.js +19 -0
  205. package/dist/providers/forms/lib/hatch.js +72 -0
  206. package/dist/providers/forms/openapi.generated.js +23 -0
  207. package/dist/providers/forms/safety.js +34 -0
  208. package/dist/providers/forms/skill.generated.js +2 -8
  209. package/dist/providers/forms/tools.js +1024 -0
  210. package/dist/providers/github/api.js +150 -0
  211. package/dist/providers/github/index.d.ts +4 -5
  212. package/dist/providers/github/index.js +30 -87
  213. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  214. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  215. package/dist/providers/github/lib/discovery.js +132 -0
  216. package/dist/providers/github/lib/operations.js +58 -0
  217. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  218. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  219. package/dist/providers/github/openapi.generated.js +1216 -0
  220. package/dist/providers/github/safety.js +216 -0
  221. package/dist/providers/github/skill.generated.js +2 -5
  222. package/dist/providers/github/tools.js +506 -0
  223. package/dist/providers/gmail/api.js +114 -0
  224. package/dist/providers/gmail/index.d.ts +1 -12
  225. package/dist/providers/gmail/index.js +73 -1621
  226. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  227. package/dist/providers/gmail/lib/constants.js +16 -0
  228. package/dist/providers/gmail/lib/index.js +173 -0
  229. package/dist/providers/gmail/lib/schemas.js +176 -0
  230. package/dist/providers/gmail/lib/threading.js +120 -0
  231. package/dist/providers/gmail/openapi.generated.js +92 -0
  232. package/dist/providers/gmail/safety.js +21 -0
  233. package/dist/providers/gmail/skill.generated.js +2 -6
  234. package/dist/providers/gmail/tools.js +1435 -0
  235. package/dist/providers/overflow/api.js +1008 -0
  236. package/dist/providers/overflow/index.d.ts +3 -17
  237. package/dist/providers/overflow/index.js +60 -1488
  238. package/dist/providers/overflow/skill.generated.js +2 -5
  239. package/dist/providers/overflow/tools.js +873 -0
  240. package/dist/providers/planning-center/api.js +467 -0
  241. package/dist/providers/planning-center/index.d.ts +6 -35
  242. package/dist/providers/planning-center/index.js +69 -2445
  243. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  244. package/dist/providers/planning-center/lib/constants.js +83 -0
  245. package/dist/providers/planning-center/lib/discovery.js +40 -0
  246. package/dist/providers/planning-center/lib/guide.js +39 -0
  247. package/dist/providers/planning-center/lib/json-api.js +83 -0
  248. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  249. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  250. package/dist/providers/planning-center/safety.js +188 -0
  251. package/dist/providers/planning-center/skill.generated.js +2 -27
  252. package/dist/providers/planning-center/tools.js +1010 -0
  253. package/dist/providers/sheets/api.js +133 -0
  254. package/dist/providers/sheets/index.d.ts +4 -16
  255. package/dist/providers/sheets/index.js +61 -1172
  256. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  257. package/dist/providers/sheets/lib/constants.js +14 -0
  258. package/dist/providers/sheets/lib/hatch.js +163 -0
  259. package/dist/providers/sheets/lib/requests.js +105 -0
  260. package/dist/providers/sheets/lib/schemas.js +138 -0
  261. package/dist/providers/sheets/openapi.generated.js +30 -0
  262. package/dist/providers/sheets/safety.js +27 -0
  263. package/dist/providers/sheets/skill.generated.js +2 -7
  264. package/dist/providers/sheets/tools.js +734 -0
  265. package/dist/providers/slides/api.js +147 -0
  266. package/dist/providers/slides/index.d.ts +2 -10
  267. package/dist/providers/slides/index.js +48 -2555
  268. package/dist/providers/slides/lib/constants.d.ts +11 -0
  269. package/dist/providers/slides/lib/constants.js +11 -0
  270. package/dist/providers/slides/lib/requests.js +60 -0
  271. package/dist/providers/slides/lib/schemas.js +565 -0
  272. package/dist/providers/slides/openapi.generated.js +18 -0
  273. package/dist/providers/slides/skill.generated.js +2 -6
  274. package/dist/providers/slides/tools.js +1968 -0
  275. package/dist/providers/stripe/api.js +401 -0
  276. package/dist/providers/stripe/index.d.ts +7 -27
  277. package/dist/providers/stripe/index.js +75 -191
  278. package/dist/providers/stripe/lib/config.d.ts +4 -0
  279. package/dist/providers/stripe/lib/config.js +2 -0
  280. package/dist/providers/stripe/openapi.generated.js +4 -3
  281. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  282. package/dist/providers/stripe/skill.generated.js +2 -10
  283. package/dist/providers/stripe/tools.js +77 -0
  284. package/dist/providers/tithely/api.js +531 -0
  285. package/dist/providers/tithely/index.d.ts +19 -0
  286. package/dist/providers/tithely/index.js +86 -965
  287. package/dist/providers/tithely/skill.generated.js +2 -5
  288. package/dist/providers/tithely/tools.js +426 -0
  289. package/dist/providers/vercel/api.js +551 -0
  290. package/dist/providers/vercel/index.d.ts +11 -25
  291. package/dist/providers/vercel/index.js +67 -261
  292. package/dist/providers/vercel/lib/config.d.ts +2 -0
  293. package/dist/providers/vercel/lib/config.js +2 -0
  294. package/dist/providers/vercel/lib/index.js +117 -0
  295. package/dist/providers/vercel/lib/logs.js +100 -0
  296. package/dist/providers/vercel/lib/pin.js +270 -0
  297. package/dist/providers/vercel/openapi.generated.js +398 -376
  298. package/dist/providers/vercel/{value-safety.js → safety.js} +261 -42
  299. package/dist/providers/vercel/skill.generated.js +2 -7
  300. package/dist/providers/vercel/tools.js +642 -0
  301. package/dist/redaction-identity.js +47 -0
  302. package/dist/redaction-marker.js +125 -0
  303. package/dist/registry.d.ts +30 -28
  304. package/dist/registry.js +446 -413
  305. package/dist/routes/access-tokens.js +1 -1
  306. package/dist/routes/actor-labels.js +1 -1
  307. package/dist/routes/connect.js +1 -1
  308. package/dist/routes/dispatch.js +103 -0
  309. package/dist/routes/mcp.js +170 -79
  310. package/dist/routes/oauth.js +3 -1
  311. package/dist/routes/operator.js +2 -2
  312. package/dist/routes/shared.d.ts +5 -4
  313. package/dist/routes/shared.js +244 -177
  314. package/dist/routes/skills.js +10 -8
  315. package/dist/routes/ui-config.js +27 -3
  316. package/dist/routes/ui-data.js +29 -22
  317. package/dist/routes/ui.js +1 -1
  318. package/dist/runtime/call-admission.js +0 -26
  319. package/dist/runtime/call-entry.js +30 -0
  320. package/dist/runtime/call.js +556 -0
  321. package/dist/runtime/connector-scope.js +7 -0
  322. package/dist/runtime/credential-probe.js +34 -0
  323. package/dist/runtime/executor.js +40 -0
  324. package/dist/runtime/native-storage.js +63 -0
  325. package/dist/runtime/registry.js +27 -0
  326. package/dist/runtime/request-scope.js +72 -0
  327. package/dist/runtime/run.js +15 -7
  328. package/dist/runtime/shared-read.js +34 -5
  329. package/dist/runtime/storage.js +34 -21
  330. package/dist/sent-secrets.d.ts +194 -37
  331. package/dist/sent-secrets.js +1743 -340
  332. package/dist/server.js +5 -56
  333. package/dist/skills.js +330 -224
  334. package/dist/sqlite.js +15 -14
  335. package/dist/storage/d1-copy.js +255 -0
  336. package/dist/storage/d1-driver.js +15 -0
  337. package/dist/storage/keys.js +28 -0
  338. package/dist/storage/sql-driver.js +88 -0
  339. package/dist/storage/sql-native.js +544 -0
  340. package/dist/storage/sql-schema.d.ts +6 -0
  341. package/dist/storage/sql-schema.js +15 -0
  342. package/dist/storage/sql.d.ts +14 -20
  343. package/dist/storage/sql.js +29 -535
  344. package/dist/timeout.js +0 -26
  345. package/dist/tool-safety.js +20 -10
  346. package/dist/types.d.ts +11 -99
  347. package/dist/upward.js +3 -0
  348. package/dist/usage-guide.js +3 -1
  349. package/dist/validate.d.ts +4 -2
  350. package/dist/validate.js +86 -9
  351. package/dist/version.d.ts +1 -1
  352. package/dist/version.js +1 -1
  353. package/dist/worker.js +312 -292
  354. package/dist/workspace-subject.js +5 -1
  355. package/dist/write-outcome.js +454 -34
  356. package/documentation/README.md +27 -7
  357. package/documentation/architecture.md +2550 -186
  358. package/documentation/auth.md +821 -98
  359. package/documentation/code-mode.md +56 -21
  360. package/documentation/deploying.md +164 -20
  361. package/documentation/hosted-mcp-migration.md +460 -0
  362. package/documentation/integrating.md +144 -105
  363. package/documentation/meta-tools.md +411 -34
  364. package/documentation/operating.md +28 -4
  365. package/documentation/operator-tests.md +11 -2
  366. package/documentation/operator-ui.md +103 -33
  367. package/documentation/provider-auth-migration.md +38 -63
  368. package/documentation/provider-migration-0.29.md +10 -5
  369. package/documentation/provider-migration-0.35.md +975 -0
  370. package/documentation/providers.md +965 -0
  371. package/examples/worker/AGENTS.md +23 -9
  372. package/examples/worker/README.md +254 -135
  373. package/examples/worker/alchemy.run.ts +116 -0
  374. package/examples/worker/gitignore +10 -0
  375. package/examples/worker/src/connecta.config.ts +23 -21
  376. package/examples/worker/wrangler.jsonc +14 -5
  377. package/guides/connecting-agents.md +157 -0
  378. package/guides/how-it-works.md +156 -0
  379. package/guides/safety-and-trust.md +153 -0
  380. package/package.json +27 -42
  381. package/templates/node/.env.example +3 -0
  382. package/templates/node/README.md +22 -2
  383. package/templates/node/docker-compose.yml +1 -0
  384. package/templates/node/package.json +3 -2
  385. package/templates/node/src/connecta.config.ts +8 -0
  386. package/dist/catalog-drift.d.ts +0 -134
  387. package/dist/catalog-drift.js +0 -493
  388. package/dist/providers/_shared/request-token.js +0 -83
  389. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  390. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  391. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  392. package/dist/providers/basecamp/index.d.ts +0 -43
  393. package/dist/providers/basecamp/index.js +0 -997
  394. package/dist/providers/basecamp/skill.generated.js +0 -9
  395. package/dist/providers/cloudflare/rest.d.ts +0 -37
  396. package/dist/providers/cloudflare/rest.js +0 -1078
  397. package/dist/providers/github/hosted.js +0 -218
  398. package/dist/providers/github/rest.js +0 -321
  399. package/dist/providers/infisical/index.d.ts +0 -7
  400. package/dist/providers/infisical/index.js +0 -713
  401. package/dist/providers/infisical/skill.generated.js +0 -8
  402. package/dist/providers/linear/index.d.ts +0 -55
  403. package/dist/providers/linear/index.js +0 -352
  404. package/dist/providers/linear/skill.generated.js +0 -8
  405. package/dist/providers/mixpanel/index.d.ts +0 -57
  406. package/dist/providers/mixpanel/index.js +0 -468
  407. package/dist/providers/mixpanel/operations.js +0 -20
  408. package/dist/providers/mixpanel/rest.js +0 -603
  409. package/dist/providers/mixpanel/skill.generated.js +0 -10
  410. package/dist/providers/mixpanel/value-safety.js +0 -16
  411. package/dist/providers/notion/index.d.ts +0 -65
  412. package/dist/providers/notion/index.js +0 -368
  413. package/dist/providers/notion/openapi.generated.js +0 -75
  414. package/dist/providers/notion/rest.d.ts +0 -24
  415. package/dist/providers/notion/rest.js +0 -1226
  416. package/dist/providers/notion/skill.generated.js +0 -11
  417. package/dist/providers/notion/value-safety.js +0 -56
  418. package/dist/providers/revenuecat/index.d.ts +0 -49
  419. package/dist/providers/revenuecat/index.js +0 -557
  420. package/dist/providers/revenuecat/skill.generated.js +0 -11
  421. package/dist/providers/stripe/rest.d.ts +0 -14
  422. package/dist/providers/stripe/rest.js +0 -402
  423. package/dist/providers/vercel/rest.d.ts +0 -20
  424. package/dist/providers/vercel/rest.js +0 -1020
  425. package/dist/providers/wispr-flow/index.d.ts +0 -14
  426. package/dist/providers/wispr-flow/index.js +0 -117
  427. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  428. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -0,0 +1,551 @@
1
+ // Vercel's pinned contract, authentication, failures and value-safety boundary.
2
+ import { Effect, Schema } from "effect";
3
+ import { ConnectorCallError } from "../../errors.js";
4
+ import { Refusal, StatusFailure, UnreadableBody } from "../../http/errors.js";
5
+ import { restSafety } from "../../http/safety.js";
6
+ import { Credentials, RequestSecrets } from "../../http/services.js";
7
+ import { get, post, patch } from "../../http/vendor.js";
8
+ import { checked, indexedVendor } from "../_shared/rest/kit.js";
9
+ import { OperationIndex } from "../_shared/rest/operation-index.js";
10
+ import { valueSafety, withholdEmbeddedUrlsIn, refuseWithheldLinks, refuseWithheldBase64, } from "../_shared/rest/value-safety.js";
11
+ import { openapi } from "./openapi.generated.js";
12
+ import { discoveryIndex } from "./lib/index.js";
13
+ import { VERCEL_VALUE_SAFETY } from "./safety.js";
14
+ import { vercelPage as timestampPage } from "../../http/hatch-paging.js";
15
+ import { completeRows } from "./lib/logs.js";
16
+ import { pinAdmission, pinOptions, pinQuery, pinRoute, readPinnedTeam } from "./lib/pin.js";
17
+ export const MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
18
+ export const READ_CAP_MS = 60_000;
19
+ /** POSTs that only read, admitted by `vercel_api_read`. */
20
+ export const READ_POSTS = [
21
+ ["POST", "/v2/observability/query", "Runs an Observability metrics query; Vercel persists nothing."],
22
+ ["POST", "/v1/registrar/domains/availability", "Checks availability for a list of domains; buys nothing."],
23
+ ["POST", "/v1/registrar/domains/price", "Quotes registrar prices for a list of domains; buys nothing."],
24
+ ["POST", "/v1/registrar/domains/search", "Searches domain availability and pricing; buys nothing."],
25
+ ["POST", "/v8/artifacts", "Reads Remote Cache metadata for a list of artifact hashes; uploads nothing."],
26
+ ];
27
+ export function isRecord(value) {
28
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29
+ }
30
+ export function record(value) {
31
+ return isRecord(value) ? value : {};
32
+ }
33
+ export function text(value) {
34
+ return typeof value === "string" && value.trim() !== "" ? value : undefined;
35
+ }
36
+ export function invalid(message) {
37
+ throw new ConnectorCallError("invalid_args", message);
38
+ }
39
+ export function compact(value) {
40
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
41
+ }
42
+ export function truthy(value) {
43
+ return value === true || value === 1 || (typeof value === "string" && /^(?:1|true)$/i.test(value.trim()));
44
+ }
45
+ /**
46
+ * Error codes a secret-family failure may name: Vercel's documented generic
47
+ * codes and its environment-variable conflicts. Anything else is withheld,
48
+ * since a code is vendor text too.
49
+ */
50
+ const REVIEWED_CODES = new Set([
51
+ "bad_request",
52
+ "forbidden",
53
+ "not_found",
54
+ "rate_limited",
55
+ "conflict",
56
+ "unauthorized",
57
+ "invalid_token",
58
+ "internal_server_error",
59
+ "ENV_ALREADY_EXISTS",
60
+ "ENV_CONFLICT",
61
+ "ENV_KEY_RESERVED",
62
+ "ENV_NOT_FOUND",
63
+ "ENV_SIZE_LIMIT_EXCEEDED",
64
+ ]);
65
+ /** A reviewed code, or nothing. */
66
+ export function reviewedCode(value) {
67
+ return typeof value === "string" && REVIEWED_CODES.has(value) ? value : undefined;
68
+ }
69
+ export const vercelErrors = {
70
+ meanings: { unknownId: "not_found", provesAbsence: true, conflicts: [] },
71
+ factVocabulary: { code: [...REVIEWED_CODES], envRejected: [true, false] },
72
+ numericFacts: {
73
+ retryAfterMs: {
74
+ header: "retry-after",
75
+ format: "retry-after",
76
+ review: "HTTP Retry-After delay for failure recovery.",
77
+ },
78
+ resetAfterMs: {
79
+ header: "x-ratelimit-reset",
80
+ format: "epoch-seconds",
81
+ review: "Vercel endpoint rate-limit reset time in epoch seconds.",
82
+ },
83
+ },
84
+ provider: "Vercel",
85
+ facts: (body) => ({
86
+ // Shape-only fact: no variable names, values or vendor prose survive here.
87
+ envRejected: Array.isArray(record(body)["failed"]) &&
88
+ record(body)["failed"].length > 0 &&
89
+ !(Array.isArray(record(body)["created"])
90
+ ? record(body)["created"].length
91
+ : record(body)["created"]),
92
+ code: reviewedCode(record(record(body)["error"])["code"]) ??
93
+ reviewedCode(record(record((Array.isArray(record(body)["failed"]) ? record(body)["failed"] : [])[0])["error"])["code"]),
94
+ }),
95
+ detail: ({ body, status, withheld, facts }) => {
96
+ const root = record(withholdEmbeddedUrlsIn(body));
97
+ const error = record(root["error"]);
98
+ const code = text(error["code"]);
99
+ const message = text(error["message"])?.trim() ?? text(root["message"])?.trim() ?? `Vercel returned HTTP ${status}.`;
100
+ const reviewed = withheld ? facts["code"] : reviewedCode(code);
101
+ const detail = (code ? `Vercel ${code}: ${message}` : message).slice(0, 1_000);
102
+ if (status >= 200 && status <= 299 && facts["envRejected"] === true)
103
+ return `Vercel rejected the environment-variable write${reviewed ? ` (${reviewed})` : ""}; its message is withheld because this operation handles secret values.`;
104
+ return withheld
105
+ ? `Vercel answered HTTP ${status}${reviewed ? ` (${reviewed})` : ""}; its message is withheld because this operation handles secret values.`
106
+ : /[.!?]$/.test(detail)
107
+ ? detail
108
+ : `${detail}.`;
109
+ },
110
+ classify: [
111
+ ({ status, facts, operation }) => status >= 200 &&
112
+ status <= 299 &&
113
+ facts["envRejected"] === true &&
114
+ operation.method === "POST" &&
115
+ canonicalTemplate(operation.template) === "/v10/projects/{idOrName}/env"
116
+ ? {
117
+ code: "invalid_args",
118
+ retryable: false,
119
+ words: (detail) => `${detail}${facts["code"] === "ENV_ALREADY_EXISTS" || facts["code"] === "ENV_CONFLICT"
120
+ ? " Pass upsert: true to replace it, or update it by id with update_project_env_var."
121
+ : ""} Check the target before repeating the write.`,
122
+ }
123
+ : undefined,
124
+ ],
125
+ statuses: {
126
+ 429: ({ numbers, retryAfterMs }) => ({
127
+ code: "rate_limited",
128
+ retryAfterMs: retryAfterMs ?? numbers["resetAfterMs"],
129
+ words: (detail) => `${detail} Vercel meters endpoints separately.`,
130
+ advice: "; wait for the reported reset before retrying this operation",
131
+ }),
132
+ 401: () => ({
133
+ code: "auth_required",
134
+ words: (detail) => `${detail} The configured access token is invalid, expired, outside this team, or lacks the required scope. An operator must replace it or widen its Vercel scope.`,
135
+ }),
136
+ 403: () => ({
137
+ code: "provider_permission_denied",
138
+ words: (detail) => `${detail} Vercel refused access to this team or resource. Ask the team administrator to grant access and an operator to widen the configured token's Vercel scope.`,
139
+ }),
140
+ 404: () => ({
141
+ code: "not_found",
142
+ words: (detail) => `${detail} Confirm the team, project, deployment, domain, or environment-variable id with a list read.`,
143
+ }),
144
+ },
145
+ unreadable: "Vercel returned malformed JSON.",
146
+ };
147
+ class VercelIndex extends OperationIndex {
148
+ search(query, options) {
149
+ // A custom environment is a container, not a variable. Only variable-specific
150
+ // summaries participate in a variable-phrase search; other query words keep
151
+ // the shared partial-match behavior.
152
+ const operations = super.search(query, options);
153
+ const variablePhrase = /\b(?:environment variables?|env vars?)\b/i;
154
+ return variablePhrase.test(query) ? operations.filter((op) => variablePhrase.test(op.summary)) : operations;
155
+ }
156
+ }
157
+ export const vercelIndex = new VercelIndex(discoveryIndex(openapi), { vendor: "vercel", title: "Vercel" });
158
+ export const vercelSafety = valueSafety(VERCEL_VALUE_SAFETY, () => vercelIndex);
159
+ const Query = Schema.Record(Schema.String, Schema.Union([Schema.String, Schema.Array(Schema.String)]));
160
+ const params = (...names) => Schema.Struct(Object.fromEntries(names.map((name) => [name, Schema.String])));
161
+ export const currentUser = get("currentUser", "/v2/user", { success: Schema.Unknown });
162
+ export const teams = get("teams", "/v2/teams", { query: Query, success: Schema.Unknown });
163
+ export const projectEnv = get("projectEnv", "/v10/projects/:idOrName/env", {
164
+ params: params("idOrName"),
165
+ query: Query,
166
+ success: Schema.Unknown,
167
+ });
168
+ export const upsertEnv = post("upsertEnv", "/v10/projects/:idOrName/env", {
169
+ params: params("idOrName"),
170
+ query: Query,
171
+ payload: Schema.Unknown,
172
+ success: Schema.Unknown,
173
+ });
174
+ export const updateEnv = patch("updateEnv", "/v9/projects/:idOrName/env/:id", {
175
+ params: params("idOrName", "id"),
176
+ query: Query,
177
+ payload: Schema.Unknown,
178
+ success: Schema.Unknown,
179
+ });
180
+ export const buildLogs = get("buildLogs", "/v3/deployments/:idOrUrl/events", {
181
+ params: params("idOrUrl"),
182
+ query: Query,
183
+ success: Schema.Unknown,
184
+ });
185
+ export const runtimeLogs = get("runtimeLogs", "/v1/projects/:projectId/deployments/:deploymentId/runtime-logs", {
186
+ params: params("projectId", "deploymentId"),
187
+ query: Query,
188
+ success: Schema.Unknown,
189
+ });
190
+ export const named = [currentUser, teams, projectEnv, upsertEnv, updateEnv, buildLogs, runtimeLogs];
191
+ const canonicalTemplate = (path) => path.replace(/:([^/]+)/g, "{$1}");
192
+ /** Exact operation/media pairs from the pin; named logs also accept bounded equivalents. */
193
+ const LOG_PATHS = [
194
+ "/v3/deployments/{idOrUrl}/events",
195
+ "/v1/projects/{projectId}/deployments/{deploymentId}/runtime-logs",
196
+ ];
197
+ const FRAMED_MEDIA = {
198
+ "GET /v1/billing/charges": ["application/jsonl"],
199
+ "GET /v1/billing/contract-commitments": ["application/jsonl"],
200
+ "GET /v2/sandboxes/sessions/{sessionId}/cmd/{cmdId}/logs": ["application/x-ndjson"],
201
+ "POST /v2/sandboxes/sessions/{sessionId}/cmd": ["application/x-ndjson"],
202
+ "GET /v3/deployments/{idOrUrl}/events": ["application/stream+json"],
203
+ "GET /v1/projects/{projectId}/deployments/{deploymentId}/runtime-logs": ["application/stream+json"],
204
+ };
205
+ export const VercelApi = {
206
+ ...indexedVendor("vercel", vercelIndex, named),
207
+ textBodies: {
208
+ review: "Exact pinned jsonl/ndjson billing and sandbox command operations, plus build/runtime stream+json logs. Bounded named log readers also accept JSON arrays/NDJSON equivalents. JSON-only writes never accept HTML/text (#1000).",
209
+ forResponse: (status, operation, type = "") => {
210
+ const path = canonicalTemplate(operation.template);
211
+ const media = type.split(";", 1)[0].trim().toLowerCase();
212
+ return status >= 200 &&
213
+ status <= 299 &&
214
+ (FRAMED_MEDIA[`${operation.method} ${path}`]?.includes(media) ||
215
+ (operation.method === "GET" &&
216
+ operation.flags?.["log"] &&
217
+ LOG_PATHS.includes(path) &&
218
+ /^(?:application\/(?:json|[^/]+\+json|x-ndjson|jsonl))$/.test(media)))
219
+ ? "text"
220
+ : undefined;
221
+ },
222
+ },
223
+ binaryBodies: {
224
+ review: "Pinned sandbox fs/read alone declares application/octet-stream success. No other operation may acknowledge a JSON write as binary.",
225
+ forResponse: (status, operation, type) => status >= 200 &&
226
+ status <= 299 &&
227
+ canonicalTemplate(operation.template) === "/v2/sandboxes/sessions/{sessionId}/fs/read" &&
228
+ type.split(";", 1)[0].trim().toLowerCase() === "application/octet-stream",
229
+ },
230
+ };
231
+ export const result = (body, answer) => {
232
+ if (answer.operation.method === "HEAD")
233
+ return Effect.succeed(Object.fromEntries([...answer.headers].filter(([name]) => name !== "set-cookie")));
234
+ if (canonicalTemplate(answer.operation.template) === "/v10/projects/{idOrName}/env" &&
235
+ answer.operation.method === "POST") {
236
+ const payload = record(body);
237
+ if (Array.isArray(payload["failed"]) &&
238
+ payload["failed"].length &&
239
+ !(Array.isArray(payload["created"]) ? payload["created"].length : payload["created"]))
240
+ return Effect.fail(new StatusFailure({ status: answer.status, headers: answer.headers, body, operation: answer.operation }));
241
+ const created = Array.isArray(payload["created"]) ? payload["created"][0] : payload["created"];
242
+ const variable = record(created ?? payload);
243
+ if (!variable["id"] || !variable["key"] || !variable["type"])
244
+ return Effect.fail(new UnreadableBody());
245
+ }
246
+ if (answer.operation.flags?.["log"])
247
+ return Effect.succeed(typeof body === "string" ? completeRows(body) : []);
248
+ if (answer.bodyFormat === "text" && typeof body === "string")
249
+ return Effect.succeed(completeRows(body));
250
+ return Effect.succeed(body);
251
+ };
252
+ export const authenticate = Effect.gen(function* () {
253
+ const values = yield* (yield* Credentials).values.pipe(Effect.mapError((error) => new Refusal({ error })));
254
+ const token = typeof values?.value === "string" ? values.value.trim() : undefined;
255
+ if (!token)
256
+ return yield* Effect.fail(new Refusal({
257
+ error: new ConnectorCallError("auth_required", "No Vercel access token is configured for this connector. An operator must add one in this connection in the operator UI."),
258
+ }));
259
+ return { Authorization: `Bearer ${token}` };
260
+ });
261
+ export function safety() {
262
+ return { reviewed: restSafety(vercelSafety, vercelIndex), sensitiveFields: { names: [], choice: "drop" } };
263
+ }
264
+ export function defaultTeam(options) {
265
+ return typeof options.teamId === "string" ? options.teamId.trim() || undefined : undefined;
266
+ }
267
+ /** Query parameter names each operation declares, by index row. */
268
+ const queryNames = new Map();
269
+ function queryNamesOf(operations, op) {
270
+ let names = queryNames.get(op.row);
271
+ if (!names) {
272
+ names = new Set(operations
273
+ .contract(op)
274
+ .parameters.filter((parameter) => parameter.in === "query")
275
+ .map((parameter) => parameter.name));
276
+ queryNames.set(op.row, names);
277
+ }
278
+ return names;
279
+ }
280
+ export const refuse = (call) => {
281
+ if (call.method === "PATCH" &&
282
+ call.op.path === "/v3/domains/{domain}" &&
283
+ String(record(call.body)["op"]).trim().toLowerCase() === "move-out") {
284
+ return "Connecta refuses a domain move-out: Vercel answers it with a transfer token that lets the destination account claim the domain. Move domains in the Vercel dashboard.";
285
+ }
286
+ if (truthy(call.query["decrypt"])) {
287
+ return "Connecta never asks Vercel to decrypt environment values. Use list_project_env_vars for metadata.";
288
+ }
289
+ if (call.op.path === "/v1/projects/{projectId}/deployments/{deploymentId}/runtime-logs") {
290
+ return "Runtime logs are a live stream that never ends on its own. Read them with get_runtime_logs, which stops after waitMs or limit.";
291
+ }
292
+ if (truthy(call.query["follow"])) {
293
+ return "follow streams live events until the connection drops. Omit it (or pass 0); read build events with get_deployment_build_logs.";
294
+ }
295
+ return undefined;
296
+ };
297
+ export function scope(call, teamId, pin) {
298
+ if (pin)
299
+ return { ...call, query: pinQuery(vercelIndex, call, pin) };
300
+ const query = { ...call.query };
301
+ if (query["teamId"] === null) {
302
+ delete query["teamId"];
303
+ return { ...call, query };
304
+ }
305
+ if (teamId &&
306
+ query["teamId"] === undefined &&
307
+ query["slug"] === undefined &&
308
+ queryNamesOf(vercelIndex, call.op).has("teamId"))
309
+ query["teamId"] = teamId;
310
+ return { ...call, query };
311
+ }
312
+ export function restCall(method, path, input = {}, teamId, pin) {
313
+ const { op, params } = vercelIndex.resolve(method, path);
314
+ return scope({ method, path, op, params, query: { ...input.query }, body: input.body }, teamId, pin);
315
+ }
316
+ export function checkServer(server) {
317
+ return server === undefined
318
+ ? undefined
319
+ : `This operation is served from ${server}, which this connector does not reach.`;
320
+ }
321
+ export function admit(call, connection, options) {
322
+ return Effect.tryPromise({
323
+ try: async () => {
324
+ if (call.method === "GET" ||
325
+ call.method === "HEAD" ||
326
+ READ_POSTS.some(([method, path]) => method === call.method && path === call.op.path))
327
+ return;
328
+ refuseWithheldLinks([call.body, call.query, call.path], "Vercel");
329
+ if (call.method === "POST" && call.op.path === "/v13/deployments") {
330
+ const files = record(call.body)["files"];
331
+ if (Array.isArray(files))
332
+ for (const file of files)
333
+ if (record(file)["encoding"] === "base64")
334
+ await refuseWithheldBase64(record(file)["data"], "Vercel");
335
+ }
336
+ },
337
+ catch: (error) => error,
338
+ }).pipe(Effect.tap(() => Effect.gen(function* () {
339
+ if (call.method === "POST" && call.op.path === "/v11/projects") {
340
+ (yield* RequestSecrets).arguments(record(call.body)["environmentVariables"], {
341
+ items: { properties: { value: { writeOnly: true } } },
342
+ });
343
+ }
344
+ if (call.method !== "GET" &&
345
+ call.method !== "HEAD" &&
346
+ (call.op.path === "/v1/env" || /^\/v(?:9|10)\/projects\/\{idOrName\}\/env(?:\/\{id\})?$/.test(call.op.path))) {
347
+ const value = { properties: { value: { writeOnly: true } } };
348
+ const body = call.op.path === "/v1/env"
349
+ ? call.method === "POST"
350
+ ? record(call.body)["evs"]
351
+ : call.method === "PATCH"
352
+ ? Object.values(record(record(call.body)["updates"]))
353
+ : []
354
+ : call.body;
355
+ (yield* RequestSecrets).arguments(body, { ...value, items: value });
356
+ }
357
+ })), Effect.catch((error) => error instanceof ConnectorCallError ? Effect.fail(new Refusal({ error })) : Effect.die(error)), Effect.flatMap(() => pinAdmission(connection, vercelIndex, call, options.pin)));
358
+ }
359
+ export function queryOf(call) {
360
+ const out = {};
361
+ const scalar = (v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean";
362
+ for (const [key, value] of Object.entries(call.query)) {
363
+ if (value === undefined)
364
+ continue;
365
+ if (scalar(value))
366
+ out[key] = String(value);
367
+ else if (Array.isArray(value) && value.every(scalar))
368
+ out[key] = value.map(String);
369
+ else
370
+ invalid(`Vercel query parameter ${key} takes a string, number, boolean, or a list of them.`);
371
+ }
372
+ return out;
373
+ }
374
+ export function queryPairs(call) {
375
+ return Object.entries(queryOf(call)).flatMap(([key, value]) => (Array.isArray(value) ? value : [value]).map((value) => [key, value]));
376
+ }
377
+ export function sendVercel(connection, call, options, sendOptions) {
378
+ return checked(() => {
379
+ const server = checkServer(call.op.server);
380
+ if (server)
381
+ invalid(server);
382
+ return queryOf(call);
383
+ }).pipe(Effect.flatMap((query) => admit(call, connection, options).pipe(Effect.flatMap(() => connection.sendPath({
384
+ method: call.method,
385
+ path: call.path,
386
+ template: call.op.path,
387
+ query: Object.entries(query).flatMap(([key, value]) => (Array.isArray(value) ? value : [value]).map((value) => [key, value])),
388
+ ...(call.body === undefined ? {} : { json: JSON.stringify(call.body) }),
389
+ }, sendOptions)))));
390
+ }
391
+ export const probe = {
392
+ run: (connection, options) => {
393
+ const pin = pinOptions(options).pin;
394
+ return pin
395
+ ? readPinnedTeam(connection, pin)
396
+ : connection.send(currentUser, {}).pipe(Effect.map((answer) => answer.data));
397
+ },
398
+ describe: (data, options) => {
399
+ const pin = pinOptions(options).pin;
400
+ if (pin)
401
+ return `Authenticated for pinned team ${pin.teamId}.`;
402
+ const payload = record(data);
403
+ const user = record(payload["user"] ?? payload);
404
+ const identity = text(user["username"]) ?? text(user["email"]) ?? text(user["name"]) ?? text(user["id"]);
405
+ return `Authenticated as ${identity ?? "a Vercel user"}.`;
406
+ },
407
+ failure: (error) => ({
408
+ ok: false,
409
+ message: error.code === "auth_required"
410
+ ? "Vercel rejected the token: it is invalid, expired, or revoked."
411
+ : error.code === "provider_permission_denied"
412
+ ? "Vercel accepted the token but refused to read the current user; check the token's scope."
413
+ : error.code === "rate_limited" || error.code === "unavailable"
414
+ ? "Vercel could not check the token right now; try again shortly."
415
+ : "Vercel did not accept the token.",
416
+ }),
417
+ };
418
+ export function usageGuide(options) {
419
+ options = pinOptions(options);
420
+ const team = defaultTeam(options);
421
+ return {
422
+ context: [
423
+ `Vercel REST access token is already configured. Account purpose: ${options.purpose}`,
424
+ options.pin
425
+ ? `Deployment team pin: ${options.pin.teamId}. Every call stays within this team; foreign or personal selectors and unprovable global routes are refused. Team/project/deployment checks may spend additional reads. Token permissions still apply.`
426
+ : team
427
+ ? `Routing defaults to team ${team}. This is not a restriction or tenant pin: an explicit teamId or slug overrides it, and teamId: null selects personal scope. The token's Vercel permissions enforce access.`
428
+ : "Routing defaults to the token owner's personal account. Explicit teamId or slug selects a team within the token's permissions.",
429
+ ...(options.readOnly ? ["This connection is read-only."] : []),
430
+ ],
431
+ required: true,
432
+ };
433
+ }
434
+ function operationRefusal(op) {
435
+ return ((op.method === "GET" && op.path === "/v8/artifacts/{hash}"
436
+ ? "Artifact downloads serve binary bytes despite this pin's JSON contract; this connector does not support artifact downloads."
437
+ : undefined) ??
438
+ vercelSafety.refusal(op.method, op.path) ??
439
+ checkServer(op.server) ??
440
+ (/octet-stream|^multipart\//.test(vercelIndex.bodyType(op) ?? "")
441
+ ? "This operation takes explicit bytes; use vercel_api_upload."
442
+ : undefined));
443
+ }
444
+ export const VERCEL_VERDICTS = Object.fromEntries(vercelIndex.ops.map((op) => [
445
+ `${op.method} ${op.path}`,
446
+ operationRefusal(op)
447
+ ? "refuse"
448
+ : op.method === "GET" ||
449
+ op.method === "HEAD" ||
450
+ READ_POSTS.some(([method, path]) => method === op.method && path === op.path)
451
+ ? "read"
452
+ : "destructive",
453
+ ]));
454
+ const PIN_DISCOVERY_REFUSALS = Object.freeze(Object.fromEntries(vercelIndex.ops
455
+ .filter((op) => pinRoute(vercelIndex, op) === "denied")
456
+ .map((op) => [`${op.method} ${op.path}`, "This operation has no reviewed deployment-team confinement."])));
457
+ /** Change only the generated Hatch count, after the shared guide renderer selects deployment blocks. */
458
+ export function transformGuide(guide, options) {
459
+ if (!pinOptions(options).pin)
460
+ return guide;
461
+ const base = Object.values(VERCEL_VERDICTS).filter((verdict) => verdict === "refuse").length;
462
+ const total = vercelIndex.ops.filter((op) => VERCEL_VERDICTS[`${op.method} ${op.path}`] === "refuse" ||
463
+ PIN_DISCOVERY_REFUSALS[`${op.method} ${op.path}`] !== undefined).length;
464
+ const sentence = `${base} operations are refused by design; use \`vercel_api_details\` with the method and path to inspect the original operation summary and its separate refusal.`;
465
+ const lines = guide.content.split("\n");
466
+ const targets = lines.flatMap((line, position) => line.startsWith("- **Hatch:** `vercel_api_search` ") && line.includes(sentence) ? [position] : []);
467
+ const position = targets[0];
468
+ const line = position === undefined ? undefined : lines[position];
469
+ if (targets.length !== 1 || line === undefined || line.indexOf(sentence) !== line.lastIndexOf(sentence))
470
+ throw new Error("Vercel's generated guide needs exactly one Hatch refusal-count sentence.");
471
+ const at = line.indexOf(sentence);
472
+ lines[position] = `${line.slice(0, at)}${total}${line.slice(at + String(base).length)}`;
473
+ return { ...guide, content: lines.join("\n") };
474
+ }
475
+ const cursorInputMessage = "Pass the signed page.nextCursor unchanged; omit it for the first page (numeric until may anchor its time window).";
476
+ const continuation = (next, call) => typeof next === "string" && /^(?:[a-z][a-z0-9+.-]*:\/\/|\/\/)/i.test(next.trim())
477
+ ? { hasMore: true }
478
+ : timestampPage.next({ pagination: { next } }, call);
479
+ /** Only indexed parameters and documented response continuation names opt in. */
480
+ const paginationPage = (param, timestamp = false) => ({
481
+ ...timestampPage,
482
+ param,
483
+ cursorInputMessage,
484
+ ...(timestamp ? { initialAnchor: true } : {}),
485
+ next(data, call) {
486
+ const pagination = record(record(data)["pagination"]);
487
+ if (!Object.keys(pagination).length)
488
+ return undefined;
489
+ if (pagination["hasNext"] === false || pagination["hasMore"] === false)
490
+ return null;
491
+ const next = pagination["next"] ?? pagination["nextCursor"];
492
+ if (next === undefined) {
493
+ if (pagination["hasNext"] === true || pagination["hasMore"] === true)
494
+ throw new ConnectorCallError("connector_call_failed", "Vercel returned invalid paging metadata.", {
495
+ retryable: false,
496
+ });
497
+ return null;
498
+ }
499
+ return continuation(next, call);
500
+ },
501
+ });
502
+ export const VERCEL_PAGES = Object.fromEntries(vercelIndex.ops.flatMap((op) => {
503
+ if (VERCEL_VERDICTS[`${op.method} ${op.path}`] !== "read")
504
+ return [];
505
+ const names = queryNamesOf(vercelIndex, op), fields = vercelIndex
506
+ .fields(op)
507
+ .filter((f) => f.in === "response")
508
+ .map((f) => f.path);
509
+ if (fields.includes("pagination")) {
510
+ if (names.has("until"))
511
+ return [[`${op.method} ${op.path}`, paginationPage("until", true)]];
512
+ if (names.has("next"))
513
+ return [[`${op.method} ${op.path}`, paginationPage("next")]];
514
+ if (names.has("cursor"))
515
+ return [[`${op.method} ${op.path}`, paginationPage("cursor")]];
516
+ }
517
+ for (const key of ["nextCursor", "cursor", "next"])
518
+ if (fields.includes(key) && (names.has(key) || (key === "nextCursor" && names.has("cursor"))))
519
+ return [
520
+ [
521
+ `${op.method} ${op.path}`,
522
+ {
523
+ ...timestampPage,
524
+ param: names.has(key) ? key : "cursor",
525
+ cursorInputMessage,
526
+ next: (data) => {
527
+ const value = record(data)[key];
528
+ return value === null || value === undefined
529
+ ? null
530
+ : continuation(value, { path: "", query: {}, headers: {} });
531
+ },
532
+ },
533
+ ],
534
+ ];
535
+ return [];
536
+ }));
537
+ export function vercelBinding({ connection, options, }) {
538
+ options = pinOptions(options);
539
+ return {
540
+ ...(options.pin ? { cursorScope: Object.freeze({ vercelTeamPin: options.pin.teamId }) } : {}),
541
+ ...(options.pin ? { discoveryRefusal: (op) => PIN_DISCOVERY_REFUSALS[`${op.method} ${op.path}`] } : {}),
542
+ review: "The same teamId/slug/null routing used by named tools and uploads, resolved before request validation and signed cursor binding. Token permissions remain the boundary. JSON framing through the existing connection.",
543
+ query: (call) => scope(call, defaultTeam(options), options.pin).query,
544
+ refusal: (op) => operationRefusal(op) ??
545
+ (options.pin && pinRoute(vercelIndex, op) === "denied"
546
+ ? "This operation has no reviewed deployment-team confinement."
547
+ : undefined),
548
+ refuse: (call) => operationRefusal(call.op) ?? refuse(call),
549
+ send: (call, sendOptions) => sendVercel(connection, call, options, sendOptions),
550
+ };
551
+ }
@@ -1,7 +1,5 @@
1
1
  import type { ConnectorCallAdmissionPolicy } from "../../types.js";
2
- export { VERCEL_API_BASE_URL } from "./rest.js";
3
- /** Vercel's official hosted MCP endpoint. */
4
- export declare const VERCEL_MCP_ENDPOINT = "https://mcp.vercel.com";
2
+ export { VERCEL_API_BASE_URL } from "./lib/config.js";
5
3
  interface VercelCommonOptions {
6
4
  /** Human-readable display name; defaults identify the implementation. */
7
5
  title?: string;
@@ -15,39 +13,27 @@ interface VercelCommonOptions {
15
13
  callAdmission?: ConnectorCallAdmissionPolicy;
16
14
  /** Connector-specific inline result limit; omit to inherit the deployment. */
17
15
  maxResultBytes?: number;
18
- }
19
- /**
20
- * Vercel's hosted MCP server over OAuth. Vercel admits only reviewed and
21
- * approved MCP clients, an operational gate outside Connecta.
22
- */
23
- export interface VercelOAuthOptions extends VercelCommonOptions {
24
- auth: {
25
- type: "oauth";
26
- };
27
- /** Refused: the hosted server scopes by the teams the grant can reach. */
28
- teamId?: never;
29
- /** Refused: the hosted server has one endpoint. */
30
- baseUrl?: never;
16
+ /** Serve only read-classified tools on every endpoint. Defaults to false. */
17
+ readOnly?: boolean;
31
18
  }
32
19
  /**
33
20
  * Connecta's REST connector to `api.vercel.com` with one operator-managed
34
21
  * access token, pasted into the connection in the operator UI.
35
22
  */
23
+ export interface VercelTeamPin {
24
+ readonly teamId: string;
25
+ }
36
26
  export interface VercelTokenOptions extends VercelCommonOptions {
37
27
  auth: {
38
28
  type: "token";
39
29
  };
40
30
  /** Default team id for operations that accept one. Omit for the token owner's personal account. */
41
31
  teamId?: string;
32
+ /** Deployment-owned confinement to one team, independent of routing defaults and token permissions. */
33
+ pin?: VercelTeamPin;
42
34
  /** API base override for a proxy or test double. */
43
35
  baseUrl?: string;
44
36
  }
45
- export type VercelOptions = VercelOAuthOptions | VercelTokenOptions;
46
- /**
47
- * A maintained Vercel connection. `auth` selects the implementation: OAuth
48
- * reaches Vercel's hosted MCP server; an access token reaches Connecta's REST
49
- * connector to `api.vercel.com`.
50
- */
51
- export declare const vercel: import("../../provider.js").ProviderFactory<VercelOptions>;
52
- /** @deprecated Read `vercel.definition.classify` instead. Kept for existing imports. */
53
- export declare const VERCEL_MCP_VETTED_CATALOG: import("../../catalog-drift.js").VettedCatalog;
37
+ export type VercelOptions = VercelTokenOptions;
38
+ /** Maintained API connection. Hosted MCP uses a separate generic connection. */
39
+ export declare const vercel: import("../../provider.js").ProviderFactory<VercelTokenOptions>;