@zackbart/connecta 0.34.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +62 -105
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2051 -1160
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +663 -271
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +15 -7
  53. package/dist/connectors/api-connector.js +147 -57
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/option-shapes.js +1 -1
  58. package/dist/connectors/remote-mcp.d.ts +12 -30
  59. package/dist/connectors/remote-mcp.js +960 -564
  60. package/dist/d1.js +10 -243
  61. package/dist/derived-context.js +5 -0
  62. package/dist/describe-config.d.ts +5 -1
  63. package/dist/describe-config.js +3 -0
  64. package/dist/downstream-input.js +347 -260
  65. package/dist/errors.d.ts +87 -6
  66. package/dist/errors.js +114 -4
  67. package/dist/execute.js +87 -50
  68. package/dist/executor-admission.js +3 -0
  69. package/dist/executors/quickjs.js +163 -112
  70. package/dist/guarded-transport.js +50 -0
  71. package/dist/guest-runtime.js +1 -1
  72. package/dist/http/client.js +439 -0
  73. package/dist/http/errors.js +558 -0
  74. package/dist/http/fields.js +49 -0
  75. package/dist/http/hatch-paging.js +318 -0
  76. package/dist/http/hatch.js +1279 -0
  77. package/dist/http/json-schema.js +267 -0
  78. package/dist/http/node-transport.js +241 -0
  79. package/dist/http/oauth.js +162 -0
  80. package/dist/http/paging.js +228 -0
  81. package/dist/http/provider.js +221 -0
  82. package/dist/http/safety.js +82 -0
  83. package/dist/http/services.js +79 -0
  84. package/dist/http/tools.js +383 -0
  85. package/dist/http/vendor-index.js +138 -0
  86. package/dist/http/vendor.js +448 -0
  87. package/dist/http/write-request.js +66 -0
  88. package/dist/http-policy.d.ts +11 -0
  89. package/dist/http-policy.js +45 -0
  90. package/dist/inbound-credential.js +1 -1
  91. package/dist/index.d.ts +2 -2
  92. package/dist/index.js +4 -0
  93. package/dist/invocation-auth.js +30 -19
  94. package/dist/invocation.js +221 -87
  95. package/dist/mcp-result.js +0 -4
  96. package/dist/membership.d.ts +4 -0
  97. package/dist/meta-output.js +1 -1
  98. package/dist/meta-tools.js +534 -408
  99. package/dist/native-recovery.js +52 -0
  100. package/dist/native-tools.js +382 -0
  101. package/dist/node.d.ts +4 -3
  102. package/dist/node.js +45 -8
  103. package/dist/oauth-handoff.js +177 -104
  104. package/dist/oauth-partition.js +6 -20
  105. package/dist/oauth-sealing.js +6 -7
  106. package/dist/operation-vocabulary.js +101 -0
  107. package/dist/operator-record.d.ts +2 -2
  108. package/dist/operator-record.js +17 -4
  109. package/dist/operator-ui/agents.d.ts +5 -4
  110. package/dist/operator-ui/agents.js +17 -7
  111. package/dist/operator-ui/config-summary.js +8 -4
  112. package/dist/operator-ui/connection-map.js +9 -6
  113. package/dist/operator-ui/contract.d.ts +7 -3
  114. package/dist/operator-ui/endpoints.js +5 -14
  115. package/dist/operator-ui/fix-prompts.d.ts +1 -1
  116. package/dist/operator-ui/fix-prompts.js +0 -8
  117. package/dist/operator-ui/generated.js +3 -3
  118. package/dist/operator-ui/health.js +52 -0
  119. package/dist/operator-ui/model.d.ts +2 -3
  120. package/dist/operator-ui/overview.js +11 -19
  121. package/dist/operator-ui/setup-commands.js +0 -4
  122. package/dist/operator-ui/view.d.ts +5 -29
  123. package/dist/operator-ui/view.js +3 -59
  124. package/dist/program-writes.js +47 -26
  125. package/dist/provider-call-facts.d.ts +115 -0
  126. package/dist/provider-call-facts.js +182 -0
  127. package/dist/provider-call.d.ts +112 -0
  128. package/dist/provider-call.js +271 -0
  129. package/dist/provider.d.ts +71 -32
  130. package/dist/provider.js +134 -40
  131. package/dist/providers/_shared/google/hatch.js +91 -0
  132. package/dist/providers/_shared/google/kit.js +537 -0
  133. package/dist/providers/_shared/google/result-size.js +15 -2
  134. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  135. package/dist/providers/_shared/google/service-account.js +8 -4
  136. package/dist/providers/_shared/google/workspace.d.ts +8 -209
  137. package/dist/providers/_shared/google/workspace.js +7 -426
  138. package/dist/providers/_shared/rest/compact-index.js +86 -0
  139. package/dist/providers/_shared/rest/dispatch.js +3 -23
  140. package/dist/providers/_shared/rest/kit.js +546 -0
  141. package/dist/providers/_shared/rest/operation-index.js +230 -14
  142. package/dist/providers/_shared/rest/response-media.js +11 -0
  143. package/dist/providers/_shared/rest/tools.js +101 -78
  144. package/dist/providers/_shared/rest/value-safety.js +353 -195
  145. package/dist/providers/_shared/sensitive-fields.js +27 -0
  146. package/dist/providers/breeze/api.js +584 -0
  147. package/dist/providers/breeze/index.d.ts +3 -3
  148. package/dist/providers/breeze/index.js +67 -1420
  149. package/dist/providers/breeze/openapi.generated.js +60 -0
  150. package/dist/providers/breeze/skill.generated.js +2 -6
  151. package/dist/providers/breeze/tools.js +696 -0
  152. package/dist/providers/ccb/api.js +496 -0
  153. package/dist/providers/ccb/index.d.ts +17 -37
  154. package/dist/providers/ccb/index.js +77 -1702
  155. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  156. package/dist/providers/ccb/lib/constants.js +74 -0
  157. package/dist/providers/ccb/lib/guide.js +9 -0
  158. package/dist/providers/ccb/lib/verdicts.js +387 -0
  159. package/dist/providers/ccb/openapi.generated.js +397 -0
  160. package/dist/providers/ccb/safety.js +295 -0
  161. package/dist/providers/ccb/skill.generated.js +2 -6
  162. package/dist/providers/ccb/tools.js +853 -0
  163. package/dist/providers/cloudflare/api.js +1066 -0
  164. package/dist/providers/cloudflare/index.d.ts +7 -22
  165. package/dist/providers/cloudflare/index.js +80 -194
  166. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  167. package/dist/providers/cloudflare/lib/config.js +2 -0
  168. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  169. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  170. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  171. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  172. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  173. package/dist/providers/cloudflare/openapi.generated.js +3299 -3208
  174. package/dist/providers/cloudflare/{value-safety.js → safety.js} +538 -18
  175. package/dist/providers/cloudflare/skill.generated.js +2 -10
  176. package/dist/providers/cloudflare/tools.js +360 -0
  177. package/dist/providers/docs/api.js +51 -0
  178. package/dist/providers/docs/index.d.ts +1 -12
  179. package/dist/providers/docs/index.js +53 -1165
  180. package/dist/providers/docs/lib/constants.d.ts +18 -0
  181. package/dist/providers/docs/lib/constants.js +18 -0
  182. package/dist/providers/docs/lib/discovery.js +26 -0
  183. package/dist/providers/docs/lib/requests.js +48 -0
  184. package/dist/providers/docs/lib/schemas.js +168 -0
  185. package/dist/providers/docs/openapi.generated.js +16 -0
  186. package/dist/providers/docs/safety.js +54 -0
  187. package/dist/providers/docs/skill.generated.js +2 -6
  188. package/dist/providers/docs/tools.js +802 -0
  189. package/dist/providers/drive/api.js +177 -0
  190. package/dist/providers/drive/index.d.ts +1 -12
  191. package/dist/providers/drive/index.js +38 -1448
  192. package/dist/providers/drive/lib/constants.d.ts +6 -0
  193. package/dist/providers/drive/lib/constants.js +6 -0
  194. package/dist/providers/drive/lib/contracts.js +532 -0
  195. package/dist/providers/drive/lib/hatch.js +197 -0
  196. package/dist/providers/drive/openapi.generated.js +77 -0
  197. package/dist/providers/drive/safety.js +90 -0
  198. package/dist/providers/drive/skill.generated.js +2 -6
  199. package/dist/providers/drive/tools.js +1290 -0
  200. package/dist/providers/forms/api.js +71 -0
  201. package/dist/providers/forms/index.d.ts +1 -12
  202. package/dist/providers/forms/index.js +49 -1145
  203. package/dist/providers/forms/lib/constants.d.ts +14 -0
  204. package/dist/providers/forms/lib/constants.js +19 -0
  205. package/dist/providers/forms/lib/hatch.js +72 -0
  206. package/dist/providers/forms/openapi.generated.js +23 -0
  207. package/dist/providers/forms/safety.js +34 -0
  208. package/dist/providers/forms/skill.generated.js +2 -8
  209. package/dist/providers/forms/tools.js +1024 -0
  210. package/dist/providers/github/api.js +150 -0
  211. package/dist/providers/github/index.d.ts +4 -5
  212. package/dist/providers/github/index.js +30 -87
  213. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  214. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  215. package/dist/providers/github/lib/discovery.js +132 -0
  216. package/dist/providers/github/lib/operations.js +58 -0
  217. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  218. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  219. package/dist/providers/github/openapi.generated.js +1216 -0
  220. package/dist/providers/github/safety.js +216 -0
  221. package/dist/providers/github/skill.generated.js +2 -5
  222. package/dist/providers/github/tools.js +506 -0
  223. package/dist/providers/gmail/api.js +114 -0
  224. package/dist/providers/gmail/index.d.ts +1 -12
  225. package/dist/providers/gmail/index.js +73 -1621
  226. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  227. package/dist/providers/gmail/lib/constants.js +16 -0
  228. package/dist/providers/gmail/lib/index.js +173 -0
  229. package/dist/providers/gmail/lib/schemas.js +176 -0
  230. package/dist/providers/gmail/lib/threading.js +120 -0
  231. package/dist/providers/gmail/openapi.generated.js +92 -0
  232. package/dist/providers/gmail/safety.js +21 -0
  233. package/dist/providers/gmail/skill.generated.js +2 -6
  234. package/dist/providers/gmail/tools.js +1435 -0
  235. package/dist/providers/overflow/api.js +1008 -0
  236. package/dist/providers/overflow/index.d.ts +3 -17
  237. package/dist/providers/overflow/index.js +60 -1488
  238. package/dist/providers/overflow/skill.generated.js +2 -5
  239. package/dist/providers/overflow/tools.js +873 -0
  240. package/dist/providers/planning-center/api.js +467 -0
  241. package/dist/providers/planning-center/index.d.ts +6 -35
  242. package/dist/providers/planning-center/index.js +69 -2445
  243. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  244. package/dist/providers/planning-center/lib/constants.js +83 -0
  245. package/dist/providers/planning-center/lib/discovery.js +40 -0
  246. package/dist/providers/planning-center/lib/guide.js +39 -0
  247. package/dist/providers/planning-center/lib/json-api.js +83 -0
  248. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  249. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  250. package/dist/providers/planning-center/safety.js +188 -0
  251. package/dist/providers/planning-center/skill.generated.js +2 -27
  252. package/dist/providers/planning-center/tools.js +1010 -0
  253. package/dist/providers/sheets/api.js +133 -0
  254. package/dist/providers/sheets/index.d.ts +4 -16
  255. package/dist/providers/sheets/index.js +61 -1172
  256. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  257. package/dist/providers/sheets/lib/constants.js +14 -0
  258. package/dist/providers/sheets/lib/hatch.js +163 -0
  259. package/dist/providers/sheets/lib/requests.js +105 -0
  260. package/dist/providers/sheets/lib/schemas.js +138 -0
  261. package/dist/providers/sheets/openapi.generated.js +30 -0
  262. package/dist/providers/sheets/safety.js +27 -0
  263. package/dist/providers/sheets/skill.generated.js +2 -7
  264. package/dist/providers/sheets/tools.js +734 -0
  265. package/dist/providers/slides/api.js +147 -0
  266. package/dist/providers/slides/index.d.ts +2 -10
  267. package/dist/providers/slides/index.js +48 -2555
  268. package/dist/providers/slides/lib/constants.d.ts +11 -0
  269. package/dist/providers/slides/lib/constants.js +11 -0
  270. package/dist/providers/slides/lib/requests.js +60 -0
  271. package/dist/providers/slides/lib/schemas.js +565 -0
  272. package/dist/providers/slides/openapi.generated.js +18 -0
  273. package/dist/providers/slides/skill.generated.js +2 -6
  274. package/dist/providers/slides/tools.js +1968 -0
  275. package/dist/providers/stripe/api.js +401 -0
  276. package/dist/providers/stripe/index.d.ts +7 -27
  277. package/dist/providers/stripe/index.js +75 -191
  278. package/dist/providers/stripe/lib/config.d.ts +4 -0
  279. package/dist/providers/stripe/lib/config.js +2 -0
  280. package/dist/providers/stripe/openapi.generated.js +4 -3
  281. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  282. package/dist/providers/stripe/skill.generated.js +2 -10
  283. package/dist/providers/stripe/tools.js +77 -0
  284. package/dist/providers/tithely/api.js +531 -0
  285. package/dist/providers/tithely/index.d.ts +19 -0
  286. package/dist/providers/tithely/index.js +86 -965
  287. package/dist/providers/tithely/skill.generated.js +2 -5
  288. package/dist/providers/tithely/tools.js +426 -0
  289. package/dist/providers/vercel/api.js +551 -0
  290. package/dist/providers/vercel/index.d.ts +11 -25
  291. package/dist/providers/vercel/index.js +67 -261
  292. package/dist/providers/vercel/lib/config.d.ts +2 -0
  293. package/dist/providers/vercel/lib/config.js +2 -0
  294. package/dist/providers/vercel/lib/index.js +117 -0
  295. package/dist/providers/vercel/lib/logs.js +100 -0
  296. package/dist/providers/vercel/lib/pin.js +270 -0
  297. package/dist/providers/vercel/openapi.generated.js +398 -376
  298. package/dist/providers/vercel/{value-safety.js → safety.js} +261 -42
  299. package/dist/providers/vercel/skill.generated.js +2 -7
  300. package/dist/providers/vercel/tools.js +642 -0
  301. package/dist/redaction-identity.js +47 -0
  302. package/dist/redaction-marker.js +125 -0
  303. package/dist/registry.d.ts +30 -28
  304. package/dist/registry.js +446 -413
  305. package/dist/routes/access-tokens.js +1 -1
  306. package/dist/routes/actor-labels.js +1 -1
  307. package/dist/routes/connect.js +1 -1
  308. package/dist/routes/dispatch.js +103 -0
  309. package/dist/routes/mcp.js +170 -79
  310. package/dist/routes/oauth.js +3 -1
  311. package/dist/routes/operator.js +2 -2
  312. package/dist/routes/shared.d.ts +5 -4
  313. package/dist/routes/shared.js +244 -177
  314. package/dist/routes/skills.js +10 -8
  315. package/dist/routes/ui-config.js +27 -3
  316. package/dist/routes/ui-data.js +29 -22
  317. package/dist/routes/ui.js +1 -1
  318. package/dist/runtime/call-admission.js +0 -26
  319. package/dist/runtime/call-entry.js +30 -0
  320. package/dist/runtime/call.js +556 -0
  321. package/dist/runtime/connector-scope.js +7 -0
  322. package/dist/runtime/credential-probe.js +34 -0
  323. package/dist/runtime/executor.js +40 -0
  324. package/dist/runtime/native-storage.js +63 -0
  325. package/dist/runtime/registry.js +27 -0
  326. package/dist/runtime/request-scope.js +72 -0
  327. package/dist/runtime/run.js +15 -7
  328. package/dist/runtime/shared-read.js +34 -5
  329. package/dist/runtime/storage.js +34 -21
  330. package/dist/sent-secrets.d.ts +194 -37
  331. package/dist/sent-secrets.js +1743 -340
  332. package/dist/server.js +5 -56
  333. package/dist/skills.js +330 -224
  334. package/dist/sqlite.js +15 -14
  335. package/dist/storage/d1-copy.js +255 -0
  336. package/dist/storage/d1-driver.js +15 -0
  337. package/dist/storage/keys.js +28 -0
  338. package/dist/storage/sql-driver.js +88 -0
  339. package/dist/storage/sql-native.js +544 -0
  340. package/dist/storage/sql-schema.d.ts +6 -0
  341. package/dist/storage/sql-schema.js +15 -0
  342. package/dist/storage/sql.d.ts +14 -20
  343. package/dist/storage/sql.js +29 -535
  344. package/dist/timeout.js +0 -26
  345. package/dist/tool-safety.js +20 -10
  346. package/dist/types.d.ts +11 -99
  347. package/dist/upward.js +3 -0
  348. package/dist/usage-guide.js +3 -1
  349. package/dist/validate.d.ts +4 -2
  350. package/dist/validate.js +86 -9
  351. package/dist/version.d.ts +1 -1
  352. package/dist/version.js +1 -1
  353. package/dist/worker.js +312 -292
  354. package/dist/workspace-subject.js +5 -1
  355. package/dist/write-outcome.js +454 -34
  356. package/documentation/README.md +27 -7
  357. package/documentation/architecture.md +2550 -186
  358. package/documentation/auth.md +821 -98
  359. package/documentation/code-mode.md +56 -21
  360. package/documentation/deploying.md +164 -20
  361. package/documentation/hosted-mcp-migration.md +460 -0
  362. package/documentation/integrating.md +144 -105
  363. package/documentation/meta-tools.md +411 -34
  364. package/documentation/operating.md +28 -4
  365. package/documentation/operator-tests.md +11 -2
  366. package/documentation/operator-ui.md +103 -33
  367. package/documentation/provider-auth-migration.md +38 -63
  368. package/documentation/provider-migration-0.29.md +10 -5
  369. package/documentation/provider-migration-0.35.md +975 -0
  370. package/documentation/providers.md +965 -0
  371. package/examples/worker/AGENTS.md +23 -9
  372. package/examples/worker/README.md +254 -135
  373. package/examples/worker/alchemy.run.ts +116 -0
  374. package/examples/worker/gitignore +10 -0
  375. package/examples/worker/src/connecta.config.ts +23 -21
  376. package/examples/worker/wrangler.jsonc +14 -5
  377. package/guides/connecting-agents.md +157 -0
  378. package/guides/how-it-works.md +156 -0
  379. package/guides/safety-and-trust.md +153 -0
  380. package/package.json +27 -42
  381. package/templates/node/.env.example +3 -0
  382. package/templates/node/README.md +22 -2
  383. package/templates/node/docker-compose.yml +1 -0
  384. package/templates/node/package.json +3 -2
  385. package/templates/node/src/connecta.config.ts +8 -0
  386. package/dist/catalog-drift.d.ts +0 -134
  387. package/dist/catalog-drift.js +0 -493
  388. package/dist/providers/_shared/request-token.js +0 -83
  389. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  390. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  391. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  392. package/dist/providers/basecamp/index.d.ts +0 -43
  393. package/dist/providers/basecamp/index.js +0 -997
  394. package/dist/providers/basecamp/skill.generated.js +0 -9
  395. package/dist/providers/cloudflare/rest.d.ts +0 -37
  396. package/dist/providers/cloudflare/rest.js +0 -1078
  397. package/dist/providers/github/hosted.js +0 -218
  398. package/dist/providers/github/rest.js +0 -321
  399. package/dist/providers/infisical/index.d.ts +0 -7
  400. package/dist/providers/infisical/index.js +0 -713
  401. package/dist/providers/infisical/skill.generated.js +0 -8
  402. package/dist/providers/linear/index.d.ts +0 -55
  403. package/dist/providers/linear/index.js +0 -352
  404. package/dist/providers/linear/skill.generated.js +0 -8
  405. package/dist/providers/mixpanel/index.d.ts +0 -57
  406. package/dist/providers/mixpanel/index.js +0 -468
  407. package/dist/providers/mixpanel/operations.js +0 -20
  408. package/dist/providers/mixpanel/rest.js +0 -603
  409. package/dist/providers/mixpanel/skill.generated.js +0 -10
  410. package/dist/providers/mixpanel/value-safety.js +0 -16
  411. package/dist/providers/notion/index.d.ts +0 -65
  412. package/dist/providers/notion/index.js +0 -368
  413. package/dist/providers/notion/openapi.generated.js +0 -75
  414. package/dist/providers/notion/rest.d.ts +0 -24
  415. package/dist/providers/notion/rest.js +0 -1226
  416. package/dist/providers/notion/skill.generated.js +0 -11
  417. package/dist/providers/notion/value-safety.js +0 -56
  418. package/dist/providers/revenuecat/index.d.ts +0 -49
  419. package/dist/providers/revenuecat/index.js +0 -557
  420. package/dist/providers/revenuecat/skill.generated.js +0 -11
  421. package/dist/providers/stripe/rest.d.ts +0 -14
  422. package/dist/providers/stripe/rest.js +0 -402
  423. package/dist/providers/vercel/rest.d.ts +0 -20
  424. package/dist/providers/vercel/rest.js +0 -1020
  425. package/dist/providers/wispr-flow/index.d.ts +0 -14
  426. package/dist/providers/wispr-flow/index.js +0 -117
  427. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  428. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -1,13 +1,5 @@
1
1
  // Generated by scripts/generate-providers.mjs; do not edit.
2
2
  export const skill = {
3
- "content": "- Resolve account and zone ids before acting; never guess one. Ids are 32-character hex strings, and a zone is found by its domain name. Defaults and pins route a connector; Cloudflare's permissions still decide what the credential may do.\n- Read state before replacing, rolling back, or purging. For DNS, PATCH changes the fields you send and PUT replaces the whole record, so read the record first and send its type, name, and content with the change. Prefer a targeted cache purge (files, tags, hosts, or prefixes) over purging everything.\n- Cloudflare reports failures in `errors` with numeric codes and returns `success: false`; read the message instead of retrying the same call.\n- Honor rate-limit waits. Cloudflare documents 1,200 requests per five minutes per user, counted across the dashboard and every token; Connecta's per-runtime window approximates it, and a limited user is blocked for the rest of the window.\n- Treat every create, update, delete, purge, deploy, and upload as a write. For guest calls, classification, and routing, fetch `skills({ name: \"usage\" })`.\n",
4
- "instructionsHeading": "Account instructions",
5
- "fragments": {
6
- "oauth": "\n\n- The catalog is Cloudflare's own `search` and `execute`. `search` runs code against Cloudflare's OpenAPI document; `execute` runs code that may call any Cloudflare API endpoint the OAuth grant allows.\n- Connecta classifies `execute` as a write, even for a program that only reads, because one program can mix GET, POST, PUT, PATCH, and DELETE and no schema proves otherwise. A read-only endpoint therefore gets only `search` here. Deployments that need API reads from a read-only endpoint configure an API-token connector, whose `cloudflare_api_read` and named reads are reads.\n- Use `search` to find the exact method, path, and fields before writing an execute program. Do not guess an endpoint from product naming.\n- Keep returned values small. Filter and project inside the Cloudflare program, then reduce again inside Connecta's `execute_code` when several calls must be joined.\n- This connection has none of the REST connector's tools: no `cloudflare_api_*` validation against a pinned index, no `graphql_query`, no `cloudflare_api_upload`, and no account or zone pin. OAuth permissions are the boundary.\n",
7
- "oauth_tail": "- An `auth_required` failure means this connector's Cloudflare authorization is missing or expired: run `authorize_connector` for this connector id, then retry the same call unchanged.\n",
8
- "global_warning": "\n\nThis connector holds a Global API Key. It acts as its Cloudflare user with every permission that user has, in every account and zone the user belongs to, and nothing on Cloudflare's side narrows it. A mistaken write can reach production domains, billing, and members across all of them. Prefer reads, state the account and zone of every write, and stop when a request is ambiguous. Writes under `/user` and `/memberships` are refused. R2 accepts API tokens only, so R2 operations fail with this key.\n",
9
- "key": "\n\n- This is Connecta's REST connector to the Cloudflare v4 API, holding one operator-managed credential. `cloudflare_api_search` finds API operations in a pinned index (not records) and names the tool that calls each; `cloudflare_api_details` returns one operation's parameters and body with types, enums, and required names. Neither sends a request.\n- `cloudflare_api_read` calls GET operations plus reviewed read-only POSTs: analytics queries, Analytics Engine and SQL API queries, Log Explorer SQL, Vectorize queries, KV bulk get, telemetry queries, and validation checks. `cloudflare_api_write` calls every other POST, PUT, PATCH, and DELETE with `method` and `path` stated. D1 `…/query` and `…/raw`, Durable Object queries, Workers AI `…/ai/run`, AI Search and AutoRAG search (query rewriting runs billed models), monetization checks, and flag evaluation are writes: they can change data, cost money, or activate something.\n- Paths are concrete: substitute ids into the template search returned (`/zones/<zone id>/dns_records/<record id>`). Pass `query` and `body` as JSON named as details lists them; text operations (Analytics Engine SQL, Log Explorer SQL, Worker scripts) take a string body, and Vectorize inserts a list of objects sent as NDJSON. R2 calls accept `headers` with `cf-r2-jurisdiction` or `cf-r2-storage-class`. Encode a `/` inside an R2 object key or KV key name as `%2F`.\n- Every call is checked against the pinned index before it is sent. An unknown path returns the nearest operations; an unknown or missing parameter returns `validation.issues` with the accepted names. Nothing reached Cloudflare, so fix the call from that answer.\n- Under an account pin, each uncached zone-ownership check also spends the connector's call budget. Checks stay capped at three per call and 60 per five minutes per connector; an exhausted budget stops the check and the requested operation.\n- Results arrive as `{ status, data, page? }` with Cloudflare's envelope unwrapped: `data` is the `result`. On a list, pass `page.next` as the `page.param` query argument (`page` for numbered lists, `cursor` for KV, R2, and other cursor lists). Lists belong inside `execute_code`; pass `select` (dot paths such as `id` and `name`) to keep only the fields the question needs.\n- `list_zones` and `list_accounts` resolve names to ids; `verify_credential` separates a bad credential from a missing permission. `graphql_query` runs read-only GraphQL Analytics queries (mutations are refused before sending); filter every `zones` or `accounts` field by `zoneTag` or `accountTag`. A pinned connector sends one query per document, with every fragment it defines used.\n- Multipart, binary, and file bodies go through `cloudflare_api_upload`: Worker scripts and versions, KV values, R2 objects, Pages deployments, Images, Stream, DNS zone-file import, and Snippets. It takes `textBody`, `base64Body`, or multipart `parts`, never a local file.\n- Refused by design: every operation that mints, rotates, or hands back a credential (API tokens, Access service tokens, R2 temporary credentials, tunnel and Mesh node tokens, signing keys, registry credentials, direct-upload URLs, deploy hooks, preview and participant tokens), payment client secrets, URL Scanner captures (results, HAR, DOM, raw responses: they hold the scanned session's cookies and headers; use the scan search for verdicts), and GETs that act (an email unsubscribe, a PagerDuty connect). Stored and embedded secrets (Turnstile, TSIG, webhook and identity-provider secrets, Stream keys, Logpush destination credentials, probe and custom-provider headers, BGP keys, Zaraz variables, Hyperdrive database passwords, RealtimeKit storage credentials, transform-rule header values) and every environment or plain-text binding value (Pages, Containers, Workers, Builds; names and types stay) come back as `\"[redacted]\"` on every method. Notification, RealtimeKit, and data security webhook destinations keep only their scheme and host. Workers KV values are application data and come back as stored. Reviewed operations, and operations that take credentials, report Cloudflare's error codes without its error text. Worker script content is readable: it is code, and secret bindings are not part of it.\n- An `auth_required` failure means the credential is missing, revoked, or malformed: an operator must replace it in this connection in the operator UI, and `authorize_connector` returns that handoff. `provider_permission_denied` means the credential works but lacks this permission or resource, or the call is outside the pin; ask rather than retry.\n- Embedded URL safety uses reviewed paths plus global signing parameters. Generic credential-named query parameters (`code`, `key`, `token`, `sig`, etc.) and credential-looking fragments withhold the destination's entire query/fragment only in Workers build `lines`, Pages log `data.line`, and telemetry `$metadata.message`/`error` and raw string/object `source` payloads in both `events.events` and `invocations.*` on the reviewed log operations and vendor error text. Ordinary `code`/`key` links can therefore be false positives in these diagnostics. DNS TXT content, KV values, Access/Waiting Room custom HTML and other operator content keep those ordinary URL parameters byte for byte. Literal AWS SigV4/Google V4 `X-Amz-*`/`X-Goog-*` Signature, Credential and Security-Token values are withheld in every decoded string before projection. A withheld value is not the original: do not write it back. KV bulk writes also inspect decoded `value` fields with `base64: true` (up to Cloudflare's 25 MiB decoded value limit; malformed or oversized base64 is refused, and the host's inbound body cap still applies). All writes, including named writes and supported raw/base64/multipart uploads, reject URL destinations whose own query/fragment contains the exact `[redacted]` placeholder, plain or encoded, with `invalid_args` before dispatch. Admission iteratively checks every JSON key and value within the host's accepted request size, without separate depth or node-count ceilings; cyclic direct arguments are refused. A marker outside the destination remains ordinary text. Split strings, encoded host/signing names, bare hosts without `//`, and opaque bearer paths remain outside this scan. Binary responses represented as base64, including Worker JavaScript served as `application/javascript`, are returned unchanged and are not decoded/scanned. An envelope cursor that would change under URL sanitizing is omitted rather than echoed or reused.\n",
10
- "shared": "- Resolve account and zone ids before acting; never guess one. Ids are 32-character hex strings, and a zone is found by its domain name. Defaults and pins route a connector; Cloudflare's permissions still decide what the credential may do.\n- Read state before replacing, rolling back, or purging. For DNS, PATCH changes the fields you send and PUT replaces the whole record, so read the record first and send its type, name, and content with the change. Prefer a targeted cache purge (files, tags, hosts, or prefixes) over purging everything.\n- Cloudflare reports failures in `errors` with numeric codes and returns `success: false`; read the message instead of retrying the same call.\n- Honor rate-limit waits. Cloudflare documents 1,200 requests per five minutes per user, counted across the dashboard and every token; Connecta's per-runtime window approximates it, and a limited user is blocked for the rest of the window.\n- Treat every create, update, delete, purge, deploy, and upload as a write. For guest calls, classification, and routing, fetch `skills({ name: \"usage\" })`.\n",
11
- "key_tail": "- Cloudflare answers a rate limit with HTTP 429; the failure carries `retryAfterMs`. Failed authentication is limited separately (code 10502), so diagnose a credential once with `verify_credential` rather than retrying calls.\n"
12
- }
3
+ "content": "## Accounts, domains and records\n\nResolve account and zone ids before acting. A zone is a domain, found by its name;\nits account id joins it to the account inventory. Cloudflare ids are normally\n32-character hex strings. A default id routes a request; a pin limits its scope.\n\nDNS TTL is in seconds; TTL 1 means automatic. Read the record before changing it.\nPATCH changes supplied fields; PUT replaces the record, so preserve its type,\nname and content. Read state before replacing, rolling back or purging. Prefer\na targeted cache purge by files, tags, hosts or prefixes over purging everything.\n\nHatch data keeps Cloudflare's vendor envelope. For example, select DNS record\nidentities with `fields: [\"result.id\", \"result.name\"]`; a list stays under\n`data.result`. Named account and zone lists keep projected rows with camelCase\naccount and name-server fields.\n\n## Workers, storage and analytics\n\nWorker script source is code; secret binding values are separate and unavailable.\nKV values are application data. Encode a slash inside a KV key or R2 object key\nas `%2F`. R2 requires API-token authentication, rather than a Global API Key.\n\nGraphQL Analytics uses accountTag and zoneTag for account/zone identities.\nFilter every accounts/zones field by equality or an explicit set of those ids.\nA pinned query uses one operation per document and every declared fragment.\nAnalytics Engine SQL is read-only; D1 SQL and Durable Object queries can write.\nAI inference, previews and outbound checks can cost money or activate work.\n\n## Disqualifiers and recovery\n\nCredential minting, rotation, stored secrets, private session captures and signed\nupload or deployment links are unavailable. Use the Cloudflare dashboard for\ncredential administration. A Global API Key cannot change user settings or\nmemberships through this connection.\n\nAfter an authentication failure, use `verify_credential` once to distinguish a\nrejected credential from a permission gap. An operator replaces the credential;\nrepeating the failed request does not add permissions. Cloudflare's global limit\ncounts dashboard traffic and all tokens together, so reduce requests as well as\nhonoring the returned wait.\n\n## Conventions\n\n- **Paging:** while `page.hasMore` is true, continue with `page.nextCursor` unchanged. For `cloudflare_api_details`, `cloudflare_api_search`, `list_accounts`, `list_zones`, pass it as the top-level `cursor`; omit raw paging anchors on continuations. For `cloudflare_api_read`, put it in `query[page.param]` or `body[page.param]`, as `page.in` specifies. Keep the original method, path, filters, page size, fields and headers. Paged `list_*` and `search_*` reads take `limit` (default 20, at most 50). The last page has no `nextCursor`. If `page.hasMore` is true without a cursor, the data is incomplete and continuation was withheld. When approaching execute_code's per-program call limit, return page.nextCursor before the call that would exceed it and continue in the next program; don't restart.\n- **Results:** `fields` narrows a read's result to the dot paths you name. `truncated` lists the dot paths a result cut for size; the ids that fetch what was cut stay in the result.\n- **Envelope fields:** hatch data keeps the vendor envelope. Select declared fields with `fields: [\"result.id\", \"result.name\"]`; array traversal also accepts `result[].id`. Named reads keep their projected fields.\n- **Hatch:** `cloudflare_api_search` finds this API's operations and reads no account data, `cloudflare_api_details` shows one operation's contract, and `cloudflare_api_read` calls a reviewed read. `cloudflare_api_write` calls a reviewed write; the host may ask the user to confirm it. An operation without a reviewed verdict is refused. 70 operations are refused by design; use `cloudflare_api_details` with the method and path to inspect the original operation summary and its separate refusal. Use details for refused methods outside the read/write call schemas; those methods remain unavailable.\n- **Writes:** a write is sent once and never retried. When its outcome is unknown, read the target before repeating it. Writes take no idempotency key.\n- **Errors:** codes come from the vendor's statuses and error facts, never its prose. `not_found` means the record does not exist; this API tells absence from a permission gap. It documents no conflict.\n- **Withheld values:** a value withheld for safety reads `\"[redacted]\"`. Writes refuse whole marker values and withheld links; longer prose may mention the marker. Paths and queries refuse any containment.",
4
+ "instructionsHeading": "Account instructions"
13
5
  };
@@ -0,0 +1,360 @@
1
+ // Curated, projected tools; the standard hatch covers the pinned REST API.
2
+ import { Effect, Schema } from "effect";
3
+ import { ConnectorCallError } from "../../errors.js";
4
+ import { list, read, write } from "../../http/tools.js";
5
+ import { RequestSecrets } from "../../http/services.js";
6
+ import { checked, schema } from "../_shared/rest/kit.js";
7
+ import { inspectGraphqlQuery } from "./lib/graphql.js";
8
+ import { cloudflareRuntime, cloudflareIndex, SAFETY, WRITE_STEPS, UPLOADS, HEADERS, RawUpload, bytesFromBase64, record, text, invalid, describeErrors, } from "./api.js";
9
+ import { settings } from "./api.js";
10
+ import { cloudflarePage } from "../../http/hatch-paging.js";
11
+ import { isMinChars, isMaxChars } from "../../http/json-schema.js";
12
+ function closed(properties, required = []) {
13
+ return { type: "object", properties, required, additionalProperties: false };
14
+ }
15
+ export function cloudflareTools({ connection, options, }) {
16
+ const configured = settings(options), pin = configured.pin, operations = cloudflareIndex;
17
+ const runtime = cloudflareRuntime(connection, configured);
18
+ const projectZone = (value) => {
19
+ const zone = record(value);
20
+ const account = record(zone["account"]);
21
+ return {
22
+ id: zone["id"],
23
+ name: zone["name"],
24
+ status: zone["status"] ?? null,
25
+ paused: zone["paused"] ?? null,
26
+ type: zone["type"] ?? null,
27
+ accountId: account["id"] ?? null,
28
+ accountName: account["name"] ?? null,
29
+ nameServers: Array.isArray(zone["name_servers"]) ? zone["name_servers"] : [],
30
+ plan: record(zone["plan"])["name"] ?? null,
31
+ };
32
+ };
33
+ const declarations = [
34
+ {
35
+ name: "verify_credential",
36
+ description: "Verify the configured Cloudflare credential and report its status. Call this first when another call fails with auth_required.",
37
+ annotations: { readOnlyHint: true },
38
+ inputSchema: closed({}),
39
+ outputSchema: {
40
+ type: "object",
41
+ properties: {
42
+ auth: { type: "string", enum: ["apiToken", "globalApiKey"] },
43
+ status: { type: ["string", "null"], description: '"active" for a usable credential.' },
44
+ id: { type: ["string", "null"] },
45
+ email: { type: ["string", "null"], description: "The Global API Key's user." },
46
+ expiresOn: { type: ["string", "null"] },
47
+ scope: { type: "string", enum: ["user", "account"], description: "Who owns the token." },
48
+ accountId: { type: "string" },
49
+ },
50
+ required: ["auth", "status", "scope"],
51
+ },
52
+ run: () => runtime.verify(),
53
+ },
54
+ {
55
+ name: "graphql_query",
56
+ description: "Run a read-only GraphQL Analytics API query (POST /graphql). Mutations and subscriptions are refused before sending; filter by zoneTag or accountTag.",
57
+ annotations: { readOnlyHint: true },
58
+ inputSchema: closed({
59
+ query: { type: "string", minLength: 1, maxLength: 20_000, description: "A GraphQL query document." },
60
+ variables: { type: "object", description: "Variables the query declares, as JSON." },
61
+ operationName: {
62
+ type: "string",
63
+ minLength: 1,
64
+ maxLength: 200,
65
+ description: "Which query to run when the document has several.",
66
+ },
67
+ }, ["query"]),
68
+ outputSchema: {
69
+ type: "object",
70
+ properties: {
71
+ data: { description: "The query result." },
72
+ errors: { type: "array", description: "GraphQL errors, when Cloudflare returned partial data." },
73
+ },
74
+ required: ["data"],
75
+ },
76
+ run: (args) => Effect.gen(function* () {
77
+ const source = String(args["query"]);
78
+ const variables = record(args["variables"]);
79
+ const scoped = yield* checked(() => inspectGraphqlQuery(source, variables, {
80
+ strict: pin !== undefined,
81
+ ...(typeof args["operationName"] === "string" ? { operationName: args["operationName"] } : {}),
82
+ }));
83
+ if (pin) {
84
+ yield* checked(() => {
85
+ if (scoped.openTags.length > 0) {
86
+ invalid(`A pinned connector filters GraphQL by zoneTag or accountTag equality or _in, not ${scoped.openTags.join(", ")}.`);
87
+ }
88
+ if (scoped.unscopedFields.length > 0 || scoped.accountTags.length + scoped.zoneTags.length === 0) {
89
+ invalid("A pinned connector's GraphQL queries filter every accounts and zones field by a pinned accountTag or zoneTag.");
90
+ }
91
+ for (const account of scoped.accountTags)
92
+ runtime.assertAccount(account);
93
+ });
94
+ for (const zone of scoped.zoneTags)
95
+ yield* runtime.assertZone(zone);
96
+ }
97
+ const graphql = Object.freeze({
98
+ method: "POST",
99
+ path: "/graphql",
100
+ operationId: "graphql",
101
+ summary: "GraphQL Analytics API",
102
+ tag: "graphql",
103
+ server: undefined,
104
+ row: -1,
105
+ });
106
+ const body = { query: source };
107
+ if (args["variables"] !== undefined)
108
+ body["variables"] = variables;
109
+ if (typeof args["operationName"] === "string")
110
+ body["operationName"] = args["operationName"];
111
+ const response = yield* runtime.send({
112
+ method: "POST",
113
+ path: "/graphql",
114
+ op: graphql,
115
+ params: {},
116
+ query: {},
117
+ body,
118
+ });
119
+ const document = record(response.data);
120
+ const errors = Array.isArray(document["errors"]) ? document["errors"] : [];
121
+ if ((document["data"] === undefined || document["data"] === null) && errors.length > 0) {
122
+ const redacted = (yield* RequestSecrets).redact(errors);
123
+ return yield* checked(() => invalid(`Cloudflare GraphQL rejected the query: ${describeErrors(redacted)}`));
124
+ }
125
+ return { data: document["data"] ?? null, ...(errors.length > 0 ? { errors } : {}) };
126
+ }),
127
+ },
128
+ {
129
+ name: "cloudflare_api_upload",
130
+ description: "Upload text, base64 bytes, or multipart parts to a reviewed Cloudflare upload operation. Covers Workers scripts, KV values, R2 objects, Pages, Images, Stream, DNS import, and Snippets; never reads local files.",
131
+ annotations: { readOnlyHint: false, destructiveHint: true },
132
+ inputSchema: closed({
133
+ method: { type: "string", enum: ["POST", "PUT", "PATCH"], description: "The operation's HTTP method." },
134
+ path: {
135
+ type: "string",
136
+ minLength: 2,
137
+ maxLength: 2048,
138
+ description: "Concrete path from cloudflare_api_search; encode a / inside an R2 or KV key as %2F.",
139
+ },
140
+ query: { type: "object", description: "Query parameters as JSON, named as details lists them." },
141
+ headers: {
142
+ type: "object",
143
+ description: "Optional R2 headers.",
144
+ properties: Object.fromEntries(Object.entries(HEADERS).map(([name, description]) => [
145
+ name,
146
+ { type: "string", minLength: 1, maxLength: 40, description },
147
+ ])),
148
+ additionalProperties: false,
149
+ },
150
+ contentType: {
151
+ type: "string",
152
+ minLength: 1,
153
+ maxLength: 200,
154
+ description: "Content-Type of a text or base64 body.",
155
+ },
156
+ textBody: { type: "string", description: "A UTF-8 body; exclusive with base64Body and parts." },
157
+ base64Body: { type: "string", description: "Body bytes as base64; exclusive with textBody and parts." },
158
+ parts: {
159
+ type: "array",
160
+ maxItems: 100,
161
+ description: "multipart/form-data parts; a part with fileName is sent as a file.",
162
+ items: {
163
+ type: "object",
164
+ properties: {
165
+ name: { type: "string", minLength: 1, maxLength: 200, description: "Form field name, e.g. metadata." },
166
+ text: { type: "string", description: "Text value; exclusive with base64." },
167
+ base64: { type: "string", description: "Bytes as base64; exclusive with text." },
168
+ fileName: {
169
+ type: "string",
170
+ minLength: 1,
171
+ maxLength: 500,
172
+ description: "Send as a file with this name.",
173
+ },
174
+ contentType: { type: "string", minLength: 1, maxLength: 200, description: "The part's Content-Type." },
175
+ },
176
+ required: ["name"],
177
+ additionalProperties: false,
178
+ },
179
+ },
180
+ }, ["method", "path"]),
181
+ outputSchema: {
182
+ type: "object",
183
+ properties: {
184
+ status: { type: "integer", description: "HTTP status." },
185
+ data: {
186
+ description: "Cloudflare's response envelope after value safety: result, errors, messages, success.",
187
+ },
188
+ },
189
+ required: ["status", "data"],
190
+ },
191
+ run: (args) => Effect.gen(function* () {
192
+ const preparedUpload = yield* checked(() => {
193
+ const method = String(args["method"]);
194
+ const prepared = runtime.call(method, String(args["path"]), {
195
+ query: record(args["query"]),
196
+ ...(Object.keys(record(args["headers"])).length
197
+ ? { headers: record(args["headers"]) }
198
+ : {}),
199
+ });
200
+ const refusal = SAFETY.refusal(prepared.method, prepared.op.path) ?? runtime.refuse(prepared);
201
+ if (refusal)
202
+ invalid(refusal);
203
+ if (!UPLOADS.some(([verb, template]) => verb === prepared.op.method && template === prepared.op.path)) {
204
+ invalid(`${prepared.op.method} ${prepared.op.path} is not a reviewed upload operation; JSON writes go through cloudflare_api_write.`);
205
+ }
206
+ const accepted = operations
207
+ .contract(prepared.op)
208
+ .parameters.filter((parameter) => parameter.in === "query");
209
+ for (const name of Object.keys(prepared.query)) {
210
+ if (!accepted.some((parameter) => parameter.name === name)) {
211
+ invalid(`${prepared.op.path} has no query parameter ${name}; it accepts ${accepted.map((parameter) => parameter.name).join(", ") || "none"}.`);
212
+ }
213
+ }
214
+ const parts = Array.isArray(args["parts"]) ? args["parts"].map(record) : [];
215
+ const textBody = typeof args["textBody"] === "string" ? args["textBody"] : undefined;
216
+ const base64Body = typeof args["base64Body"] === "string" ? args["base64Body"] : undefined;
217
+ if (Number(parts.length > 0) + Number(textBody !== undefined) + Number(base64Body !== undefined) !== 1) {
218
+ invalid("cloudflare_api_upload needs exactly one body: textBody, base64Body, or parts.");
219
+ }
220
+ let upload;
221
+ if (parts.length > 0) {
222
+ const form = new FormData();
223
+ for (const part of parts) {
224
+ const name = String(part["name"]);
225
+ const value = typeof part["text"] === "string" ? part["text"] : undefined;
226
+ const bytes = typeof part["base64"] === "string" ? part["base64"] : undefined;
227
+ if (Number(value !== undefined) + Number(bytes !== undefined) !== 1) {
228
+ invalid(`Multipart part ${name} needs exactly one of text or base64.`);
229
+ }
230
+ const fileName = text(part["fileName"]);
231
+ const type = text(part["contentType"]);
232
+ if (fileName || type || bytes !== undefined) {
233
+ const blob = new Blob([value ?? bytesFromBase64(bytes, `part ${name}`)], {
234
+ type: type ?? "application/octet-stream",
235
+ });
236
+ form.append(name, blob, fileName ?? name);
237
+ }
238
+ else {
239
+ form.append(name, value);
240
+ }
241
+ }
242
+ upload = new RawUpload(form, undefined);
243
+ }
244
+ else {
245
+ upload = new RawUpload(textBody ?? bytesFromBase64(base64Body, "base64Body"), text(args["contentType"]) ??
246
+ (textBody !== undefined ? "text/plain; charset=utf-8" : "application/octet-stream"));
247
+ }
248
+ return { ...prepared, body: upload };
249
+ });
250
+ const { status, data } = yield* runtime.sendEnvelope(preparedUpload);
251
+ return { status, data };
252
+ }),
253
+ },
254
+ ];
255
+ return [
256
+ ...["accounts", "zones"].map((noun) => {
257
+ const zone = noun === "zones";
258
+ const filters = {
259
+ name: Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(zone ? 253 : 200)).annotate({
260
+ description: zone ? "Exact domain name, e.g. example.com." : "Exact account name.",
261
+ })),
262
+ ...(zone
263
+ ? {
264
+ status: Schema.optionalKey(Schema.Literals(["initializing", "pending", "active", "moved"])),
265
+ accountId: Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(64)).annotate({
266
+ description: "Only zones in this account.",
267
+ })),
268
+ }
269
+ : {}),
270
+ };
271
+ const row = Schema.Struct(zone
272
+ ? {
273
+ id: Schema.optionalKey(Schema.String),
274
+ name: Schema.optionalKey(Schema.String),
275
+ status: Schema.optionalKey(Schema.NullOr(Schema.String)),
276
+ paused: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),
277
+ type: Schema.optionalKey(Schema.NullOr(Schema.String)),
278
+ accountId: Schema.optionalKey(Schema.NullOr(Schema.String)),
279
+ accountName: Schema.optionalKey(Schema.NullOr(Schema.String)),
280
+ nameServers: Schema.optionalKey(Schema.Array(Schema.String)),
281
+ plan: Schema.optionalKey(Schema.NullOr(Schema.String)),
282
+ }
283
+ : {
284
+ id: Schema.optionalKey(Schema.String),
285
+ name: Schema.optionalKey(Schema.String),
286
+ type: Schema.optionalKey(Schema.NullOr(Schema.String)),
287
+ });
288
+ const tool = list(connection, {
289
+ name: `list_${noun}`,
290
+ description: zone
291
+ ? "List Cloudflare zones (domains) by name, status or account; only pinned zones. Resolves domain names to zone/account ids for DNS, cache and analytics."
292
+ : "List Cloudflare accounts by name; only pinned accounts. Resolves account ids for zones, Workers, KV and R2.",
293
+ filters,
294
+ row,
295
+ limit: { default: 20, max: 50, description: "Results per page: 5 to 50; default 20." },
296
+ cursor: "bound",
297
+ total: true,
298
+ page: (args, cursor) => Effect.gen(function* () {
299
+ if (args.limit < 5)
300
+ yield* checked(() => invalid("Cloudflare account and zone lists require limit from 5 to 50."));
301
+ const page = cursor === undefined ? 1 : Number(cursor);
302
+ if (!Number.isSafeInteger(page) || page < 1)
303
+ yield* checked(() => invalid("This cursor contains no valid Cloudflare page."));
304
+ const query = { page, per_page: args.limit };
305
+ if (args.name !== undefined)
306
+ query["name"] = args.name;
307
+ if ("status" in args && args.status !== undefined)
308
+ query["status"] = args.status;
309
+ if ("accountId" in args && args.accountId !== undefined)
310
+ query["account.id"] = args.accountId;
311
+ const answer = yield* runtime.sendEnvelope(runtime.call("GET", `/${noun}`, { query }));
312
+ const body = record(answer.data), info = record(body["result_info"]);
313
+ const rows = body["result"];
314
+ if (!Array.isArray(rows))
315
+ yield* checked(() => {
316
+ throw new ConnectorCallError("connector_call_failed", "Cloudflare returned a list without a result array.", { retryable: false });
317
+ });
318
+ const next = yield* checked(() => cloudflarePage.next(body, { path: `/${noun}`, query, headers: {} }));
319
+ const total = pin ? undefined : info["total_count"];
320
+ if (total !== undefined && (!Number.isSafeInteger(total) || total < 0))
321
+ yield* checked(() => {
322
+ throw new ConnectorCallError("connector_call_failed", "Cloudflare returned an invalid exact list total.", { retryable: false });
323
+ });
324
+ return {
325
+ rows: rows.map((item) => zone
326
+ ? projectZone(item)
327
+ : { id: record(item)["id"], name: record(item)["name"], type: record(item)["type"] ?? null }),
328
+ page: {
329
+ hasMore: next !== undefined && next !== null,
330
+ nextCursor: typeof next === "number" ? String(next) : null,
331
+ ...(typeof total === "number" ? { total } : {}),
332
+ },
333
+ };
334
+ }),
335
+ });
336
+ tool.inputSchema.properties["limit"].minimum = 5;
337
+ return tool;
338
+ }),
339
+ ...declarations.map((declaration) => {
340
+ const spec = {
341
+ writeSteps: WRITE_STEPS,
342
+ name: declaration.name,
343
+ description: declaration.description,
344
+ input: Object.keys(declaration.inputSchema.properties ?? {}).length === 0
345
+ ? Schema.Struct({})
346
+ : schema(declaration.inputSchema),
347
+ output: schema(declaration.outputSchema),
348
+ run: (args) => declaration.run(args),
349
+ };
350
+ const tool = declaration.annotations.readOnlyHint
351
+ ? read(connection, {
352
+ fields: true,
353
+ ...spec,
354
+ review: "Credential verification, GraphQL query-only inspection and account/zone lists are read-only; every pin is checked before dispatch.",
355
+ })
356
+ : write(connection, { ...spec, destructive: true });
357
+ return tool;
358
+ }),
359
+ ];
360
+ }
@@ -0,0 +1,51 @@
1
+ // Google Docs' vendor on the provider kit (C.7 step 1).
2
+ import { Schema } from "effect";
3
+ import { get, post, vendor } from "../../http/vendor.js";
4
+ import { googleErrors } from "../_shared/google/kit.js";
5
+ import { docsSafety } from "./safety.js";
6
+ import { DOCS_SCOPES } from "./lib/constants.js";
7
+ export const DOCS = {
8
+ provider: "Google Docs",
9
+ api: "Google Docs API",
10
+ scopes: DOCS_SCOPES,
11
+ // A document is a Drive file: 404 means absent or not shared with this user.
12
+ notFound: "ambiguous",
13
+ };
14
+ const DocumentId = { documentId: Schema.String };
15
+ export const getDocument = get("getDocument", "/documents/:documentId", {
16
+ params: DocumentId,
17
+ query: {
18
+ includeTabsContent: Schema.optionalKey(Schema.String),
19
+ suggestionsViewMode: Schema.optionalKey(Schema.String),
20
+ },
21
+ success: Schema.Unknown,
22
+ });
23
+ const OPERATIONS = [
24
+ getDocument,
25
+ post("createDocument", "/documents", { payload: Schema.Unknown, success: Schema.Unknown }),
26
+ post("batchUpdate", "/documents/:documentId:batchUpdate", {
27
+ params: DocumentId,
28
+ payload: Schema.Unknown,
29
+ success: Schema.Unknown,
30
+ }),
31
+ ];
32
+ /** The three methods declared by the Docs API v1 Discovery document. */
33
+ export const DocsApi = vendor({ name: "Google Docs", manifestBase: "/v1" }, ...OPERATIONS);
34
+ const standardErrors = googleErrors(DOCS, { standard: true, revisionConflicts: true });
35
+ export const errors = {
36
+ ...standardErrors,
37
+ meanings: {
38
+ ...standardErrors.meanings,
39
+ conflicts: [
40
+ ...standardErrors.meanings.conflicts.map((meaning) => meaning.replace(/\.$/, "")),
41
+ "The document content or revision changed during indexed content paging",
42
+ ],
43
+ },
44
+ };
45
+ export const safety = docsSafety(OPERATIONS);
46
+ /** Delegation has no operator credential to test; this probe is never run. */
47
+ export const probe = {
48
+ operation: getDocument,
49
+ request: { params: { documentId: "-" } },
50
+ describe: () => "Google Docs delegation has no credential to test.",
51
+ };
@@ -1,17 +1,6 @@
1
1
  import { type GoogleWorkspaceOptions } from "../_shared/google/workspace.js";
2
+ export { DOCS_API_BASE_URL, DOCS_SCOPES } from "./lib/constants.js";
2
3
  export type { GoogleServiceAccount, GoogleSubjectContext, GoogleWorkspaceOptions, GoogleWorkspaceSubject, } from "../_shared/google/workspace.js";
3
- /**
4
- * The Docs API root. Unlike Gmail there is no per-user path segment: the
5
- * delegated token's subject decides which documents a request can reach.
6
- */
7
- export declare const DOCS_API_BASE_URL = "https://docs.googleapis.com/v1";
8
- /**
9
- * Exactly the scope this connection requests, and exactly what the Admin
10
- * console's domain-wide delegation entry must list for it. `documents` reads
11
- * and edits Docs the user can reach; it lists nothing and touches no other
12
- * Drive file type.
13
- */
14
- export declare const DOCS_SCOPES: readonly ["https://www.googleapis.com/auth/documents"];
15
4
  /** Options for {@link docs}: the shared Workspace delegation options. */
16
5
  export type DocsOptions = GoogleWorkspaceOptions;
17
6
  /**