@zackbart/connecta 0.34.1 → 0.36.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 (441) hide show
  1. package/CHANGELOG.md +418 -0
  2. package/README.md +65 -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 +2044 -1161
  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 +751 -281
  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 +29 -7
  53. package/dist/connectors/api-connector.js +145 -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/remote-mcp.d.ts +10 -30
  58. package/dist/connectors/remote-mcp.js +955 -563
  59. package/dist/d1.js +10 -243
  60. package/dist/derived-context.js +5 -0
  61. package/dist/describe-config.d.ts +3 -1
  62. package/dist/describe-config.js +2 -0
  63. package/dist/downstream-input.js +347 -260
  64. package/dist/errors.d.ts +87 -6
  65. package/dist/errors.js +114 -4
  66. package/dist/execute.js +87 -50
  67. package/dist/executor-admission.js +3 -0
  68. package/dist/executors/quickjs.js +163 -112
  69. package/dist/guarded-transport.js +50 -0
  70. package/dist/guest-runtime.js +1 -1
  71. package/dist/http/client.js +439 -0
  72. package/dist/http/errors.js +558 -0
  73. package/dist/http/fields.js +49 -0
  74. package/dist/http/hatch-paging.js +318 -0
  75. package/dist/http/hatch.js +1279 -0
  76. package/dist/http/json-schema.js +267 -0
  77. package/dist/http/node-transport.js +241 -0
  78. package/dist/http/oauth.js +162 -0
  79. package/dist/http/paging.js +227 -0
  80. package/dist/http/provider.js +221 -0
  81. package/dist/http/safety.js +82 -0
  82. package/dist/http/services.js +79 -0
  83. package/dist/http/tools.js +379 -0
  84. package/dist/http/vendor-index.js +138 -0
  85. package/dist/http/vendor.js +448 -0
  86. package/dist/http/write-request.js +66 -0
  87. package/dist/http-policy.d.ts +11 -0
  88. package/dist/http-policy.js +45 -0
  89. package/dist/inbound-credential.js +1 -1
  90. package/dist/index.d.ts +2 -2
  91. package/dist/index.js +4 -0
  92. package/dist/invocation-auth.js +30 -19
  93. package/dist/invocation.js +218 -85
  94. package/dist/mcp-result.js +0 -4
  95. package/dist/membership.d.ts +4 -0
  96. package/dist/meta-output.js +1 -1
  97. package/dist/meta-tools.js +531 -406
  98. package/dist/native-recovery.js +52 -0
  99. package/dist/native-tools.js +382 -0
  100. package/dist/node.d.ts +4 -3
  101. package/dist/node.js +45 -8
  102. package/dist/oauth-handoff.js +177 -104
  103. package/dist/oauth-partition.js +6 -20
  104. package/dist/oauth-sealing.js +6 -7
  105. package/dist/operation-vocabulary.js +101 -0
  106. package/dist/operator-record.d.ts +2 -2
  107. package/dist/operator-record.js +17 -4
  108. package/dist/operator-ui/contract.d.ts +8 -3
  109. package/dist/operator-ui/generated.js +4 -4
  110. package/dist/operator-ui/model.d.ts +2 -3
  111. package/dist/program-writes.js +47 -26
  112. package/dist/provider-call-facts.d.ts +115 -0
  113. package/dist/provider-call-facts.js +182 -0
  114. package/dist/provider-call.d.ts +112 -0
  115. package/dist/provider-call.js +271 -0
  116. package/dist/provider.d.ts +65 -31
  117. package/dist/provider.js +116 -39
  118. package/dist/providers/_shared/google/hatch.js +91 -0
  119. package/dist/providers/_shared/google/kit.js +427 -0
  120. package/dist/providers/_shared/google/result-size.js +15 -2
  121. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  122. package/dist/providers/_shared/google/service-account.js +8 -4
  123. package/dist/providers/_shared/google/workspace.d.ts +6 -210
  124. package/dist/providers/_shared/google/workspace.js +6 -425
  125. package/dist/providers/_shared/rest/compact-index.js +86 -0
  126. package/dist/providers/_shared/rest/kit.js +146 -0
  127. package/dist/providers/_shared/rest/operation-index.js +230 -14
  128. package/dist/providers/_shared/rest/response-media.js +11 -0
  129. package/dist/providers/_shared/rest/value-safety.js +353 -195
  130. package/dist/providers/_shared/sensitive-fields.js +27 -0
  131. package/dist/providers/breeze/api.js +584 -0
  132. package/dist/providers/breeze/index.d.ts +1 -3
  133. package/dist/providers/breeze/index.js +67 -1420
  134. package/dist/providers/breeze/openapi.generated.js +60 -0
  135. package/dist/providers/breeze/skill.generated.js +2 -6
  136. package/dist/providers/breeze/tools.js +696 -0
  137. package/dist/providers/ccb/api.js +496 -0
  138. package/dist/providers/ccb/index.d.ts +15 -37
  139. package/dist/providers/ccb/index.js +77 -1702
  140. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  141. package/dist/providers/ccb/lib/constants.js +74 -0
  142. package/dist/providers/ccb/lib/guide.js +9 -0
  143. package/dist/providers/ccb/lib/verdicts.js +387 -0
  144. package/dist/providers/ccb/openapi.generated.js +397 -0
  145. package/dist/providers/ccb/safety.js +295 -0
  146. package/dist/providers/ccb/skill.generated.js +2 -6
  147. package/dist/providers/ccb/tools.js +853 -0
  148. package/dist/providers/cloudflare/api.js +1066 -0
  149. package/dist/providers/cloudflare/index.d.ts +5 -22
  150. package/dist/providers/cloudflare/index.js +79 -197
  151. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  152. package/dist/providers/cloudflare/lib/config.js +2 -0
  153. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  154. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  155. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  156. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  157. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  158. package/dist/providers/cloudflare/openapi.generated.js +4 -3
  159. package/dist/providers/cloudflare/{value-safety.js → safety.js} +487 -0
  160. package/dist/providers/cloudflare/skill.generated.js +2 -10
  161. package/dist/providers/cloudflare/tools.js +360 -0
  162. package/dist/providers/docs/api.js +51 -0
  163. package/dist/providers/docs/index.d.ts +1 -12
  164. package/dist/providers/docs/index.js +53 -1165
  165. package/dist/providers/docs/lib/constants.d.ts +18 -0
  166. package/dist/providers/docs/lib/constants.js +18 -0
  167. package/dist/providers/docs/lib/discovery.js +26 -0
  168. package/dist/providers/docs/lib/requests.js +48 -0
  169. package/dist/providers/docs/lib/schemas.js +168 -0
  170. package/dist/providers/docs/openapi.generated.js +16 -0
  171. package/dist/providers/docs/safety.js +54 -0
  172. package/dist/providers/docs/skill.generated.js +2 -6
  173. package/dist/providers/docs/tools.js +801 -0
  174. package/dist/providers/drive/api.js +177 -0
  175. package/dist/providers/drive/index.d.ts +1 -12
  176. package/dist/providers/drive/index.js +38 -1448
  177. package/dist/providers/drive/lib/constants.d.ts +6 -0
  178. package/dist/providers/drive/lib/constants.js +6 -0
  179. package/dist/providers/drive/lib/contracts.js +532 -0
  180. package/dist/providers/drive/lib/hatch.js +197 -0
  181. package/dist/providers/drive/openapi.generated.js +77 -0
  182. package/dist/providers/drive/safety.js +90 -0
  183. package/dist/providers/drive/skill.generated.js +2 -6
  184. package/dist/providers/drive/tools.js +1290 -0
  185. package/dist/providers/forms/api.js +71 -0
  186. package/dist/providers/forms/index.d.ts +1 -12
  187. package/dist/providers/forms/index.js +49 -1145
  188. package/dist/providers/forms/lib/constants.d.ts +14 -0
  189. package/dist/providers/forms/lib/constants.js +19 -0
  190. package/dist/providers/forms/lib/hatch.js +72 -0
  191. package/dist/providers/forms/openapi.generated.js +23 -0
  192. package/dist/providers/forms/safety.js +34 -0
  193. package/dist/providers/forms/skill.generated.js +2 -8
  194. package/dist/providers/forms/tools.js +1023 -0
  195. package/dist/providers/github/api.js +150 -0
  196. package/dist/providers/github/index.d.ts +4 -5
  197. package/dist/providers/github/index.js +30 -87
  198. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  199. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  200. package/dist/providers/github/lib/discovery.js +132 -0
  201. package/dist/providers/github/lib/operations.js +58 -0
  202. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  203. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  204. package/dist/providers/github/openapi.generated.js +1216 -0
  205. package/dist/providers/github/safety.js +216 -0
  206. package/dist/providers/github/skill.generated.js +2 -5
  207. package/dist/providers/github/tools.js +506 -0
  208. package/dist/providers/gmail/api.js +114 -0
  209. package/dist/providers/gmail/index.d.ts +1 -12
  210. package/dist/providers/gmail/index.js +73 -1621
  211. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  212. package/dist/providers/gmail/lib/constants.js +16 -0
  213. package/dist/providers/gmail/lib/index.js +173 -0
  214. package/dist/providers/gmail/lib/schemas.js +176 -0
  215. package/dist/providers/gmail/lib/threading.js +120 -0
  216. package/dist/providers/gmail/openapi.generated.js +92 -0
  217. package/dist/providers/gmail/safety.js +21 -0
  218. package/dist/providers/gmail/skill.generated.js +2 -6
  219. package/dist/providers/gmail/tools.js +1435 -0
  220. package/dist/providers/overflow/api.js +1008 -0
  221. package/dist/providers/overflow/index.d.ts +1 -17
  222. package/dist/providers/overflow/index.js +60 -1488
  223. package/dist/providers/overflow/skill.generated.js +2 -5
  224. package/dist/providers/overflow/tools.js +873 -0
  225. package/dist/providers/planning-center/api.js +467 -0
  226. package/dist/providers/planning-center/index.d.ts +4 -35
  227. package/dist/providers/planning-center/index.js +69 -2445
  228. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  229. package/dist/providers/planning-center/lib/constants.js +83 -0
  230. package/dist/providers/planning-center/lib/discovery.js +40 -0
  231. package/dist/providers/planning-center/lib/guide.js +39 -0
  232. package/dist/providers/planning-center/lib/json-api.js +83 -0
  233. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  234. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  235. package/dist/providers/planning-center/safety.js +188 -0
  236. package/dist/providers/planning-center/skill.generated.js +2 -27
  237. package/dist/providers/planning-center/tools.js +1010 -0
  238. package/dist/providers/quickbooks/api.js +299 -0
  239. package/dist/providers/quickbooks/index.d.ts +13 -0
  240. package/dist/providers/quickbooks/index.js +93 -0
  241. package/dist/providers/quickbooks/lib/query.js +118 -0
  242. package/dist/providers/quickbooks/lib/writes.js +168 -0
  243. package/dist/providers/quickbooks/safety.js +222 -0
  244. package/dist/providers/quickbooks/skill.generated.js +5 -0
  245. package/dist/providers/quickbooks/tools.js +117 -0
  246. package/dist/providers/sheets/api.js +133 -0
  247. package/dist/providers/sheets/index.d.ts +4 -16
  248. package/dist/providers/sheets/index.js +61 -1172
  249. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  250. package/dist/providers/sheets/lib/constants.js +14 -0
  251. package/dist/providers/sheets/lib/hatch.js +163 -0
  252. package/dist/providers/sheets/lib/requests.js +105 -0
  253. package/dist/providers/sheets/lib/schemas.js +138 -0
  254. package/dist/providers/sheets/openapi.generated.js +30 -0
  255. package/dist/providers/sheets/safety.js +27 -0
  256. package/dist/providers/sheets/skill.generated.js +2 -7
  257. package/dist/providers/sheets/tools.js +733 -0
  258. package/dist/providers/slides/api.js +147 -0
  259. package/dist/providers/slides/index.d.ts +2 -10
  260. package/dist/providers/slides/index.js +48 -2555
  261. package/dist/providers/slides/lib/constants.d.ts +11 -0
  262. package/dist/providers/slides/lib/constants.js +11 -0
  263. package/dist/providers/slides/lib/requests.js +60 -0
  264. package/dist/providers/slides/lib/schemas.js +565 -0
  265. package/dist/providers/slides/openapi.generated.js +18 -0
  266. package/dist/providers/slides/skill.generated.js +2 -6
  267. package/dist/providers/slides/tools.js +1968 -0
  268. package/dist/providers/stripe/api.js +401 -0
  269. package/dist/providers/stripe/index.d.ts +5 -27
  270. package/dist/providers/stripe/index.js +74 -210
  271. package/dist/providers/stripe/lib/config.d.ts +4 -0
  272. package/dist/providers/stripe/lib/config.js +2 -0
  273. package/dist/providers/stripe/openapi.generated.js +4 -3
  274. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  275. package/dist/providers/stripe/skill.generated.js +2 -11
  276. package/dist/providers/stripe/tools.js +77 -0
  277. package/dist/providers/tithely/api.js +531 -0
  278. package/dist/providers/tithely/index.d.ts +17 -0
  279. package/dist/providers/tithely/index.js +86 -965
  280. package/dist/providers/tithely/skill.generated.js +2 -5
  281. package/dist/providers/tithely/tools.js +426 -0
  282. package/dist/providers/vercel/api.js +551 -0
  283. package/dist/providers/vercel/index.d.ts +9 -25
  284. package/dist/providers/vercel/index.js +65 -260
  285. package/dist/providers/vercel/lib/config.d.ts +2 -0
  286. package/dist/providers/vercel/lib/config.js +2 -0
  287. package/dist/providers/vercel/lib/index.js +117 -0
  288. package/dist/providers/vercel/lib/logs.js +100 -0
  289. package/dist/providers/vercel/lib/pin.js +270 -0
  290. package/dist/providers/vercel/openapi.generated.js +10 -5
  291. package/dist/providers/vercel/{value-safety.js → safety.js} +247 -38
  292. package/dist/providers/vercel/skill.generated.js +2 -7
  293. package/dist/providers/vercel/tools.js +642 -0
  294. package/dist/redaction-identity.js +47 -0
  295. package/dist/redaction-marker.js +125 -0
  296. package/dist/registry.d.ts +21 -15
  297. package/dist/registry.js +409 -376
  298. package/dist/routes/access-tokens.js +1 -1
  299. package/dist/routes/actor-labels.js +1 -1
  300. package/dist/routes/connect.js +1 -1
  301. package/dist/routes/dispatch.js +103 -0
  302. package/dist/routes/mcp.js +170 -79
  303. package/dist/routes/oauth.js +6 -1
  304. package/dist/routes/operator.js +2 -2
  305. package/dist/routes/shared.d.ts +5 -4
  306. package/dist/routes/shared.js +244 -177
  307. package/dist/routes/skills.js +10 -8
  308. package/dist/routes/ui-config.js +27 -3
  309. package/dist/routes/ui-data.js +21 -20
  310. package/dist/routes/ui.js +1 -1
  311. package/dist/runtime/call-admission.js +0 -26
  312. package/dist/runtime/call-entry.js +30 -0
  313. package/dist/runtime/call.js +552 -0
  314. package/dist/runtime/connector-scope.js +7 -0
  315. package/dist/runtime/credential-probe.js +34 -0
  316. package/dist/runtime/executor.js +40 -0
  317. package/dist/runtime/native-storage.js +63 -0
  318. package/dist/runtime/registry.js +27 -0
  319. package/dist/runtime/request-scope.js +72 -0
  320. package/dist/runtime/run.js +15 -7
  321. package/dist/runtime/shared-read.js +34 -5
  322. package/dist/runtime/storage.js +34 -21
  323. package/dist/sent-secrets.d.ts +194 -37
  324. package/dist/sent-secrets.js +1743 -340
  325. package/dist/server.js +5 -56
  326. package/dist/skills.js +322 -223
  327. package/dist/sqlite.js +15 -14
  328. package/dist/storage/d1-copy.js +255 -0
  329. package/dist/storage/d1-driver.js +15 -0
  330. package/dist/storage/keys.js +28 -0
  331. package/dist/storage/sql-driver.js +88 -0
  332. package/dist/storage/sql-native.js +544 -0
  333. package/dist/storage/sql-schema.d.ts +6 -0
  334. package/dist/storage/sql-schema.js +15 -0
  335. package/dist/storage/sql.d.ts +14 -20
  336. package/dist/storage/sql.js +29 -535
  337. package/dist/timeout.js +0 -26
  338. package/dist/tool-safety.js +20 -10
  339. package/dist/types.d.ts +9 -109
  340. package/dist/ui.d.ts +1 -1
  341. package/dist/ui.js +0 -1
  342. package/dist/upward.js +3 -0
  343. package/dist/usage-guide.js +3 -1
  344. package/dist/validate.d.ts +4 -2
  345. package/dist/validate.js +86 -9
  346. package/dist/version.d.ts +1 -1
  347. package/dist/version.js +1 -1
  348. package/dist/worker.js +312 -292
  349. package/dist/workspace-subject.js +5 -1
  350. package/dist/write-outcome.js +454 -34
  351. package/documentation/README.md +28 -7
  352. package/documentation/architecture.md +2409 -255
  353. package/documentation/auth.md +867 -114
  354. package/documentation/code-mode.md +49 -16
  355. package/documentation/deploying.md +164 -20
  356. package/documentation/hosted-mcp-migration.md +460 -0
  357. package/documentation/integrating.md +129 -144
  358. package/documentation/meta-tools.md +409 -32
  359. package/documentation/operating.md +27 -3
  360. package/documentation/operator-tests.md +3 -0
  361. package/documentation/operator-ui.md +84 -48
  362. package/documentation/provider-auth-migration.md +16 -63
  363. package/documentation/provider-migration-0.29.md +10 -5
  364. package/documentation/provider-migration-0.35.md +975 -0
  365. package/documentation/providers.md +1347 -0
  366. package/examples/worker/AGENTS.md +23 -9
  367. package/examples/worker/README.md +254 -135
  368. package/examples/worker/alchemy.run.ts +116 -0
  369. package/examples/worker/gitignore +10 -0
  370. package/examples/worker/src/connecta.config.ts +23 -21
  371. package/examples/worker/wrangler.jsonc +14 -5
  372. package/guides/connecting-agents.md +157 -0
  373. package/guides/how-it-works.md +156 -0
  374. package/guides/safety-and-trust.md +153 -0
  375. package/package.json +30 -50
  376. package/templates/node/.env.example +3 -0
  377. package/templates/node/README.md +22 -2
  378. package/templates/node/docker-compose.yml +1 -0
  379. package/templates/node/package.json +3 -2
  380. package/templates/node/src/connecta.config.ts +8 -0
  381. package/dist/catalog-drift.d.ts +0 -138
  382. package/dist/catalog-drift.js +0 -578
  383. package/dist/operator-ui/agents.d.ts +0 -74
  384. package/dist/operator-ui/agents.js +0 -104
  385. package/dist/operator-ui/config-summary.js +0 -565
  386. package/dist/operator-ui/connection-map.js +0 -376
  387. package/dist/operator-ui/endpoints.js +0 -221
  388. package/dist/operator-ui/fix-prompts.d.ts +0 -18
  389. package/dist/operator-ui/fix-prompts.js +0 -87
  390. package/dist/operator-ui/health.js +0 -52
  391. package/dist/operator-ui/member-page.js +0 -97
  392. package/dist/operator-ui/overview.js +0 -123
  393. package/dist/operator-ui/setup-commands.js +0 -51
  394. package/dist/operator-ui/view.d.ts +0 -401
  395. package/dist/operator-ui/view.js +0 -705
  396. package/dist/providers/_shared/request-token.js +0 -83
  397. package/dist/providers/_shared/rest/dispatch.js +0 -41
  398. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  399. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  400. package/dist/providers/_shared/rest/tools.js +0 -569
  401. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  402. package/dist/providers/basecamp/index.d.ts +0 -45
  403. package/dist/providers/basecamp/index.js +0 -997
  404. package/dist/providers/basecamp/skill.generated.js +0 -9
  405. package/dist/providers/cloudflare/rest.d.ts +0 -37
  406. package/dist/providers/cloudflare/rest.js +0 -1097
  407. package/dist/providers/github/hosted.js +0 -218
  408. package/dist/providers/github/rest.js +0 -321
  409. package/dist/providers/infisical/index.d.ts +0 -7
  410. package/dist/providers/infisical/index.js +0 -713
  411. package/dist/providers/infisical/skill.generated.js +0 -8
  412. package/dist/providers/intercom/index.d.ts +0 -24
  413. package/dist/providers/intercom/index.js +0 -121
  414. package/dist/providers/intercom/skill.generated.js +0 -8
  415. package/dist/providers/linear/index.d.ts +0 -55
  416. package/dist/providers/linear/index.js +0 -537
  417. package/dist/providers/linear/skill.generated.js +0 -8
  418. package/dist/providers/mixpanel/index.d.ts +0 -59
  419. package/dist/providers/mixpanel/index.js +0 -472
  420. package/dist/providers/mixpanel/operations.js +0 -20
  421. package/dist/providers/mixpanel/rest.js +0 -603
  422. package/dist/providers/mixpanel/skill.generated.js +0 -10
  423. package/dist/providers/mixpanel/value-safety.js +0 -16
  424. package/dist/providers/notion/index.d.ts +0 -67
  425. package/dist/providers/notion/index.js +0 -368
  426. package/dist/providers/notion/openapi.generated.js +0 -75
  427. package/dist/providers/notion/rest.d.ts +0 -24
  428. package/dist/providers/notion/rest.js +0 -1226
  429. package/dist/providers/notion/skill.generated.js +0 -11
  430. package/dist/providers/notion/value-safety.js +0 -56
  431. package/dist/providers/revenuecat/index.d.ts +0 -51
  432. package/dist/providers/revenuecat/index.js +0 -697
  433. package/dist/providers/revenuecat/skill.generated.js +0 -11
  434. package/dist/providers/stripe/rest.d.ts +0 -14
  435. package/dist/providers/stripe/rest.js +0 -402
  436. package/dist/providers/vercel/rest.d.ts +0 -20
  437. package/dist/providers/vercel/rest.js +0 -1020
  438. package/dist/providers/wispr-flow/index.d.ts +0 -14
  439. package/dist/providers/wispr-flow/index.js +0 -117
  440. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  441. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
package/README.md CHANGED
@@ -2,137 +2,97 @@
2
2
 
3
3
  **One connection between your agent and the services you choose.**
4
4
 
5
- Connecta puts your MCP servers and HTTP APIs behind one endpoint that you run
6
- yourself. Connect your agent once; decide in code who can reach what.
7
-
8
- ## How it works
5
+ Connecta puts the services your agent needs behind one connection. It uses
6
+ **Model Context Protocol (MCP)**, a standard that lets AI apps use tools.
7
+ You run Connecta and choose what each agent may access.
9
8
 
10
9
  ```mermaid
11
10
  flowchart LR
12
- Agent["Your agent"] <-->|"One connection<br/>six small tools"| Connecta
13
-
14
- subgraph Connecta["Your Connecta deployment"]
15
- Sandbox["Sandbox<br/>runs the agent's short programs"]
16
- Keys["Credentials<br/>stay on the server"]
11
+ Agents["Agent apps and people"] --> Pools
12
+ subgraph Connecta["Your Connecta server"]
13
+ Pools["Pools<br/>which tools each caller can use"] --> Checks["Access checks<br/>reads · changes · secrets"]
17
14
  end
18
-
19
- Connecta <--> Work["Linear, GitHub, Notion"]
20
- Connecta <--> Business["Stripe, RevenueCat, Mixpanel"]
21
- Connecta <--> Yours["Any remote MCP server<br/>or HTTP API"]
22
-
23
- style Connecta fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b,stroke-width:2px
15
+ Checks --> Stripe
16
+ Checks --> Google["Google Workspace"]
17
+ Checks --> Other["Other services"]
24
18
  ```
25
19
 
26
- The agent doesn't load every service's tools into the conversation. It writes
27
- a short program that gathers, joins, and trims results inside Connecta, so
28
- only the answer comes back.
20
+ A tool is an action, such as finding a ticket or updating a record. The agent
21
+ can call one action directly or combine several in a short program inside
22
+ Connecta. The program can return a small answer instead of every record.
23
+ Connecta supplies the service credentials, so the agent doesn't need them.
29
24
 
30
25
  ## What you can connect
31
26
 
32
- Maintained connections: <!-- providers:start -->Basecamp, Breeze ChMS, Church Community Builder, Cloudflare, GitHub, Gmail, Google Docs, Google Drive, Google Forms, Google Sheets, Google Slides, Infisical, Intercom, Linear, Mixpanel, Notion, Overflow, Planning Center, RevenueCat, Stripe, Tithe.ly, Vercel, and Wispr Flow<!-- providers:end -->.
33
- Plus any remote MCP server or HTTP API you describe.
27
+ Maintained connections: <!-- providers:start -->Breeze ChMS, Church Community Builder, Cloudflare, GitHub, Gmail, Google Docs, Google Drive, Google Forms, Google Sheets, Google Slides, Overflow, Planning Center, QuickBooks Online, Stripe, Tithe.ly, and Vercel<!-- providers:end -->.
34
28
 
35
- ## Who can use it
29
+ Maintained API providers pair reviewed vendor contracts with tools built by
30
+ Connecta. See the [API sources and tool inventory](./documentation/providers.md#api-sources-and-tool-inventory)
31
+ for each provider's named workflows and reviewed API tools.
36
32
 
37
- | | People | Agents |
38
- | ----------------- | ---------------------------------------------------- | ---------------------------------------- |
39
- | What they are | You and your team | Bots, assistants, CI, scheduled jobs |
40
- | How they prove it | Sign in: Clerk (Node) or Cloudflare Access (Workers) | One token Connecta issues to that agent |
41
- | Their own logins | Yes, on personal connections | No. An agent uses accounts you assign it |
33
+ You can also connect another hosted MCP tool server through `remoteMcp()`,
34
+ which discovers the server's live tool catalog, or describe an API Connecta
35
+ should call.
42
36
 
43
- **Maintainers** are the people who run the deployment: they reach every tool
44
- and manage credentials and agent tokens. Everyone else reaches only the pools
45
- they are listed in.
37
+ ## What it protects
46
38
 
47
- ### Pools
39
+ | Boundary | What Connecta does |
40
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
41
+ | Access | A pool limits the tools its members can reach. |
42
+ | Writes | For tools marked as writes, once a change is sent, Connecta won't automatically send it again. |
43
+ | Secrets | Known secrets are redacted from agent output. Enable the credential vault to encrypt stored credentials and OAuth tokens. |
44
+ | Read-only access | Read-only endpoints hide writes and refuse attempts to call them. |
48
45
 
49
- A **pool** is a named set of tools plus a list of who may use it. Each pool
50
- has its own address, and every caller sees exactly that pool's tools.
46
+ Read-only protection and single-attempt writes depend on truthful tool labels.
47
+ The AI app using Connecta decides when to ask for approval; a writable pool
48
+ can write unattended. [Safety and trust](./guides/safety-and-trust.md)
49
+ explains these boundaries and their limits.
51
50
 
52
- ```mermaid
53
- flowchart LR
54
- Maint["Maintainer<br/>(signs in)"] --> Main["/mcp<br/>every tool"]
55
- Bob["Bob<br/>(signs in)"] --> Team["/mcp/team<br/>CRM + tickets"]
56
- Bot["assistant agent<br/>(token)"] --> AgentPool["/agent/assistant<br/>CRM + tickets"]
51
+ ## Try it in three steps
57
52
 
58
- style Main fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b
59
- style Team fill:#dcfce7,stroke:#15803d,color:#14532d
60
- style AgentPool fill:#fef3c7,stroke:#b45309,color:#78350f
61
- ```
53
+ You'll need somewhere to run Connecta and permission to connect the service
54
+ accounts you choose. Creating the project is the start of setup; account
55
+ connections and access rules still need configuring.
62
56
 
63
- People use a pool at `/mcp/<pool>` and agents at `/agent/<pool>`. A caller
64
- outside a pool gets the same "not found" as a pool that doesn't exist, and
65
- someone in two pools uses two addresses: pools never merge.
57
+ 1. **Create a deployment.** Start with the Node template:
66
58
 
67
- ### One agent, many people
59
+ ```sh
60
+ npx @zackbart/connecta init my-connecta
61
+ cd my-connecta
62
+ npm install
63
+ ```
68
64
 
69
- An assistant that talks to several people keeps **one token and one
70
- connection**. Its harness, not the model, picks the pool each turn: a chat
71
- gets the most capable tier that everyone in it is cleared for, and a
72
- one-on-one gets that person's own pool.
65
+ 2. **Choose services and access.** Your operator—the person or team running
66
+ Connecta—can use a coding assistant as a setup agent. Give that assistant
67
+ the [operator documentation](./documentation/README.md). It configures
68
+ services, enables the credential vault, connects accounts, and starts
69
+ the server with the access rules you choose.
70
+ 3. **Connect your AI app.** This app is the MCP client: it uses Connecta's
71
+ tools on your agent's behalf. Give it the pool address and authentication
72
+ method supplied by your operator. [Connecting agents](./guides/connecting-agents.md)
73
+ explains what to ask for; the [deployment guide](./documentation/deploying.md)
74
+ has runnable steps.
73
75
 
74
76
  ```mermaid
75
77
  flowchart LR
76
- Guests["Chat with anyone unknown"] --> Base["/agent/assistant<br/>read-only basics"]
77
- Group["Chat of team members"] --> TeamTier["/agent/assistant-team<br/>shared tools"]
78
- Leads["Chat of leads only"] --> LeadsTier["/agent/assistant-leads<br/>shared tools + billing"]
79
- Alice["One-on-one<br/>with Alice"] --> PA["/agent/assistant-alice<br/>her tier + her accounts"]
80
-
81
- Base -.-> TeamTier -.-> LeadsTier
82
-
83
- style Base fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b
84
- style TeamTier fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b
85
- style LeadsTier fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b
86
- style PA fill:#dcfce7,stroke:#15803d,color:#14532d
78
+ Create["1 · Create"] --> Configure["2 · Choose services + access"] --> Connect["3 · Connect your AI app"]
87
79
  ```
88
80
 
89
- Each tier builds on the one below it. A person's own pool builds on the
90
- highest tier they are cleared for and holds only the agent, since anyone else
91
- in it would act as that person. A tier can double as a team's own pool for
92
- the people cleared for it. [Organizing an agent's pools](./documentation/auth.md#organizing-an-agents-pools)
93
- has the full layout.
81
+ The package is `@zackbart/connecta` (`npm install @zackbart/connecta`). Run it
82
+ on Node, in Docker, or on Cloudflare Workers. The
83
+ [deployment guide](./documentation/deploying.md#choose-a-deployment) covers each.
94
84
 
95
- ### Whose account a connection uses
85
+ ## Read a little more
96
86
 
97
- - **Shared** (the default): the deployment's account, connected once by a
98
- maintainer.
99
- - **Personal**: each person's own account. Agents never see these.
100
- - **Google Workspace**: the signed-in person's account; for an agent, the
101
- owner of a person's pool, or one fixed shared account. Without an owner,
102
- mapping connections are absent for agents.
103
-
104
- ## Reads and writes
105
-
106
- Every endpoint is writable or read-only, and you choose explicitly. A
107
- read-only endpoint hides write tools and refuses every write. You can also make
108
- one connection read-only across all endpoints. On a writable
109
- one, your agent's host decides what to approve.
110
-
111
- ## Where it runs
112
-
113
- Node or Docker (Clerk sign-in, SQLite) or Cloudflare Workers (Cloudflare
114
- Access, D1). Both serve the same agent tools. An optional operator UI shows
115
- a connection map, endpoints, connectors, and activity; integrations and access
116
- still change only in deployment code.
117
-
118
- ## Getting started
119
-
120
- Give your agent the [agent documentation](./documentation/README.md) and ask
121
- it to set up Connecta with the integrations you want, where to run it, and who
122
- should have access.
87
+ | Guide | What you'll understand |
88
+ | --------------------------------------------------- | ------------------------------------------------------------------------ |
89
+ | [How it works](./guides/how-it-works.md) | Connectors, pools, people, and how a call reaches a service. |
90
+ | [Connecting agents](./guides/connecting-agents.md) | Agent tokens, Vercel identity, and the optional Eve helper. |
91
+ | [Safety and trust](./guides/safety-and-trust.md) | Uncertain changes, secrets, read-only access, and your responsibilities. |
92
+ | [Operator documentation](./documentation/README.md) | Setup, feature availability, upgrades, and exact contracts. |
123
93
 
124
94
  <a id="existing-client-tokens"></a>
125
95
 
126
- Upgrading? Point your agent at the
127
- [upgrade guidance](./documentation/deploying.md#upgrade-an-existing-deployment).
128
-
129
- ## Status
130
-
131
- Built for its author's deployments first and published openly. Breaking
132
- changes are expected before 1.0. See the [changelog](./CHANGELOG.md) and
133
- [security policy](./SECURITY.md).
134
-
135
- [Principles](https://github.com/zackbart/connecta/blob/main/PRINCIPLES.md) ·
136
- [Decision records](https://github.com/zackbart/connecta/tree/main/decisions) ·
137
- [Planned work](https://github.com/zackbart/connecta/issues) (a plan is not a
138
- shipped feature)
96
+ Upgrading? Follow the [upgrade guide](./documentation/deploying.md#upgrade-an-existing-deployment).
97
+ Breaking changes are expected before 1.0. See the [changelog](./CHANGELOG.md)
98
+ and [security policy](./SECURITY.md).
package/SECURITY.md CHANGED
@@ -17,8 +17,9 @@ findings are reviewed for reachability and recorded when an upstream package has
17
17
  not yet released a compatible fix.
18
18
 
19
19
  The MCP TypeScript SDK 2.x packages and Effect are exact-pinned. Effect is the
20
- runtime core, and its unstable modules can break in a minor release, so its pin
21
- moves in a dedicated upgrade. The split client and server packages no longer
20
+ runtime core, and its `effect/http`, `effect/http-api`, and `effect/sql` area
21
+ modules carry `@stability unstable` within the 4.x LTS line, so its pin moves
22
+ in a dedicated upgrade. The split client and server packages no longer
22
23
  install Hono or `@hono/node-server`, so the temporary root-project override
23
24
  used with SDK 1.x is gone. A dependency bump must pass `pnpm run release:check`
24
25
  and the Node/Workers runtime suites before a pin moves.
package/bin/connecta.mjs CHANGED
@@ -244,32 +244,57 @@ async function doctor() {
244
244
  fetch: doctorFetch,
245
245
  });
246
246
  let negotiatedVersion;
247
+ let native = false;
248
+ let executeCode = true;
247
249
  try {
248
250
  await client.connect(transport);
249
251
  negotiatedVersion = client.getNegotiatedProtocolVersion();
250
252
  const listed = await client.listTools({}, { timeout: DOCTOR_TIMEOUT_MS });
251
253
  const actual = listed.tools.map((tool) => tool.name).sort();
252
- const expected = [...META_TOOL_NAMES].sort();
253
- if (JSON.stringify(actual) !== JSON.stringify(expected)) {
254
+ const surface = listed.tools.find((tool) => tool.name === "skills")?._meta?.["dev.connecta/surface"];
255
+ native = surface?.surface === "native";
256
+ executeCode = !native || surface.executeCode === true;
257
+ if (native && surface.catalogErrors?.length)
258
+ throw new Error(
259
+ `Native catalogs unavailable: ${surface.catalogErrors.join(", ")}. Inspect connector status and authentication.`,
260
+ );
261
+ const expected = native
262
+ ? ["skills", executeCode ? "execute_code" : "read_result"].sort()
263
+ : [...META_TOOL_NAMES].sort();
264
+ if (
265
+ native
266
+ ? expected.some((name) => !actual.includes(name)) ||
267
+ [
268
+ "search_tools",
269
+ "call_tool",
270
+ "call_destructive_tool",
271
+ "authorize_connector",
272
+ executeCode ? "read_result" : "execute_code",
273
+ ].some((name) => actual.includes(name))
274
+ : JSON.stringify(actual) !== JSON.stringify(expected)
275
+ ) {
254
276
  throw new Error(
255
277
  `Unexpected MCP surface. Expected ${expected.join(", ")}; received ` +
256
278
  `${Array.isArray(actual) ? actual.join(", ") : "no tool list"}.`,
257
279
  );
258
280
  }
259
281
 
260
- const executed = await client.callTool(
261
- {
262
- name: "execute_code",
263
- arguments: { code: "async () => 42" },
264
- },
265
- undefined,
266
- { timeout: DOCTOR_TIMEOUT_MS },
267
- );
268
- const executionResult = executed.structuredContent ?? JSON.parse(executed.content?.[0]?.text ?? "null");
269
- if (executed.isError || executionResult?.result !== 42) {
270
- throw new Error(
271
- `${executorName ? `${executorName} execution` : "execute_code"} check ` + `failed: ${JSON.stringify(executed)}`,
282
+ if (executeCode) {
283
+ const executed = await client.callTool(
284
+ {
285
+ name: "execute_code",
286
+ arguments: { code: "async () => 42" },
287
+ },
288
+ undefined,
289
+ { timeout: DOCTOR_TIMEOUT_MS },
272
290
  );
291
+ const executionResult = executed.structuredContent ?? JSON.parse(executed.content?.[0]?.text ?? "null");
292
+ if (executed.isError || executionResult?.result !== 42) {
293
+ throw new Error(
294
+ `${executorName ? `${executorName} execution` : "execute_code"} check ` +
295
+ `failed: ${JSON.stringify(executed)}`,
296
+ );
297
+ }
273
298
  }
274
299
  } finally {
275
300
  await client.close();
@@ -277,8 +302,8 @@ async function doctor() {
277
302
 
278
303
  console.log(
279
304
  `Connecta doctor passed: ${health.connectors} connector(s), ` +
280
- `${executorName ? `${executorName} executed` : "code executed"}, ` +
281
- `prescribed ${META_TOOL_NAMES.length}-tool surface, MCP ${negotiatedVersion}, package ${CONNECTA_VERSION}.`,
305
+ `${executeCode ? (executorName ? `${executorName} executed` : "code executed") : "code disabled"}, ` +
306
+ `${native ? "native tool surface" : `prescribed ${META_TOOL_NAMES.length}-tool surface`}, MCP ${negotiatedVersion}, package ${CONNECTA_VERSION}.`,
282
307
  );
283
308
  }
284
309
 
package/bin/version.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  // Generated from package.json by scripts/generate-version.mjs.
2
2
  // Workers-safe: no runtime filesystem read or deployment override.
3
- export const CONNECTA_VERSION = "0.34.1";
3
+ export const CONNECTA_VERSION = "0.36.0";
@@ -1,5 +1,6 @@
1
1
  import type { InboundAuth, KVStorage } from "./types.js";
2
2
  import type { AccessTokensModule } from "./module-contracts.js";
3
+ import { type AgentConfig } from "./agent-config.js";
3
4
  /**
4
5
  * One declared agent's token slot as management sees it. Never secret
5
6
  * material. `revision` is opaque: it changes on every commit to the slot and
@@ -69,7 +70,7 @@ export declare class AccessTokenManager {
69
70
  private readonly agents;
70
71
  private readonly agentOrder;
71
72
  constructor(storage: KVStorage, options?: {
72
- agents?: readonly string[];
73
+ agents?: readonly AgentConfig[];
73
74
  });
74
75
  private declared;
75
76
  private read;
@@ -1,9 +1,14 @@
1
+ import { withAuthenticationDeadline } from "./auth-admission.js";
1
2
  import { authorizationCredential, isMachineCredential } from "./inbound-credential.js";
2
- import { assertKnownOptions, ConfigError, optionsOf } from "./config-schema.js";
3
+ import { assertKnownOptions, ConfigError, optionsOf, readPlain } from "./config-schema.js";
3
4
  import { routeAccessTokens } from "./routes/access-tokens.js";
4
5
  import { validIdentityReference } from "./identity.js";
5
6
  import { accessTokenKeys } from "./storage/keys.js";
6
- import { AGENT_NAMESPACE, agentSubjectId, assertAgentNames, isAgentName, trustAgentProvider, } from "./agent-identity.js";
7
+ import { AGENT_NAMESPACE, agentSubjectId, isAgentName, trustAgentProvider } from "./agent-identity.js";
8
+ import { keepErrorName } from "./redaction-identity.js";
9
+ import { agentConfig } from "./agent-config.js";
10
+ import { authCall, authCatch, authFlow, authInvoke, authMethod, authOwnMethod, authStorage, registerAuthMethod, } from "./auth/native.js";
11
+ import { runEdge } from "./runtime/run.js";
7
12
  const TOKEN_PREFIX = "cta_";
8
13
  const TOKEN_BYTES = 32;
9
14
  const TOKEN_VALUE_RE = /^cta_[A-Za-z0-9_-]{43}$/;
@@ -31,6 +36,7 @@ export class AccessTokenError extends Error {
31
36
  this.code = code;
32
37
  }
33
38
  }
39
+ keepErrorName(AccessTokenError, "AccessTokenError");
34
40
  /** What each operation tells its caller when its outcome cannot be settled. */
35
41
  const UNKNOWN = {
36
42
  rotate: "Rotation outcome unknown: no secret was returned, so rotate again for a replacement",
@@ -251,8 +257,10 @@ export class AccessTokenManager {
251
257
  throw new Error("accessTokens requires storage that implements list and compareAndSet " +
252
258
  "(d1Storage, sqliteStorage, or memoryStorage)");
253
259
  }
254
- const agents = options.agents ?? [];
255
- assertAgentNames(agents, "agents");
260
+ const input = readPlain(options.agents ?? [], "agents", agentConfig);
261
+ if (input.unknown.length)
262
+ throw new ConfigError("agents contains unknown declaration options.");
263
+ const agents = agentConfig.parse(input.value, "agents").map((agent) => agent.name);
256
264
  this.agentOrder = Object.freeze([...agents]);
257
265
  this.agents = new Set(agents);
258
266
  this.auth = trustAgentProvider({
@@ -270,7 +278,7 @@ export class AccessTokenManager {
270
278
  return undefined;
271
279
  }
272
280
  },
273
- authorize: (request) => this.authorize(request).catch(() => unauthorized()),
281
+ authorize: authMethod((request) => authCatch(authInvoke(this, "authorize", [request]), unauthorized)),
274
282
  });
275
283
  }
276
284
  declared(name) {
@@ -779,31 +787,59 @@ export class AccessTokenManager {
779
787
  .sort((a, b) => a.createdAt.localeCompare(b.createdAt))
780
788
  .map(({ id, name, createdAt }) => ({ id, name, createdAt }));
781
789
  }
782
- async authorize(request) {
783
- const credential = authorizationCredential(request);
784
- const token = credential.kind === "bearer" ? credential.token : undefined;
785
- if (!token || !TOKEN_VALUE_RE.test(token))
786
- return unauthorized();
787
- const hash = await hashToken(token);
788
- const lookupRaw = await this.storage.get(lookupKey(hash));
789
- if (!lookupRaw)
790
- return unauthorized();
791
- const lookup = parseLookup(lookupRaw);
792
- if (!lookup)
793
- return unauthorized();
794
- const record = await this.read(lookup.id);
795
- if (!record || record.revokedAt || record.tokenHash !== hash || record.tokenPrefix !== token.slice(0, 12)) {
796
- return unauthorized();
797
- }
798
- // The slot is the authority: a surviving lookup or record it does not
799
- // name is inert. Human-bound and unbound records, and agents no longer in
800
- // code, refuse exactly as an unknown token does.
801
- if (record.principal || record.agent === undefined || !this.agents.has(record.agent))
802
- return unauthorized();
803
- const { slot } = await this.readSlot(record.agent);
804
- if (slot?.state !== "issued" || slot.tokenId !== record.id)
805
- return unauthorized();
806
- return { ok: true, subjectId: agentSubjectId(record.agent), agent: record.agent };
790
+ authorize(request) {
791
+ return runEdge(authOwnMethod(AccessTokenManager.prototype, this, "authorize", [request]));
792
+ }
793
+ static {
794
+ registerAuthMethod(AccessTokenManager.prototype, "authorize", function (request) {
795
+ return authFlow(function* () {
796
+ const credential = authorizationCredential(request);
797
+ const token = credential.kind === "bearer" ? credential.token : undefined;
798
+ if (!token || !TOKEN_VALUE_RE.test(token))
799
+ return unauthorized();
800
+ return (yield authCall(withAuthenticationDeadline, [
801
+ request,
802
+ authMethod((signal) => {
803
+ return authFlow(function* () {
804
+ signal.throwIfAborted();
805
+ const hash = (yield authCall(hashToken, [token]));
806
+ signal.throwIfAborted();
807
+ const lookupRaw = (yield authStorage(this.storage, "get", [lookupKey(hash)]));
808
+ signal.throwIfAborted();
809
+ if (!lookupRaw)
810
+ return unauthorized();
811
+ const lookup = parseLookup(lookupRaw);
812
+ if (!lookup)
813
+ return unauthorized();
814
+ const recordRaw = ID_RE.test(lookup.id)
815
+ ? (yield authStorage(this.storage, "get", [recordKey(lookup.id)]))
816
+ : null;
817
+ const record = recordRaw ? parseRecord(recordRaw) : null;
818
+ if (record && record.id !== lookup.id)
819
+ throw new Error("Stored access token id mismatch");
820
+ signal.throwIfAborted();
821
+ if (!record ||
822
+ record.revokedAt ||
823
+ record.tokenHash !== hash ||
824
+ record.tokenPrefix !== token.slice(0, 12)) {
825
+ return unauthorized();
826
+ }
827
+ // The slot is the authority: a surviving lookup or record it does not
828
+ // name is inert. Human-bound and unbound records, and agents no longer in
829
+ // code, refuse exactly as an unknown token does.
830
+ if (record.principal || record.agent === undefined || !this.agents.has(record.agent))
831
+ return unauthorized();
832
+ const slotRaw = (yield authStorage(this.storage, "get", [slotKey(record.agent)]));
833
+ const slot = slotRaw === null ? null : parseSlot(slotRaw, record.agent);
834
+ signal.throwIfAborted();
835
+ if (slot?.state !== "issued" || slot.tokenId !== record.id)
836
+ return unauthorized();
837
+ return { ok: true, subjectId: agentSubjectId(record.agent), agent: record.agent };
838
+ }.bind(this));
839
+ }),
840
+ ]));
841
+ }.bind(this));
842
+ }, AccessTokenManager.prototype.authorize);
807
843
  }
808
844
  }
809
845
  const ACCESS_TOKENS_OPTIONS = optionsOf()({});
@@ -5,7 +5,7 @@ import type { Logger } from "./types.js";
5
5
  export declare function activityClientFact(value: unknown, field: "name" | "version"): string | undefined;
6
6
  /** Stored package versions use a bounded release-version grammar, including prereleases. */
7
7
  export declare function activityPackageVersion(value: unknown): string | undefined;
8
- export type ActivityCallSource = "catalog_refresh" | "call_tool" | "call_destructive_tool" | "batch_call" | "execute_code" | "resume_execution";
8
+ export type ActivityCallSource = "catalog_refresh" | "native" | "call_tool" | "call_destructive_tool" | "batch_call" | "execute_code" | "resume_execution";
9
9
  export type ActivityOutcome = "success" | "error" | "timeout" | "cancelled" | "paused" | "approved";
10
10
  /** Read-only history: how much one `resume_execution` approved (#672). */
11
11
  export type ActivityApproval = "call" | "tool";
package/dist/activity.js CHANGED
@@ -3,6 +3,7 @@ import { assertKnownOptions, keys, optionsOf } from "./config-schema.js";
3
3
  import { routeActivity } from "./routes/activity.js";
4
4
  import { boundedEchoText, classificationCode } from "./errors.js";
5
5
  import { failureRecord, logFailure } from "./operator-record.js";
6
+ import { keepErrorName } from "./redaction-identity.js";
6
7
  /**
7
8
  * How long an identity field may be before the store stops believing it.
8
9
  *
@@ -91,6 +92,7 @@ export class InvalidActivityCursorError extends Error {
91
92
  super("invalid activity cursor");
92
93
  }
93
94
  }
95
+ keepErrorName(InvalidActivityCursorError, "InvalidActivityCursorError");
94
96
  /**
95
97
  * Best-effort by design: activity storage can never change a tool result.
96
98
  * Workers attach async sinks to waitUntil; synchronous sinks such as Analytics
@@ -0,0 +1,23 @@
1
+ import { type Field } from "./config-schema.js";
2
+ type VercelEnvironment = "production" | "preview" | "development";
3
+ /** Vercel workload binding: immutable team_ ID; prefer a prj_ project ID. */
4
+ interface VercelAgentCredential {
5
+ team: string;
6
+ project: string;
7
+ environments?: readonly VercelEnvironment[] | undefined;
8
+ }
9
+ /** A string keeps the existing token-only declaration. */
10
+ export type AgentConfig = string | {
11
+ name: string;
12
+ vercel: VercelAgentCredential;
13
+ };
14
+ export interface ResolvedAgent {
15
+ readonly name: string;
16
+ readonly vercel?: {
17
+ readonly team: string;
18
+ readonly project: string;
19
+ readonly environments: readonly VercelEnvironment[];
20
+ };
21
+ }
22
+ export declare const agentConfig: Field<readonly AgentConfig[], readonly ResolvedAgent[], true>;
23
+ export {};
@@ -0,0 +1,59 @@
1
+ import { assertAgentNames } from "./agent-identity.js";
2
+ import { array, ConfigError, object, opaque, required, text } from "./config-schema.js";
3
+ const segment = (kind) => required(opaque({
4
+ check(value, path) {
5
+ const pattern = kind === "team" ? /^team_[A-Za-z0-9]+(?![\s\S])/ : /^[A-Za-z0-9._-]+(?![\s\S])/;
6
+ if (typeof value !== "string" || value.length > 128 || !pattern.test(value)) {
7
+ throw new ConfigError(`${path} must be ${kind === "team" ? "an immutable Vercel team_ ID" : "an exact Vercel project ID or name"}.`);
8
+ }
9
+ },
10
+ }));
11
+ const environments = opaque({
12
+ check(value, path) {
13
+ if (!Array.isArray(value) ||
14
+ value.length === 0 ||
15
+ value.some((env) => !["production", "preview", "development"].includes(env)) ||
16
+ new Set(value).size !== value.length) {
17
+ throw new ConfigError(`${path} must list unique production, preview or development environments.`);
18
+ }
19
+ },
20
+ resolve: (value) => Object.freeze([...(value ?? ["production"])]),
21
+ });
22
+ const declaration = object({
23
+ name: required(text()),
24
+ vercel: required(object({ team: segment("team"), project: segment("project"), environments })),
25
+ });
26
+ const entry = {
27
+ ...declaration,
28
+ optional: false,
29
+ parse: (value, path) => (typeof value === "string" ? Object.freeze({ name: value }) : declaration.parse(value, path)),
30
+ absent: (path) => {
31
+ throw new ConfigError(`${path} must declare an agent.`);
32
+ },
33
+ };
34
+ const list = array(entry);
35
+ export const agentConfig = {
36
+ ...list,
37
+ parse(value, path) {
38
+ const agents = list.parse(value, path);
39
+ assertAgentNames(agents.map((agent) => agent.name), path);
40
+ for (let i = 0; i < agents.length; i++) {
41
+ const a = agents[i].vercel;
42
+ if (!a)
43
+ continue;
44
+ for (const prior of agents.slice(0, i)) {
45
+ const b = prior.vercel;
46
+ // A project name and an ID can designate the same project. Refuse possible
47
+ // overlap rather than let declaration order select another identity.
48
+ if (b &&
49
+ a.team === b.team &&
50
+ (a.project === b.project || a.project.startsWith("prj_") !== b.project.startsWith("prj_")) &&
51
+ a.environments.some((env) => b.environments.includes(env))) {
52
+ throw new ConfigError(`${path}[${i}].vercel overlaps another agent's workload binding.`);
53
+ }
54
+ }
55
+ }
56
+ return agents;
57
+ },
58
+ absent: () => Object.freeze([]),
59
+ };
@@ -0,0 +1,16 @@
1
+ const empty = Object.freeze([]);
2
+ const descriptions = new WeakMap();
3
+ export function registerAgentDescriptions(config, agents, tokens) {
4
+ if (descriptions.has(config))
5
+ return;
6
+ descriptions.set(config, Object.freeze(agents.map((agent) => Object.freeze({
7
+ name: agent.name,
8
+ credentialTypes: Object.freeze([
9
+ ...(tokens ? ["access_token"] : []),
10
+ ...(agent.vercel ? ["vercel_oidc"] : []),
11
+ ]),
12
+ }))));
13
+ }
14
+ export function agentDescriptions(config) {
15
+ return descriptions.get(config) ?? empty;
16
+ }
@@ -1,6 +1,6 @@
1
1
  // Code-declared agents (#837): the names deployment code lists in `agents`,
2
- // the identity an admitted agent carries, and the one provider trusted to
3
- // assert it. Pure, so core reads it without reaching the token module.
2
+ // the identity an admitted agent carries, and the built-in providers trusted
3
+ // to assert it. Pure, so core reads it without reaching credential modules.
4
4
  import { ConfigError } from "./config-schema.js";
5
5
  /** Agent names: lowercase letters, digits, `_` and `-`. */
6
6
  const AGENT_NAME_RE = /^[a-z0-9_-]+$/u;
@@ -36,12 +36,12 @@ export function assertAgentNames(value, path) {
36
36
  });
37
37
  }
38
38
  const agentProviders = new WeakSet();
39
- /** Mark the built-in access-token adapter as the one provider whose `agent` is trusted. */
39
+ /** Mark a built-in credential adapter as trusted to assert `agent`. */
40
40
  export function trustAgentProvider(provider) {
41
41
  agentProviders.add(provider);
42
42
  return provider;
43
43
  }
44
- /** Whether `provider` is the built-in access-token adapter. */
44
+ /** Whether `provider` is a trusted built-in agent credential adapter. */
45
45
  export function assertsAgents(provider) {
46
46
  return agentProviders.has(provider);
47
47
  }