@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,12 +1,6 @@
1
1
  import { type Field } from "./config-schema.js";
2
- import type { Connector, ConnectorCallAdmissionPolicy, ConnectorUsageGuide, ToolClassification } from "./types.js";
3
- /**
4
- * How a provider reaches its vendor: the vendor's hosted MCP server, an
5
- * `api()` connector over the vendor's HTTP API, one connector composing both
6
- * with an explicit operation ownership map, or `"dual"`: configuration selects the implementation, usually by `auth.type`. Mixpanel
7
- * uses explicit `via` because service accounts reach both implementations.
8
- */
9
- export type ProviderKind = "mcp" | "api" | "composed" | "dual";
2
+ import { type ConnectorCallErrorCode } from "./errors.js";
3
+ import type { Connector, ConnectorCallAdmissionPolicy, ConnectorUsageGuide } from "./types.js";
10
4
  /** Options every provider accepts, validated before `create` runs. */
11
5
  export interface ProviderOptions {
12
6
  /** What this connection is for and which decisions it answers. Required. */
@@ -19,6 +13,8 @@ export interface ProviderOptions {
19
13
  authScope?: "shared" | "personal";
20
14
  /** Connector-specific inline result limit; omit to inherit the deployment. */
21
15
  maxResultBytes?: number;
16
+ /** Serve only read-classified tools on every endpoint. Defaults to false. */
17
+ readOnly?: boolean;
22
18
  /** Optional per-runtime downstream call-admission policy. */
23
19
  callAdmission?: ConnectorCallAdmissionPolicy;
24
20
  }
@@ -82,8 +78,11 @@ export declare const CALL_ADMISSION: Omit<Field<unknown, ConnectorCallAdmissionP
82
78
  parse(value: unknown, path: string): ConnectorCallAdmissionPolicy;
83
79
  readonly shape: typeof admissionPolicy.shape;
84
80
  };
81
+ /** Validate the common connector policy before a deployment can serve. */
82
+ export declare const READ_ONLY: Field<boolean, boolean | undefined, true>;
85
83
  /** Options every maintained provider shares. */
86
84
  export declare const PROVIDER_COMMON: {
85
+ readOnly: Field<boolean, boolean | undefined, true>;
87
86
  callAdmission: Omit<Field<unknown, ConnectorCallAdmissionPolicy | undefined, true>, "parse"> & {
88
87
  parse(value: unknown, path: string): ConnectorCallAdmissionPolicy;
89
88
  readonly shape: typeof admissionPolicy.shape;
@@ -91,15 +90,18 @@ export declare const PROVIDER_COMMON: {
91
90
  instructions: Field<unknown, unknown, true>;
92
91
  title: Field<unknown, unknown, true>;
93
92
  authScope: Field<unknown, unknown, true>;
94
- maxResultBytes: Field<unknown, unknown, true>;
95
93
  purpose: Field<unknown, unknown, true>;
94
+ maxResultBytes: Field<unknown, unknown, true>;
96
95
  };
97
96
  /** The provider's maintained, connection-independent usage guide. */
98
97
  export interface ProviderSkill {
99
98
  /**
100
99
  * Markdown rendered after the heading and the connection context. It states
101
100
  * conventions the vendor's schemas cannot carry, and never varies by
102
- * deployment.
101
+ * deployment. A standard guide (decision 0011, G) is `SKILL.md`'s body
102
+ * followed by its generated `## Conventions`; text that differs by
103
+ * implementation or option stands in `<!-- when: <key> -->` …
104
+ * `<!-- end -->` blocks the definition's `blocks` selects.
103
105
  */
104
106
  content: string;
105
107
  /** Heading for deployment instructions, such as `"Workspace instructions"`. */
@@ -107,6 +109,56 @@ export interface ProviderSkill {
107
109
  /** Exact generated guide fragments used by existing renderers. */
108
110
  fragments?: Readonly<Record<string, string>>;
109
111
  }
112
+ /**
113
+ * The closed key set of a guide's `<!-- when: <key> -->` blocks and the pure
114
+ * selector that picks a connection's keys from its options (decision 0011,
115
+ * G2). Select only the blocks this API configuration uses.
116
+ */
117
+ export interface ProviderGuideBlocks<O> {
118
+ readonly keys: readonly string[];
119
+ /** The keys whose blocks this connection renders, in any order. */
120
+ select(options: Readonly<O>): readonly string[];
121
+ }
122
+ /**
123
+ * Facts the provider kit (decision 0010) declares for `providers:generate`:
124
+ * `drift.json`'s `generated.operations` and the guide's Conventions. Plain
125
+ * data, never read at runtime. The kit's `defineApiProvider` sets them.
126
+ */
127
+ export interface ProviderKitFacts {
128
+ /** `manifest(vendor)`: every operation the provider's tools send, as `"METHOD /path"`. */
129
+ readonly operations: readonly string[];
130
+ /** The `limit` default and maximum every paged read declares. */
131
+ readonly pageSize?: {
132
+ readonly default: number;
133
+ readonly max: number;
134
+ };
135
+ /** The hatch's tool prefix and its reviewed verdict per `"METHOD /path"`. */
136
+ readonly hatch?: {
137
+ readonly name: string;
138
+ readonly verdicts: Readonly<Record<string, "read" | "write" | "destructive" | "refuse">>;
139
+ /** Separate-cursor paging opts into the generated hatch paging convention. */
140
+ readonly paging?: "argument" | "parameter";
141
+ readonly fieldsRoot?: string;
142
+ };
143
+ /**
144
+ * The vendor's declared error meanings, for the Errors convention: the code
145
+ * an unknown id fails with, whether it proves absence, and each documented
146
+ * conflict source.
147
+ */
148
+ readonly errors?: {
149
+ readonly unknownId: ConnectorCallErrorCode;
150
+ readonly provesAbsence: boolean;
151
+ readonly conflicts: readonly string[];
152
+ };
153
+ /** Whether a write takes an idempotency key the vendor honors, checked against the built tools. */
154
+ readonly idempotencyKey?: boolean;
155
+ /**
156
+ * Set only when the hatch refuses a write carrying a withheld placeholder
157
+ * value; the Withheld values convention promises exactly that. The kit sets
158
+ * it for its standard hatch; kit write builders refuse the same markers.
159
+ */
160
+ readonly refusesWithheld?: true;
161
+ }
110
162
  /** Connection facts a provider renders around its maintained guide. */
111
163
  export interface ProviderGuideInput {
112
164
  /**
@@ -123,13 +175,11 @@ export interface ProviderGuideInput {
123
175
  }
124
176
  /** What `defineProvider()` hands `create` after validating its options. */
125
177
  export interface ProviderContext {
126
- /** The definition's reviewed classification, for `remoteMcp({ classify })`. */
127
- readonly classify?: ToolClassification;
128
178
  /**
129
179
  * Common connector options the deployment set, and only those, ready to
130
180
  * spread into `remoteMcp()` or `api()` options.
131
181
  */
132
- readonly connectorOptions: Readonly<Pick<ProviderOptions, "authScope" | "maxResultBytes" | "callAdmission">>;
182
+ readonly connectorOptions: Readonly<Pick<ProviderOptions, "authScope" | "maxResultBytes" | "callAdmission" | "readOnly">>;
133
183
  /**
134
184
  * Render the maintained skill with this connection's context and the
135
185
  * deployment's instructions. Instructions are appended; they never replace
@@ -145,26 +195,23 @@ export interface ProviderDefinition<O extends ProviderOptions> {
145
195
  name: string;
146
196
  /** Vendor display name, and the default guide heading. */
147
197
  title: string;
148
- kind: ProviderKind;
198
+ kind: "api";
149
199
  skill: ProviderSkill;
150
200
  /** Maintained display name in the generated README inventory. */
151
201
  readme?: string;
152
- /** Reviewed build facts; generation never raises an observed cap. */
202
+ /** Reviewed build facts: the bundle report's baseline, never a cap. */
153
203
  bundle?: {
154
204
  baselineGzip: number;
155
- maxGzip: number;
205
+ /** @deprecated Ignored: provider entries are reported, not capped. */
206
+ maxGzip?: number;
156
207
  note?: string;
157
208
  };
158
209
  /** Closed factory options, declared with `optionsOf<O>()` for key parity. */
159
210
  options: Field<unknown, unknown>;
160
- /**
161
- * Reviewed classification of the vendor's hosted MCP catalog. Hosted,
162
- * composed, and dual providers pass it to `remoteMcp({ classify })` through
163
- * `ProviderContext.classify`, so the verdicts that classify live tools and
164
- * the record a drift check reads cannot disagree. `api()` providers annotate
165
- * each tool they author and must omit it.
166
- */
167
- classify?: ToolClassification;
211
+ /** Required when the guide holds `<!-- when: <key> -->` blocks. */
212
+ blocks?: ProviderGuideBlocks<O>;
213
+ /** Set by the provider kit; see `ProviderKitFacts`. */
214
+ kit?: ProviderKitFacts;
168
215
  /**
169
216
  * Build the connector. Runs synchronously at construction after its closed
170
217
  * options and common values are validated. Throw here for provider-specific
@@ -185,12 +232,4 @@ export interface ProviderFactory<O extends ProviderOptions> {
185
232
  * so a deployment never boots in the wrong shape (INV-11).
186
233
  */
187
234
  export declare function defineProvider<O extends ProviderOptions>(definition: ProviderDefinition<O>): ProviderFactory<O>;
188
- /**
189
- * Attach the same validated definition to an existing provider constructor.
190
- * Its option policy stays in its builder during the mechanical folder move;
191
- * adopting defineProvider's common-value policy is a separate conversion.
192
- */
193
- export declare function asProviderFactory<O extends ProviderOptions>(definition: Omit<ProviderDefinition<O>, "create"> & {
194
- create(id: string, options: Readonly<O>): Connector;
195
- }): ProviderFactory<O>;
196
235
  export {};
package/dist/provider.js CHANGED
@@ -1,10 +1,7 @@
1
- // The one shape every maintained provider takes. Deliberately transport-free:
2
- // it imports neither `remoteMcp()` nor `api()`, so an `api()` provider does not
3
- // acquire the MCP client, OAuth, or Effect graph by using it, and a hosted
4
- // provider does not acquire `api()`. Its runtime imports validate plain
5
- // options and reviewed classification, with no I/O.
1
+ // Transport-free maintained API provider definitions and construction validation.
6
2
  import { array, assertKnownOptions, ConfigError, fn, keys, object, opaque, required, whole, } from "./config-schema.js";
7
- import { reviewedClassification } from "./catalog-drift.js";
3
+ import { aliasCallIdentity } from "./provider-call-facts.js";
4
+ import { isConnectorCallErrorCode } from "./errors.js";
8
5
  const budget = {
9
6
  ...object({
10
7
  kind: required(opaque({
@@ -50,16 +47,89 @@ export const CALL_ADMISSION = {
50
47
  return policy;
51
48
  },
52
49
  };
50
+ /** Validate the common connector policy before a deployment can serve. */
51
+ export const READ_ONLY = opaque({
52
+ check(value, path) {
53
+ if (typeof value !== "boolean")
54
+ throw new ConfigError(`${path} must be a boolean.`);
55
+ },
56
+ });
53
57
  /** Options every maintained provider shares. */
54
58
  export const PROVIDER_COMMON = {
55
59
  ...keys("title", "authScope", "purpose", "instructions", "maxResultBytes"),
60
+ readOnly: READ_ONLY,
56
61
  callAdmission: CALL_ADMISSION,
57
62
  };
58
63
  const PROVIDER_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
59
- const KINDS = new Set(["mcp", "api", "composed", "dual"]);
64
+ const BLOCK_KEY = /^[a-z][a-z0-9:-]*$/;
65
+ /** A when-block marker, alone on its line. */
66
+ const BLOCK_MARKER = /^<!--\s*(?:when:\s*([a-z][a-z0-9:-]*)|end)\s*-->$/;
60
67
  function nonEmpty(value) {
61
68
  return typeof value === "string" && value.trim() !== "";
62
69
  }
70
+ /**
71
+ * Render a guide's selected when-blocks, or, with no selection, check them
72
+ * and return their keys. Markers stand alone on their lines and never nest.
73
+ * Removing an unselected block also removes the blank line it leaves, so
74
+ * paragraphs and tight lists keep their spacing.
75
+ */
76
+ function guideBlocks(content, selected) {
77
+ const keys = new Set();
78
+ const kept = [];
79
+ let open;
80
+ let seam = false;
81
+ for (const line of content.split("\n")) {
82
+ const marker = BLOCK_MARKER.exec(line.trim());
83
+ if (marker) {
84
+ if (marker[1] !== undefined ? open !== undefined : open === undefined) {
85
+ throw new Error("when-blocks must open and close in turn, unnested");
86
+ }
87
+ if (marker[1] !== undefined)
88
+ keys.add((open = marker[1]));
89
+ else {
90
+ seam = selected !== undefined && !selected.has(open);
91
+ open = undefined;
92
+ }
93
+ continue;
94
+ }
95
+ if (/<!--\s*(?:when:|end\s*-->)/.test(line))
96
+ throw new Error("a when-block marker stands alone on its line");
97
+ if (open !== undefined && !selected?.has(open))
98
+ continue;
99
+ if (seam && !line.trim() && (kept.length === 0 || !kept.at(-1).trim()))
100
+ continue;
101
+ seam = false;
102
+ kept.push(line);
103
+ }
104
+ if (open !== undefined)
105
+ throw new Error(`the when-block "${open}" is never closed`);
106
+ return { text: kept.join("\n").trim(), keys };
107
+ }
108
+ /** A frozen copy: kit facts are review evidence `providers:generate` reads. */
109
+ function kitFacts(kit) {
110
+ if (kit.errors && !isConnectorCallErrorCode(kit.errors.unknownId)) {
111
+ throw new Error("Provider kit errors.unknownId must be a ConnectorCallErrorCode.");
112
+ }
113
+ return Object.freeze({
114
+ operations: Object.freeze([...kit.operations]),
115
+ ...(kit.pageSize ? { pageSize: Object.freeze({ ...kit.pageSize }) } : {}),
116
+ ...(kit.hatch
117
+ ? {
118
+ hatch: Object.freeze({
119
+ name: kit.hatch.name,
120
+ verdicts: Object.freeze({ ...kit.hatch.verdicts }),
121
+ ...(kit.hatch.paging ? { paging: kit.hatch.paging } : {}),
122
+ ...(kit.hatch.fieldsRoot ? { fieldsRoot: kit.hatch.fieldsRoot } : {}),
123
+ }),
124
+ }
125
+ : {}),
126
+ ...(kit.errors
127
+ ? { errors: Object.freeze({ ...kit.errors, conflicts: Object.freeze([...kit.errors.conflicts]) }) }
128
+ : {}),
129
+ ...(kit.idempotencyKey !== undefined ? { idempotencyKey: kit.idempotencyKey } : {}),
130
+ ...(kit.refusesWithheld ? { refusesWithheld: true } : {}),
131
+ });
132
+ }
63
133
  /**
64
134
  * Define a maintained provider: one validated description and one factory.
65
135
  *
@@ -75,23 +145,37 @@ export function defineProvider(definition) {
75
145
  if (!nonEmpty(definition.title)) {
76
146
  throw new Error(`${label} requires a non-empty title.`);
77
147
  }
78
- if (!KINDS.has(definition.kind)) {
79
- throw new Error(`${label} kind must be "mcp", "api", "composed", or "dual".`);
80
- }
148
+ if (definition.kind !== "api")
149
+ throw new Error(`${label} kind must be "api".`);
81
150
  if (!nonEmpty(definition.skill?.content) || !nonEmpty(definition.skill.instructionsHeading)) {
82
151
  throw new Error(`${label} skill requires non-empty content and instructionsHeading.`);
83
152
  }
84
- if (definition.classify !== undefined && definition.kind === "api") {
85
- throw new Error(`${label} is an api() provider; annotate each authored tool instead of classifying a hosted catalog.`);
86
- }
153
+ if (Object.hasOwn(definition, "classify"))
154
+ throw new Error(`${label} classify was removed; use ConnectaConfig.classification.`);
87
155
  if (!definition.options?.shape && !definition.options?.variants) {
88
156
  throw new Error(`${label} requires a closed options shape from optionsOf().`);
89
157
  }
90
- // A validated, deep-frozen copy. The definition is what build and check
91
- // tools read and what every later connector classifies with, so nothing
92
- // reachable from it may change a verdict after review: neither the
93
- // caller's original object nor a write through `factory.definition`.
94
- const classify = definition.classify === undefined ? undefined : reviewedClassification(definition.classify, label);
158
+ const blocks = definition.blocks;
159
+ if (blocks !== undefined &&
160
+ (!Array.isArray(blocks.keys) ||
161
+ blocks.keys.length === 0 ||
162
+ !blocks.keys.every((key) => typeof key === "string" && BLOCK_KEY.test(key)) ||
163
+ new Set(blocks.keys).size !== blocks.keys.length ||
164
+ typeof blocks.select !== "function")) {
165
+ throw new Error(`${label} blocks require unique lowercase keys and a select function.`);
166
+ }
167
+ let used;
168
+ try {
169
+ used = guideBlocks(definition.skill.content).keys;
170
+ }
171
+ catch (error) {
172
+ throw new Error(`${label} skill: ${error instanceof Error ? error.message : String(error)}.`, { cause: error });
173
+ }
174
+ for (const key of used) {
175
+ if (!blocks?.keys.includes(key))
176
+ throw new Error(`${label} skill uses the when-block "${key}" its blocks omit.`);
177
+ }
178
+ // Freeze definition facts consumed by construction, generation and checks.
95
179
  if (typeof definition.create !== "function") {
96
180
  throw new Error(`${label} requires a create function.`);
97
181
  }
@@ -102,7 +186,8 @@ export function defineProvider(definition) {
102
186
  ...(definition.skill.fragments ? { fragments: Object.freeze(definition.skill.fragments) } : {}),
103
187
  }),
104
188
  ...(definition.bundle ? { bundle: Object.freeze({ ...definition.bundle }) } : {}),
105
- ...(classify !== undefined ? { classify } : {}),
189
+ ...(blocks ? { blocks: Object.freeze({ keys: Object.freeze([...blocks.keys]), select: blocks.select }) } : {}),
190
+ ...(definition.kit ? { kit: kitFacts(definition.kit) } : {}),
106
191
  });
107
192
  const factoryName = `${frozen.name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())}()`;
108
193
  const factory = (id, options) => asProvider(frozen.name, frozen.options, id, options, (id, options) => {
@@ -125,15 +210,28 @@ export function defineProvider(definition) {
125
210
  const resolved = { ...options, purpose: options.purpose.trim() };
126
211
  const instructions = options.instructions?.trim();
127
212
  const connector = frozen.create(id, resolved, {
128
- ...(frozen.classify !== undefined ? { classify: frozen.classify } : {}),
129
213
  connectorOptions: {
214
+ ...(options.readOnly !== undefined ? { readOnly: options.readOnly } : {}),
130
215
  ...(options.authScope !== undefined ? { authScope: options.authScope } : {}),
131
216
  ...(options.maxResultBytes !== undefined ? { maxResultBytes: options.maxResultBytes } : {}),
132
217
  ...(options.callAdmission !== undefined ? { callAdmission: options.callAdmission } : {}),
133
218
  },
134
219
  usageGuide(input) {
135
220
  const heading = input.heading ?? `${frozen.title} usage`;
136
- const body = [...input.context, frozen.skill.content.trim()].join("\n\n");
221
+ let guide = frozen.skill.content.trim();
222
+ if (frozen.blocks) {
223
+ const { keys, select } = frozen.blocks;
224
+ const selected = select(resolved);
225
+ if (!Array.isArray(selected))
226
+ throw new Error(`${at} requires blocks.select() to return an array of keys.`);
227
+ for (const key of selected) {
228
+ if (!keys.includes(key)) {
229
+ throw new Error(`${at} requires blocks.select() to return declared keys; it returned ${String(key)}.`);
230
+ }
231
+ }
232
+ guide = guideBlocks(frozen.skill.content, new Set(selected)).text;
233
+ }
234
+ const body = [...input.context, guide].join("\n\n");
137
235
  return {
138
236
  content: `# ${heading}\n\n${body}\n` +
139
237
  (instructions ? `\n## ${frozen.skill.instructionsHeading}\n\n${instructions}\n` : ""),
@@ -147,28 +245,13 @@ export function defineProvider(definition) {
147
245
  }
148
246
  return connector;
149
247
  });
150
- // Frozen whole: build and check tools read `definition` to learn what the
151
- // factory classifies, so neither replacing nor deleting it may take effect.
152
- return Object.freeze(Object.assign(factory, { definition: frozen }));
153
- }
154
- /**
155
- * Attach the same validated definition to an existing provider constructor.
156
- * Its option policy stays in its builder during the mechanical folder move;
157
- * adopting defineProvider's common-value policy is a separate conversion.
158
- */
159
- export function asProviderFactory(definition) {
160
- const frozen = defineProvider(definition).definition;
161
- const create = definition.create;
162
- const factory = (id, options) => asProvider(frozen.name, frozen.options, id, options, create);
163
- Object.defineProperty(factory, "name", {
164
- value: frozen.name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()),
165
- });
248
+ // Build and check tools rely on this definition remaining attached.
166
249
  return Object.freeze(Object.assign(factory, { definition: frozen }));
167
250
  }
168
251
  /**
169
252
  * Build a maintained provider's connector: refuse unknown options and
170
253
  * accessors by path before the builder reads any of them, then stamp the
171
- * provider onto its description, so the operator surface can say "Linear"
254
+ * provider onto its description, so the operator surface can say "Stripe"
172
255
  * rather than "remote MCP". This is the same construction path defineProvider
173
256
  * uses; existing constructors retain their provider-specific option policy.
174
257
  */
@@ -178,6 +261,8 @@ function asProvider(provider, shape, id, options, build) {
178
261
  let connector;
179
262
  try {
180
263
  options = assertKnownOptions(options, `${factory}(${JSON.stringify(id)})`, shape);
264
+ if (options?.readOnly !== undefined)
265
+ READ_ONLY.parse(options.readOnly, `${factory}(${JSON.stringify(id)}).readOnly`);
181
266
  const admission = options == null ? undefined : options.callAdmission;
182
267
  if (admission !== undefined)
183
268
  CALL_ADMISSION.parse(admission, `${factory}(${JSON.stringify(id)}).callAdmission`);
@@ -188,12 +273,21 @@ function asProvider(provider, shape, id, options, build) {
188
273
  }
189
274
  const describe = connector.describe?.bind(connector);
190
275
  const ownDescribe = Object.getOwnPropertyDescriptor(connector, "describe");
276
+ const ownReadOnly = Object.getOwnPropertyDescriptor(connector, "readOnly");
191
277
  // Keep the receiver of prototype methods (including private fields). When
192
278
  // the description cannot be replaced, inherit the whole connector instead
193
- // of copying it: decorators may inherit their id, methods, and review.
194
- const stamped = Object.isExtensible(connector) && (!ownDescribe || ownDescribe.configurable)
279
+ // of copying it: decorators may inherit their id and methods.
280
+ const stamped = Object.isExtensible(connector) &&
281
+ (!ownDescribe || ownDescribe.configurable) &&
282
+ (options.readOnly === undefined || !ownReadOnly || ownReadOnly.configurable)
195
283
  ? connector
196
284
  : Object.create(connector);
285
+ // An inheriting stamp serves the connector itself, so it keeps its call identity.
286
+ if (stamped !== connector)
287
+ aliasCallIdentity(stamped, connector);
288
+ if (options.readOnly !== undefined) {
289
+ Object.defineProperty(stamped, "readOnly", { value: options.readOnly, enumerable: true, configurable: true });
290
+ }
197
291
  Object.defineProperty(stamped, "describe", {
198
292
  configurable: true,
199
293
  enumerable: false,
@@ -0,0 +1,91 @@
1
+ // Opt-in plumbing only. Product PRs supply their reviewed literal verdicts.
2
+ import { Effect } from "effect";
3
+ import { ConnectorCallError } from "../../../errors.js";
4
+ export function requireGoogleIndex(index) {
5
+ if (!index)
6
+ throw new Error("Google requests require their reviewed operation index.");
7
+ if (index.pathMatching !== "uri-template")
8
+ throw new Error('Google indexes require pathMatching: "uri-template".');
9
+ }
10
+ /** Independent of compact schema depth: only reviewed batch kinds can execute. */
11
+ export function googleBatchGuard(body, options) {
12
+ if (!body || typeof body !== "object" || Array.isArray(body))
13
+ return "A Google batch body must be an object.";
14
+ const value = body;
15
+ const requests = value["requests"];
16
+ if (!Array.isArray(requests) || !requests.length || requests.length > (options.max ?? 100))
17
+ return `A Google batch needs 1–${options.max ?? 100} requests.`;
18
+ if (requests.some((request) => !request ||
19
+ typeof request !== "object" ||
20
+ Array.isArray(request) ||
21
+ Object.keys(request).length !== 1 ||
22
+ !options.kinds.includes(Object.keys(request)[0])))
23
+ return "Each Google batch request must contain exactly one reviewed request kind.";
24
+ const control = value["writeControl"];
25
+ if (options.revision &&
26
+ (!control || typeof control["requiredRevisionId"] !== "string" || !control["requiredRevisionId"].trim()))
27
+ return "This Google batch needs a nonempty writeControl.requiredRevisionId from a current read.";
28
+ return undefined;
29
+ }
30
+ /** Ensure a substituted named id still reaches the endpoint the tool declared. */
31
+ export function googleNamedOperation(index, method, path, template) {
32
+ requireGoogleIndex(index);
33
+ if (index.resolve(method, path).op.path !== template)
34
+ throw new ConnectorCallError("invalid_args", "This Google id resolves to a different operation; no request was sent.");
35
+ }
36
+ export function googleHatchBinding(connection, options) {
37
+ requireGoogleIndex(options.index);
38
+ return {
39
+ index: options.index,
40
+ ...(options.wrapSend ? { warnings: true } : {}),
41
+ review: options.review,
42
+ ...(options.refusal ? { refusal: options.refusal } : {}),
43
+ refuse: (call) => {
44
+ for (const match of call.path.matchAll(/%([a-f0-9]{2})/gi))
45
+ if (/^[-A-Za-z0-9._~:]$/.test(String.fromCharCode(parseInt(match[1], 16))))
46
+ return "Google paths must spell unreserved characters and action separators literally.";
47
+ if (call.headers && Object.keys(call.headers).length)
48
+ return "Google hatches do not accept caller headers.";
49
+ for (const key of Object.keys(call.query))
50
+ if ([
51
+ "access_token",
52
+ "oauth_token",
53
+ "key",
54
+ "callback",
55
+ "upload_protocol",
56
+ "uploadType",
57
+ "userId",
58
+ "quotaUser",
59
+ ].includes(key))
60
+ return `Google query.${key} is owned by the deployment and cannot be selected by a caller.`;
61
+ if (call.query["alt"] !== undefined && call.query["alt"] !== "json")
62
+ return "Google hatches return JSON only; use a named content tool for media.";
63
+ return options.refuse?.(call);
64
+ },
65
+ send: (call, sendOptions) => Effect.suspend(() => {
66
+ // Capture the admitted wire request before the wrapper can inspect its copy.
67
+ const request = {
68
+ method: call.method,
69
+ path: call.path,
70
+ template: call.op.path,
71
+ query: Object.entries(call.query).flatMap(([name, value]) => value === undefined
72
+ ? []
73
+ : (Array.isArray(value) ? value : [value]).map((item) => [name, String(item)])),
74
+ headers: { accept: "application/json" },
75
+ ...(call.body === undefined ? {} : { json: JSON.stringify(call.body) }),
76
+ };
77
+ const optionsForSend = {
78
+ ...sendOptions,
79
+ ...(options.revisionGuarded?.(call) ? { flags: { revisionGuarded: true } } : {}),
80
+ };
81
+ let sent = false;
82
+ const send = () => Effect.suspend(() => {
83
+ if (sent)
84
+ return Effect.die(new Error("A Google hatch wrapper may send its admitted request only once."));
85
+ sent = true;
86
+ return connection.sendPath(request, optionsForSend);
87
+ });
88
+ return options.wrapSend ? options.wrapSend(structuredClone(call), send) : send();
89
+ }),
90
+ };
91
+ }