@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,271 @@
1
+ import { boundaryFor, delegatorFor, recordRequestField, recordProviderResponse, tracksRequests, isKnownProviderFailure, } from "./provider-call-facts.js";
2
+ // One API call's request ledger in call services, and private failure
3
+ // provenance. Each api() entry installs fresh services even if a direct caller
4
+ // reuses its context concurrently. No request facts escape into agent or
5
+ // operator records.
6
+ import { Classification, ProviderLedger, LogicalLedger, recordedService, requestClosed, viewClosed, setViewService, callFromContext, contextView, viewLease, settleOnClose, } from "./runtime/call.js";
7
+ import { callClassification } from "./call-classification.js";
8
+ import { ConnectorCallError } from "./errors.js";
9
+ export function providerCallContext(ctx, classification) {
10
+ const parent = recordedService(ctx, ProviderLedger);
11
+ const call = { requests: [], classification, closed: false, nested: [], ...(parent ? { parent } : {}) };
12
+ parent?.nested.push(call);
13
+ let view;
14
+ const lease = callFromContext(ctx, classification ?? callClassification(ctx) ?? "write", {
15
+ providerLedger: call,
16
+ ledger: {
17
+ open: ({ auxiliary, provider, method, key }) => providerRequest(view, auxiliary, provider, { method, ...(key === undefined ? {} : { key }) }),
18
+ dispatch: (request, headers, method) => dispatchProviderRequest(view, request, headers, method),
19
+ },
20
+ });
21
+ view = contextView(lease, ctx);
22
+ return view;
23
+ }
24
+ /** Whether `ctx`'s call was entered by another api() boundary's handler. */
25
+ export function nestedProviderCall(ctx) {
26
+ return recordedService(ctx, ProviderLedger)?.parent !== undefined;
27
+ }
28
+ export function providerRequests(ctx) {
29
+ return recordedService(ctx, ProviderLedger)?.requests;
30
+ }
31
+ /**
32
+ * Every request the ledgers of api() boundaries nested beneath `ctx`'s call
33
+ * recorded, at any depth: an inner call's 401 still decides the outer's
34
+ * write (Q8), whatever the outer handler made of the inner's failure.
35
+ */
36
+ export function nestedProviderRequests(ctx) {
37
+ const found = [];
38
+ const visit = (call) => {
39
+ for (const inner of call.nested) {
40
+ found.push(...inner.requests);
41
+ visit(inner);
42
+ }
43
+ };
44
+ const call = recordedService(ctx, ProviderLedger);
45
+ if (call)
46
+ visit(call);
47
+ return found;
48
+ }
49
+ /**
50
+ * End the call's ledger before its outcome is decided. A request still in
51
+ * flight already counts as dispatched; one that has not left yet (a sibling
52
+ * still reading its credential, say) is refused by {@link dispatchProviderRequest}
53
+ * and never leaves after the failure is reported.
54
+ */
55
+ export function closeProviderCall(ctx) {
56
+ const call = recordedService(ctx, ProviderLedger);
57
+ if (call) {
58
+ const close = (current) => {
59
+ current.closed = true;
60
+ for (const child of current.nested)
61
+ close(child);
62
+ };
63
+ close(call);
64
+ }
65
+ viewLease(ctx)?.close();
66
+ }
67
+ /**
68
+ * Refuse every request after its request scope ends, before credential reads
69
+ * and again immediately before dispatch. Resource requests also require an
70
+ * open call. Auxiliary requests (token mints, lookups) may outlive that call,
71
+ * but never their request.
72
+ */
73
+ export function assertProviderCallOpen(ctx, provider, auxiliary) {
74
+ if (requestClosed(ctx))
75
+ throw new ConnectorCallError("connector_call_failed", `This ${provider} request belongs to a request that has already ended, so it was not sent.`, { retryable: false });
76
+ if (auxiliary || (recordedService(ctx, ProviderLedger)?.closed !== true && !viewClosed(ctx)))
77
+ return;
78
+ throw new ConnectorCallError("connector_call_failed", `This ${provider} request belongs to a call that has already ended, so it was not sent.`, { retryable: false });
79
+ }
80
+ /** Record that a request leaves now; synchronous with the send that follows it. */
81
+ export function dispatchProviderRequest(ctx, request, headers, method = request.method) {
82
+ if (ctx)
83
+ assertProviderCallOpen(ctx, request.provider, request.auxiliary);
84
+ if (request.dispatched)
85
+ throw new Error("Provider request already dispatched.");
86
+ if (hasMethodOverride(headers))
87
+ request.classification = "write";
88
+ recordRequestField(request, "method", method);
89
+ recordRequestField(request, "dispatched", true);
90
+ const logical = ctx && recordedService(ctx, LogicalLedger);
91
+ if (logical) {
92
+ if (!request.auxiliary)
93
+ logical.sent.push(request);
94
+ // Auxiliary ownership is the provider's read declaration; the served
95
+ // classification may still be write. Bind method/header evidence now,
96
+ // so token POSTs and overridden GETs cannot supply this proof later.
97
+ else if (method !== undefined && readRequest({ classification: "read", method }, headers))
98
+ logical.auxiliaryReads.push(request);
99
+ else if (request.blocksAuxiliaryProof)
100
+ logical.nonReadAuxiliaryDispatched = true;
101
+ }
102
+ }
103
+ // Only a fetch that records physical sends may accept an unsent handoff.
104
+ const recordingFetches = new WeakSet();
105
+ export function recordingFetch(send) {
106
+ recordingFetches.add(send);
107
+ return send;
108
+ }
109
+ export function isRecordingFetch(send) {
110
+ return send !== undefined && recordingFetches.has(send);
111
+ }
112
+ const handoffs = new WeakMap();
113
+ export function handoffProviderRequest(init, request) {
114
+ if (request.dispatched)
115
+ throw new Error("Provider request already dispatched.");
116
+ handoffs.set(init, request);
117
+ }
118
+ export function takeProviderHandoff(init) {
119
+ // Consume before any await: a read replay or another call cannot take it.
120
+ const request = handoffs.get(init);
121
+ handoffs.delete(init);
122
+ return request?.dispatched ? undefined : request;
123
+ }
124
+ // Observation only: a mapper must name the physical reply it actually received.
125
+ const responseRequests = new WeakMap();
126
+ export function bindProviderResponse(response, request, owner) {
127
+ if (owner)
128
+ responseRequests.set(response, { request, owner });
129
+ }
130
+ export function responseProviderRequest(response, owner) {
131
+ const answer = responseRequests.get(response);
132
+ return answer?.owner === owner ? answer.request : undefined;
133
+ }
134
+ /** Override presence invalidates read evidence, whatever value the header carries. */
135
+ function hasMethodOverride(headers) {
136
+ const sent = new Headers(headers);
137
+ return ["x-http-method-override", "x-http-method", "x-method-override"].some((name) => sent.has(name));
138
+ }
139
+ export function providerRequest(ctx, auxiliary, provider, sent = {}) {
140
+ const request = {
141
+ dispatched: false,
142
+ auxiliary,
143
+ provider,
144
+ classification: recordedService(ctx, ProviderLedger)?.classification ??
145
+ recordedService(ctx, Classification) ??
146
+ callClassification(ctx),
147
+ ...sent,
148
+ };
149
+ recordedService(ctx, ProviderLedger)?.requests.push(request);
150
+ return request;
151
+ }
152
+ /**
153
+ * The invocation opens one logical call on the context it hands a connector,
154
+ * naming the exact object and `callTool` function it is about to invoke.
155
+ */
156
+ export function openLogicalCall(ctx, target, entered) {
157
+ const call = {
158
+ target,
159
+ entered,
160
+ boundaries: [],
161
+ sent: [],
162
+ auxiliaryReads: [],
163
+ nonReadAuxiliaryDispatched: false,
164
+ };
165
+ setViewService(ctx, LogicalLedger, call);
166
+ return call;
167
+ }
168
+ /**
169
+ * An api() or remoteMcp() boundary was entered under `ctx`'s logical call.
170
+ * `boundary` is the object it was built as, from its own closure, never `this`.
171
+ */
172
+ export function enterProviderBoundary(ctx, boundary) {
173
+ recordedService(ctx, LogicalLedger)?.boundaries.push(boundary);
174
+ }
175
+ /**
176
+ * Whether a failure's known mark holds for its whole logical call (INV-9).
177
+ * A boundary marks a write known only when every request it dispatched is
178
+ * proven unapplied, so the mark stands when that boundary owned the call
179
+ * ({@link ownsLogicalCall}) and at most one boundary was entered. A wrapper
180
+ * that composed several calls, or could send around them, never inherits an
181
+ * inner verdict.
182
+ */
183
+ export function knownCallFailure(call, error) {
184
+ return call !== undefined && isKnownProviderFailure(error) && call.boundaries.length <= 1 && ownsLogicalCall(call);
185
+ }
186
+ /**
187
+ * Positive proof that a complete tracked call dispatched only auxiliaries,
188
+ * including a recorded resource read (positive GET/HEAD evidence). An
189
+ * authentication POST alone is not evidence of that call's resource work:
190
+ * token mints can be shared with callers whose ledgers did not send them.
191
+ * An empty resource ledger is not this proof: even a declared api() entry
192
+ * can report a timeout and recovery facts without recording any dispatch.
193
+ * Keep those calls conservative rather than inferring an auxiliary failure
194
+ * from the absence of a resource request. Wrappers and untracked boundaries
195
+ * cannot borrow an inner call's observations.
196
+ */
197
+ export function onlyAuxiliaryRequests(call) {
198
+ const [boundary, ...others] = call?.boundaries ?? [];
199
+ return (call !== undefined &&
200
+ boundary !== undefined &&
201
+ others.length === 0 &&
202
+ tracksRequests(boundary) &&
203
+ ownsLogicalCall(call) &&
204
+ call.auxiliaryReads.some((request) => request.dispatched) &&
205
+ !call.nonReadAuxiliaryDispatched &&
206
+ !call.sent.some((request) => request.dispatched && !request.auxiliary));
207
+ }
208
+ /**
209
+ * Whether reusing `key` with the exact original arguments cannot repeat any
210
+ * write of `ctx`'s logical call, the one basis for key-reuse advice (INV-9).
211
+ * It holds only when the call entered exactly one boundary, which owned it
212
+ * and tracks every request, and sent exactly one write, carrying `key`. A
213
+ * request counts as a read only with positive classification and a recorded
214
+ * GET or HEAD ({@link readRequest}). An inner request's key never speaks for a composite,
215
+ * a wrapper, a second write, or an earlier unrelated request.
216
+ */
217
+ export function keyProtectsCall(call, key) {
218
+ const [boundary, ...others] = call?.boundaries ?? [];
219
+ if (!call || key === undefined || boundary === undefined || others.length > 0 || !tracksRequests(boundary))
220
+ return false;
221
+ const writes = call.sent.filter((request) => !readRequest(request));
222
+ return ownsLogicalCall(call) && writes.length === 1 && writes[0]?.key === key;
223
+ }
224
+ /**
225
+ * The call's invoked object owns it: a boundary object invoked with the
226
+ * function recorded for it at construction, and that boundary was the one
227
+ * entered; or a declared delegator object, likewise. Only identities captured
228
+ * at construction, dispatch and entry decide it, so a wrapper that reassigns
229
+ * `callTool` mid-call, or a copy that shares a boundary's function, cannot
230
+ * borrow its standing.
231
+ */
232
+ function ownsLogicalCall(call) {
233
+ const boundary = boundaryFor(call.target);
234
+ return ((boundary?.own === call.entered && boundary.boundary === call.boundaries[0]) ||
235
+ delegatorFor(call.target) === call.entered);
236
+ }
237
+ /** Positive read evidence, with GET/HEAD as #902's additional conservative bound. */
238
+ export function readRequest(request, headers) {
239
+ const method = request.method?.toUpperCase();
240
+ return (request.classification === "read" &&
241
+ (method === "GET" || method === "HEAD") &&
242
+ (headers === undefined || !hasMethodOverride(headers)));
243
+ }
244
+ export function providerFetch(ctx, provider, auxiliary, send) {
245
+ return (input, init) => settleOnClose(ctx, async (signal) => {
246
+ const method = init?.method ?? (input instanceof Request ? input.method : "GET");
247
+ const request = providerRequest(ctx, auxiliary, provider, { method });
248
+ dispatchProviderRequest(ctx, request, init?.headers ?? (input instanceof Request ? input.headers : undefined));
249
+ const signals = [signal, init?.signal ?? (input instanceof Request ? input.signal : undefined)].filter((signal) => signal !== undefined && signal !== null);
250
+ const sent = signals.length ? { ...init, signal: AbortSignal.any(signals) } : init;
251
+ const response = await send(input, sent);
252
+ recordProviderResponse(request, response.status);
253
+ if (signal.aborted) {
254
+ void response.body?.cancel().catch(() => { });
255
+ throw signal.reason;
256
+ }
257
+ return response;
258
+ }, auxiliary);
259
+ }
260
+ /** Whether an invocation opened the logical call `ctx` belongs to; it then settles Q8 itself. */
261
+ export function inLogicalCall(ctx) {
262
+ return recordedService(ctx, LogicalLedger) !== undefined;
263
+ }
264
+ /**
265
+ * Every resource request dispatched under `ctx`'s logical call, from any
266
+ * ledger, nested ones included; undefined outside one.
267
+ */
268
+ export function logicalCallRequests(ctx) {
269
+ return ctx ? recordedService(ctx, LogicalLedger)?.sent : undefined;
270
+ }
271
+ export { recordProviderResponse, tracksEveryRequest, tracksRequests, delegatesEachCall, providerBoundary, refusedStatus, vendorRefusal, authorizationFailure, unauthorizedAnswer, renewedAfterUnauthorized, refusalRequest, knownProviderFailure, isKnownProviderFailure, forgetProviderFailure, explainedUnauthorizedVerdict, explainsUnauthorized, settledWrite, isSettledWrite, } from "./provider-call-facts.js";
@@ -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. */
@@ -96,15 +90,18 @@ export declare const PROVIDER_COMMON: {
96
90
  instructions: Field<unknown, unknown, true>;
97
91
  title: Field<unknown, unknown, true>;
98
92
  authScope: Field<unknown, unknown, true>;
99
- maxResultBytes: Field<unknown, unknown, true>;
100
93
  purpose: Field<unknown, unknown, true>;
94
+ maxResultBytes: Field<unknown, unknown, true>;
101
95
  };
102
96
  /** The provider's maintained, connection-independent usage guide. */
103
97
  export interface ProviderSkill {
104
98
  /**
105
99
  * Markdown rendered after the heading and the connection context. It states
106
100
  * conventions the vendor's schemas cannot carry, and never varies by
107
- * 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.
108
105
  */
109
106
  content: string;
110
107
  /** Heading for deployment instructions, such as `"Workspace instructions"`. */
@@ -112,6 +109,56 @@ export interface ProviderSkill {
112
109
  /** Exact generated guide fragments used by existing renderers. */
113
110
  fragments?: Readonly<Record<string, string>>;
114
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
+ }
115
162
  /** Connection facts a provider renders around its maintained guide. */
116
163
  export interface ProviderGuideInput {
117
164
  /**
@@ -128,8 +175,6 @@ export interface ProviderGuideInput {
128
175
  }
129
176
  /** What `defineProvider()` hands `create` after validating its options. */
130
177
  export interface ProviderContext {
131
- /** The definition's reviewed classification, for `remoteMcp({ classify })`. */
132
- readonly classify?: ToolClassification;
133
178
  /**
134
179
  * Common connector options the deployment set, and only those, ready to
135
180
  * spread into `remoteMcp()` or `api()` options.
@@ -150,26 +195,23 @@ export interface ProviderDefinition<O extends ProviderOptions> {
150
195
  name: string;
151
196
  /** Vendor display name, and the default guide heading. */
152
197
  title: string;
153
- kind: ProviderKind;
198
+ kind: "api";
154
199
  skill: ProviderSkill;
155
200
  /** Maintained display name in the generated README inventory. */
156
201
  readme?: string;
157
- /** Reviewed build facts; generation never raises an observed cap. */
202
+ /** Reviewed build facts: the bundle report's baseline, never a cap. */
158
203
  bundle?: {
159
204
  baselineGzip: number;
160
- maxGzip: number;
205
+ /** @deprecated Ignored: provider entries are reported, not capped. */
206
+ maxGzip?: number;
161
207
  note?: string;
162
208
  };
163
209
  /** Closed factory options, declared with `optionsOf<O>()` for key parity. */
164
210
  options: Field<unknown, unknown>;
165
- /**
166
- * Reviewed classification of the vendor's hosted MCP catalog. Hosted,
167
- * composed, and dual providers pass it to `remoteMcp({ classify })` through
168
- * `ProviderContext.classify`, so the verdicts that classify live tools and
169
- * the record a drift check reads cannot disagree. `api()` providers annotate
170
- * each tool they author and must omit it.
171
- */
172
- 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;
173
215
  /**
174
216
  * Build the connector. Runs synchronously at construction after its closed
175
217
  * options and common values are validated. Throw here for provider-specific
@@ -190,12 +232,4 @@ export interface ProviderFactory<O extends ProviderOptions> {
190
232
  * so a deployment never boots in the wrong shape (INV-11).
191
233
  */
192
234
  export declare function defineProvider<O extends ProviderOptions>(definition: ProviderDefinition<O>): ProviderFactory<O>;
193
- /**
194
- * Attach the same validated definition to an existing provider constructor.
195
- * Its option policy stays in its builder during the mechanical folder move;
196
- * adopting defineProvider's common-value policy is a separate conversion.
197
- */
198
- export declare function asProviderFactory<O extends ProviderOptions>(definition: Omit<ProviderDefinition<O>, "create"> & {
199
- create(id: string, options: Readonly<O>): Connector;
200
- }): ProviderFactory<O>;
201
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({
@@ -64,10 +61,75 @@ export const PROVIDER_COMMON = {
64
61
  callAdmission: CALL_ADMISSION,
65
62
  };
66
63
  const PROVIDER_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
67
- 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*-->$/;
68
67
  function nonEmpty(value) {
69
68
  return typeof value === "string" && value.trim() !== "";
70
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
+ }
71
133
  /**
72
134
  * Define a maintained provider: one validated description and one factory.
73
135
  *
@@ -83,23 +145,37 @@ export function defineProvider(definition) {
83
145
  if (!nonEmpty(definition.title)) {
84
146
  throw new Error(`${label} requires a non-empty title.`);
85
147
  }
86
- if (!KINDS.has(definition.kind)) {
87
- throw new Error(`${label} kind must be "mcp", "api", "composed", or "dual".`);
88
- }
148
+ if (definition.kind !== "api")
149
+ throw new Error(`${label} kind must be "api".`);
89
150
  if (!nonEmpty(definition.skill?.content) || !nonEmpty(definition.skill.instructionsHeading)) {
90
151
  throw new Error(`${label} skill requires non-empty content and instructionsHeading.`);
91
152
  }
92
- if (definition.classify !== undefined && definition.kind === "api") {
93
- throw new Error(`${label} is an api() provider; annotate each authored tool instead of classifying a hosted catalog.`);
94
- }
153
+ if (Object.hasOwn(definition, "classify"))
154
+ throw new Error(`${label} classify was removed; use ConnectaConfig.classification.`);
95
155
  if (!definition.options?.shape && !definition.options?.variants) {
96
156
  throw new Error(`${label} requires a closed options shape from optionsOf().`);
97
157
  }
98
- // A validated, deep-frozen copy. The definition is what build and check
99
- // tools read and what every later connector classifies with, so nothing
100
- // reachable from it may change a verdict after review: neither the
101
- // caller's original object nor a write through `factory.definition`.
102
- 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.
103
179
  if (typeof definition.create !== "function") {
104
180
  throw new Error(`${label} requires a create function.`);
105
181
  }
@@ -110,7 +186,8 @@ export function defineProvider(definition) {
110
186
  ...(definition.skill.fragments ? { fragments: Object.freeze(definition.skill.fragments) } : {}),
111
187
  }),
112
188
  ...(definition.bundle ? { bundle: Object.freeze({ ...definition.bundle }) } : {}),
113
- ...(classify !== undefined ? { classify } : {}),
189
+ ...(blocks ? { blocks: Object.freeze({ keys: Object.freeze([...blocks.keys]), select: blocks.select }) } : {}),
190
+ ...(definition.kit ? { kit: kitFacts(definition.kit) } : {}),
114
191
  });
115
192
  const factoryName = `${frozen.name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())}()`;
116
193
  const factory = (id, options) => asProvider(frozen.name, frozen.options, id, options, (id, options) => {
@@ -133,7 +210,6 @@ export function defineProvider(definition) {
133
210
  const resolved = { ...options, purpose: options.purpose.trim() };
134
211
  const instructions = options.instructions?.trim();
135
212
  const connector = frozen.create(id, resolved, {
136
- ...(frozen.classify !== undefined ? { classify: frozen.classify } : {}),
137
213
  connectorOptions: {
138
214
  ...(options.readOnly !== undefined ? { readOnly: options.readOnly } : {}),
139
215
  ...(options.authScope !== undefined ? { authScope: options.authScope } : {}),
@@ -142,7 +218,20 @@ export function defineProvider(definition) {
142
218
  },
143
219
  usageGuide(input) {
144
220
  const heading = input.heading ?? `${frozen.title} usage`;
145
- 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");
146
235
  return {
147
236
  content: `# ${heading}\n\n${body}\n` +
148
237
  (instructions ? `\n## ${frozen.skill.instructionsHeading}\n\n${instructions}\n` : ""),
@@ -156,28 +245,13 @@ export function defineProvider(definition) {
156
245
  }
157
246
  return connector;
158
247
  });
159
- // Frozen whole: build and check tools read `definition` to learn what the
160
- // factory classifies, so neither replacing nor deleting it may take effect.
161
- return Object.freeze(Object.assign(factory, { definition: frozen }));
162
- }
163
- /**
164
- * Attach the same validated definition to an existing provider constructor.
165
- * Its option policy stays in its builder during the mechanical folder move;
166
- * adopting defineProvider's common-value policy is a separate conversion.
167
- */
168
- export function asProviderFactory(definition) {
169
- const frozen = defineProvider(definition).definition;
170
- const create = definition.create;
171
- const factory = (id, options) => asProvider(frozen.name, frozen.options, id, options, create);
172
- Object.defineProperty(factory, "name", {
173
- value: frozen.name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()),
174
- });
248
+ // Build and check tools rely on this definition remaining attached.
175
249
  return Object.freeze(Object.assign(factory, { definition: frozen }));
176
250
  }
177
251
  /**
178
252
  * Build a maintained provider's connector: refuse unknown options and
179
253
  * accessors by path before the builder reads any of them, then stamp the
180
- * provider onto its description, so the operator surface can say "Linear"
254
+ * provider onto its description, so the operator surface can say "Stripe"
181
255
  * rather than "remote MCP". This is the same construction path defineProvider
182
256
  * uses; existing constructors retain their provider-specific option policy.
183
257
  */
@@ -202,12 +276,15 @@ function asProvider(provider, shape, id, options, build) {
202
276
  const ownReadOnly = Object.getOwnPropertyDescriptor(connector, "readOnly");
203
277
  // Keep the receiver of prototype methods (including private fields). When
204
278
  // the description cannot be replaced, inherit the whole connector instead
205
- // of copying it: decorators may inherit their id, methods, and review.
279
+ // of copying it: decorators may inherit their id and methods.
206
280
  const stamped = Object.isExtensible(connector) &&
207
281
  (!ownDescribe || ownDescribe.configurable) &&
208
282
  (options.readOnly === undefined || !ownReadOnly || ownReadOnly.configurable)
209
283
  ? connector
210
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);
211
288
  if (options.readOnly !== undefined) {
212
289
  Object.defineProperty(stamped, "readOnly", { value: options.readOnly, enumerable: true, configurable: true });
213
290
  }