@zackbart/connecta 0.34.1 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (441) hide show
  1. package/CHANGELOG.md +418 -0
  2. package/README.md +65 -105
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2044 -1161
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +751 -281
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +29 -7
  53. package/dist/connectors/api-connector.js +145 -57
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/remote-mcp.d.ts +10 -30
  58. package/dist/connectors/remote-mcp.js +955 -563
  59. package/dist/d1.js +10 -243
  60. package/dist/derived-context.js +5 -0
  61. package/dist/describe-config.d.ts +3 -1
  62. package/dist/describe-config.js +2 -0
  63. package/dist/downstream-input.js +347 -260
  64. package/dist/errors.d.ts +87 -6
  65. package/dist/errors.js +114 -4
  66. package/dist/execute.js +87 -50
  67. package/dist/executor-admission.js +3 -0
  68. package/dist/executors/quickjs.js +163 -112
  69. package/dist/guarded-transport.js +50 -0
  70. package/dist/guest-runtime.js +1 -1
  71. package/dist/http/client.js +439 -0
  72. package/dist/http/errors.js +558 -0
  73. package/dist/http/fields.js +49 -0
  74. package/dist/http/hatch-paging.js +318 -0
  75. package/dist/http/hatch.js +1279 -0
  76. package/dist/http/json-schema.js +267 -0
  77. package/dist/http/node-transport.js +241 -0
  78. package/dist/http/oauth.js +162 -0
  79. package/dist/http/paging.js +227 -0
  80. package/dist/http/provider.js +221 -0
  81. package/dist/http/safety.js +82 -0
  82. package/dist/http/services.js +79 -0
  83. package/dist/http/tools.js +379 -0
  84. package/dist/http/vendor-index.js +138 -0
  85. package/dist/http/vendor.js +448 -0
  86. package/dist/http/write-request.js +66 -0
  87. package/dist/http-policy.d.ts +11 -0
  88. package/dist/http-policy.js +45 -0
  89. package/dist/inbound-credential.js +1 -1
  90. package/dist/index.d.ts +2 -2
  91. package/dist/index.js +4 -0
  92. package/dist/invocation-auth.js +30 -19
  93. package/dist/invocation.js +218 -85
  94. package/dist/mcp-result.js +0 -4
  95. package/dist/membership.d.ts +4 -0
  96. package/dist/meta-output.js +1 -1
  97. package/dist/meta-tools.js +531 -406
  98. package/dist/native-recovery.js +52 -0
  99. package/dist/native-tools.js +382 -0
  100. package/dist/node.d.ts +4 -3
  101. package/dist/node.js +45 -8
  102. package/dist/oauth-handoff.js +177 -104
  103. package/dist/oauth-partition.js +6 -20
  104. package/dist/oauth-sealing.js +6 -7
  105. package/dist/operation-vocabulary.js +101 -0
  106. package/dist/operator-record.d.ts +2 -2
  107. package/dist/operator-record.js +17 -4
  108. package/dist/operator-ui/contract.d.ts +8 -3
  109. package/dist/operator-ui/generated.js +4 -4
  110. package/dist/operator-ui/model.d.ts +2 -3
  111. package/dist/program-writes.js +47 -26
  112. package/dist/provider-call-facts.d.ts +115 -0
  113. package/dist/provider-call-facts.js +182 -0
  114. package/dist/provider-call.d.ts +112 -0
  115. package/dist/provider-call.js +271 -0
  116. package/dist/provider.d.ts +65 -31
  117. package/dist/provider.js +116 -39
  118. package/dist/providers/_shared/google/hatch.js +91 -0
  119. package/dist/providers/_shared/google/kit.js +427 -0
  120. package/dist/providers/_shared/google/result-size.js +15 -2
  121. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  122. package/dist/providers/_shared/google/service-account.js +8 -4
  123. package/dist/providers/_shared/google/workspace.d.ts +6 -210
  124. package/dist/providers/_shared/google/workspace.js +6 -425
  125. package/dist/providers/_shared/rest/compact-index.js +86 -0
  126. package/dist/providers/_shared/rest/kit.js +146 -0
  127. package/dist/providers/_shared/rest/operation-index.js +230 -14
  128. package/dist/providers/_shared/rest/response-media.js +11 -0
  129. package/dist/providers/_shared/rest/value-safety.js +353 -195
  130. package/dist/providers/_shared/sensitive-fields.js +27 -0
  131. package/dist/providers/breeze/api.js +584 -0
  132. package/dist/providers/breeze/index.d.ts +1 -3
  133. package/dist/providers/breeze/index.js +67 -1420
  134. package/dist/providers/breeze/openapi.generated.js +60 -0
  135. package/dist/providers/breeze/skill.generated.js +2 -6
  136. package/dist/providers/breeze/tools.js +696 -0
  137. package/dist/providers/ccb/api.js +496 -0
  138. package/dist/providers/ccb/index.d.ts +15 -37
  139. package/dist/providers/ccb/index.js +77 -1702
  140. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  141. package/dist/providers/ccb/lib/constants.js +74 -0
  142. package/dist/providers/ccb/lib/guide.js +9 -0
  143. package/dist/providers/ccb/lib/verdicts.js +387 -0
  144. package/dist/providers/ccb/openapi.generated.js +397 -0
  145. package/dist/providers/ccb/safety.js +295 -0
  146. package/dist/providers/ccb/skill.generated.js +2 -6
  147. package/dist/providers/ccb/tools.js +853 -0
  148. package/dist/providers/cloudflare/api.js +1066 -0
  149. package/dist/providers/cloudflare/index.d.ts +5 -22
  150. package/dist/providers/cloudflare/index.js +79 -197
  151. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  152. package/dist/providers/cloudflare/lib/config.js +2 -0
  153. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  154. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  155. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  156. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  157. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  158. package/dist/providers/cloudflare/openapi.generated.js +4 -3
  159. package/dist/providers/cloudflare/{value-safety.js → safety.js} +487 -0
  160. package/dist/providers/cloudflare/skill.generated.js +2 -10
  161. package/dist/providers/cloudflare/tools.js +360 -0
  162. package/dist/providers/docs/api.js +51 -0
  163. package/dist/providers/docs/index.d.ts +1 -12
  164. package/dist/providers/docs/index.js +53 -1165
  165. package/dist/providers/docs/lib/constants.d.ts +18 -0
  166. package/dist/providers/docs/lib/constants.js +18 -0
  167. package/dist/providers/docs/lib/discovery.js +26 -0
  168. package/dist/providers/docs/lib/requests.js +48 -0
  169. package/dist/providers/docs/lib/schemas.js +168 -0
  170. package/dist/providers/docs/openapi.generated.js +16 -0
  171. package/dist/providers/docs/safety.js +54 -0
  172. package/dist/providers/docs/skill.generated.js +2 -6
  173. package/dist/providers/docs/tools.js +801 -0
  174. package/dist/providers/drive/api.js +177 -0
  175. package/dist/providers/drive/index.d.ts +1 -12
  176. package/dist/providers/drive/index.js +38 -1448
  177. package/dist/providers/drive/lib/constants.d.ts +6 -0
  178. package/dist/providers/drive/lib/constants.js +6 -0
  179. package/dist/providers/drive/lib/contracts.js +532 -0
  180. package/dist/providers/drive/lib/hatch.js +197 -0
  181. package/dist/providers/drive/openapi.generated.js +77 -0
  182. package/dist/providers/drive/safety.js +90 -0
  183. package/dist/providers/drive/skill.generated.js +2 -6
  184. package/dist/providers/drive/tools.js +1290 -0
  185. package/dist/providers/forms/api.js +71 -0
  186. package/dist/providers/forms/index.d.ts +1 -12
  187. package/dist/providers/forms/index.js +49 -1145
  188. package/dist/providers/forms/lib/constants.d.ts +14 -0
  189. package/dist/providers/forms/lib/constants.js +19 -0
  190. package/dist/providers/forms/lib/hatch.js +72 -0
  191. package/dist/providers/forms/openapi.generated.js +23 -0
  192. package/dist/providers/forms/safety.js +34 -0
  193. package/dist/providers/forms/skill.generated.js +2 -8
  194. package/dist/providers/forms/tools.js +1023 -0
  195. package/dist/providers/github/api.js +150 -0
  196. package/dist/providers/github/index.d.ts +4 -5
  197. package/dist/providers/github/index.js +30 -87
  198. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  199. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  200. package/dist/providers/github/lib/discovery.js +132 -0
  201. package/dist/providers/github/lib/operations.js +58 -0
  202. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  203. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  204. package/dist/providers/github/openapi.generated.js +1216 -0
  205. package/dist/providers/github/safety.js +216 -0
  206. package/dist/providers/github/skill.generated.js +2 -5
  207. package/dist/providers/github/tools.js +506 -0
  208. package/dist/providers/gmail/api.js +114 -0
  209. package/dist/providers/gmail/index.d.ts +1 -12
  210. package/dist/providers/gmail/index.js +73 -1621
  211. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  212. package/dist/providers/gmail/lib/constants.js +16 -0
  213. package/dist/providers/gmail/lib/index.js +173 -0
  214. package/dist/providers/gmail/lib/schemas.js +176 -0
  215. package/dist/providers/gmail/lib/threading.js +120 -0
  216. package/dist/providers/gmail/openapi.generated.js +92 -0
  217. package/dist/providers/gmail/safety.js +21 -0
  218. package/dist/providers/gmail/skill.generated.js +2 -6
  219. package/dist/providers/gmail/tools.js +1435 -0
  220. package/dist/providers/overflow/api.js +1008 -0
  221. package/dist/providers/overflow/index.d.ts +1 -17
  222. package/dist/providers/overflow/index.js +60 -1488
  223. package/dist/providers/overflow/skill.generated.js +2 -5
  224. package/dist/providers/overflow/tools.js +873 -0
  225. package/dist/providers/planning-center/api.js +467 -0
  226. package/dist/providers/planning-center/index.d.ts +4 -35
  227. package/dist/providers/planning-center/index.js +69 -2445
  228. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  229. package/dist/providers/planning-center/lib/constants.js +83 -0
  230. package/dist/providers/planning-center/lib/discovery.js +40 -0
  231. package/dist/providers/planning-center/lib/guide.js +39 -0
  232. package/dist/providers/planning-center/lib/json-api.js +83 -0
  233. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  234. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  235. package/dist/providers/planning-center/safety.js +188 -0
  236. package/dist/providers/planning-center/skill.generated.js +2 -27
  237. package/dist/providers/planning-center/tools.js +1010 -0
  238. package/dist/providers/quickbooks/api.js +299 -0
  239. package/dist/providers/quickbooks/index.d.ts +13 -0
  240. package/dist/providers/quickbooks/index.js +93 -0
  241. package/dist/providers/quickbooks/lib/query.js +118 -0
  242. package/dist/providers/quickbooks/lib/writes.js +168 -0
  243. package/dist/providers/quickbooks/safety.js +222 -0
  244. package/dist/providers/quickbooks/skill.generated.js +5 -0
  245. package/dist/providers/quickbooks/tools.js +117 -0
  246. package/dist/providers/sheets/api.js +133 -0
  247. package/dist/providers/sheets/index.d.ts +4 -16
  248. package/dist/providers/sheets/index.js +61 -1172
  249. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  250. package/dist/providers/sheets/lib/constants.js +14 -0
  251. package/dist/providers/sheets/lib/hatch.js +163 -0
  252. package/dist/providers/sheets/lib/requests.js +105 -0
  253. package/dist/providers/sheets/lib/schemas.js +138 -0
  254. package/dist/providers/sheets/openapi.generated.js +30 -0
  255. package/dist/providers/sheets/safety.js +27 -0
  256. package/dist/providers/sheets/skill.generated.js +2 -7
  257. package/dist/providers/sheets/tools.js +733 -0
  258. package/dist/providers/slides/api.js +147 -0
  259. package/dist/providers/slides/index.d.ts +2 -10
  260. package/dist/providers/slides/index.js +48 -2555
  261. package/dist/providers/slides/lib/constants.d.ts +11 -0
  262. package/dist/providers/slides/lib/constants.js +11 -0
  263. package/dist/providers/slides/lib/requests.js +60 -0
  264. package/dist/providers/slides/lib/schemas.js +565 -0
  265. package/dist/providers/slides/openapi.generated.js +18 -0
  266. package/dist/providers/slides/skill.generated.js +2 -6
  267. package/dist/providers/slides/tools.js +1968 -0
  268. package/dist/providers/stripe/api.js +401 -0
  269. package/dist/providers/stripe/index.d.ts +5 -27
  270. package/dist/providers/stripe/index.js +74 -210
  271. package/dist/providers/stripe/lib/config.d.ts +4 -0
  272. package/dist/providers/stripe/lib/config.js +2 -0
  273. package/dist/providers/stripe/openapi.generated.js +4 -3
  274. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  275. package/dist/providers/stripe/skill.generated.js +2 -11
  276. package/dist/providers/stripe/tools.js +77 -0
  277. package/dist/providers/tithely/api.js +531 -0
  278. package/dist/providers/tithely/index.d.ts +17 -0
  279. package/dist/providers/tithely/index.js +86 -965
  280. package/dist/providers/tithely/skill.generated.js +2 -5
  281. package/dist/providers/tithely/tools.js +426 -0
  282. package/dist/providers/vercel/api.js +551 -0
  283. package/dist/providers/vercel/index.d.ts +9 -25
  284. package/dist/providers/vercel/index.js +65 -260
  285. package/dist/providers/vercel/lib/config.d.ts +2 -0
  286. package/dist/providers/vercel/lib/config.js +2 -0
  287. package/dist/providers/vercel/lib/index.js +117 -0
  288. package/dist/providers/vercel/lib/logs.js +100 -0
  289. package/dist/providers/vercel/lib/pin.js +270 -0
  290. package/dist/providers/vercel/openapi.generated.js +10 -5
  291. package/dist/providers/vercel/{value-safety.js → safety.js} +247 -38
  292. package/dist/providers/vercel/skill.generated.js +2 -7
  293. package/dist/providers/vercel/tools.js +642 -0
  294. package/dist/redaction-identity.js +47 -0
  295. package/dist/redaction-marker.js +125 -0
  296. package/dist/registry.d.ts +21 -15
  297. package/dist/registry.js +409 -376
  298. package/dist/routes/access-tokens.js +1 -1
  299. package/dist/routes/actor-labels.js +1 -1
  300. package/dist/routes/connect.js +1 -1
  301. package/dist/routes/dispatch.js +103 -0
  302. package/dist/routes/mcp.js +170 -79
  303. package/dist/routes/oauth.js +6 -1
  304. package/dist/routes/operator.js +2 -2
  305. package/dist/routes/shared.d.ts +5 -4
  306. package/dist/routes/shared.js +244 -177
  307. package/dist/routes/skills.js +10 -8
  308. package/dist/routes/ui-config.js +27 -3
  309. package/dist/routes/ui-data.js +21 -20
  310. package/dist/routes/ui.js +1 -1
  311. package/dist/runtime/call-admission.js +0 -26
  312. package/dist/runtime/call-entry.js +30 -0
  313. package/dist/runtime/call.js +552 -0
  314. package/dist/runtime/connector-scope.js +7 -0
  315. package/dist/runtime/credential-probe.js +34 -0
  316. package/dist/runtime/executor.js +40 -0
  317. package/dist/runtime/native-storage.js +63 -0
  318. package/dist/runtime/registry.js +27 -0
  319. package/dist/runtime/request-scope.js +72 -0
  320. package/dist/runtime/run.js +15 -7
  321. package/dist/runtime/shared-read.js +34 -5
  322. package/dist/runtime/storage.js +34 -21
  323. package/dist/sent-secrets.d.ts +194 -37
  324. package/dist/sent-secrets.js +1743 -340
  325. package/dist/server.js +5 -56
  326. package/dist/skills.js +322 -223
  327. package/dist/sqlite.js +15 -14
  328. package/dist/storage/d1-copy.js +255 -0
  329. package/dist/storage/d1-driver.js +15 -0
  330. package/dist/storage/keys.js +28 -0
  331. package/dist/storage/sql-driver.js +88 -0
  332. package/dist/storage/sql-native.js +544 -0
  333. package/dist/storage/sql-schema.d.ts +6 -0
  334. package/dist/storage/sql-schema.js +15 -0
  335. package/dist/storage/sql.d.ts +14 -20
  336. package/dist/storage/sql.js +29 -535
  337. package/dist/timeout.js +0 -26
  338. package/dist/tool-safety.js +20 -10
  339. package/dist/types.d.ts +9 -109
  340. package/dist/ui.d.ts +1 -1
  341. package/dist/ui.js +0 -1
  342. package/dist/upward.js +3 -0
  343. package/dist/usage-guide.js +3 -1
  344. package/dist/validate.d.ts +4 -2
  345. package/dist/validate.js +86 -9
  346. package/dist/version.d.ts +1 -1
  347. package/dist/version.js +1 -1
  348. package/dist/worker.js +312 -292
  349. package/dist/workspace-subject.js +5 -1
  350. package/dist/write-outcome.js +454 -34
  351. package/documentation/README.md +28 -7
  352. package/documentation/architecture.md +2409 -255
  353. package/documentation/auth.md +867 -114
  354. package/documentation/code-mode.md +49 -16
  355. package/documentation/deploying.md +164 -20
  356. package/documentation/hosted-mcp-migration.md +460 -0
  357. package/documentation/integrating.md +129 -144
  358. package/documentation/meta-tools.md +409 -32
  359. package/documentation/operating.md +27 -3
  360. package/documentation/operator-tests.md +3 -0
  361. package/documentation/operator-ui.md +84 -48
  362. package/documentation/provider-auth-migration.md +16 -63
  363. package/documentation/provider-migration-0.29.md +10 -5
  364. package/documentation/provider-migration-0.35.md +975 -0
  365. package/documentation/providers.md +1347 -0
  366. package/examples/worker/AGENTS.md +23 -9
  367. package/examples/worker/README.md +254 -135
  368. package/examples/worker/alchemy.run.ts +116 -0
  369. package/examples/worker/gitignore +10 -0
  370. package/examples/worker/src/connecta.config.ts +23 -21
  371. package/examples/worker/wrangler.jsonc +14 -5
  372. package/guides/connecting-agents.md +157 -0
  373. package/guides/how-it-works.md +156 -0
  374. package/guides/safety-and-trust.md +153 -0
  375. package/package.json +30 -50
  376. package/templates/node/.env.example +3 -0
  377. package/templates/node/README.md +22 -2
  378. package/templates/node/docker-compose.yml +1 -0
  379. package/templates/node/package.json +3 -2
  380. package/templates/node/src/connecta.config.ts +8 -0
  381. package/dist/catalog-drift.d.ts +0 -138
  382. package/dist/catalog-drift.js +0 -578
  383. package/dist/operator-ui/agents.d.ts +0 -74
  384. package/dist/operator-ui/agents.js +0 -104
  385. package/dist/operator-ui/config-summary.js +0 -565
  386. package/dist/operator-ui/connection-map.js +0 -376
  387. package/dist/operator-ui/endpoints.js +0 -221
  388. package/dist/operator-ui/fix-prompts.d.ts +0 -18
  389. package/dist/operator-ui/fix-prompts.js +0 -87
  390. package/dist/operator-ui/health.js +0 -52
  391. package/dist/operator-ui/member-page.js +0 -97
  392. package/dist/operator-ui/overview.js +0 -123
  393. package/dist/operator-ui/setup-commands.js +0 -51
  394. package/dist/operator-ui/view.d.ts +0 -401
  395. package/dist/operator-ui/view.js +0 -705
  396. package/dist/providers/_shared/request-token.js +0 -83
  397. package/dist/providers/_shared/rest/dispatch.js +0 -41
  398. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  399. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  400. package/dist/providers/_shared/rest/tools.js +0 -569
  401. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  402. package/dist/providers/basecamp/index.d.ts +0 -45
  403. package/dist/providers/basecamp/index.js +0 -997
  404. package/dist/providers/basecamp/skill.generated.js +0 -9
  405. package/dist/providers/cloudflare/rest.d.ts +0 -37
  406. package/dist/providers/cloudflare/rest.js +0 -1097
  407. package/dist/providers/github/hosted.js +0 -218
  408. package/dist/providers/github/rest.js +0 -321
  409. package/dist/providers/infisical/index.d.ts +0 -7
  410. package/dist/providers/infisical/index.js +0 -713
  411. package/dist/providers/infisical/skill.generated.js +0 -8
  412. package/dist/providers/intercom/index.d.ts +0 -24
  413. package/dist/providers/intercom/index.js +0 -121
  414. package/dist/providers/intercom/skill.generated.js +0 -8
  415. package/dist/providers/linear/index.d.ts +0 -55
  416. package/dist/providers/linear/index.js +0 -537
  417. package/dist/providers/linear/skill.generated.js +0 -8
  418. package/dist/providers/mixpanel/index.d.ts +0 -59
  419. package/dist/providers/mixpanel/index.js +0 -472
  420. package/dist/providers/mixpanel/operations.js +0 -20
  421. package/dist/providers/mixpanel/rest.js +0 -603
  422. package/dist/providers/mixpanel/skill.generated.js +0 -10
  423. package/dist/providers/mixpanel/value-safety.js +0 -16
  424. package/dist/providers/notion/index.d.ts +0 -67
  425. package/dist/providers/notion/index.js +0 -368
  426. package/dist/providers/notion/openapi.generated.js +0 -75
  427. package/dist/providers/notion/rest.d.ts +0 -24
  428. package/dist/providers/notion/rest.js +0 -1226
  429. package/dist/providers/notion/skill.generated.js +0 -11
  430. package/dist/providers/notion/value-safety.js +0 -56
  431. package/dist/providers/revenuecat/index.d.ts +0 -51
  432. package/dist/providers/revenuecat/index.js +0 -697
  433. package/dist/providers/revenuecat/skill.generated.js +0 -11
  434. package/dist/providers/stripe/rest.d.ts +0 -14
  435. package/dist/providers/stripe/rest.js +0 -402
  436. package/dist/providers/vercel/rest.d.ts +0 -20
  437. package/dist/providers/vercel/rest.js +0 -1020
  438. package/dist/providers/wispr-flow/index.d.ts +0 -14
  439. package/dist/providers/wispr-flow/index.js +0 -117
  440. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  441. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -0,0 +1,27 @@
1
+ // A provider's sensitive fields leave every result unless deployment code
2
+ // returns them; no tool argument can. Shared by the providers whose raw rows
3
+ // and hatches would otherwise reach what their projections drop.
4
+ /** What `raw: true` and the hatches return, under the deployment's `sensitiveFields` choice. */
5
+ export function unprojectedResults(sensitiveFields, names) {
6
+ if (sensitiveFields === "return")
7
+ return (body) => body;
8
+ const dropped = new Set(names);
9
+ const strip = (value) => {
10
+ if (Array.isArray(value))
11
+ return value.map(strip);
12
+ if (!value || typeof value !== "object")
13
+ return value;
14
+ return Object.fromEntries(Object.entries(value)
15
+ .filter(([name]) => !dropped.has(name))
16
+ .map(([name, entry]) => [name, strip(entry)]));
17
+ };
18
+ return (body) => strip(body);
19
+ }
20
+ /** Refuse anything but the two choices, at construction (INV-11). */
21
+ export function sensitiveFieldsOption(provider, value) {
22
+ if (value === undefined)
23
+ return "drop";
24
+ if (value === "drop" || value === "return")
25
+ return value;
26
+ throw new Error(`${provider}() sensitiveFields must be "drop" or "return".`);
27
+ }
@@ -0,0 +1,584 @@
1
+ // Breeze's reviewed GET-only vendor. HTTP methods do not establish safety: see tools.ts.
2
+ import { Effect, Schema } from "effect";
3
+ import { ConnectorCallError, resendAdvice } from "../../errors.js";
4
+ import { Refusal } from "../../http/errors.js";
5
+ import { Credentials, RequestSecrets } from "../../http/services.js";
6
+ import { get, Summary, vendor } from "../../http/vendor.js";
7
+ import { vendorIndex } from "../../http/vendor-index.js";
8
+ import { openapi } from "./openapi.generated.js";
9
+ export const DEFAULT_PAGE_SIZE = 100;
10
+ export const MAX_PAGE_SIZE = 1000;
11
+ export const BREEZE_MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
12
+ export function asRecord(value) {
13
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
14
+ }
15
+ export function asArray(value) {
16
+ return Array.isArray(value) ? value : [];
17
+ }
18
+ // --- The read hatch's allowlist ----------------------------------------------
19
+ /** Reviewed observational endpoints and their documented query names. GET alone establishes nothing. */
20
+ export const READ_ENDPOINTS = new Map([
21
+ ["/people", ["details", "filter_json", "limit", "offset"]],
22
+ ["/people/{id}", ["details"]],
23
+ ["/profile", []],
24
+ ["/tags/list_tags", ["folder_id"]],
25
+ ["/tags/list_folders", []],
26
+ ["/events", ["start", "end", "category_id", "calendar_id", "eligible", "details", "limit"]],
27
+ ["/events/list_event", ["instance_id", "schedule", "schedule_direction", "schedule_limit", "eligible", "details"]],
28
+ ["/events/calendars/list", []],
29
+ ["/events/locations", []],
30
+ ["/events/attendance/list", ["instance_id", "details", "type"]],
31
+ ["/events/attendance/eligible", ["instance_id"]],
32
+ ["/forms/list_forms", ["is_archived"]],
33
+ ["/forms/list_form_fields", ["form_id"]],
34
+ ["/forms/list_form_entries", ["form_id", "details"]],
35
+ ["/volunteers/list", ["instance_id"]],
36
+ ["/volunteers/list_roles", ["instance_id", "show_quantity"]],
37
+ ["/account/summary", []],
38
+ ["/account/list_log", ["action", "start", "end", "user_id", "details", "limit"]],
39
+ // Undocumented since ~2023-09; parameters from the 2023-06-07 reference.
40
+ [
41
+ "/giving/list",
42
+ [
43
+ "start",
44
+ "end",
45
+ "person_id",
46
+ "include_family",
47
+ "amount_min",
48
+ "amount_max",
49
+ "method_ids",
50
+ "fund_ids",
51
+ "envelope_number",
52
+ "batches",
53
+ "forms",
54
+ "pledge_ids",
55
+ ],
56
+ ],
57
+ ["/giving/view", ["payment_id"]],
58
+ ["/funds/list", ["include_totals"]],
59
+ ["/pledges/list_campaigns", []],
60
+ ["/pledges/list_pledges", ["campaign_id"]],
61
+ ]);
62
+ /** A Breeze path: lowercase segments of letters, digits, and underscores. */
63
+ const PATH_PATTERN = /^(\/[a-z0-9_]+)+\/?$/;
64
+ /**
65
+ * `/events/calendars/list` answers each calendar's private iCal feed address,
66
+ * which reads the calendar without a key, and its embed key. Neither hatch
67
+ * returns them.
68
+ */
69
+ export function withoutCalendarFeeds(path, body) {
70
+ if (path !== "/events/calendars/list")
71
+ return body;
72
+ const strip = (value) => {
73
+ if (Array.isArray(value))
74
+ return value.map(strip);
75
+ if (!value || typeof value !== "object")
76
+ return value;
77
+ return Object.fromEntries(Object.entries(value)
78
+ .filter(([key]) => key !== "address" && key !== "embed_key")
79
+ .map(([key, child]) => [key, strip(child)]));
80
+ };
81
+ return strip(body);
82
+ }
83
+ export function normalizedPath(raw) {
84
+ const path = typeof raw === "string" ? raw : "";
85
+ if (!PATH_PATTERN.test(path)) {
86
+ throw new ConnectorCallError("invalid_args", "A Breeze path is relative to /api, begins with '/', and uses only lowercase letters, digits, underscores, and '/' — for example /tags/list_folders. No query string, host, or dot segments.");
87
+ }
88
+ return path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path;
89
+ }
90
+ // --- Projections -------------------------------------------------------------
91
+ // The HTML pin/conversion remains drift evidence. These reviewed declarations
92
+ // are the hatch's one runtime operation list; success properties are lenient
93
+ // discovery/selection metadata, never response decoders.
94
+ const loose = (names, extra = {}) => Schema.Struct({
95
+ ...Object.fromEntries(names
96
+ .split(" ")
97
+ .filter(Boolean)
98
+ .map((name) => [name, Schema.optionalKey(Schema.Unknown)])),
99
+ ...extra,
100
+ });
101
+ const Person = loose("id oid first_name force_first_name last_name nick_name middle_name maiden_name path thumb_path details family street_address city state zip");
102
+ const ProfileField = loose("id oid field_id field_type name position profile_id profile_section_id created_on options");
103
+ const Event = loose("id oid event_id name category_id settings_id is_modified created_on start_datetime end_datetime description check_in_settings eligible");
104
+ const Tag = loose("id name created_on folder_id");
105
+ const TagFolder = loose("id name parent_id created_on");
106
+ const FamilyAnswer = loose("success");
107
+ const Payment = loose("id oid paid_on created_on num method method_id amount note person_id first_name last_name envelope_number meta batch_num batch_id person", {
108
+ funds: Schema.optionalKey(Schema.Array(loose("id oid payment_id fund_id amount created_on fund_name tax_deductible"))),
109
+ });
110
+ const GivingAnswer = loose("success errors payment_id", { payment: Schema.optionalKey(Payment) });
111
+ const responseByPath = {
112
+ "/people": Schema.Array(Person),
113
+ "/people/{PERSON_ID}": Person,
114
+ "/people/add": Schema.Union([Person, Schema.Array(Person)]),
115
+ "/people/update": Schema.Union([Person, Schema.Array(Person), Schema.Boolean]),
116
+ "/profile": Schema.Array(loose("id oid section_id name column_id position profile_id created_on", {
117
+ fields: Schema.optionalKey(Schema.Array(ProfileField)),
118
+ })),
119
+ "/tags/list_tags": Schema.Array(Tag),
120
+ "/tags/list_folders": Schema.Array(TagFolder),
121
+ "/tags/add_tag": Schema.Array(Tag),
122
+ "/tags/add_tag_folder": Schema.Array(TagFolder),
123
+ "/events": Schema.Array(Event),
124
+ "/events/list_event": Schema.Union([Event, Schema.Array(Event)]),
125
+ "/events/add": Schema.Array(Event),
126
+ "/events/calendars/list": Schema.Array(loose("id oid name color created_on address embed_key")),
127
+ "/events/locations": Schema.Array(loose("id name")),
128
+ "/events/attendance/list": Schema.Array(loose("id instance_id person_id created_on check_out details")),
129
+ "/events/attendance/eligible": Schema.Array(Person),
130
+ "/forms/list_forms": Schema.Array(loose("id name url_slug is_archived created_on")),
131
+ "/forms/list_form_fields": Schema.Array(ProfileField),
132
+ "/forms/list_form_entries": Schema.Array(loose("id form_id created_on person_id response")),
133
+ "/volunteers/list": Schema.Array(loose("id oid instance_id person_id response comment rsvped_on created_on role_ids")),
134
+ "/volunteers/list_roles": Schema.Array(loose("id name quantity")),
135
+ "/volunteers/add_role": loose("id name quantity"),
136
+ "/account/summary": loose("id name subdomain status created_on", {
137
+ details: Schema.optionalKey(loose("timezone", { country: Schema.optionalKey(loose("id name currency currency_symbol")) })),
138
+ }),
139
+ "/account/list_log": Schema.Array(loose("id oid user_id action object_json created_on details")),
140
+ "/families/create": FamilyAnswer,
141
+ "/families/destroy": FamilyAnswer,
142
+ "/families/add": FamilyAnswer,
143
+ "/families/remove": FamilyAnswer,
144
+ "/giving/list": Schema.Array(Payment),
145
+ "/giving/view": GivingAnswer,
146
+ "/giving/add": GivingAnswer,
147
+ "/giving/edit": GivingAnswer,
148
+ "/giving/delete": GivingAnswer,
149
+ "/funds/list": Schema.Array(loose("id name tax_deductible is_default created_on total")),
150
+ "/pledges/list_campaigns": Schema.Array(loose("id oid name created_on number_of_pledges total_pledged")),
151
+ "/pledges/list_pledges": Schema.Array(loose("id oid person_id fundraiser_id amount started_on ends_type ends_date ends_number frequency fund_ids_json note include_family created_on first_name last_name fundraiser_name total_pledged family_id total_paid paid_percent")),
152
+ };
153
+ // Required identities and values follow the public and archived reference's
154
+ // endpoint tables/examples. Optional names (including query JSON strings) stay optional.
155
+ const requiredByPath = {
156
+ "/people/add": ["first", "last"],
157
+ "/people/update": ["person_id", "fields_json"],
158
+ "/people/delete": ["person_id"],
159
+ "/tags/add_tag": ["name"],
160
+ "/tags/add_tag_folder": ["name"],
161
+ "/tags/delete_tag": ["tag_id"],
162
+ "/tags/delete_tag_folder": ["folder_id"],
163
+ "/tags/assign": ["person_id", "tag_id"],
164
+ "/tags/unassign": ["person_id", "tag_id"],
165
+ "/events/add": ["name", "starts_on"],
166
+ "/events/delete": ["instance_id"],
167
+ "/events/list_event": ["instance_id"],
168
+ "/events/attendance/add": ["instance_id", "person_id"],
169
+ "/events/attendance/delete": ["instance_id", "person_id"],
170
+ "/events/attendance/list": ["instance_id"],
171
+ "/events/attendance/eligible": ["instance_id"],
172
+ "/forms/list_form_fields": ["form_id"],
173
+ "/forms/list_form_entries": ["form_id"],
174
+ "/forms/remove_form_entry": ["entry_id"],
175
+ "/volunteers/list": ["instance_id"],
176
+ "/volunteers/add": ["instance_id", "person_id"],
177
+ "/volunteers/remove": ["instance_id", "person_id"],
178
+ "/volunteers/update": ["instance_id", "person_id"],
179
+ "/volunteers/list_roles": ["instance_id"],
180
+ "/volunteers/add_role": ["instance_id", "name"],
181
+ "/volunteers/remove_role": ["instance_id", "role_id"],
182
+ "/families/create": ["people_ids_json"],
183
+ "/families/destroy": ["people_ids_json"],
184
+ "/families/remove": ["people_ids_json"],
185
+ "/families/add": ["people_ids_json", "target_person_id"],
186
+ "/account/list_log": ["action"],
187
+ "/giving/view": ["payment_id"],
188
+ "/giving/edit": ["payment_id"],
189
+ "/giving/delete": ["payment_id"],
190
+ "/pledges/list_pledges": ["campaign_id"],
191
+ };
192
+ const GIVING_QUERY = [
193
+ "date",
194
+ "person_id",
195
+ "person_json",
196
+ "uid",
197
+ "processor",
198
+ "method",
199
+ "funds_json",
200
+ "amount",
201
+ "group",
202
+ "batch_number",
203
+ "batch_name",
204
+ "note",
205
+ ];
206
+ // Explicitly reviewed write endpoints; the absence of a read review never grants one.
207
+ const WRITES = new Set([
208
+ "/events/add",
209
+ "/events/attendance/add",
210
+ "/events/attendance/delete",
211
+ "/events/delete",
212
+ "/families/add",
213
+ "/families/create",
214
+ "/families/destroy",
215
+ "/families/remove",
216
+ "/forms/remove_form_entry",
217
+ "/giving/add",
218
+ "/giving/edit",
219
+ "/giving/delete",
220
+ "/people/add",
221
+ "/people/delete",
222
+ "/people/update",
223
+ "/tags/add_tag",
224
+ "/tags/add_tag_folder",
225
+ "/tags/assign",
226
+ "/tags/delete_tag",
227
+ "/tags/delete_tag_folder",
228
+ "/tags/unassign",
229
+ "/volunteers/add",
230
+ "/volunteers/add_role",
231
+ "/volunteers/remove",
232
+ "/volunteers/remove_role",
233
+ "/volunteers/update",
234
+ ]);
235
+ // Reviewed against the endpoint descriptions/examples in the public and archived reference.
236
+ const summaries = {
237
+ "/account/list_log": "Read the account audit log of actions on people and other records.",
238
+ "/account/summary": "Read account identity, timezone, country and giving currency.",
239
+ "/events": "List event occurrences in a date range, with series ids and times.",
240
+ "/events/add": "Create an event occurrence, optionally in an existing series.",
241
+ "/events/delete": "Delete an event occurrence by instance id.",
242
+ "/events/list_event": "Read one event occurrence and optionally its series schedule.",
243
+ "/events/calendars/list": "List event calendars; private feed addresses and embed keys are removed.",
244
+ "/events/locations": "List event locations and their ids.",
245
+ "/events/attendance/add": "Record attendance: check in or check out a person at an event occurrence.",
246
+ "/events/attendance/delete": "Delete a person's attendance record for an event occurrence.",
247
+ "/events/attendance/eligible": "List people eligible to attend an event occurrence.",
248
+ "/events/attendance/list": "List attendance for an event occurrence, including check-out times.",
249
+ "/families/add": "Add people to the family of a target person, replacing previous family associations.",
250
+ "/families/create": "Create a family from the specified people.",
251
+ "/families/destroy": "Destroy family associations for the specified people.",
252
+ "/families/remove": "Remove specified people from their family associations.",
253
+ "/forms/list_forms": "List forms, optionally selecting archived forms.",
254
+ "/forms/list_form_fields": "Read a form's field definitions for decoding entry responses.",
255
+ "/forms/list_form_entries": "List entries submitted to a form, optionally including response details.",
256
+ "/forms/remove_form_entry": "Delete a submitted form entry by entry id.",
257
+ "/funds/list": "List giving funds, optionally including contribution totals.",
258
+ "/giving/add": "Record a giving contribution or donation with donor and fund allocations.",
259
+ "/giving/delete": "Delete a giving contribution or donation by payment id.",
260
+ "/giving/edit": "Edit a giving contribution or donation; the payment id may change.",
261
+ "/giving/list": "List giving contributions or donations by date, donor, amount and fund filters.",
262
+ "/giving/view": "Read one giving contribution or donation by payment id.",
263
+ "/people": "List people with optional profile details and tag or profile-field filters.",
264
+ "/people/add": "Create a person with first/last names and optional profile values.",
265
+ "/people/delete": "Delete a person profile by person id.",
266
+ "/people/update": "Update a person's profile values by field id.",
267
+ "/people/{PERSON_ID}": "Read a person profile and optionally field-id details and family members.",
268
+ "/pledges/list_campaigns": "List pledge campaigns before reading their individual pledges.",
269
+ "/pledges/list_pledges": "List a campaign's pledge rows, amounts, donors and payment progress.",
270
+ "/profile": "List profile sections, field definitions and multiple-choice option ids.",
271
+ "/tags/add_tag": "Create a tag, optionally within a tag folder.",
272
+ "/tags/add_tag_folder": "Create a tag folder, optionally within a parent folder.",
273
+ "/tags/assign": "Assign a tag to a person.",
274
+ "/tags/delete_tag": "Delete a tag by tag id.",
275
+ "/tags/delete_tag_folder": "Delete a tag folder by folder id.",
276
+ "/tags/list_folders": "List tag folders and their parent ids.",
277
+ "/tags/list_tags": "List tags, optionally within a folder.",
278
+ "/tags/unassign": "Unassign a tag from a person.",
279
+ "/volunteers/add": "Assign a person to volunteer at an event occurrence.",
280
+ "/volunteers/add_role": "Create a volunteer role for an event occurrence.",
281
+ "/volunteers/list": "List volunteers assigned to an event occurrence and their responses.",
282
+ "/volunteers/list_roles": "List volunteer roles for an event occurrence.",
283
+ "/volunteers/remove": "Remove a person's volunteer assignment from an event occurrence.",
284
+ "/volunteers/remove_role": "Delete a volunteer role from an event occurrence.",
285
+ "/volunteers/update": "Update a person's volunteer roles at an event occurrence.",
286
+ };
287
+ const parameterDescriptions = {
288
+ action: "Account-log action to match, for example person_updated.",
289
+ start: "First date in the requested range; use YYYY-MM-DD.",
290
+ end: "Last date in the requested range; use YYYY-MM-DD.",
291
+ user_id: "Account user id whose actions to list.",
292
+ details: "Set 1 to include the endpoint's expanded record details; 0 omits them.",
293
+ limit: "Maximum rows requested from the vendor; a full result can require paging or a narrower range.",
294
+ offset: "Opaque nextCursor from the preceding people page; omit on the first call.",
295
+ category_id: "Event category id to select or assign.",
296
+ calendar_id: "Calendar id from /events/calendars/list.",
297
+ eligible: "Set 1 to include check-in eligibility settings and associated tags.",
298
+ name: "Name of the record being created or edited.",
299
+ starts_on: "Event start as a Unix timestamp in seconds.",
300
+ ends_on: "Event end as a Unix timestamp in seconds; defaults to one hour after starts_on.",
301
+ all_day: "Set 1 for an all-day event, 0 otherwise.",
302
+ description: "Event description text.",
303
+ event_id: "Existing event series id when adding an occurrence to that series.",
304
+ direction: "Attendance direction: in records check-in, out records check-out; default in.",
305
+ person_id: "Person id from /people; resolve the target before writing.",
306
+ instance_id: "Event occurrence id, not the recurring series event_id.",
307
+ type: "Attendance selector: person for people, anonymous for anonymous counts.",
308
+ schedule: "Set 1 to include the event series schedule.",
309
+ schedule_direction: "Schedule direction relative to this occurrence: before or after; default before.",
310
+ schedule_limit: "Maximum scheduled occurrences to include.",
311
+ people_ids_json: "JSON-encoded array of person ids for the family operation.",
312
+ target_person_id: "Person whose family receives the specified people.",
313
+ form_id: "Form id from /forms/list_forms.",
314
+ is_archived: "Set 1 for archived forms, 0 for active forms.",
315
+ entry_id: "Submitted form entry id from /forms/list_form_entries.",
316
+ include_totals: "Set 1 to include each fund's contribution total.",
317
+ date: "Giving transaction date; the archived parameter table specifies DD-MM-YYYY.",
318
+ person_json: "JSON-encoded donor details when supplying an unassociated donor.",
319
+ uid: "External donor id from the giving platform, used with processor when the Breeze person id is unknown.",
320
+ processor: "Payment processor name associated with the transaction.",
321
+ method: "Giving payment method name, for example Cash or Check.",
322
+ funds_json: "JSON-encoded array of fund allocations with name, amount and optional id; amounts must sum to amount.",
323
+ amount: "Giving transaction amount as an exact decimal string.",
324
+ group: "Unique group for a giving batch; repeated groups reuse the remembered batch.",
325
+ batch_number: "Giving batch number to assign.",
326
+ batch_name: "Giving batch name to assign.",
327
+ note: "Giving transaction note.",
328
+ payment_id: "Giving transaction id from /giving/list; editing can return a new id.",
329
+ include_family: "Set 1 to include giving from the person's family.",
330
+ amount_min: "Minimum giving amount as an exact decimal string.",
331
+ amount_max: "Maximum giving amount as an exact decimal string.",
332
+ method_ids: "Giving method ids to include, separated by dashes.",
333
+ fund_ids: "Giving fund ids to include, separated by dashes.",
334
+ envelope_number: "Donor envelope number to match.",
335
+ batches: "Giving batch numbers to include, separated by dashes.",
336
+ forms: "Giving form ids to include, separated by dashes.",
337
+ pledge_ids: "Pledge campaign ids to include in the giving filter, separated by dashes.",
338
+ filter_json: "JSON-encoded profile-field and tag filters; resolve field, option and tag ids first.",
339
+ first: "Person's first name.",
340
+ last: "Person's last name.",
341
+ fields_json: "JSON-encoded profile values keyed by field_id, with field_type and response or details.",
342
+ campaign_id: "Pledge campaign id from /pledges/list_campaigns.",
343
+ folder_id: "Tag folder id from /tags/list_folders.",
344
+ parent_id: "Parent tag-folder id; omit to use the root.",
345
+ tag_id: "Tag id from /tags/list_tags.",
346
+ quantity: "Number of volunteer positions for the role.",
347
+ show_quantity: "Set 1 to include the number of positions for each volunteer role.",
348
+ role_id: "Volunteer role id from /volunteers/list_roles.",
349
+ role_ids_json: "JSON-encoded array of volunteer role ids to assign.",
350
+ };
351
+ const PEOPLE_LIMIT_PATTERN = "^(?:0|[1-9][0-9]{0,2}|1000)$";
352
+ const details = JSON.parse(openapi.details);
353
+ const declared = openapi.ops.map(([, path, name], row) => {
354
+ const params = Object.fromEntries([...path.matchAll(/\{([^}]+)\}/g)].map((m) => [
355
+ m[1],
356
+ Schema.String.annotate({ description: "Numeric person id from /people." }),
357
+ ]));
358
+ const entry = details.o[row];
359
+ const names = path === "/giving/add"
360
+ ? GIVING_QUERY
361
+ : path === "/giving/edit"
362
+ ? ["payment_id", "name", ...GIVING_QUERY]
363
+ : entry === 0 || !entry
364
+ ? []
365
+ : entry[0].filter(([, at]) => at === "query").map(([name]) => name);
366
+ const query = Object.fromEntries(names.map((key) => {
367
+ const value = path === "/people" && key === "limit"
368
+ ? Schema.String.check(Schema.makeFilter((raw) => new RegExp(PEOPLE_LIMIT_PATTERN).test(raw), {
369
+ toJsonSchema: () => ({ pattern: PEOPLE_LIMIT_PATTERN }),
370
+ }))
371
+ : Schema.String;
372
+ const description = path === "/people" && key === "limit"
373
+ ? "Whole decimal count from 1 to 1000; 0 or omission requests all people without paging."
374
+ : path === "/giving/edit" && key === "name"
375
+ ? "Donor name, as shown in the archived edit example."
376
+ : parameterDescriptions[key];
377
+ if (!description)
378
+ throw new Error(`Breeze parameter ${path} ${key} needs a reviewed description.`);
379
+ return [
380
+ key,
381
+ (requiredByPath[path]?.includes(key) ? value : Schema.optionalKey(value)).pipe(Schema.annotateKey({
382
+ description,
383
+ })),
384
+ ];
385
+ }));
386
+ if (!summaries[path])
387
+ throw new Error(`Breeze operation ${path} needs a reviewed summary.`);
388
+ const summary = summaries[path] +
389
+ (path.startsWith("/giving/") || path.startsWith("/pledges/") || path === "/funds/list"
390
+ ? " (archival API; verify support)"
391
+ : "") +
392
+ (path === "/giving/add" ? "; requiredness is not specified in the archived contract" : "");
393
+ return get(name, path.replace(/\{([^}]+)\}/g, ":$1"), {
394
+ params,
395
+ query,
396
+ success: responseByPath[path] ?? Schema.Unknown,
397
+ }).annotate(Summary, summary);
398
+ });
399
+ export const BreezeApi = {
400
+ ...vendor("Breeze", declared[0], ...declared.slice(1)),
401
+ textBodies: {
402
+ review: "Breeze error responses are bounded text or HTML; successes require JSON.",
403
+ forResponse: (status) => (status < 200 || status > 299 ? "text" : undefined),
404
+ },
405
+ };
406
+ export const BREEZE_INDEX = vendorIndex(BreezeApi, {
407
+ prefix: "breeze",
408
+ title: "Breeze ChMS",
409
+ revision: openapi.revision,
410
+ });
411
+ export const BREEZE_VERDICTS = Object.fromEntries(BREEZE_INDEX.ops.map((op) => {
412
+ const read = READ_ENDPOINTS.has(op.path === "/people/{PERSON_ID}" ? "/people/{id}" : op.path);
413
+ if (!read && !WRITES.has(op.path))
414
+ throw new Error(`Breeze operation ${op.path} needs a review.`);
415
+ return [`${op.method} ${op.path}`, read ? "read" : "destructive"];
416
+ }));
417
+ export const BREEZE_NAMED = {
418
+ "GET /account/summary": "get_account_summary",
419
+ "GET /people": "list_people",
420
+ "GET /people/{PERSON_ID}": "get_person",
421
+ "GET /profile": "list_profile_fields",
422
+ "GET /tags/list_tags": "list_tags",
423
+ "GET /events": "list_events",
424
+ "GET /events/attendance/list": "list_attendance",
425
+ "GET /giving/list": "list_contributions",
426
+ "GET /funds/list": "list_funds",
427
+ "GET /people/add": "add_person",
428
+ "GET /people/update": "update_person",
429
+ };
430
+ /** Breeze returns all people when limit is absent/zero, so only a positive explicit limit pages. */
431
+ export const breezePeoplePage = {
432
+ param: "offset",
433
+ in: "query",
434
+ decode: (cursor) => {
435
+ const value = Number(cursor);
436
+ if (!/^\d+$/.test(String(cursor)) || !Number.isSafeInteger(value) || value < 0)
437
+ throw new ConnectorCallError("invalid_args", "Breeze needs a nonnegative whole offset.");
438
+ return value;
439
+ },
440
+ next(data, call) {
441
+ const limit = Number(call.query["limit"] ?? 0), offset = Number(call.query["offset"] ?? 0);
442
+ if (!Number.isSafeInteger(limit) ||
443
+ limit < 0 ||
444
+ !Number.isSafeInteger(offset) ||
445
+ offset < 0 ||
446
+ !Array.isArray(data) ||
447
+ !Number.isSafeInteger(offset + data.length))
448
+ throw new ConnectorCallError("connector_call_failed", "Breeze returned invalid people paging data.", {
449
+ retryable: false,
450
+ });
451
+ return limit === 0 ? undefined : data.length >= limit ? offset + data.length : null;
452
+ },
453
+ };
454
+ export const accountSummary = declared.find((operation) => operation.identifier === "account_summary");
455
+ /** Breeze accepts one value per query name; REST-style repeated scalars are not a batch. */
456
+ export const admit = (url) => {
457
+ // The compact vendor index does not preserve string-pattern constraints.
458
+ const limit = url.searchParams.get("limit");
459
+ if (url.pathname === "/api/people" && limit !== null && !new RegExp(PEOPLE_LIMIT_PATTERN).test(limit))
460
+ return Effect.fail(new Refusal({
461
+ error: new ConnectorCallError("invalid_args", "Breeze people limit must be a whole decimal count from 0 to 1000; 0 requests all people without paging."),
462
+ }));
463
+ const seen = new Set();
464
+ for (const name of url.searchParams.keys()) {
465
+ if (seen.has(name))
466
+ return Effect.fail(new Refusal({
467
+ error: new ConnectorCallError("invalid_args", `Breeze takes one value for query parameter ${name}; serialize JSON parameters as strings.`),
468
+ }));
469
+ seen.add(name);
470
+ }
471
+ return Effect.void;
472
+ };
473
+ export const authenticate = Effect.gen(function* () {
474
+ const values = yield* (yield* Credentials).values.pipe(Effect.mapError((error) => new Refusal({ error })));
475
+ const key = values?.["value"]?.trim();
476
+ if (!key)
477
+ return yield* Effect.fail(new Refusal({
478
+ error: new ConnectorCallError("auth_required", "No Breeze API key is configured for this connector. Call authorize_connector for recovery options. When available, an operator can add the key in this connection in the operator UI."),
479
+ }));
480
+ return { "Api-Key": key };
481
+ });
482
+ function bodyDetail(text, status) {
483
+ const trimmed = text.trim();
484
+ if (!trimmed || trimmed.startsWith("<") || trimmed.length > 200)
485
+ return `Breeze returned HTTP ${status}.`;
486
+ return `Breeze said: ${trimmed}${/[.!?]$/.test(trimmed) ? "" : "."}`;
487
+ }
488
+ // These account-wide keys have no scopes: 401 and 403 both mean key recovery;
489
+ // a 404 is an absent endpoint or record. No evidence establishes auth before execution.
490
+ export const errors = {
491
+ numericFacts: {
492
+ retryAfterMs: {
493
+ header: "retry-after",
494
+ format: "retry-after",
495
+ review: "HTTP Retry-After delay for failure recovery.",
496
+ },
497
+ },
498
+ provider: "Breeze",
499
+ facts: () => ({}),
500
+ detail: ({ body, status }) => bodyDetail(typeof body === "string" ? body : "", status),
501
+ meanings: { unknownId: "not_found", provesAbsence: true, conflicts: [] },
502
+ unreadable: "Breeze returned a non-JSON successful response.",
503
+ statuses: {
504
+ 401: ({ status }) => ({
505
+ code: "auth_required",
506
+ words: (detail) => `Breeze rejected the configured API key (HTTP ${status}). ${detail} An operator must replace it with the key from this church's Extensions → API page.`,
507
+ }),
508
+ 403: ({ status }) => ({
509
+ code: "auth_required",
510
+ words: (detail) => `Breeze rejected the configured API key (HTTP ${status}). ${detail} An operator must replace it with the key from this church's Extensions → API page.`,
511
+ }),
512
+ 404: () => ({
513
+ code: "not_found",
514
+ words: () => "Breeze has no such endpoint or record (HTTP 404). Check the path against the API reference, or re-read the id from its list tool.",
515
+ }),
516
+ },
517
+ };
518
+ export const result = (body, answer) => {
519
+ return RequestSecrets.use((secrets) => {
520
+ if (body === false &&
521
+ answer.operation.method === "GET" &&
522
+ BREEZE_VERDICTS[`GET ${answer.operation.template}`] === "destructive")
523
+ return Effect.fail(new Refusal({
524
+ error: new ConnectorCallError("connector_call_failed", `Breeze answered false to ${answer.operation.template}. Breeze gives no reason; check the target and confirm the ids with their list tools before any fresh call.`, { retryable: false }),
525
+ }));
526
+ const failure = reportedFailure(body, secrets);
527
+ return failure ? Effect.fail(new Refusal({ error: failure })) : Effect.succeed(body ?? null);
528
+ });
529
+ };
530
+ // The only documented capability-bearing response values are calendar feeds.
531
+ // Every result passes through the same drop before any projection or fields selection.
532
+ export const breezeSafety = {
533
+ review: "Breeze's indexed hatch admits only reviewed operations. The reviewed reference exposes no stored credential values outside calendar feed addresses and embed keys, which are dropped on every result path. Unknown paths are refused.",
534
+ reviewed: {
535
+ resolve: (method, path) => ({
536
+ method,
537
+ template: (() => {
538
+ const op = BREEZE_INDEX.resolve(method, normalizedPath(path)).op;
539
+ if (op.path === "/people/{PERSON_ID}" && !/^\/people\/\d+\/?$/.test(path))
540
+ throw new ConnectorCallError("invalid_args", "A Breeze person path requires a numeric person id.");
541
+ return op.path;
542
+ })(),
543
+ }),
544
+ redact: (body, op) => withoutCalendarFeeds(op.template, body),
545
+ withholdsErrors: () => false,
546
+ },
547
+ sensitiveFields: { names: [], choice: "drop" },
548
+ };
549
+ function shortText(value, secrets) {
550
+ if (typeof value === "string")
551
+ return value.trim() || undefined;
552
+ if (value === undefined || value === null)
553
+ return undefined;
554
+ // The kit redacted the answer's values and kept its keys (#703); serialized, a key is text
555
+ // the cut below could split, so the whole text is checked before it is cut.
556
+ const text = secrets.redact(JSON.stringify(value));
557
+ return text.length > 300 ? `${text.slice(0, 300)}…` : text;
558
+ }
559
+ /**
560
+ * Breeze can report a failure inside a 200: `{ success: false, errors: … }`
561
+ * or an `errorCode`. The giving endpoints' success shape is
562
+ * `{ success: true, errors: null }`, so a null or empty `errors` is not one.
563
+ */
564
+ function reportedFailure(payload, secrets) {
565
+ const root = asRecord(payload);
566
+ const errors = root["errors"];
567
+ const hasErrors = errors !== undefined &&
568
+ errors !== null &&
569
+ errors !== false &&
570
+ errors !== "" &&
571
+ !(Array.isArray(errors) && errors.length === 0) &&
572
+ !(typeof errors === "object" && !Array.isArray(errors) && Object.keys(errors).length === 0);
573
+ if (root["success"] !== false && root["errorCode"] === undefined && !hasErrors) {
574
+ return undefined;
575
+ }
576
+ const message = shortText(root["errorMessage"], secrets) ??
577
+ shortText(root["message"], secrets) ??
578
+ shortText(root["errors"], secrets) ??
579
+ shortText(root["errorCode"], secrets) ??
580
+ "no detail";
581
+ // Breeze uses the same envelope for a rejected argument and a missing
582
+ // record, so the code stays the honest generic one and the message says so.
583
+ return resendAdvice(new ConnectorCallError("connector_call_failed", `Breeze reported a failure: ${message}. Breeze does not say whether an argument or a record is at fault.`, { retryable: false }), "; re-check ids with the list tools before retrying");
584
+ }
@@ -1,5 +1,4 @@
1
1
  import type { ConnectorCallAdmissionPolicy } from "../../types.js";
2
- /** Every church's API lives at `https://<subdomain>.breezechms.com/api`. */
3
2
  export declare const BREEZE_HOST_SUFFIX = ".breezechms.com";
4
3
  export interface BreezeOptions {
5
4
  /**
@@ -29,8 +28,7 @@ export interface BreezeOptions {
29
28
  maxResultBytes?: number;
30
29
  /** Serve only read-classified tools on every endpoint. Defaults to false. */
31
30
  readOnly?: boolean;
32
- /** Default `list_people` page size. Defaults to 100; connecta's cap is 1,000. */
31
+ /** Default page size for paged lists. Defaults to 100; connecta's cap is 1,000. */
33
32
  defaultPageSize?: number;
34
33
  }
35
- /** A maintained Breeze ChMS connection for one church's subdomain. */
36
34
  export declare const breeze: import("../../provider.js").ProviderFactory<BreezeOptions>;