@zackbart/connecta 0.34.1 → 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 (429) hide show
  1. package/CHANGELOG.md +363 -0
  2. package/README.md +62 -106
  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 +12 -7
  53. package/dist/connectors/api-connector.js +142 -56
  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 +228 -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 +383 -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/agents.d.ts +5 -4
  109. package/dist/operator-ui/agents.js +17 -7
  110. package/dist/operator-ui/config-summary.js +5 -4
  111. package/dist/operator-ui/connection-map.js +7 -5
  112. package/dist/operator-ui/contract.d.ts +7 -3
  113. package/dist/operator-ui/endpoints.js +4 -13
  114. package/dist/operator-ui/fix-prompts.d.ts +1 -1
  115. package/dist/operator-ui/fix-prompts.js +0 -8
  116. package/dist/operator-ui/generated.js +3 -3
  117. package/dist/operator-ui/model.d.ts +2 -3
  118. package/dist/operator-ui/overview.js +5 -2
  119. package/dist/operator-ui/setup-commands.js +0 -4
  120. package/dist/operator-ui/view.d.ts +2 -25
  121. package/dist/operator-ui/view.js +2 -76
  122. package/dist/program-writes.js +47 -26
  123. package/dist/provider-call-facts.d.ts +115 -0
  124. package/dist/provider-call-facts.js +182 -0
  125. package/dist/provider-call.d.ts +112 -0
  126. package/dist/provider-call.js +271 -0
  127. package/dist/provider.d.ts +65 -31
  128. package/dist/provider.js +116 -39
  129. package/dist/providers/_shared/google/hatch.js +91 -0
  130. package/dist/providers/_shared/google/kit.js +537 -0
  131. package/dist/providers/_shared/google/result-size.js +15 -2
  132. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  133. package/dist/providers/_shared/google/service-account.js +8 -4
  134. package/dist/providers/_shared/google/workspace.d.ts +6 -210
  135. package/dist/providers/_shared/google/workspace.js +6 -425
  136. package/dist/providers/_shared/rest/compact-index.js +86 -0
  137. package/dist/providers/_shared/rest/dispatch.js +3 -23
  138. package/dist/providers/_shared/rest/kit.js +546 -0
  139. package/dist/providers/_shared/rest/operation-index.js +230 -14
  140. package/dist/providers/_shared/rest/response-media.js +11 -0
  141. package/dist/providers/_shared/rest/tools.js +101 -78
  142. package/dist/providers/_shared/rest/value-safety.js +353 -195
  143. package/dist/providers/_shared/sensitive-fields.js +27 -0
  144. package/dist/providers/breeze/api.js +584 -0
  145. package/dist/providers/breeze/index.d.ts +1 -3
  146. package/dist/providers/breeze/index.js +67 -1420
  147. package/dist/providers/breeze/openapi.generated.js +60 -0
  148. package/dist/providers/breeze/skill.generated.js +2 -6
  149. package/dist/providers/breeze/tools.js +696 -0
  150. package/dist/providers/ccb/api.js +496 -0
  151. package/dist/providers/ccb/index.d.ts +15 -37
  152. package/dist/providers/ccb/index.js +77 -1702
  153. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  154. package/dist/providers/ccb/lib/constants.js +74 -0
  155. package/dist/providers/ccb/lib/guide.js +9 -0
  156. package/dist/providers/ccb/lib/verdicts.js +387 -0
  157. package/dist/providers/ccb/openapi.generated.js +397 -0
  158. package/dist/providers/ccb/safety.js +295 -0
  159. package/dist/providers/ccb/skill.generated.js +2 -6
  160. package/dist/providers/ccb/tools.js +853 -0
  161. package/dist/providers/cloudflare/api.js +1066 -0
  162. package/dist/providers/cloudflare/index.d.ts +5 -22
  163. package/dist/providers/cloudflare/index.js +79 -197
  164. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  165. package/dist/providers/cloudflare/lib/config.js +2 -0
  166. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  167. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  168. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  169. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  170. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  171. package/dist/providers/cloudflare/openapi.generated.js +4 -3
  172. package/dist/providers/cloudflare/{value-safety.js → safety.js} +487 -0
  173. package/dist/providers/cloudflare/skill.generated.js +2 -10
  174. package/dist/providers/cloudflare/tools.js +360 -0
  175. package/dist/providers/docs/api.js +51 -0
  176. package/dist/providers/docs/index.d.ts +1 -12
  177. package/dist/providers/docs/index.js +53 -1165
  178. package/dist/providers/docs/lib/constants.d.ts +18 -0
  179. package/dist/providers/docs/lib/constants.js +18 -0
  180. package/dist/providers/docs/lib/discovery.js +26 -0
  181. package/dist/providers/docs/lib/requests.js +48 -0
  182. package/dist/providers/docs/lib/schemas.js +168 -0
  183. package/dist/providers/docs/openapi.generated.js +16 -0
  184. package/dist/providers/docs/safety.js +54 -0
  185. package/dist/providers/docs/skill.generated.js +2 -6
  186. package/dist/providers/docs/tools.js +802 -0
  187. package/dist/providers/drive/api.js +177 -0
  188. package/dist/providers/drive/index.d.ts +1 -12
  189. package/dist/providers/drive/index.js +38 -1448
  190. package/dist/providers/drive/lib/constants.d.ts +6 -0
  191. package/dist/providers/drive/lib/constants.js +6 -0
  192. package/dist/providers/drive/lib/contracts.js +532 -0
  193. package/dist/providers/drive/lib/hatch.js +197 -0
  194. package/dist/providers/drive/openapi.generated.js +77 -0
  195. package/dist/providers/drive/safety.js +90 -0
  196. package/dist/providers/drive/skill.generated.js +2 -6
  197. package/dist/providers/drive/tools.js +1290 -0
  198. package/dist/providers/forms/api.js +71 -0
  199. package/dist/providers/forms/index.d.ts +1 -12
  200. package/dist/providers/forms/index.js +49 -1145
  201. package/dist/providers/forms/lib/constants.d.ts +14 -0
  202. package/dist/providers/forms/lib/constants.js +19 -0
  203. package/dist/providers/forms/lib/hatch.js +72 -0
  204. package/dist/providers/forms/openapi.generated.js +23 -0
  205. package/dist/providers/forms/safety.js +34 -0
  206. package/dist/providers/forms/skill.generated.js +2 -8
  207. package/dist/providers/forms/tools.js +1024 -0
  208. package/dist/providers/github/api.js +150 -0
  209. package/dist/providers/github/index.d.ts +4 -5
  210. package/dist/providers/github/index.js +30 -87
  211. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  212. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  213. package/dist/providers/github/lib/discovery.js +132 -0
  214. package/dist/providers/github/lib/operations.js +58 -0
  215. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  216. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  217. package/dist/providers/github/openapi.generated.js +1216 -0
  218. package/dist/providers/github/safety.js +216 -0
  219. package/dist/providers/github/skill.generated.js +2 -5
  220. package/dist/providers/github/tools.js +506 -0
  221. package/dist/providers/gmail/api.js +114 -0
  222. package/dist/providers/gmail/index.d.ts +1 -12
  223. package/dist/providers/gmail/index.js +73 -1621
  224. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  225. package/dist/providers/gmail/lib/constants.js +16 -0
  226. package/dist/providers/gmail/lib/index.js +173 -0
  227. package/dist/providers/gmail/lib/schemas.js +176 -0
  228. package/dist/providers/gmail/lib/threading.js +120 -0
  229. package/dist/providers/gmail/openapi.generated.js +92 -0
  230. package/dist/providers/gmail/safety.js +21 -0
  231. package/dist/providers/gmail/skill.generated.js +2 -6
  232. package/dist/providers/gmail/tools.js +1435 -0
  233. package/dist/providers/overflow/api.js +1008 -0
  234. package/dist/providers/overflow/index.d.ts +1 -17
  235. package/dist/providers/overflow/index.js +60 -1488
  236. package/dist/providers/overflow/skill.generated.js +2 -5
  237. package/dist/providers/overflow/tools.js +873 -0
  238. package/dist/providers/planning-center/api.js +467 -0
  239. package/dist/providers/planning-center/index.d.ts +4 -35
  240. package/dist/providers/planning-center/index.js +69 -2445
  241. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  242. package/dist/providers/planning-center/lib/constants.js +83 -0
  243. package/dist/providers/planning-center/lib/discovery.js +40 -0
  244. package/dist/providers/planning-center/lib/guide.js +39 -0
  245. package/dist/providers/planning-center/lib/json-api.js +83 -0
  246. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  247. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  248. package/dist/providers/planning-center/safety.js +188 -0
  249. package/dist/providers/planning-center/skill.generated.js +2 -27
  250. package/dist/providers/planning-center/tools.js +1010 -0
  251. package/dist/providers/sheets/api.js +133 -0
  252. package/dist/providers/sheets/index.d.ts +4 -16
  253. package/dist/providers/sheets/index.js +61 -1172
  254. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  255. package/dist/providers/sheets/lib/constants.js +14 -0
  256. package/dist/providers/sheets/lib/hatch.js +163 -0
  257. package/dist/providers/sheets/lib/requests.js +105 -0
  258. package/dist/providers/sheets/lib/schemas.js +138 -0
  259. package/dist/providers/sheets/openapi.generated.js +30 -0
  260. package/dist/providers/sheets/safety.js +27 -0
  261. package/dist/providers/sheets/skill.generated.js +2 -7
  262. package/dist/providers/sheets/tools.js +734 -0
  263. package/dist/providers/slides/api.js +147 -0
  264. package/dist/providers/slides/index.d.ts +2 -10
  265. package/dist/providers/slides/index.js +48 -2555
  266. package/dist/providers/slides/lib/constants.d.ts +11 -0
  267. package/dist/providers/slides/lib/constants.js +11 -0
  268. package/dist/providers/slides/lib/requests.js +60 -0
  269. package/dist/providers/slides/lib/schemas.js +565 -0
  270. package/dist/providers/slides/openapi.generated.js +18 -0
  271. package/dist/providers/slides/skill.generated.js +2 -6
  272. package/dist/providers/slides/tools.js +1968 -0
  273. package/dist/providers/stripe/api.js +401 -0
  274. package/dist/providers/stripe/index.d.ts +5 -27
  275. package/dist/providers/stripe/index.js +74 -210
  276. package/dist/providers/stripe/lib/config.d.ts +4 -0
  277. package/dist/providers/stripe/lib/config.js +2 -0
  278. package/dist/providers/stripe/openapi.generated.js +4 -3
  279. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  280. package/dist/providers/stripe/skill.generated.js +2 -11
  281. package/dist/providers/stripe/tools.js +77 -0
  282. package/dist/providers/tithely/api.js +531 -0
  283. package/dist/providers/tithely/index.d.ts +17 -0
  284. package/dist/providers/tithely/index.js +86 -965
  285. package/dist/providers/tithely/skill.generated.js +2 -5
  286. package/dist/providers/tithely/tools.js +426 -0
  287. package/dist/providers/vercel/api.js +551 -0
  288. package/dist/providers/vercel/index.d.ts +9 -25
  289. package/dist/providers/vercel/index.js +66 -260
  290. package/dist/providers/vercel/lib/config.d.ts +2 -0
  291. package/dist/providers/vercel/lib/config.js +2 -0
  292. package/dist/providers/vercel/lib/index.js +117 -0
  293. package/dist/providers/vercel/lib/logs.js +100 -0
  294. package/dist/providers/vercel/lib/pin.js +270 -0
  295. package/dist/providers/vercel/openapi.generated.js +10 -5
  296. package/dist/providers/vercel/{value-safety.js → safety.js} +247 -38
  297. package/dist/providers/vercel/skill.generated.js +2 -7
  298. package/dist/providers/vercel/tools.js +642 -0
  299. package/dist/redaction-identity.js +47 -0
  300. package/dist/redaction-marker.js +125 -0
  301. package/dist/registry.d.ts +21 -15
  302. package/dist/registry.js +409 -376
  303. package/dist/routes/access-tokens.js +1 -1
  304. package/dist/routes/actor-labels.js +1 -1
  305. package/dist/routes/connect.js +1 -1
  306. package/dist/routes/dispatch.js +103 -0
  307. package/dist/routes/mcp.js +170 -79
  308. package/dist/routes/oauth.js +3 -1
  309. package/dist/routes/operator.js +2 -2
  310. package/dist/routes/shared.d.ts +5 -4
  311. package/dist/routes/shared.js +244 -177
  312. package/dist/routes/skills.js +10 -8
  313. package/dist/routes/ui-config.js +27 -3
  314. package/dist/routes/ui-data.js +21 -20
  315. package/dist/routes/ui.js +1 -1
  316. package/dist/runtime/call-admission.js +0 -26
  317. package/dist/runtime/call-entry.js +30 -0
  318. package/dist/runtime/call.js +556 -0
  319. package/dist/runtime/connector-scope.js +7 -0
  320. package/dist/runtime/credential-probe.js +34 -0
  321. package/dist/runtime/executor.js +40 -0
  322. package/dist/runtime/native-storage.js +63 -0
  323. package/dist/runtime/registry.js +27 -0
  324. package/dist/runtime/request-scope.js +72 -0
  325. package/dist/runtime/run.js +15 -7
  326. package/dist/runtime/shared-read.js +34 -5
  327. package/dist/runtime/storage.js +34 -21
  328. package/dist/sent-secrets.d.ts +194 -37
  329. package/dist/sent-secrets.js +1743 -340
  330. package/dist/server.js +5 -56
  331. package/dist/skills.js +322 -222
  332. package/dist/sqlite.js +15 -14
  333. package/dist/storage/d1-copy.js +255 -0
  334. package/dist/storage/d1-driver.js +15 -0
  335. package/dist/storage/keys.js +28 -0
  336. package/dist/storage/sql-driver.js +88 -0
  337. package/dist/storage/sql-native.js +544 -0
  338. package/dist/storage/sql-schema.d.ts +6 -0
  339. package/dist/storage/sql-schema.js +15 -0
  340. package/dist/storage/sql.d.ts +14 -20
  341. package/dist/storage/sql.js +29 -535
  342. package/dist/timeout.js +0 -26
  343. package/dist/tool-safety.js +20 -10
  344. package/dist/types.d.ts +7 -109
  345. package/dist/upward.js +3 -0
  346. package/dist/usage-guide.js +3 -1
  347. package/dist/validate.d.ts +4 -2
  348. package/dist/validate.js +86 -9
  349. package/dist/version.d.ts +1 -1
  350. package/dist/version.js +1 -1
  351. package/dist/worker.js +312 -292
  352. package/dist/workspace-subject.js +5 -1
  353. package/dist/write-outcome.js +454 -34
  354. package/documentation/README.md +27 -7
  355. package/documentation/architecture.md +2547 -226
  356. package/documentation/auth.md +821 -98
  357. package/documentation/code-mode.md +49 -16
  358. package/documentation/deploying.md +164 -20
  359. package/documentation/hosted-mcp-migration.md +460 -0
  360. package/documentation/integrating.md +129 -144
  361. package/documentation/meta-tools.md +409 -32
  362. package/documentation/operating.md +27 -3
  363. package/documentation/operator-tests.md +3 -0
  364. package/documentation/operator-ui.md +68 -45
  365. package/documentation/provider-auth-migration.md +16 -63
  366. package/documentation/provider-migration-0.29.md +10 -5
  367. package/documentation/provider-migration-0.35.md +975 -0
  368. package/documentation/providers.md +965 -0
  369. package/examples/worker/AGENTS.md +23 -9
  370. package/examples/worker/README.md +254 -135
  371. package/examples/worker/alchemy.run.ts +116 -0
  372. package/examples/worker/gitignore +10 -0
  373. package/examples/worker/src/connecta.config.ts +23 -21
  374. package/examples/worker/wrangler.jsonc +14 -5
  375. package/guides/connecting-agents.md +157 -0
  376. package/guides/how-it-works.md +156 -0
  377. package/guides/safety-and-trust.md +153 -0
  378. package/package.json +27 -46
  379. package/templates/node/.env.example +3 -0
  380. package/templates/node/README.md +22 -2
  381. package/templates/node/docker-compose.yml +1 -0
  382. package/templates/node/package.json +3 -2
  383. package/templates/node/src/connecta.config.ts +8 -0
  384. package/dist/catalog-drift.d.ts +0 -138
  385. package/dist/catalog-drift.js +0 -578
  386. package/dist/providers/_shared/request-token.js +0 -83
  387. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  388. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  389. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  390. package/dist/providers/basecamp/index.d.ts +0 -45
  391. package/dist/providers/basecamp/index.js +0 -997
  392. package/dist/providers/basecamp/skill.generated.js +0 -9
  393. package/dist/providers/cloudflare/rest.d.ts +0 -37
  394. package/dist/providers/cloudflare/rest.js +0 -1097
  395. package/dist/providers/github/hosted.js +0 -218
  396. package/dist/providers/github/rest.js +0 -321
  397. package/dist/providers/infisical/index.d.ts +0 -7
  398. package/dist/providers/infisical/index.js +0 -713
  399. package/dist/providers/infisical/skill.generated.js +0 -8
  400. package/dist/providers/intercom/index.d.ts +0 -24
  401. package/dist/providers/intercom/index.js +0 -121
  402. package/dist/providers/intercom/skill.generated.js +0 -8
  403. package/dist/providers/linear/index.d.ts +0 -55
  404. package/dist/providers/linear/index.js +0 -537
  405. package/dist/providers/linear/skill.generated.js +0 -8
  406. package/dist/providers/mixpanel/index.d.ts +0 -59
  407. package/dist/providers/mixpanel/index.js +0 -472
  408. package/dist/providers/mixpanel/operations.js +0 -20
  409. package/dist/providers/mixpanel/rest.js +0 -603
  410. package/dist/providers/mixpanel/skill.generated.js +0 -10
  411. package/dist/providers/mixpanel/value-safety.js +0 -16
  412. package/dist/providers/notion/index.d.ts +0 -67
  413. package/dist/providers/notion/index.js +0 -368
  414. package/dist/providers/notion/openapi.generated.js +0 -75
  415. package/dist/providers/notion/rest.d.ts +0 -24
  416. package/dist/providers/notion/rest.js +0 -1226
  417. package/dist/providers/notion/skill.generated.js +0 -11
  418. package/dist/providers/notion/value-safety.js +0 -56
  419. package/dist/providers/revenuecat/index.d.ts +0 -51
  420. package/dist/providers/revenuecat/index.js +0 -697
  421. package/dist/providers/revenuecat/skill.generated.js +0 -11
  422. package/dist/providers/stripe/rest.d.ts +0 -14
  423. package/dist/providers/stripe/rest.js +0 -402
  424. package/dist/providers/vercel/rest.d.ts +0 -20
  425. package/dist/providers/vercel/rest.js +0 -1020
  426. package/dist/providers/wispr-flow/index.d.ts +0 -14
  427. package/dist/providers/wispr-flow/index.js +0 -117
  428. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  429. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -0,0 +1,965 @@
1
+ # Maintained provider setup
2
+
3
+ Each section below sets up one maintained provider: a construction example,
4
+ its credential, the options that change behavior or data boundaries, what the
5
+ vendor must enable first, and its limits. [Change the connector
6
+ roster](./integrating.md#add-or-remove-a-connector) covers the general
7
+ procedure and the providers not listed here. Agent guidance for each
8
+ provider ships with its connection's usage guide, not here.
9
+
10
+ Standard API operation search accepts resource nouns, actions and conversational
11
+ phrasing. A leading create/add/update/edit/make/set/apply/change/rename/send/delete/remove/cancel/stop
12
+ with an object prefers reviewed writes and keeps later read words as nouns, as in
13
+ `update list` or `update subscription status`. Make, set, apply, change, edit and
14
+ rename use update synonyms. Otherwise, read words anywhere prefer reviewed reads,
15
+ including after refund/charge/issue/process. The requested verb or a synonym in
16
+ an operation's summary, id or path sorts next, followed by resource focus.
17
+ A refused operation with a matching verb shares the intent tier when it covers
18
+ more query nouns than any admitted operation matching that verb and intent.
19
+ Its original indexed `summary` stays separate from the reviewed `refusal`, and
20
+ it omits the read/write hatch pointer; a named alternative can still be shown.
21
+ Search keeps up to 512 UTF-16 units of refusal text and marks any cut reason as
22
+ `operations[i].refusal` in `truncated`. Details supplies complete refusal text,
23
+ in 32 KiB pages/chunks when necessary. The summary has its separate 300-unit
24
+ search budget; ranking uses the indexed language, not attached refusal prose.
25
+
26
+ Use `_api_details` with the indexed method and path when a refused method lies
27
+ outside the call tool's schema. For example, `gmail_api_details` with
28
+ `method: "POST", path: "/messages/send"` explains the sending refusal; Gmail's
29
+ read hatch still has no method argument and there is no Gmail write hatch.
30
+ `forms_api_details` likewise explains `DELETE /forms/{formId}/watches/{watchId}`
31
+ even though DELETE remains absent from the Forms write schema. GitHub
32
+ `PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge` also remains outside its raw
33
+ write schema; inspect its refusal and named alternative through details. All such calls
34
+ remain refused before authentication or downstream I/O.
35
+
36
+ Partial lexical matches are included even when other operations match every
37
+ term. Short function words and id-shaped tokens do not count toward noun
38
+ coverage. For action/read queries, an operation must cover every content noun in
39
+ its text, or match a noun in its path or operation id while covering at least
40
+ half the nouns. Field-only matches need half-noun coverage across the text and
41
+ declared field names. Verb-less noun phrases keep their broader rule: any noun
42
+ in the path/id, or every noun in the text. Framing-only queries return no matches.
43
+
44
+ A noun phrase first prefers fuller noun coverage and an exact summary phrase
45
+ prefix, then an exact terminal
46
+ resource (its last literal segment matches the last noun or the complete
47
+ compound phrase). An authored read whose
48
+ summary/id covers every noun shares the terminal-resource tier when an exact
49
+ terminal resource exists and its
50
+ description begins with a read action; the action word does not supply resource
51
+ noun coverage. When both terminal
52
+ resources match, reviewed reads precede writes and refusals. Path depth with a
53
+ one-segment authored-tool preference, exact resource nouns and authored tools
54
+ break remaining ties. A pointer to another hatch receives no authored preference.
55
+ Literal namespaces on either side of a version segment count as resource nouns;
56
+ version markers and parameters do not. A single noun, or a leading
57
+ `list` with only one exact resource noun plus modifiers, prefers the root
58
+ collection before nested routes. Other `list` phrases prefer an authored tool
59
+ whose summary/id covers every noun. Lexical relevance and stable index order
60
+ resolve remaining ties; field-only matches follow all primary matches.
61
+ For example, search a configured `crm` connection's API index for `person`,
62
+ then follow `page.nextCursor` to reach operations beyond the leading profile
63
+ results. Responses contain at most eight compact hits within 16 KiB; fetch
64
+ operation details separately and keep the same query when continuing.
65
+
66
+ Maintained REST hatches validate path parameters against their pinned contracts
67
+ before dispatch. Integer ids use canonical ASCII decimal notation within the
68
+ safe-integer range and obey the operation's declared bounds; for example,
69
+ `/individuals/42` is valid for an unbounded integer id while `/individuals/01`
70
+ is refused.
71
+
72
+ Stripe, Cloudflare and Vercel accept non-JSON success bodies only for reviewed
73
+ operation/media pairs from their pins. Cloudflare also preserves three raw Worker
74
+ content downloads with any non-JSON media. R2/KV object downloads use the full
75
+ JSON value-safety boundary for application/json and +json replies; other stored
76
+ media return bounded bytes with sent-secret checks. An unexpected HTML or text answer to a
77
+ JSON write reports an unknown outcome after one send; check the target before
78
+ repeating the write. Documented PDFs, text exports and streaming formats retain
79
+ their reviewed handling.
80
+
81
+ Vercel project-environment partial replies withhold failure prose before `fields`
82
+ selection. Named upsert partial-write reports identify the sent key and reviewed
83
+ failure codes, with reconciliation guidance; safe created and failed entries are retained, and submitted env values are private
84
+ write-only inputs on both named tools and raw env writes. Shared-env POST, PATCH
85
+ and DELETE failure prose is withheld too.
86
+
87
+ Overflow refund initiation accepts an `application/json` string or a bounded
88
+ `text/plain` acknowledgement, a narrow NestJS compatibility exception. Empty 2xx
89
+ refund acknowledgements also succeed. Nonempty HTML, binary, other media and
90
+ JSON-object replies fail with an unknown outcome after one dispatch;
91
+ check whether the refund took effect before repeating it.
92
+
93
+ ## Planning Center
94
+
95
+ `planningCenter()` connects one organization's reviewed product APIs.
96
+
97
+ ```ts
98
+ import { planningCenter } from "@zackbart/connecta/providers/planning-center";
99
+
100
+ const crm = planningCenter("crm", {
101
+ purpose: "Staff follow-up, groups and service planning",
102
+ excludeApps: ["giving"],
103
+ });
104
+ ```
105
+
106
+ **Credential.** Create a Personal Access Token in Planning Center's API
107
+ applications dashboard as a user whose product permissions match this
108
+ connection's purpose. Enter its Application ID and Secret in the operator UI.
109
+ The credential test reads `/people/v2/me` with the organization included.
110
+ A missing or malformed pair is refused before transport. Personal auth ownership
111
+ is available with `authScope: "personal"`; agents use shared credentials.
112
+
113
+ **Options and boundaries.** `readOnly: true` omits and refuses writes.
114
+ `defaultPageSize` sets the named lists' default limit (25 normally, at most 100).
115
+ `userAgent` identifies the deployment and a contact; a nonempty single line is
116
+ required. `baseUrl` is an HTTPS proxy override, or HTTP on loopback for tests.
117
+ The connector supplies each product's reviewed `X-PCO-API-Version`; tool calls
118
+ cannot override it.
119
+
120
+ `excludeApps` removes product endpoints and named tools. People cannot be
121
+ excluded because its identities join other products and its me endpoint tests
122
+ the token. While any product is excluded, People lists/results/rules/conditions
123
+ are also refused by path or include: a saved list can query another product.
124
+ Webhook event/delivery payloads and changes to existing subscriptions are
125
+ refused because their ids do not name a product. A new subscription must name
126
+ a reachable product's event. Paths must be literal while exclusions apply:
127
+ no traversal, ambiguous separators, whitespace or encoded delimiters. Checks
128
+ run before credentials and again on the exact URL to fetch.
129
+
130
+ Exclusion controls live API access. It cannot identify information staff or
131
+ automations copied into reachable notes, workflows, forms or custom fields.
132
+ For a hard product boundary, use a PAT belonging to a user with No Access in
133
+ that product. No tool argument or nominal `sensitiveFields` option returns
134
+ stored credentials. Signing secrets, organization secrets, private calendar
135
+ codes, private file destinations and opaque webhook payload/header fields
136
+ stay withheld in named and hatch replies, including included resources.
137
+
138
+ **Vendor prerequisites.** The organization must subscribe to each product it
139
+ uses, and the PAT's user needs that product's permissions. Permissions are
140
+ per user and product; organization administrator status does not grant every
141
+ product. File uploads use a separate host this connector does not reach.
142
+
143
+ **Limits.** Planning Center meters 100 requests per 20 seconds per user,
144
+ shared with every integration using that user's tokens. The default per-runtime
145
+ admission budget is 100 calls per 20 seconds, concurrency five; `callAdmission`
146
+ can narrow or split it when connections share a user. Isolates and other
147
+ integrations share no local counter, so this is an approximation. `get_plan`
148
+ issues three bounded reads. A response is capped at 8 MiB; named lists request
149
+ at most 100 rows. Search answers have at most eight hits and 16 KiB of tool
150
+ JSON; details have 32 KiB with explicit continuation for larger contracts.
151
+ Named lists use signed cursors over the vendor offset; paged hatch reads return
152
+ `page.nextCursor` for the `offset` query parameter. Keep the other query and
153
+ field arguments unchanged when continuing a hatch read.
154
+
155
+ Named lists and paged hatch reads expose `page.total` only when Planning Center
156
+ supplies a nonnegative safe integer in `meta.total_count`. This is the vendor's
157
+ count for the requested collection and vendor filters, across all pages;
158
+ `meta.count` describes one vendor page. For example, a filtered collection can
159
+ report `page.total: 57` while this reply emits two items. Local filtering,
160
+ projection and size truncation can reduce the items shown without changing the
161
+ vendor total. Missing, malformed or oversized optional totals are omitted.
162
+ `page.hasMore` and signed continuation still follow `meta.next.offset`, never
163
+ the total, item count, offset or limit.
164
+
165
+ Excluded products' unavailable named tools are omitted from authored and
166
+ generated guide sections and from hatch search/details suggestions. For example,
167
+ excluding Services removes `list_plans` suggestions while retaining People
168
+ identity tools. The indexed vendor contract remains inspectable; exclusion
169
+ still refuses those operations before dispatch. Changing the credential owner
170
+ or original filters invalidates a continuation; totals add no new cursor scope.
171
+
172
+ ## Stripe
173
+
174
+ `stripe()` connects one Stripe account in one mode through the pinned REST API.
175
+
176
+ ```ts
177
+ import { stripe } from "@zackbart/connecta/providers/stripe";
178
+
179
+ const billing = stripe("billing", {
180
+ purpose: "Payment investigations and reconciliation",
181
+ auth: { type: "apiKey" },
182
+ mode: "sandbox",
183
+ readOnly: true,
184
+ });
185
+ ```
186
+
187
+ **Credential.** Enter one secret (`sk_test_…`/`sk_live_…`) or restricted
188
+ (`rk_test_…`/`rk_live_…`) key in this connection in the operator UI. Prefer a
189
+ restricted key with only the required permissions. The key prefix must match
190
+ the declared mode; publishable and organization keys are refused. The Test
191
+ action reads the account. If account-read permission is absent, the test can
192
+ still establish that the key was accepted. Stored keys never reach agents.
193
+
194
+ **Options.** `mode` is required: `"sandbox"` or `"production"`.
195
+ `connectedAccount: "acct_example"` binds every call to that Connect account
196
+ using Stripe-Account on v1 and Stripe-Context on v2. `readOnly: true` omits
197
+ writes and refuses their calls on every endpoint. `authScope: "personal"`
198
+ partitions stored credentials by admitted owner instead of sharing a grant.
199
+ `maxResultBytes` narrows this connector's inline result budget. There is no
200
+ separate optional sensitive-field set: reviewed secret withholding applies to
201
+ every result, and `fields` only reduces the remaining data. No tool argument
202
+ widens that boundary.
203
+
204
+ **Vendor prerequisites.** The key must have permission for each API operation
205
+ the workflow needs. Hosted MCP is a separate generic connection; follow
206
+ [the hosted Stripe migration](./hosted-mcp-migration.md#stripe).
207
+
208
+ **Limits.** The index is pinned to Stripe-Version `2026-09-30.endive`.
209
+ Responses are bounded to 8 MiB and request reads to 60 seconds. Default
210
+ admission is 100 calls/second and 8 concurrent calls in production, or
211
+ 25 calls/second and 4 concurrent calls in sandbox; Stripe can apply stricter
212
+ endpoint limits. Stripe v1 lists normally default to 10 and cap at 100;
213
+ the hatch keeps the pinned operation's vendor query parameters. Files can be
214
+ read as quote PDFs from the confined files origin; multipart uploads and
215
+ the meter-event stream are refused. POST writes take an optional
216
+ `idempotencyKey` (up to 255 characters), generating and returning one when
217
+ omitted; DELETE and the invoice-preview read send no key.
218
+
219
+ **Paging example.** A first read can set a raw record-id anchor in
220
+ `query.starting_after` or `query.ending_before`. To continue, pass the signed
221
+ `page.nextCursor` as the top-level `cursor`, keeping the path, filters and
222
+ `fields` unchanged. Omit both raw anchors on continuation. Do not combine
223
+ directions. Search and v2 lists also continue through `cursor`; their raw
224
+ vendor page tokens are not accepted there.
225
+ If a v2 next-page URL adds omitted parameters, the fetched data remains
226
+ available with `page.hasMore: true` but no `nextCursor`. It is incomplete;
227
+ repeat with explicit parameters or narrow the request to continue safely.
228
+
229
+ ```ts
230
+ const first = await connecta.call("billing.stripe_api_read", {
231
+ path: "/v1/charges",
232
+ query: { customer: "cus_example", starting_after: "ch_example", limit: 20 },
233
+ fields: ["data.id", "data.amount"],
234
+ });
235
+ if (first.data.page?.hasMore) {
236
+ const next = await connecta.call("billing.stripe_api_read", {
237
+ path: "/v1/charges",
238
+ query: { customer: "cus_example", limit: 20 },
239
+ fields: ["data.id", "data.amount"],
240
+ cursor: first.data.page.nextCursor,
241
+ });
242
+ }
243
+ ```
244
+
245
+ ## Breeze ChMS
246
+
247
+ `breeze()` connects one church's Breeze account through its API.
248
+
249
+ ```ts
250
+ import { breeze } from "@zackbart/connecta/providers/breeze";
251
+
252
+ const church = breeze("church", {
253
+ purpose: "Attendance and giving reports",
254
+ subdomain: "church",
255
+ });
256
+ ```
257
+
258
+ **Credential.** Enter the church's API key from **Extensions → API** on the
259
+ connection in the operator UI. The Test action reads the account summary and
260
+ checks its reported subdomain. The key has no scopes: it reaches the whole
261
+ account, giving included. It is sent only to the configured church hostname.
262
+
263
+ **Options.** `subdomain` is one hostname label before `.breezechms.com`, never
264
+ a URL. `readOnly: true` omits and refuses writes on every endpoint, including
265
+ writes that Breeze sends as GET requests. `defaultPageSize` sets paged-list
266
+ sizes from 1 to 1,000 (default 100). `list_events` separately defaults to 100
267
+ and caps at 1,000 without a continuation. `authScope` selects shared or
268
+ personal credential ownership. `callAdmission` sets a per-runtime budget;
269
+ none is declared by default because Breeze publishes no rate limit.
270
+
271
+ There is no `sensitiveFields` option: profile detail maps contain church-specific
272
+ field ids, and this provider declares no configurable sensitive set. Select
273
+ only needed fields and reduce personal records in code. Calendar feed addresses
274
+ and embed keys are always removed from every result.
275
+
276
+ **Vendor prerequisites.** An administrator must enable/access Extensions → API
277
+ and supply the account-wide key. Giving, funds and pledges use archival routes
278
+ that are no longer in Breeze's public reference; verify the church still
279
+ supports them before depending on those workflows.
280
+
281
+ **Limits.** Requests stay below the church's `/api` path. Responses are bounded
282
+ to 8 MiB and standard hatch successes must be JSON. People page by offset;
283
+ other paged named lists window a bounded vendor response locally. Events and
284
+ account logs have vendor caps; narrow date ranges when a reply fills its limit.
285
+
286
+ ## Overflow
287
+
288
+ `overflow()` connects one nonprofit's Overflow v3 API, with an explicit
289
+ production or staging environment.
290
+
291
+ ```ts
292
+ import { overflow } from "@zackbart/connecta/providers/overflow";
293
+
294
+ const giving = overflow("giving", {
295
+ purpose: "Giving reports and donor care for the nonprofit",
296
+ environment: "staging",
297
+ });
298
+ ```
299
+
300
+ **Authentication.** An operator saves the environment's `clientId` and `apiKey`
301
+ on this connection. They are sent as `x-client-id` and `x-api-key`; neither
302
+ identifies which environment it belongs to. Staging and production credentials
303
+ are separate. The credential test reads one location with the candidate pair;
304
+ `/health` is not an authenticated credential test.
305
+
306
+ **Options.** `environment` is required, with no default. `defaultPageSize`
307
+ controls numbered named lists (default 25, maximum 100). `readOnly` refuses
308
+ all writes. `authScope` selects shared or personal credential ownership.
309
+ `instructions` appends nonprofit conventions. `baseUrl` is an optional proxy
310
+ or test origin; Connecta appends `/api/v3`. `maxResultBytes` limits inline
311
+ results, and `callAdmission` replaces the default policy.
312
+
313
+ Named reads retain lean projections; `get_donor` is the full-contact lookup.
314
+ There is no configurable sensitive-field set. The indexed hatch returns other
315
+ nonsecret vendor fields and `fields` only narrows them. Webhook signing secrets
316
+ are always removed, including bare, wrapped and list responses.
317
+
318
+ **Prerequisites.** Obtain API credentials from Overflow for the intended
319
+ nonprofit and environment. A donor-account-owned profile cannot be edited
320
+ through this API even when the credentials can read it. Resolve donor,
321
+ payment-method, campaign and location ids before authorizing money writes.
322
+
323
+ **Limits.** Overflow documents 120 requests per minute per API client. The
324
+ default admission policy approximates it per runtime with a rolling 60-second
325
+ budget, concurrency four and a bounded queue. Other integrations and runtimes
326
+ share the vendor allowance without sharing this local counter. The connection
327
+ reads at most 4 MiB per response. Named lists use opaque cursors; keep the same
328
+ limit when continuing a numbered list. A vendor-stated exact count appears as
329
+ `page.total`; no count is synthesized when it is absent. Payment methods are
330
+ windowed locally from one bounded response. The webhook-log hatch accepts at
331
+ most 50 rows and returns its native continuation inside a signed cursor.
332
+
333
+ ## Tithe.ly
334
+
335
+ `tithely()` connects one Tithe.ly giving account through its v1 REST API.
336
+
337
+ ```ts
338
+ import { tithely } from "@zackbart/connecta/providers/tithely";
339
+
340
+ const giving = tithely("giving", {
341
+ purpose: "Weekly giving reports for the finance team",
342
+ environment: "live",
343
+ });
344
+ ```
345
+
346
+ **Credential.** Each connection has one operator-managed key pair: the public
347
+ key (`pub_…`, sent as the HTTP Basic user name) and the private key (`pri_…`,
348
+ the password). Enter both on the connection in the operator UI; the Test action
349
+ reads one organization to prove the pair. A missing, swapped, or malformed pair
350
+ is refused before any request leaves. Keys never reach agents.
351
+
352
+ **Options.**
353
+
354
+ - `environment` is required: `"live"` (tithe.ly) or `"test"`
355
+ (tithelydev.com). Keys are issued per environment and nothing in a key says
356
+ which, so a key pair used against the other environment fails every call
357
+ with `auth_required`. Connecta does not guess.
358
+ - `sensitiveFields` defaults to `"drop"`, which removes an organization's
359
+ payout `bank` (bank name and account last four) and `legal` contact (name
360
+ and date of birth), by field name at any depth, from every result:
361
+ named reads, `tithely_api_read` and `tithely_api_write` replies. `"return"`
362
+ lets the hatch return them; the named reads never include them. The names
363
+ are exported as `TITHELY_SENSITIVE_FIELDS`. No tool argument changes this.
364
+ - `readOnly: true` serves only reads on every endpoint, so refunds, charges,
365
+ recurring gifts, payment methods, and accounts cannot change.
366
+ - `defaultPageSize` sets the list tools' default page, 1 to 99 (default 25).
367
+ - `baseUrl` replaces the environment's endpoint for a proxy or test double;
368
+ it must be https, or http on loopback.
369
+ - `callAdmission` sets a per-runtime call budget. Tithe.ly publishes no rate
370
+ limit, so none is declared by default; set one if the account has a limit
371
+ you know.
372
+
373
+ **Vendor prerequisites.** Tithe.ly issues API keys on request: email
374
+ support@tithe.ly with the church or organization and what you are building,
375
+ and Tithe.ly sends a link to generate the key pair. Live and test are separate
376
+ accounts with separate key pairs.
377
+
378
+ **Limits.** Only API v1 is reachable; Tithe.ly's undocumented v2 is not. Card
379
+ and bank tokens for one-time charges and new payment methods come only from
380
+ Tithely.js in a donor's browser. A response is read up to 4 MiB.
381
+
382
+ ## Vercel
383
+
384
+ ```ts
385
+ import { vercel } from "@zackbart/connecta/providers/vercel";
386
+
387
+ vercel("hosting", {
388
+ purpose: "Projects and deployments for the assistant",
389
+ auth: { type: "token" },
390
+ teamId: "team_example",
391
+ });
392
+ ```
393
+
394
+ Add the access token from Vercel Account Settings → Tokens in the connection's
395
+ operator UI. Choose the account/team and expiry the deployment needs. It is
396
+ stored encrypted; it is sent only to api.vercel.com, or a configured baseUrl proxy.
397
+ `authScope: "personal"` selects per-owner credentials; the default is shared.
398
+ The legacy hosted selector is unsupported; connect hosted MCP with generic
399
+ `remoteMcp()` as described in [Hosted MCP migration](./hosted-mcp-migration.md).
400
+
401
+ Without `pin`, `teamId` is a routing default, not a tenant restriction. On operations accepting
402
+ team selectors, an explicit `teamId` or `slug` overrides it. `teamId: null` omits
403
+ the default for personal-account calls. All named tools, hatch calls and uploads
404
+ use the same routing. For example, a `hosting` call with
405
+ `query: { slug: "studio" }` targets that team; it is not forced into team_example.
406
+ Vercel token permissions enforce access. Set a suitably scoped token when access
407
+ must be restricted. Signed paging binds the resolved selectors, so reuse the
408
+ same team, path, filters and fields when passing `page.nextCursor` in
409
+ `query[page.param]`. Team path ids remain vendor identifiers, not a deployment pin.
410
+
411
+ Set `pin: { teamId: "team_example" }` to confine this connection to one Vercel
412
+ team independently of the token's permissions. If `teamId` is also configured,
413
+ it must match the pin. The pin requires a canonical `team_…` id, not a slug.
414
+ It applies to named tools, bounded logs, uploads and all hatch requests. Explicit
415
+ foreign ids, personal/null scope, duplicate/ambiguous selectors and encoded path
416
+ spellings are refused. A supplied `slug` is checked against the pinned team's
417
+ current id and slug; ordinary project, environment and flag slugs keep their
418
+ documented meaning. Token permissions can restrict access further.
419
+
420
+ Pinned calls make at most eight additional sequential ownership reads, charged
421
+ to the same call-admission budget before each request. No ownership result is
422
+ cached between calls or credential owners. Project and deployment references,
423
+ including every target in supported multi-project inputs, must prove ownership;
424
+ missing or malformed ownership refuses the affected request. For example, a
425
+ domain move to another project checks both projects before sending the write.
426
+ Unprovable global/account operations, organizations, cross-team grants and project
427
+ transfers are unavailable. The pinned `list_teams` returns one terminal item,
428
+ and the credential probe reads that team. No user/account read is an exception.
429
+ Pinned hatch search and details mark these unavailable operations as refused;
430
+ the usage guide's refusal count includes the configured team boundary.
431
+ Signed continuations bind the pin policy as well as the credential owner and
432
+ existing call scope; changing the pin or adding/removing it requires a new first
433
+ page. Writes still have one physical attempt after successful preflights.
434
+
435
+ `readOnly: true` refuses every write. `baseUrl` is only for an explicitly trusted
436
+ proxy or test double. Set `callAdmission` for downstream endpoint limits and
437
+ `maxResultBytes` for inline output sizing. Permanent credentials and environment
438
+ values cannot be returned; there is no option to widen this boundary. The token
439
+ must have the permissions and Vercel plan required by the selected endpoint.
440
+
441
+ Team lists default to 20 and allow 100 rows. Build logs default to 200 and allow
442
+ 2,000 events; runtime logs default to 200 and allow 1,000 rows over 1–20 seconds.
443
+ Log prefixes stop at 1 MiB; each projected text field stops at 4,000 characters.
444
+ Uploads accept at most 8 MiB of explicit bytes. Regular response bodies stop at
445
+ 8 MiB and calls at 60 seconds. JSON-only operations reject unexpected HTML/text
446
+ acknowledgements; check the target after an unknown write outcome before repeating.
447
+
448
+ A numeric hatch `query.until` can set the initial upper time boundary on timestamp
449
+ lists. Subsequent pages use signed `page.nextCursor` in that same parameter.
450
+ Named `list_teams` uses only its top-level `cursor` for continuation.
451
+
452
+ ## GitHub
453
+
454
+ ```ts
455
+ import { github } from "@zackbart/connecta/providers/github";
456
+
457
+ const source = github("source", {
458
+ purpose: "Repository issue triage and release work",
459
+ app: { appId: env.GITHUB_APP_ID },
460
+ scopes: [{ org: "alice", access: "read-write" }],
461
+ });
462
+ ```
463
+
464
+ Create a GitHub App with repository Metadata permission and install it on each
465
+ configured owner. Omit privateKey to populate the connector's encrypted privateKey
466
+ vault field, or supply app.privateKey from an environment secret. No per-user
467
+ OAuth is supported. Installation tokens remain in bounded memory and refresh
468
+ before expiry; key rotation partitions caches by key fingerprint.
469
+
470
+ Each scope names an organization or an exact owner/repository and explicit
471
+ read or read-write access. Exact repository grants can narrow their organization
472
+ grant. Org grants require an organization installation with All repositories,
473
+ including future repositories. Exact grants can use selected-repository installs.
474
+ A grant binds repository IDs for the provider instance; reconfigure after reviewing
475
+ a replacement repository or installation. Set readOnly:true for deployment-wide
476
+ write refusal. Only deployment code can grant workflows:"write", and only on a
477
+ read-write scope. A merge requires this explicit grant because GitHub's head-SHA
478
+ guard does not bind a concurrent base retarget.
479
+
480
+ Enable only vendor permissions needed by the workflows: Metadata read for
481
+ repository lookup; Issues read for issues/comments/labels; Pull requests read
482
+ for PRs/reviews/review comments/changed files/PR commits; Contents read for
483
+ repository commits/comparisons/contents/releases; Actions read for workflows,
484
+ runs and jobs. Release writes require Contents write. The guarded merge retains
485
+ Contents, Pull requests and Workflows write. Code search retains Contents read
486
+ and GitHub's own search restrictions. Each operation token is narrowed to its
487
+ reviewed permission and repository IDs; an org grant does not permit org admin.
488
+
489
+ The four github_api tools cover a pinned operation index with a bounded reviewed
490
+ repository read and release-write allowlist. All other operations are refused.
491
+ Use search_scoped for account data search and merge_pull_request for merges; the
492
+ corresponding raw routes are refused. Native tools present these same operations
493
+ and enforcement. Each named list defaults to 30 items, maximum 100. Search
494
+ continuation visits one partition page per call, at most twenty partitions and
495
+ ten vendor pages per partition; incomplete_results preserves capped/incomplete
496
+ searches. Cursors bind the configured grants, arguments, limit and deployment storage.
497
+ Keep the same limit with a cursor. Omission uses 30 and is accepted for a cursor
498
+ issued with limit 30; other limits must be repeated. Mismatches name the expected limit.
499
+
500
+ The transport reads at most 4 MiB per response. Inline UTF-8 file text and patch
501
+ values are redacted before a 32,768-character cut, with dot paths in truncated.
502
+ File contents retain base64 encoding; the character bound applies after decoding.
503
+ Use `/repos/alice/widget/contents/src/index.ts` for a nested file and
504
+ `/repos/alice/widget/contents` for the root directory. Contents paths must be
505
+ canonical relative paths, without dot/empty segments, backslashes or encoded
506
+ traversal. Encode branch-name slashes as `%2F` in `commits/{ref}` and
507
+ `compare/{basehead}`. Owner-prefixed object refs and cross-repository compares are
508
+ refused before authentication. PR-list head filters require `login:branch`, for
509
+ example `head:"alice:feature/x"`; they filter the selected repository's PRs.
510
+ Bare head branches are refused because GitHub silently ignores them. The base
511
+ filter stays a branch name. Configured App private keys are withheld from echoed content.
512
+ Identifiers remain beside cut patches. Raw diffs, binary files, log downloads,
513
+ archives, uploads and secret/admin operations are unavailable. Download URLs and
514
+ credentials remain withheld. fields narrows safe output and does not reduce the
515
+ bytes the vendor sends. Directory listings and search also have vendor caps;
516
+ missing content/patches do not establish completeness.
517
+
518
+ ## Cloudflare
519
+
520
+ `cloudflare()` connects the reviewed v4 API with an operator-managed credential.
521
+
522
+ ```ts
523
+ import { cloudflare } from "@zackbart/connecta/providers/cloudflare";
524
+
525
+ const edge = cloudflare("edge", {
526
+ purpose: "Domain DNS, Workers and storage administration",
527
+ auth: { type: "apiToken" },
528
+ pin: { accountIds: ["0123456789abcdef0123456789abcdef"] },
529
+ });
530
+ ```
531
+
532
+ **Credential.** Prefer a scoped user or account API token with only the required
533
+ permissions and resources. Enter it in the operator UI. Verification first tests
534
+ a user token; with `accountId`, it can test an account-owned token too. A legacy
535
+ `auth: { type: "globalApiKey" }` uses the key owner's email and API key fields;
536
+ it requires `pin` unless `unpinned: true` explicitly accepts the whole estate.
537
+ R2 accepts API tokens only. `authScope: "personal"` partitions human credentials;
538
+ agents use the shared credential.
539
+
540
+ **Options and boundaries.** `pin.accountIds` includes zones owned by those
541
+ accounts; `pin.zoneIds` admits those zones directly. Every call checks its named
542
+ account/zone ids, and scoped lists filter their results. Unscoped operations
543
+ are refused except reviewed public and identity/list routes. `accountId` and
544
+ `zoneId` fill existing path placeholders and do not impose a boundary; use `pin`
545
+ for that. Account pins may spend an extra zone-ownership read. `readOnly: true`
546
+ omits and refuses writes. No argument or sensitive-data option returns secrets;
547
+ credential values and private destinations remain unavailable. `baseUrl` is an
548
+ HTTPS proxy override (HTTP is allowed on loopback for tests).
549
+
550
+ **Vendor prerequisites.** Grant the token the required DNS, Workers, KV, R2 or
551
+ Analytics permissions for the pinned resources. Connector pins narrow the token;
552
+ they grant no additional Cloudflare permission. Global API Keys cannot change
553
+ user settings or memberships through this connector.
554
+
555
+ **Limits.** Cloudflare's global limit is 1,200 requests per five minutes per
556
+ user across the dashboard and all tokens. Connecta approximates that window
557
+ per runtime and defaults to six simultaneous requests (`maxConcurrency`). Zone
558
+ ownership checks are capped at three per call and 60 per five minutes per
559
+ connection. Responses are bounded to 8 MiB and calls to 60 seconds. Named
560
+ account/zone lists default to 20 rows, accept `limit` from 5 to 50, and return
561
+ signed `cursor` continuations. Hatch limits retain each operation's pinned
562
+ bounds; put its signed `page.nextCursor` into the parameter named by `page.param`
563
+ and `page.in`. Keep the other arguments unchanged. Discovery is bounded to eight
564
+ hits/16 KiB per search and 32 KiB per details page, with explicit continuation.
565
+
566
+ ## Church Community Builder
567
+
568
+ ```ts
569
+ import { ccb } from "@zackbart/connecta/providers/ccb";
570
+
571
+ const crm = ccb("crm", {
572
+ purpose: "Household and group coordination",
573
+ environment: "production",
574
+ mode: "system",
575
+ clientId: env.CCB_CLIENT_ID,
576
+ clientSecret: env.CCB_CLIENT_SECRET,
577
+ });
578
+ ```
579
+
580
+ Obtain a v2 OAuth client from Pushpay and register the deployment's exact
581
+ `<publicUrl>/oauth/callback/crm` redirect URI and required scopes. Production
582
+ and sandbox clients use different hosts and credentials. `environment` and
583
+ `mode` are required. System Auth stores one shared church grant authorized by
584
+ an administrator. Identity Auth stores personal grants with each person's
585
+ permissions and requires prior System Auth for the same client. Start consent
586
+ from the connector's operator connection page; catalog and status reads do
587
+ not start consent. The connector manages token rotation.
588
+
589
+ `access: "read"` is the default. `access: "read-write"` requests the maintained
590
+ write scope set; alternatively specify a nonempty exact `scopes` list.
591
+ `access` and `scopes` are exclusive. Read-only configured scopes omit the
592
+ write hatch and never dispatch a write. `readOnly: true` additionally enforces
593
+ read-only access on every endpoint. Optional `subdomain` pre-fills consent.
594
+
595
+ `sensitiveFields: "drop"` is the default. `"return"` permits the documented
596
+ sensitive fields through the hatches; named projections stay narrow. OAuth
597
+ credentials, private file download destinations, payment-session links and
598
+ private calendar feeds remain withheld. No tool argument changes this boundary.
599
+ Advanced-search filters can still test
600
+ dropped sensitive fields, so matching rows can reveal their values by inference.
601
+ Where that matters, omit `read:advanced_searches` from the exact configured
602
+ OAuth scopes.
603
+
604
+ Named lists take `limit` equal to 25, 50, 75 or 100; the vendor default is 25.
605
+ `defaultPerPage` optionally chooses another allowed deployment default. Return
606
+ `page.nextCursor` unchanged as `cursor` and keep the same effective limit.
607
+ Named `page.total` is present only when CCB states an exact `X-Total` count. Indexed reads retain vendor
608
+ `query.per_page` plus a top-level signed `cursor`; use operation details for
609
+ filters and JSON request bodies. Advanced POST searches are reads.
610
+
611
+ The default admission rule is a per-runtime, per-endpoint rolling window of
612
+ 60 calls per minute. It does not coordinate other runtimes sharing this OAuth
613
+ client or emulate the vendor's no-burst exceptions. Individual gets allow one
614
+ call per second, individual advanced searches one per five seconds, and
615
+ category schedule lists one per two seconds. Override `callAdmission` to match
616
+ shared usage, and respect the vendor's rate-limit wait. Replies are bounded
617
+ at 8 MiB. The legacy per-church v1 XML API is outside this provider's scope.
618
+
619
+ ## Gmail
620
+
621
+ Gmail uses a service account with Workspace domain-wide delegation. Enable
622
+ Gmail API, create a service account with no IAM roles, and provide its JSON
623
+ key as a deployment secret. A Workspace super administrator grants the
624
+ service account's numeric client id exactly these scopes in Admin console →
625
+ Security → Access and data control → API controls → Domain-wide delegation:
626
+ `https://www.googleapis.com/auth/gmail.readonly` and
627
+ `https://www.googleapis.com/auth/gmail.compose`. Changes can take up to 24 hours.
628
+ If key creation is blocked, an organization policy administrator must review
629
+ `iam.disableServiceAccountKeyCreation` for that project.
630
+
631
+ ```ts
632
+ import { gmail } from "@zackbart/connecta/providers/gmail";
633
+
634
+ gmail("mail", {
635
+ purpose: "Read mail and prepare reply drafts",
636
+ serviceAccount: env.GOOGLE_SERVICE_ACCOUNT_JSON,
637
+ subject: (identity) => mailboxes[identity.principal?.id ?? ""],
638
+ });
639
+ ```
640
+
641
+ Map admitted callers to Workspace addresses in deployment code. A fixed
642
+ `subject: "alice@example.com"` instead shares that mailbox with every caller.
643
+ Anonymous callers cannot use a subject function. No tool argument selects a
644
+ mailbox. Both modes retain ownerless-pool hiding and the endpoint's read-only
645
+ policy. `gmail.compose` technically permits sending; this provider admits no
646
+ send route. Drafts are written only through `create_draft` and `update_draft`.
647
+ Gmail is the documented three-hatch exception to the four-hatch default.
648
+
649
+ Named reads return projected records or `{ items, page }`; `fields` narrows a
650
+ record or each list item. Size cuts appear in `truncated`. The pinned index
651
+ contains 79 methods and admits eleven reads. Settings, forwarding,
652
+ delegation, CSE, S/MIME, watches, mailbox mutation and every send method are
653
+ refused. Full MIME JSON crosses the same decoded sent-secret safety boundary.
654
+ Use the named attachment tool for immutable part identity, charset rendering,
655
+ one-MiB download bounds and decoded-size validation.
656
+
657
+ A hatch read has three layers: the direct-call delivery contains the tool's
658
+ `{ status, data, page? }` result, whose `data` is Google's JSON. In a program:
659
+
660
+ ```js
661
+ const { data: first } = await connecta.call("mail.gmail_api_read", {
662
+ path: "/messages",
663
+ query: { q: "is:unread from:alice@example.com", maxResults: 10 },
664
+ fields: ["messages.id"],
665
+ });
666
+ return { messageIds: first.data.messages, continuation: first.page };
667
+ ```
668
+
669
+ On continuation repeat the same arguments and add top-level
670
+ `cursor: first.page.nextCursor`. Use `query.maxResults` from 1 to 500. Omit raw `query.pageToken`, even if Google's
671
+ safe body includes it. The last page has no cursor. An empty page can still
672
+ continue, and `resultSizeEstimate` never establishes an exact total. Named
673
+ thread/content cursors are separate and reject changed earlier content.
674
+
675
+ ## Google Docs
676
+
677
+ ```ts
678
+ import { docs } from "@zackbart/connecta/providers/docs";
679
+
680
+ const documents = docs("documents", {
681
+ purpose: "Team notes and drafts",
682
+ serviceAccount: env.GOOGLE_SERVICE_ACCOUNT_JSON,
683
+ subject: (identity) => accounts[identity.principal?.id ?? ""],
684
+ });
685
+ ```
686
+
687
+ Enable Google Docs API in the service account's Google Cloud project. Create
688
+ a service account and JSON key; no project IAM role grants document access.
689
+ A Workspace super administrator must authorize its numeric client ID for
690
+ `https://www.googleapis.com/auth/documents` under Admin console → Security →
691
+ Access and data control → API controls → Manage Domain Wide Delegation.
692
+ Add this scope to the same entry as other Workspace products; changes can take
693
+ 24 hours. Store the key as a deployment secret. If key creation is blocked,
694
+ an organization administrator must resolve the key-creation policy.
695
+
696
+ Configure inbound auth and map admitted identities to Workspace addresses.
697
+ Each call acts as that user and reaches documents shared with them in Drive.
698
+ An unmapped caller is refused. A fixed `subject: "alice@example.com"` instead
699
+ shares one Workspace account across callers. See [Workspace delegation](./auth.md#pool-owners-for-google-workspace).
700
+ `readOnly: true` omits and refuses all writes. Optional `instructions` append
701
+ connection-specific guidance; `baseUrl` is an operator-controlled API root.
702
+ There is no configurable sensitive-field set: document text is requested data.
703
+
704
+ Six named tools retain rendered reads and common edits. Four `docs_api_*`
705
+ hatches discover all three pinned methods and expose JSON reads and writes.
706
+ `docs_api_search` searches operations; use Drive to find document data.
707
+ Batch hatch writes require `writeControl.requiredRevisionId`, 1–100 requests,
708
+ and exactly one supported generally available request kind each. Preview
709
+ comment and suggestion writes are refused. All hatch writes are destructive.
710
+ The additive named create/append/insert catalog entries retain
711
+ `destructiveHint:false` and remain writes. Writes
712
+ are never replayed and take no idempotency key. A named create with text uses
713
+ two explicit steps: one create POST and at most one initial-text batch POST.
714
+
715
+ `get_document` supports `fields`, a shared text budget (20,000 characters by
716
+ default, at most 1,000,000), and 64 KiB pages of UTF-16 index rows. Keep the
717
+ same read arguments when passing its signed content cursor. Changed content
718
+ requires a fresh read. Docs has no vendor list pagination. `truncated` lists
719
+ size cuts; `notRendered` describes semantic omissions. Direct rendering
720
+ results can reach 4 MiB when `maxChars` is explicit; programs carry at most
721
+ 256 KiB per result. Read one tab or reduce `maxChars` to fit.
722
+
723
+ For complete styles or named ranges, use a hatch read:
724
+
725
+ ```ts
726
+ const reply = await connecta.call("documents.docs_api_read", {
727
+ path: "/documents/doc_123",
728
+ query: { includeTabsContent: true },
729
+ fields: ["documentId", "revisionId", "tabs"],
730
+ });
731
+ // The guest delivery wraps the hatch value; vendor data is under data.data.
732
+ const document = reply.data.data;
733
+ ```
734
+
735
+ With `includeTabsContent:true`, named ranges are in
736
+ `document.tabs[].documentTab.namedRanges`; select `tabs` as above to read them.
737
+ `fields` selects vendor-body paths. Hatch values are `{status,data}` inside
738
+ Connecta's [guest call delivery](./code-mode.md). Caller headers,
739
+ credential query arguments, alternate origins and media transport are refused.
740
+ A 404 cannot distinguish missing from inaccessible documents and reports
741
+ `connector_call_failed`; only reviewed revision-precondition facts report
742
+ `conflict`. Token and JSON response handling use the same safety boundary as
743
+ named tools.
744
+
745
+ Google Docs image `contentUri` values are temporary access capabilities and are
746
+ withheld in all responses. Authored links and image `sourceUri` remain available.
747
+
748
+ ## Google Sheets
749
+
750
+ ```ts
751
+ import { sheets } from "@zackbart/connecta/providers/sheets";
752
+
753
+ const workbook = sheets("workbook", {
754
+ purpose: "Review tables and quarterly budgets",
755
+ serviceAccount: env.GOOGLE_SERVICE_ACCOUNT_JSON,
756
+ subject: (identity) => accounts[identity.principal?.id ?? ""],
757
+ });
758
+ ```
759
+
760
+ **Authentication.** Enable Google Sheets API in a Google Cloud project. Create
761
+ a service account with domain-wide delegation and a JSON private key; no
762
+ project IAM role grants spreadsheet access. In the Workspace Admin console,
763
+ a super admin adds its numeric client id to API controls → Domain Wide
764
+ Delegation with `https://www.googleapis.com/auth/spreadsheets`. Add to an
765
+ existing client's scopes instead of replacing them. A grant can take up to
766
+ 24 hours to propagate. Supply the key through the deployment's secret store;
767
+ there is no operator credential slot or per-user consent flow. If organization
768
+ policy disables key creation, a Workspace administrator must authorize it.
769
+
770
+ **Options and boundaries.** `subject` is a fixed Workspace address or a
771
+ function mapping admitted identities. Unmapped callers fail `auth_required`;
772
+ agent pools need an owner unless a fixed subject is configured. Configure
773
+ inbound authentication. `readOnly: true` omits and refuses writes, including
774
+ hatch mutations. `instructions` appends deployment guidance. `baseUrl` may
775
+ select a confined HTTPS proxy (HTTP loopback for tests). Cell values, notes,
776
+ formulas and metadata are requested content; no `sensitiveFields` switch is
777
+ provided. Sent credentials and private signed destinations remain withheld.
778
+
779
+ **Coverage and limits.** Thirteen tools include the nine named workflows and
780
+ four indexed hatches over all 17 pinned Sheets v4 methods. Seven are reviewed
781
+ reads, including three POST methods: spreadsheet/get values by data filter
782
+ and developer metadata search. Ten are writes. Generic batches accept 1–100
783
+ requests, exactly one reviewed kind each; preview comments and external
784
+ data-source kinds are refused. Values use at most 20 read/clear ranges,
785
+ 100 batch write ranges, 10,000 rows per value block and 50,000 cells per write.
786
+ No new OAuth scopes, revision guarantee or automatic write replay is added.
787
+
788
+ `get_values` pages whole rows with `maxCells` (2,000 default, 10,000 maximum),
789
+ `maxBytes` (192 KiB default, 4 MiB maximum) and `maxCellChars` (5,000 default,
790
+ 50,000 maximum). A row that cannot fit is refused before returning that page;
791
+ narrow the columns or adjust the budgets. Use large byte budgets only with
792
+ direct calls; reduce within code for its bounded result bridge. Sheets has no
793
+ vendor page token. Standard result `fields` selects dot paths after safety;
794
+ Google's `query.fields` and batch field masks are distinct vendor syntax.
795
+
796
+ For full metadata, read `workbook.sheets_api_read` with
797
+ `{ method: "GET", path: "/spreadsheets/workbook_123" }`. A direct call's
798
+ Connecta delivery contains the hatch result `{ status, data }`; in code,
799
+ `const { data: reply } = await connecta.call("workbook.sheets_api_read", args)`
800
+ and `reply.data.sheets` accesses the vendor sheets. Paths are relative to
801
+ `/v4`. Range colons can be literal or `%3A`; action suffixes such as `:append`
802
+ must be literal. Prefer `append_values` for pinned `INSERT_ROWS`; generic
803
+ append's explicit `OVERWRITE` can overwrite cells.
804
+
805
+ Named-read field selection keeps `truncated` metadata, and value reads keep
806
+ `page` for continuation. `get_values` cursors are signed and bind the connection
807
+ and read arguments through the shared deployment store. Mapped Workspace
808
+ subjects also bind the admitted caller. Restart an old unsigned continuation
809
+ after upgrading; changing mapped callers requires a new read.
810
+
811
+ ## Google Forms
812
+
813
+ ```ts
814
+ import { forms } from "@zackbart/connecta/providers/forms";
815
+
816
+ forms("forms", {
817
+ purpose: "Registration forms and response summaries",
818
+ serviceAccount: env.GOOGLE_SERVICE_ACCOUNT_JSON,
819
+ subject: (identity) => accounts[identity.principal?.id ?? ""],
820
+ });
821
+ ```
822
+
823
+ Enable the Google Forms API in a Google Cloud project. Create a service
824
+ account without project IAM roles, enable domain-wide delegation, and store
825
+ its JSON key as a deployment secret. A Workspace super administrator must
826
+ add the key's numeric `client_id` to Admin console → Security → Access and
827
+ data control → API controls → Manage Domain Wide Delegation, with exactly
828
+ `https://www.googleapis.com/auth/forms.body,https://www.googleapis.com/auth/forms.responses.readonly`.
829
+ A grant can take up to 24 hours to apply. If key creation is disabled by
830
+ `iam.disableServiceAccountKeyCreation`, an organization policy administrator
831
+ must permit it for the project.
832
+
833
+ Configure inbound authentication. `subject` may be one fixed Workspace
834
+ address or a function mapping the admitted identity to an address. Calls
835
+ without a mapped account fail `auth_required`; tool arguments cannot select
836
+ an account. A fixed subject gives every admitted caller that account's view.
837
+ Each logical call resolves its subject once, including form/answer joins.
838
+ A missing form and one the account cannot open are indistinguishable.
839
+
840
+ `readOnly: true` omits and refuses writes. There is no configurable sensitive
841
+ field set: answers, respondent email and quiz answer keys are requested data
842
+ on both named tools and the hatch. Vendor-minted temporary image URLs and
843
+ credentials remain permanently withheld. Listing forms, sharing and deleting
844
+ files require a separate Drive connection and scopes. Publish-settings
845
+ mutation and every watch operation remain refused even though discoverable.
846
+
847
+ Named responses default to 25 items, at most 100, and may end earlier for
848
+ size. Results target 240 KiB; vendor responses are bounded at 8 MiB.
849
+ `list_responses` and `get_response` each read both the form and its answers.
850
+ Batches allow 1–100 reviewed request objects and require a current revision
851
+ on the batch wrapper and hatch. Google supplies no idempotency key. Set
852
+ `callAdmission` for the deployment's shared quota; the connector does not
853
+ reserve a Workspace-wide quota.
854
+
855
+ ## Google Slides
856
+
857
+ ```ts
858
+ import { slides } from "@zackbart/connecta/providers/slides";
859
+
860
+ const decks = slides("decks", {
861
+ purpose: "Team presentations",
862
+ serviceAccount: env.GOOGLE_SERVICE_ACCOUNT_JSON,
863
+ subject: (identity) => accounts[identity.principal?.id ?? ""],
864
+ });
865
+ ```
866
+
867
+ **Authentication.** Enable the Google Slides API in a Google Cloud project.
868
+ Create a service account and JSON key; no project IAM role grants access to
869
+ users' decks. A Workspace super admin must add its numeric client ID under
870
+ Security → Access and data control → API controls → Manage Domain Wide
871
+ Delegation, with `https://www.googleapis.com/auth/presentations`. The grant
872
+ can take up to 24 hours to apply. If key creation is blocked by
873
+ `iam.disableServiceAccountKeyCreation`, an organization policy administrator
874
+ can allow it for that project. Store the key in a deployment secret.
875
+
876
+ Configure inbound authentication and a subject mapping for admitted callers.
877
+ A fixed `subject: "alice@example.com"` acts as one shared account; a function
878
+ maps the admitted identity to an account. An agent uses its pool owner unless
879
+ a fixed account is configured. Unmapped callers fail `auth_required` before
880
+ minting; no tool selects another subject. A deck's absence and lack of access
881
+ are indistinguishable. Delegation is resolved when a data call needs it.
882
+
883
+ **Options and boundaries.** `readOnly: true` omits and refuses every write.
884
+ `baseUrl` is an HTTPS proxy override, or HTTP on loopback for tests. There is
885
+ no configurable sensitive-field set; field selection only narrows replies.
886
+ The five-method frozen index includes four generic executable JSON routes.
887
+ Thumbnails mint temporary access links and are refused in the generic hatch;
888
+ `get_slide_thumbnail` remains the reviewed named workflow. Existing comment
889
+ methods and request kinds remain available without adding preview methods.
890
+ Slides cannot search, share, move or delete presentation files; use Drive for
891
+ those separately authorized workflows.
892
+
893
+ **Limits.** Named content windows default to 20 slides (maximum 100), 50 page
894
+ elements (maximum 500), 100 layout rows (maximum 500), and 50 comment threads
895
+ (maximum 500). Batches allow 1–100 reviewed requests and the generic batch
896
+ requires `writeControl.requiredRevisionId`. Revision ids are preconditions,
897
+ not idempotency keys. Deck and comment changes can save separately; uncertain
898
+ comment saves require reading both outcomes before another edit. Responses
899
+ are bounded at 16 MiB; named results use a smaller content budget and provide
900
+ continuation. Set `callAdmission` when the deployment needs a tighter budget.
901
+
902
+ ## Google Drive
903
+
904
+ Import `drive` from `@zackbart/connecta/providers/drive`. Enable Google Drive API
905
+ in a Google Cloud project, create a service account with domain-wide delegation,
906
+ and retain its JSON private key in a deployment secret. As a Workspace super
907
+ admin, authorize the service account's numeric client id for exactly
908
+ `https://www.googleapis.com/auth/drive`. Delegation changes can take 24 hours.
909
+ No Google Cloud IAM role grants access to a person's Drive.
910
+
911
+ ```ts
912
+ drive("files", {
913
+ purpose: "Team files and shared drives",
914
+ serviceAccount: env.GOOGLE_SERVICE_ACCOUNT_JSON,
915
+ subject: (identity) => accounts[identity.principal?.id ?? ""],
916
+ });
917
+ ```
918
+
919
+ The subject mapping is deployment code. An agent uses its pool owner's mapped
920
+ identity; an ownerless pool has no delegated account unless `subject` is a fixed
921
+ Workspace address. Anonymous requests cannot invoke a subject function. The
922
+ scope reaches everything that user can open, including shared drives. The
923
+ provider's reviewed surface confines the available actions. Options are the
924
+ shared Workspace `purpose`, `instructions`, `serviceAccount`, `subject` and
925
+ optional `baseUrl`; there is no caller-selected account or sensitive-data mode.
926
+
927
+ The 17 named workflows remain available. `drive_api_search` and
928
+ `drive_api_details` discover the frozen 64-method inventory; `drive_api_read`
929
+ and destructive `drive_api_write` execute only 13 reviewed JSON metadata methods.
930
+ Refusals explain unreviewed methods. All grants use `share_file`, including
931
+ `anyone` and domain grants. There is no hatch media upload/download, watch,
932
+ permanent deletion or ownership transfer. Named content tools keep their bounded
933
+ export/download and the separately confined upload connection.
934
+
935
+ Named lists return `{ items, page }`; terminal pages omit `nextCursor`.
936
+ Continuation is bound to the connection, caller and listing arguments; named
937
+ `fields` and `maxBytes` may change between pages. A local byte cap can end a page
938
+ early, and a changed source page fails `conflict`. Named page
939
+ limits default to 25 and allow 1–100 rows; whole-result budgets default to 192 KiB
940
+ and allow 64 KiB–4 MiB. Large direct results use Connecta's result pager; keep
941
+ the default for programs. Named uploads allow one million text characters or
942
+ one MiB of decoded binary; content reads may return a whole-withheld binary
943
+ when credential scanning changes any byte. Size reports use `truncated` paths.
944
+
945
+ Hatch paging keeps Google's query parameters inside `query`. Omit `pageToken`
946
+ on the first request; pass the signed `page.nextCursor` as top-level `cursor`
947
+ thereafter. An empty vendor page may continue. `query.fields` is Google's wire
948
+ mask; Connecta's `fields` narrows safe returned JSON and preserves paging.
949
+ `incompleteSearch` describes incomplete corpus search, never an exact total.
950
+
951
+ ```js
952
+ const { data: result } = await connecta.call("files.drive_api_read", {
953
+ path: "/files/file_123/revisions",
954
+ query: { pageSize: 20 },
955
+ fields: ["revisions.id", "revisions.modifiedTime"],
956
+ });
957
+ const revisions = result.data.revisions;
958
+ const cursor = result.page?.nextCursor;
959
+ ```
960
+
961
+ The outer `data` is Connecta delivery; the hatch's `result.data` is the Google
962
+ body and `result.page` carries continuation. Resource keys, decryption JWTs and
963
+ private download destinations remain withheld on named and hatch responses.
964
+ A 404 does not prove absence. Auxiliary lookup failures send no move; an actual
965
+ write failure can have an unknown outcome and requires a read before repetition.