@zackbart/connecta 0.34.1 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. package/CHANGELOG.md +363 -0
  2. package/README.md +62 -106
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2051 -1160
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +663 -271
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +12 -7
  53. package/dist/connectors/api-connector.js +142 -56
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/remote-mcp.d.ts +10 -30
  58. package/dist/connectors/remote-mcp.js +955 -563
  59. package/dist/d1.js +10 -243
  60. package/dist/derived-context.js +5 -0
  61. package/dist/describe-config.d.ts +3 -1
  62. package/dist/describe-config.js +2 -0
  63. package/dist/downstream-input.js +347 -260
  64. package/dist/errors.d.ts +87 -6
  65. package/dist/errors.js +114 -4
  66. package/dist/execute.js +87 -50
  67. package/dist/executor-admission.js +3 -0
  68. package/dist/executors/quickjs.js +163 -112
  69. package/dist/guarded-transport.js +50 -0
  70. package/dist/guest-runtime.js +1 -1
  71. package/dist/http/client.js +439 -0
  72. package/dist/http/errors.js +558 -0
  73. package/dist/http/fields.js +49 -0
  74. package/dist/http/hatch-paging.js +318 -0
  75. package/dist/http/hatch.js +1279 -0
  76. package/dist/http/json-schema.js +267 -0
  77. package/dist/http/node-transport.js +241 -0
  78. package/dist/http/oauth.js +162 -0
  79. package/dist/http/paging.js +228 -0
  80. package/dist/http/provider.js +221 -0
  81. package/dist/http/safety.js +82 -0
  82. package/dist/http/services.js +79 -0
  83. package/dist/http/tools.js +383 -0
  84. package/dist/http/vendor-index.js +138 -0
  85. package/dist/http/vendor.js +448 -0
  86. package/dist/http/write-request.js +66 -0
  87. package/dist/http-policy.d.ts +11 -0
  88. package/dist/http-policy.js +45 -0
  89. package/dist/inbound-credential.js +1 -1
  90. package/dist/index.d.ts +2 -2
  91. package/dist/index.js +4 -0
  92. package/dist/invocation-auth.js +30 -19
  93. package/dist/invocation.js +218 -85
  94. package/dist/mcp-result.js +0 -4
  95. package/dist/membership.d.ts +4 -0
  96. package/dist/meta-output.js +1 -1
  97. package/dist/meta-tools.js +531 -406
  98. package/dist/native-recovery.js +52 -0
  99. package/dist/native-tools.js +382 -0
  100. package/dist/node.d.ts +4 -3
  101. package/dist/node.js +45 -8
  102. package/dist/oauth-handoff.js +177 -104
  103. package/dist/oauth-partition.js +6 -20
  104. package/dist/oauth-sealing.js +6 -7
  105. package/dist/operation-vocabulary.js +101 -0
  106. package/dist/operator-record.d.ts +2 -2
  107. package/dist/operator-record.js +17 -4
  108. package/dist/operator-ui/agents.d.ts +5 -4
  109. package/dist/operator-ui/agents.js +17 -7
  110. package/dist/operator-ui/config-summary.js +5 -4
  111. package/dist/operator-ui/connection-map.js +7 -5
  112. package/dist/operator-ui/contract.d.ts +7 -3
  113. package/dist/operator-ui/endpoints.js +4 -13
  114. package/dist/operator-ui/fix-prompts.d.ts +1 -1
  115. package/dist/operator-ui/fix-prompts.js +0 -8
  116. package/dist/operator-ui/generated.js +3 -3
  117. package/dist/operator-ui/model.d.ts +2 -3
  118. package/dist/operator-ui/overview.js +5 -2
  119. package/dist/operator-ui/setup-commands.js +0 -4
  120. package/dist/operator-ui/view.d.ts +2 -25
  121. package/dist/operator-ui/view.js +2 -76
  122. package/dist/program-writes.js +47 -26
  123. package/dist/provider-call-facts.d.ts +115 -0
  124. package/dist/provider-call-facts.js +182 -0
  125. package/dist/provider-call.d.ts +112 -0
  126. package/dist/provider-call.js +271 -0
  127. package/dist/provider.d.ts +65 -31
  128. package/dist/provider.js +116 -39
  129. package/dist/providers/_shared/google/hatch.js +91 -0
  130. package/dist/providers/_shared/google/kit.js +537 -0
  131. package/dist/providers/_shared/google/result-size.js +15 -2
  132. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  133. package/dist/providers/_shared/google/service-account.js +8 -4
  134. package/dist/providers/_shared/google/workspace.d.ts +6 -210
  135. package/dist/providers/_shared/google/workspace.js +6 -425
  136. package/dist/providers/_shared/rest/compact-index.js +86 -0
  137. package/dist/providers/_shared/rest/dispatch.js +3 -23
  138. package/dist/providers/_shared/rest/kit.js +546 -0
  139. package/dist/providers/_shared/rest/operation-index.js +230 -14
  140. package/dist/providers/_shared/rest/response-media.js +11 -0
  141. package/dist/providers/_shared/rest/tools.js +101 -78
  142. package/dist/providers/_shared/rest/value-safety.js +353 -195
  143. package/dist/providers/_shared/sensitive-fields.js +27 -0
  144. package/dist/providers/breeze/api.js +584 -0
  145. package/dist/providers/breeze/index.d.ts +1 -3
  146. package/dist/providers/breeze/index.js +67 -1420
  147. package/dist/providers/breeze/openapi.generated.js +60 -0
  148. package/dist/providers/breeze/skill.generated.js +2 -6
  149. package/dist/providers/breeze/tools.js +696 -0
  150. package/dist/providers/ccb/api.js +496 -0
  151. package/dist/providers/ccb/index.d.ts +15 -37
  152. package/dist/providers/ccb/index.js +77 -1702
  153. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  154. package/dist/providers/ccb/lib/constants.js +74 -0
  155. package/dist/providers/ccb/lib/guide.js +9 -0
  156. package/dist/providers/ccb/lib/verdicts.js +387 -0
  157. package/dist/providers/ccb/openapi.generated.js +397 -0
  158. package/dist/providers/ccb/safety.js +295 -0
  159. package/dist/providers/ccb/skill.generated.js +2 -6
  160. package/dist/providers/ccb/tools.js +853 -0
  161. package/dist/providers/cloudflare/api.js +1066 -0
  162. package/dist/providers/cloudflare/index.d.ts +5 -22
  163. package/dist/providers/cloudflare/index.js +79 -197
  164. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  165. package/dist/providers/cloudflare/lib/config.js +2 -0
  166. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  167. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  168. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  169. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  170. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  171. package/dist/providers/cloudflare/openapi.generated.js +4 -3
  172. package/dist/providers/cloudflare/{value-safety.js → safety.js} +487 -0
  173. package/dist/providers/cloudflare/skill.generated.js +2 -10
  174. package/dist/providers/cloudflare/tools.js +360 -0
  175. package/dist/providers/docs/api.js +51 -0
  176. package/dist/providers/docs/index.d.ts +1 -12
  177. package/dist/providers/docs/index.js +53 -1165
  178. package/dist/providers/docs/lib/constants.d.ts +18 -0
  179. package/dist/providers/docs/lib/constants.js +18 -0
  180. package/dist/providers/docs/lib/discovery.js +26 -0
  181. package/dist/providers/docs/lib/requests.js +48 -0
  182. package/dist/providers/docs/lib/schemas.js +168 -0
  183. package/dist/providers/docs/openapi.generated.js +16 -0
  184. package/dist/providers/docs/safety.js +54 -0
  185. package/dist/providers/docs/skill.generated.js +2 -6
  186. package/dist/providers/docs/tools.js +802 -0
  187. package/dist/providers/drive/api.js +177 -0
  188. package/dist/providers/drive/index.d.ts +1 -12
  189. package/dist/providers/drive/index.js +38 -1448
  190. package/dist/providers/drive/lib/constants.d.ts +6 -0
  191. package/dist/providers/drive/lib/constants.js +6 -0
  192. package/dist/providers/drive/lib/contracts.js +532 -0
  193. package/dist/providers/drive/lib/hatch.js +197 -0
  194. package/dist/providers/drive/openapi.generated.js +77 -0
  195. package/dist/providers/drive/safety.js +90 -0
  196. package/dist/providers/drive/skill.generated.js +2 -6
  197. package/dist/providers/drive/tools.js +1290 -0
  198. package/dist/providers/forms/api.js +71 -0
  199. package/dist/providers/forms/index.d.ts +1 -12
  200. package/dist/providers/forms/index.js +49 -1145
  201. package/dist/providers/forms/lib/constants.d.ts +14 -0
  202. package/dist/providers/forms/lib/constants.js +19 -0
  203. package/dist/providers/forms/lib/hatch.js +72 -0
  204. package/dist/providers/forms/openapi.generated.js +23 -0
  205. package/dist/providers/forms/safety.js +34 -0
  206. package/dist/providers/forms/skill.generated.js +2 -8
  207. package/dist/providers/forms/tools.js +1024 -0
  208. package/dist/providers/github/api.js +150 -0
  209. package/dist/providers/github/index.d.ts +4 -5
  210. package/dist/providers/github/index.js +30 -87
  211. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  212. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  213. package/dist/providers/github/lib/discovery.js +132 -0
  214. package/dist/providers/github/lib/operations.js +58 -0
  215. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  216. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  217. package/dist/providers/github/openapi.generated.js +1216 -0
  218. package/dist/providers/github/safety.js +216 -0
  219. package/dist/providers/github/skill.generated.js +2 -5
  220. package/dist/providers/github/tools.js +506 -0
  221. package/dist/providers/gmail/api.js +114 -0
  222. package/dist/providers/gmail/index.d.ts +1 -12
  223. package/dist/providers/gmail/index.js +73 -1621
  224. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  225. package/dist/providers/gmail/lib/constants.js +16 -0
  226. package/dist/providers/gmail/lib/index.js +173 -0
  227. package/dist/providers/gmail/lib/schemas.js +176 -0
  228. package/dist/providers/gmail/lib/threading.js +120 -0
  229. package/dist/providers/gmail/openapi.generated.js +92 -0
  230. package/dist/providers/gmail/safety.js +21 -0
  231. package/dist/providers/gmail/skill.generated.js +2 -6
  232. package/dist/providers/gmail/tools.js +1435 -0
  233. package/dist/providers/overflow/api.js +1008 -0
  234. package/dist/providers/overflow/index.d.ts +1 -17
  235. package/dist/providers/overflow/index.js +60 -1488
  236. package/dist/providers/overflow/skill.generated.js +2 -5
  237. package/dist/providers/overflow/tools.js +873 -0
  238. package/dist/providers/planning-center/api.js +467 -0
  239. package/dist/providers/planning-center/index.d.ts +4 -35
  240. package/dist/providers/planning-center/index.js +69 -2445
  241. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  242. package/dist/providers/planning-center/lib/constants.js +83 -0
  243. package/dist/providers/planning-center/lib/discovery.js +40 -0
  244. package/dist/providers/planning-center/lib/guide.js +39 -0
  245. package/dist/providers/planning-center/lib/json-api.js +83 -0
  246. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  247. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  248. package/dist/providers/planning-center/safety.js +188 -0
  249. package/dist/providers/planning-center/skill.generated.js +2 -27
  250. package/dist/providers/planning-center/tools.js +1010 -0
  251. package/dist/providers/sheets/api.js +133 -0
  252. package/dist/providers/sheets/index.d.ts +4 -16
  253. package/dist/providers/sheets/index.js +61 -1172
  254. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  255. package/dist/providers/sheets/lib/constants.js +14 -0
  256. package/dist/providers/sheets/lib/hatch.js +163 -0
  257. package/dist/providers/sheets/lib/requests.js +105 -0
  258. package/dist/providers/sheets/lib/schemas.js +138 -0
  259. package/dist/providers/sheets/openapi.generated.js +30 -0
  260. package/dist/providers/sheets/safety.js +27 -0
  261. package/dist/providers/sheets/skill.generated.js +2 -7
  262. package/dist/providers/sheets/tools.js +734 -0
  263. package/dist/providers/slides/api.js +147 -0
  264. package/dist/providers/slides/index.d.ts +2 -10
  265. package/dist/providers/slides/index.js +48 -2555
  266. package/dist/providers/slides/lib/constants.d.ts +11 -0
  267. package/dist/providers/slides/lib/constants.js +11 -0
  268. package/dist/providers/slides/lib/requests.js +60 -0
  269. package/dist/providers/slides/lib/schemas.js +565 -0
  270. package/dist/providers/slides/openapi.generated.js +18 -0
  271. package/dist/providers/slides/skill.generated.js +2 -6
  272. package/dist/providers/slides/tools.js +1968 -0
  273. package/dist/providers/stripe/api.js +401 -0
  274. package/dist/providers/stripe/index.d.ts +5 -27
  275. package/dist/providers/stripe/index.js +74 -210
  276. package/dist/providers/stripe/lib/config.d.ts +4 -0
  277. package/dist/providers/stripe/lib/config.js +2 -0
  278. package/dist/providers/stripe/openapi.generated.js +4 -3
  279. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  280. package/dist/providers/stripe/skill.generated.js +2 -11
  281. package/dist/providers/stripe/tools.js +77 -0
  282. package/dist/providers/tithely/api.js +531 -0
  283. package/dist/providers/tithely/index.d.ts +17 -0
  284. package/dist/providers/tithely/index.js +86 -965
  285. package/dist/providers/tithely/skill.generated.js +2 -5
  286. package/dist/providers/tithely/tools.js +426 -0
  287. package/dist/providers/vercel/api.js +551 -0
  288. package/dist/providers/vercel/index.d.ts +9 -25
  289. package/dist/providers/vercel/index.js +66 -260
  290. package/dist/providers/vercel/lib/config.d.ts +2 -0
  291. package/dist/providers/vercel/lib/config.js +2 -0
  292. package/dist/providers/vercel/lib/index.js +117 -0
  293. package/dist/providers/vercel/lib/logs.js +100 -0
  294. package/dist/providers/vercel/lib/pin.js +270 -0
  295. package/dist/providers/vercel/openapi.generated.js +10 -5
  296. package/dist/providers/vercel/{value-safety.js → safety.js} +247 -38
  297. package/dist/providers/vercel/skill.generated.js +2 -7
  298. package/dist/providers/vercel/tools.js +642 -0
  299. package/dist/redaction-identity.js +47 -0
  300. package/dist/redaction-marker.js +125 -0
  301. package/dist/registry.d.ts +21 -15
  302. package/dist/registry.js +409 -376
  303. package/dist/routes/access-tokens.js +1 -1
  304. package/dist/routes/actor-labels.js +1 -1
  305. package/dist/routes/connect.js +1 -1
  306. package/dist/routes/dispatch.js +103 -0
  307. package/dist/routes/mcp.js +170 -79
  308. package/dist/routes/oauth.js +3 -1
  309. package/dist/routes/operator.js +2 -2
  310. package/dist/routes/shared.d.ts +5 -4
  311. package/dist/routes/shared.js +244 -177
  312. package/dist/routes/skills.js +10 -8
  313. package/dist/routes/ui-config.js +27 -3
  314. package/dist/routes/ui-data.js +21 -20
  315. package/dist/routes/ui.js +1 -1
  316. package/dist/runtime/call-admission.js +0 -26
  317. package/dist/runtime/call-entry.js +30 -0
  318. package/dist/runtime/call.js +556 -0
  319. package/dist/runtime/connector-scope.js +7 -0
  320. package/dist/runtime/credential-probe.js +34 -0
  321. package/dist/runtime/executor.js +40 -0
  322. package/dist/runtime/native-storage.js +63 -0
  323. package/dist/runtime/registry.js +27 -0
  324. package/dist/runtime/request-scope.js +72 -0
  325. package/dist/runtime/run.js +15 -7
  326. package/dist/runtime/shared-read.js +34 -5
  327. package/dist/runtime/storage.js +34 -21
  328. package/dist/sent-secrets.d.ts +194 -37
  329. package/dist/sent-secrets.js +1743 -340
  330. package/dist/server.js +5 -56
  331. package/dist/skills.js +322 -222
  332. package/dist/sqlite.js +15 -14
  333. package/dist/storage/d1-copy.js +255 -0
  334. package/dist/storage/d1-driver.js +15 -0
  335. package/dist/storage/keys.js +28 -0
  336. package/dist/storage/sql-driver.js +88 -0
  337. package/dist/storage/sql-native.js +544 -0
  338. package/dist/storage/sql-schema.d.ts +6 -0
  339. package/dist/storage/sql-schema.js +15 -0
  340. package/dist/storage/sql.d.ts +14 -20
  341. package/dist/storage/sql.js +29 -535
  342. package/dist/timeout.js +0 -26
  343. package/dist/tool-safety.js +20 -10
  344. package/dist/types.d.ts +7 -109
  345. package/dist/upward.js +3 -0
  346. package/dist/usage-guide.js +3 -1
  347. package/dist/validate.d.ts +4 -2
  348. package/dist/validate.js +86 -9
  349. package/dist/version.d.ts +1 -1
  350. package/dist/version.js +1 -1
  351. package/dist/worker.js +312 -292
  352. package/dist/workspace-subject.js +5 -1
  353. package/dist/write-outcome.js +454 -34
  354. package/documentation/README.md +27 -7
  355. package/documentation/architecture.md +2547 -226
  356. package/documentation/auth.md +821 -98
  357. package/documentation/code-mode.md +49 -16
  358. package/documentation/deploying.md +164 -20
  359. package/documentation/hosted-mcp-migration.md +460 -0
  360. package/documentation/integrating.md +129 -144
  361. package/documentation/meta-tools.md +409 -32
  362. package/documentation/operating.md +27 -3
  363. package/documentation/operator-tests.md +3 -0
  364. package/documentation/operator-ui.md +68 -45
  365. package/documentation/provider-auth-migration.md +16 -63
  366. package/documentation/provider-migration-0.29.md +10 -5
  367. package/documentation/provider-migration-0.35.md +975 -0
  368. package/documentation/providers.md +965 -0
  369. package/examples/worker/AGENTS.md +23 -9
  370. package/examples/worker/README.md +254 -135
  371. package/examples/worker/alchemy.run.ts +116 -0
  372. package/examples/worker/gitignore +10 -0
  373. package/examples/worker/src/connecta.config.ts +23 -21
  374. package/examples/worker/wrangler.jsonc +14 -5
  375. package/guides/connecting-agents.md +157 -0
  376. package/guides/how-it-works.md +156 -0
  377. package/guides/safety-and-trust.md +153 -0
  378. package/package.json +27 -46
  379. package/templates/node/.env.example +3 -0
  380. package/templates/node/README.md +22 -2
  381. package/templates/node/docker-compose.yml +1 -0
  382. package/templates/node/package.json +3 -2
  383. package/templates/node/src/connecta.config.ts +8 -0
  384. package/dist/catalog-drift.d.ts +0 -138
  385. package/dist/catalog-drift.js +0 -578
  386. package/dist/providers/_shared/request-token.js +0 -83
  387. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  388. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  389. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  390. package/dist/providers/basecamp/index.d.ts +0 -45
  391. package/dist/providers/basecamp/index.js +0 -997
  392. package/dist/providers/basecamp/skill.generated.js +0 -9
  393. package/dist/providers/cloudflare/rest.d.ts +0 -37
  394. package/dist/providers/cloudflare/rest.js +0 -1097
  395. package/dist/providers/github/hosted.js +0 -218
  396. package/dist/providers/github/rest.js +0 -321
  397. package/dist/providers/infisical/index.d.ts +0 -7
  398. package/dist/providers/infisical/index.js +0 -713
  399. package/dist/providers/infisical/skill.generated.js +0 -8
  400. package/dist/providers/intercom/index.d.ts +0 -24
  401. package/dist/providers/intercom/index.js +0 -121
  402. package/dist/providers/intercom/skill.generated.js +0 -8
  403. package/dist/providers/linear/index.d.ts +0 -55
  404. package/dist/providers/linear/index.js +0 -537
  405. package/dist/providers/linear/skill.generated.js +0 -8
  406. package/dist/providers/mixpanel/index.d.ts +0 -59
  407. package/dist/providers/mixpanel/index.js +0 -472
  408. package/dist/providers/mixpanel/operations.js +0 -20
  409. package/dist/providers/mixpanel/rest.js +0 -603
  410. package/dist/providers/mixpanel/skill.generated.js +0 -10
  411. package/dist/providers/mixpanel/value-safety.js +0 -16
  412. package/dist/providers/notion/index.d.ts +0 -67
  413. package/dist/providers/notion/index.js +0 -368
  414. package/dist/providers/notion/openapi.generated.js +0 -75
  415. package/dist/providers/notion/rest.d.ts +0 -24
  416. package/dist/providers/notion/rest.js +0 -1226
  417. package/dist/providers/notion/skill.generated.js +0 -11
  418. package/dist/providers/notion/value-safety.js +0 -56
  419. package/dist/providers/revenuecat/index.d.ts +0 -51
  420. package/dist/providers/revenuecat/index.js +0 -697
  421. package/dist/providers/revenuecat/skill.generated.js +0 -11
  422. package/dist/providers/stripe/rest.d.ts +0 -14
  423. package/dist/providers/stripe/rest.js +0 -402
  424. package/dist/providers/vercel/rest.d.ts +0 -20
  425. package/dist/providers/vercel/rest.js +0 -1020
  426. package/dist/providers/wispr-flow/index.d.ts +0 -14
  427. package/dist/providers/wispr-flow/index.js +0 -117
  428. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  429. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -0,0 +1,150 @@
1
+ // GitHub's finite REST complement. App JWT discovery and minting remain private
2
+ // auxiliary requests; rejected installation tokens renew on the next call only.
3
+ import { Effect, Schema } from "effect";
4
+ import { indexedVendor } from "../_shared/rest/kit.js";
5
+ import { githubIndex, GITHUB_HATCH } from "./lib/discovery.js";
6
+ import { githubSafety } from "./safety.js";
7
+ import { INTERNAL_READS, MERGE, READ_PERMISSIONS, RELEASE_PERMISSIONS } from "./lib/operations.js";
8
+ import { errorMeanings } from "../../http/errors.js";
9
+ import { ConnectorCallError } from "../../errors.js";
10
+ import { guardedClient } from "../../http/client.js";
11
+ import { captureClassifierFacts, StatusFailure } from "../../http/errors.js";
12
+ import { resultSafety } from "../../http/safety.js";
13
+ import { connect, get, operations } from "../../http/vendor.js";
14
+ const repository = { owner: Schema.String, repo: Schema.String };
15
+ const success = Schema.Unknown;
16
+ export const GitHubApi = indexedVendor("GitHub", githubIndex, [
17
+ get("repository", "/repos/:owner/:repo", { params: repository, success }),
18
+ ]);
19
+ function rateLimited(status, retry, remaining) {
20
+ return status === 429 || (status === 403 && (retry !== undefined || remaining === 0));
21
+ }
22
+ export function rejectedToken(status, headers) {
23
+ if (status !== 403)
24
+ return status === 401;
25
+ const numbers = captureClassifierFacts(undefined, errors, headers)?.numbers;
26
+ return !rateLimited(status, numbers?.["retryAfterMs"], numbers?.["remaining"]);
27
+ }
28
+ const AUTH = "Verify the GitHub App key, installation, repository selection and required permissions.";
29
+ const FAILED = "The GitHub API request failed; downstream error text is withheld.";
30
+ function rate(input) {
31
+ if (!rateLimited(input.status, input.retryAfterMs, input.numbers["remaining"]))
32
+ return undefined;
33
+ const wait = input.retryAfterMs ?? input.numbers["resetAfterMs"];
34
+ return {
35
+ code: "rate_limited",
36
+ retryable: true,
37
+ ...(wait === undefined ? {} : { retryAfterMs: wait }),
38
+ words: () => "GitHub rate limit reached.",
39
+ advice: " Honor the retry timing before trying again.",
40
+ };
41
+ }
42
+ export const errors = {
43
+ numericFacts: {
44
+ retryAfterMs: {
45
+ header: "retry-after",
46
+ format: "retry-after",
47
+ review: "HTTP Retry-After delay for failure recovery.",
48
+ },
49
+ remaining: {
50
+ header: "x-ratelimit-remaining",
51
+ review: "GitHub classifies a 403 with no remaining requests as rate limited.",
52
+ },
53
+ resetAfterMs: {
54
+ header: "x-ratelimit-reset",
55
+ format: "epoch-seconds",
56
+ review: "GitHub rate-limit reset time in epoch seconds.",
57
+ },
58
+ },
59
+ provider: "GitHub",
60
+ facts: (body) => ({
61
+ merged: body && typeof body === "object" && "merged" in body && body.merged === false ? false : undefined,
62
+ }),
63
+ factVocabulary: { merged: [false] },
64
+ meanings: {
65
+ unknownId: "connector_call_failed",
66
+ provesAbsence: false,
67
+ conflicts: [
68
+ "HTTP 409 is a conflict; a merged:false response and the expected-SHA/same-repository preflight also refuse a merge",
69
+ ],
70
+ },
71
+ classify: [
72
+ ({ operation, facts }) => operation.method === "PUT" &&
73
+ operation.template === "/repos/{owner}/{repo}/pulls/{pull_number}/merge" &&
74
+ facts["merged"] === false
75
+ ? {
76
+ code: "conflict",
77
+ retryable: false,
78
+ words: () => "GitHub reported that the pull request was not merged. Read its current state before another attempt.",
79
+ }
80
+ : undefined,
81
+ rate,
82
+ ],
83
+ detail: ({ status: code }) => code === 401 || code === 403
84
+ ? AUTH
85
+ : code === 409
86
+ ? "GitHub reported a conflict. Read the current state."
87
+ : code === 404
88
+ ? "GitHub returned 404; the resource may be absent or inaccessible to this installation."
89
+ : FAILED,
90
+ statuses: {
91
+ 401: () => ({ code: "auth_required", retryable: false }),
92
+ 403: () => ({ code: "auth_required", retryable: false }),
93
+ 404: () => ({ code: "connector_call_failed", retryable: false }),
94
+ 409: () => ({ code: "conflict", retryable: false, advice: " before resubmitting" }),
95
+ },
96
+ bodyFailures: {
97
+ review: "GitHub failure classification uses only status and declared numeric headers; failed success reads disclose no raw cause.",
98
+ statusOnly: [],
99
+ readFailed: "GitHub's response body could not be read completely.",
100
+ },
101
+ unreadable: "GitHub returned malformed JSON; response text is withheld.",
102
+ };
103
+ export function githubConnection() {
104
+ const safety = resultSafety({
105
+ reviewed: {
106
+ refusal: (op) => githubSafety.refusal(op.method, op.template),
107
+ resolve: (method, path) => {
108
+ const { op } = githubIndex.resolve(method, path);
109
+ const key = `${op.method} ${op.path}`;
110
+ if (!READ_PERMISSIONS[key] && !RELEASE_PERMISSIONS[key] && !INTERNAL_READS.has(key) && key !== MERGE)
111
+ throw new ConnectorCallError("invalid_args", "This GitHub operation is not exposed by the connection.");
112
+ return { method: op.method, template: op.path };
113
+ },
114
+ redact: (data, op) => githubSafety.redact(data, op.method, op.template),
115
+ withholdsErrors: () => true,
116
+ },
117
+ sensitiveFields: { names: [], choice: "drop" },
118
+ });
119
+ return connect(GitHubApi, guardedClient({
120
+ provider: "GitHub",
121
+ baseUrl: "https://api.github.com",
122
+ maxResponseBytes: 4 * 1024 * 1024,
123
+ headers: {
124
+ Accept: "application/vnd.github+json",
125
+ "X-GitHub-Api-Version": "2022-11-28",
126
+ "User-Agent": "connecta",
127
+ },
128
+ authenticate: Effect.succeed({}),
129
+ }), {
130
+ errors,
131
+ safety,
132
+ inBandRefusals: true,
133
+ result: (body, answer) => answer.operation.method === "PUT" &&
134
+ answer.operation.template === "/repos/{owner}/{repo}/pulls/{pull_number}/merge" &&
135
+ body &&
136
+ typeof body === "object" &&
137
+ "merged" in body &&
138
+ body.merged === false
139
+ ? Effect.fail(new StatusFailure({ status: answer.status, headers: answer.headers, body, operation: answer.operation }))
140
+ : Effect.succeed(answer.bodyFormat === "empty" ? undefined : body),
141
+ });
142
+ }
143
+ export const kit = {
144
+ operations: operations(GitHubApi),
145
+ pageSize: { default: 30, max: 100 },
146
+ hatch: { name: GITHUB_HATCH.name, verdicts: GITHUB_HATCH.verdicts, paging: "argument" },
147
+ errors: errorMeanings(errors),
148
+ idempotencyKey: false,
149
+ refusesWithheld: true,
150
+ };
@@ -1,9 +1,8 @@
1
1
  import { type ProviderOptions } from "../../provider.js";
2
- import { type GitHubApp } from "./auth.js";
3
- import { type GitHubScope } from "./scope.js";
4
- export type { GitHubApp } from "./auth.js";
5
- export type { GitHubScope } from "./scope.js";
6
- export declare const GITHUB_MCP_ENDPOINT = "https://api.githubcopilot.com/mcp/";
2
+ import { type GitHubApp } from "./lib/auth.js";
3
+ import { type GitHubScope } from "./lib/scope.js";
4
+ export type { GitHubApp } from "./lib/auth.js";
5
+ export type { GitHubScope } from "./lib/scope.js";
7
6
  export interface GitHubOptions extends ProviderOptions {
8
7
  app: GitHubApp;
9
8
  /** Mixed org and exact repository grants, with explicit access. */
@@ -1,37 +1,22 @@
1
- import { remoteMcp } from "../../connectors/remote-mcp.js";
2
1
  import { array, keys, optionsOf } from "../../config-schema.js";
3
2
  import { ConnectorCallError } from "../../errors.js";
4
- import { redactSentSecrets } from "../../sent-secrets.js";
3
+ import { delegatesEachCall, knownProviderFailure } from "../../provider-call.js";
5
4
  import { defineProvider, PROVIDER_COMMON } from "../../provider.js";
6
- import { AppAuth } from "./auth.js";
7
- import { HOSTED_CLASSIFICATION, HOSTED_ROUTES, hostedTarget } from "./hosted.js";
8
- import { restConnector } from "./rest.js";
9
- import { parseScopes, ScopePolicy } from "./scope.js";
5
+ import { kit } from "./api.js";
6
+ import { AppAuth } from "./lib/auth.js";
7
+ import { restConnector } from "./tools.js";
8
+ import { parseScopes, ScopePolicy } from "./lib/scope.js";
10
9
  import { skill } from "./skill.generated.js";
11
- export const GITHUB_MCP_ENDPOINT = "https://api.githubcopilot.com/mcp/";
12
- const CLASSIFICATION = {
13
- unlisted: "hide",
14
- tools: {
15
- ...HOSTED_CLASSIFICATION.tools,
16
- list_scopes: "read",
17
- search_scoped: "read",
18
- create_release: "write",
19
- update_release: "destructive",
20
- delete_release: "destructive",
21
- merge_pull_request: "destructive",
22
- },
23
- };
24
10
  /** One GitHub App, multiple owner installations, explicit org/repo grants. */
25
11
  export const github = defineProvider({
26
12
  name: "github",
27
13
  title: "GitHub",
28
- kind: "composed",
14
+ kind: "api",
29
15
  skill,
30
- classify: CLASSIFICATION,
16
+ kit,
31
17
  bundle: {
32
- baselineGzip: 164063,
33
- maxGzip: 224063,
34
- note: "./providers/github initial measured baseline includes the hosted MCP SDK plus portable GitHub App signing, exact routing and REST complements; cap retains the existing 60,000-byte provider headroom policy.",
18
+ baselineGzip: 451137,
19
+ note: "./providers/github merged step-2 snapshot measures 451,137 B gzip standalone before recording these bundle facts (#703), Node 26.12.0 with zlib-ng 1.3.1, scripts/bundle-size.mjs. The complete immutable 1,204-operation index is retained. The same-toolchain pre-change probe was 335,233 B; growth is approximately 115 KB, below the approved 300 KB gate. This entry includes the shared Effect provider kit, paid once per deployment; standalone provider sizes are not additive. Provider entries are reported, not capped (#899).",
35
20
  },
36
21
  options: optionsOf()({
37
22
  ...PROVIDER_COMMON,
@@ -40,45 +25,23 @@ export const github = defineProvider({
40
25
  }),
41
26
  create(id, options, provider) {
42
27
  if (options.authScope === "personal")
43
- throw new Error("shared GitHub App identity; per-user OAuth attribution is planned separately for 0.29.");
28
+ throw new Error("shared GitHub App identity; per-user OAuth attribution is planned separately.");
44
29
  const policy = new ScopePolicy(parseScopes(options.scopes));
45
30
  const auth = new AppAuth(options.app, policy);
46
31
  const rest = restConnector(id, auth, policy);
32
+ // Delegation invokes these captured functions with Reflect.apply, never
33
+ // through a property or a function's own `call`.
34
+ const restCall = rest.callTool;
47
35
  const usageGuide = provider.usageGuide({
48
- context: [`Act as the GitHub App. Reachable configuration: ${policy.summary()}.`, `Purpose: ${options.purpose}`],
49
- summary: "GitHub App scopes, installation routing, confined search and workflow-file limits.",
36
+ context: [
37
+ `Act as the GitHub App. Reachable configuration: ${policy.summary()}.`,
38
+ `Purpose: ${options.purpose}`,
39
+ "The App identity is already configured. Installation access is resolved on use; ask the operator to repair configuration only after an auth failure.",
40
+ ...(options.readOnly === true ? ["This connection is read-only; every write is refused."] : []),
41
+ ],
42
+ summary: "GitHub App repository reads, scoped data search, release writes and guarded merges.",
50
43
  required: true,
51
44
  });
52
- // Each operation owns its token-bound client, transport and callback.
53
- // It closes them before returning; no shared header or client mutation.
54
- const hosted = (token, classify = HOSTED_CLASSIFICATION) => remoteMcp(id, {
55
- url: GITHUB_MCP_ENDPOINT,
56
- requireHttps: true,
57
- redirects: "none",
58
- classify,
59
- auth: {
60
- type: "request",
61
- token: async () => token,
62
- headers: {
63
- "X-MCP-Toolsets": "repos,git,issues,pull_requests,actions,labels",
64
- "X-MCP-Tools": Object.keys(HOSTED_ROUTES).join(","),
65
- },
66
- },
67
- });
68
- const withHosted = async (token, ctx, run) => {
69
- const client = hosted(token);
70
- try {
71
- return await run(client);
72
- }
73
- catch (error) {
74
- if (error instanceof ConnectorCallError && error.code === "auth_required")
75
- await auth.rejectToken(token);
76
- throw redactSentSecrets(ctx, error);
77
- }
78
- finally {
79
- await client.closeScope?.(ctx);
80
- }
81
- };
82
45
  const credential = options.app.privateKey === undefined
83
46
  ? {
84
47
  label: "GitHub App private key",
@@ -86,55 +49,35 @@ export const github = defineProvider({
86
49
  fields: [{ name: "privateKey", label: "Private key PEM", inputType: "password" }],
87
50
  }
88
51
  : undefined;
89
- return {
52
+ // Each call goes to its REST boundary, whose write-outcome verdict stands.
53
+ return delegatesEachCall({
90
54
  id,
91
55
  title: options.title ?? "GitHub",
56
+ // Preserve the REST tools' existing MCP result envelope.
92
57
  kind: "mcp",
93
58
  authScope: "shared",
94
59
  ...provider.connectorOptions,
95
60
  ...(credential ? { credential } : {}),
96
- classification: provider.classify,
97
61
  description: `GitHub App access to ${policy.summary()}.`,
98
62
  usageGuide,
99
63
  describe: () => ({
100
64
  source: { kind: "custom" },
101
- endpoint: { origin: "https://api.githubcopilot.com", path: "/mcp/" },
65
+ endpoint: { origin: "https://api.github.com", path: "/" },
102
66
  auth: { mode: "request", header: "Authorization", scheme: "Bearer" },
103
67
  }),
68
+ staticTools: rest.staticTools,
104
69
  async listTools(ctx) {
105
- // Catalog discovery authenticates only a configured scope, with read
106
- // permissions. Fetch one complete vendor catalog and preserve schemas.
107
- const first = policy.scopes[0];
108
- const owner = first.org ?? first.repo.split("/")[0];
109
- const repos = first.repo ? [first.repo.split("/")[1]] : undefined;
110
- const token = await auth.token(owner, repos, {
111
- contents: "read",
112
- issues: "read",
113
- pull_requests: "read",
114
- actions: "read",
115
- checks: "read",
116
- statuses: "read",
117
- }, ctx);
118
- const facts = await withHosted(token, ctx, (client) => client.listTools(ctx));
119
- const complement = await rest.listTools(ctx);
120
- // Names not reviewed never leave this boundary, including collisions
121
- // with the REST complement. The registry alone applies verdicts.
122
- return [...facts.filter((tool) => Object.hasOwn(HOSTED_ROUTES, tool.name)), ...complement];
70
+ return rest.listTools(ctx);
123
71
  },
124
72
  async callTool(name, args, ctx, callOptions) {
125
- if (Object.hasOwn(HOSTED_ROUTES, name)) {
126
- const route = hostedTarget(name, args, policy);
127
- const token = await auth.repo(route.target, route.permissions, ctx);
128
- return withHosted(token, ctx, (client) => client.callTool(name, args, ctx, callOptions));
129
- }
130
- if (!Object.hasOwn(CLASSIFICATION.tools, name))
131
- throw new ConnectorCallError("invalid_args", "This GitHub tool is not in the reviewed allowlist.");
132
- const result = await rest.callTool(name, args, ctx, callOptions);
73
+ if (!rest.staticTools?.some((tool) => tool.name === name))
74
+ throw knownProviderFailure(new ConnectorCallError("invalid_args", "This GitHub tool is not in the REST tool set."));
75
+ const result = await Reflect.apply(restCall, rest, [name, args, ctx, callOptions]);
133
76
  return { content: [{ type: "text", text: JSON.stringify(result) }], structuredContent: result };
134
77
  },
135
78
  async status() {
136
79
  return { state: "ok", message: "GitHub App configured; installation access is resolved lazily on use." };
137
80
  },
138
- };
81
+ });
139
82
  },
140
83
  });
@@ -1,5 +1,5 @@
1
- import { type GuardedRequest } from "../../connectors/guarded-fetch.js";
2
- import type { ConnectorContext } from "../../types.js";
1
+ import { type GuardedRequest } from "../../../connectors/guarded-fetch.js";
2
+ import type { ConnectorContext } from "../../../types.js";
3
3
  import { ScopePolicy, type Target } from "./scope.js";
4
4
  export interface GitHubApp {
5
5
  appId: string | number;
@@ -17,9 +17,11 @@ export declare class AppAuth {
17
17
  private readonly orgInstallations;
18
18
  private readonly configuredDer?;
19
19
  private readonly appId;
20
+ private readonly send;
20
21
  constructor(app: GitHubApp, policy: ScopePolicy);
21
22
  private key;
22
- json(request: GuardedRequest, bearer: string, ctx: ConnectorContext): Promise<unknown>;
23
+ /** `write` sends the request once: a failure that may follow the change is not retryable. */
24
+ json(request: GuardedRequest, bearer: string, ctx: ConnectorContext, write?: boolean): Promise<unknown>;
23
25
  private invalidate;
24
26
  rejectToken(bearer: string): Promise<void>;
25
27
  private installation;
@@ -1,8 +1,10 @@
1
- import { guardedFetch, retryAfterMs } from "../../connectors/guarded-fetch.js";
2
- import { ConnectorCallError } from "../../errors.js";
3
- import { attachFailureFacts } from "../../operator-record.js";
1
+ import { guardedFetch } from "../../../connectors/guarded-fetch.js";
2
+ import { ConnectorCallError } from "../../../errors.js";
3
+ import { captureClassifierFacts, StatusFailure, toConnectorCallError, withClassifierFacts, } from "../../../http/errors.js";
4
+ import { errors, rejectedToken } from "../api.js";
4
5
  import { appJwt, privateKeyDer } from "./key.js";
5
6
  import { target } from "./scope.js";
7
+ import { sentSecretsFor } from "../../../sent-secrets.js";
6
8
  const MAX_ENTRIES = 256;
7
9
  const REFRESH_MARGIN = 60_000;
8
10
  const INSTALLATION_TTL = 300_000;
@@ -30,6 +32,17 @@ export class AppAuth {
30
32
  orgInstallations = new Map();
31
33
  configuredDer;
32
34
  appId;
35
+ send = guardedFetch({
36
+ provider: "GitHub",
37
+ baseUrl: "https://api.github.com",
38
+ maxResponseBytes: 4 * 1024 * 1024,
39
+ headers: {
40
+ Accept: "application/vnd.github+json",
41
+ "X-GitHub-Api-Version": "2022-11-28",
42
+ "User-Agent": "connecta",
43
+ },
44
+ authenticate: () => ({}),
45
+ });
33
46
  constructor(app, policy) {
34
47
  this.app = app;
35
48
  this.policy = policy;
@@ -48,6 +61,8 @@ export class AppAuth {
48
61
  }
49
62
  async key(ctx) {
50
63
  ctx.signal?.throwIfAborted();
64
+ if (this.app.privateKey !== undefined)
65
+ sentSecretsFor(ctx).add(this.app.privateKey);
51
66
  let der = this.configuredDer;
52
67
  if (!der) {
53
68
  const pem = await ctx.credential?.get("privateKey");
@@ -67,49 +82,30 @@ export class AppAuth {
67
82
  fingerprint: `${this.appId}:${Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join("")}`,
68
83
  };
69
84
  }
70
- async json(request, bearer, ctx) {
85
+ /** `write` sends the request once: a failure that may follow the change is not retryable. */
86
+ async json(request, bearer, ctx, write = false) {
71
87
  ctx.signal?.throwIfAborted();
72
- const transport = guardedFetch({
73
- provider: "GitHub",
74
- baseUrl: "https://api.github.com",
75
- maxResponseBytes: 4 * 1024 * 1024,
76
- headers: {
77
- Accept: "application/vnd.github+json",
78
- "X-GitHub-Api-Version": "2022-11-28",
79
- "User-Agent": "connecta",
80
- },
81
- authenticate: () => ({ Authorization: `Bearer ${bearer}` }),
82
- });
83
- return transport(request, ctx, async (response) => {
88
+ return this.send({
89
+ classification: write ? "write" : "read",
90
+ ...request,
91
+ headers: { ...request.headers, Authorization: `Bearer ${bearer}` },
92
+ }, ctx, async (response) => {
84
93
  if (!response.ok) {
85
94
  // Dispose of the body without interpreting error text or Content-Type.
86
95
  await response.prefix(0);
87
- const status = response.status;
88
- const reset = Number(response.headers.get("x-ratelimit-reset"));
89
- const retry = retryAfterMs(response.headers);
90
- const wait = retry ?? (Number.isFinite(reset) && reset > 0 ? Math.max(0, reset * 1000 - Date.now()) : undefined);
91
- const rate = status === 429 ||
92
- (status === 403 && (retry !== undefined || response.headers.get("x-ratelimit-remaining") === "0"));
93
- if (status === 401 || (status === 403 && !rate))
96
+ if (rejectedToken(response.status, response.headers))
94
97
  this.invalidate(bearer);
95
- const code = rate
96
- ? "rate_limited"
97
- : status === 401 || status === 403
98
- ? "auth_required"
99
- : status === 409
100
- ? "conflict"
101
- : status >= 500
102
- ? "unavailable"
103
- : "connector_call_failed";
104
- throw attachFailureFacts(new ConnectorCallError(code, rate
105
- ? "GitHub rate limit reached. Honor the retry timing before trying again."
106
- : code === "auth_required"
107
- ? "Verify the GitHub App key, installation, repository selection and required permissions."
108
- : code === "conflict"
109
- ? "GitHub rejected a stale version. Read the current state before resubmitting."
110
- : status === 404
111
- ? "GitHub returned 404; the resource may be absent or inaccessible to this installation."
112
- : "The GitHub API request failed; downstream error text is withheld.", { retryable: rate || status >= 500, ...(rate && wait !== undefined ? { retryAfterMs: wait } : {}) }), { httpStatus: status });
98
+ const failure = withClassifierFacts(new StatusFailure({
99
+ status: response.status,
100
+ headers: response.headers,
101
+ body: undefined,
102
+ operation: { method: request.method, template: request.path },
103
+ }), captureClassifierFacts(undefined, errors, response.headers));
104
+ throw toConnectorCallError(failure, errors, {
105
+ classification: write ? "write" : "read",
106
+ dispatches: [],
107
+ withholds: () => true,
108
+ });
113
109
  }
114
110
  const parsed = await response.jsonResult();
115
111
  ctx.signal?.throwIfAborted();
@@ -147,7 +143,7 @@ export class AppAuth {
147
143
  }
148
144
  let found;
149
145
  for (let page = 1; page <= 20; page++) {
150
- const data = await this.json({ method: "GET", path: "/app/installations", query: { per_page: 100, page } }, jwt, ctx);
146
+ const data = await this.json({ auxiliary: true, method: "GET", path: "/app/installations", query: { per_page: 100, page } }, jwt, ctx);
151
147
  if (!Array.isArray(data))
152
148
  throw new ConnectorCallError("connector_call_failed", "GitHub returned an invalid installation list.");
153
149
  for (const item of data) {
@@ -204,7 +200,7 @@ export class AppAuth {
204
200
  const found = new Map();
205
201
  const configured = this.policy.scopes.filter((scope) => scope.repo?.startsWith(`${owner}/`));
206
202
  for (let page = 1; page <= 100; page++) {
207
- const data = record(await this.json({ method: "GET", path: "/installation/repositories", query: { per_page: 100, page } }, resolver, ctx));
203
+ const data = record(await this.json({ auxiliary: true, method: "GET", path: "/installation/repositories", query: { per_page: 100, page } }, resolver, ctx));
208
204
  if (!Array.isArray(data.repositories))
209
205
  throw new ConnectorCallError("connector_call_failed", "GitHub returned an invalid repository list.");
210
206
  for (const item of data.repositories) {
@@ -303,6 +299,7 @@ export class AppAuth {
303
299
  let response;
304
300
  try {
305
301
  response = record(await this.json({
302
+ auxiliary: true,
306
303
  method: "POST",
307
304
  path: `/app/installations/${installation.id}/access_tokens`,
308
305
  body: { permissions: permissionSet, ...(repositorySet ? { repository_ids: repositorySet } : {}) },
@@ -0,0 +1,132 @@
1
+ import { OperationIndex } from "../../_shared/rest/operation-index.js";
2
+ import { githubPage } from "../../../http/hatch-paging.js";
3
+ import { openapi } from "../openapi.generated.js";
4
+ import { READ_PERMISSIONS, RELEASE_PERMISSIONS, INTERNAL_READS, MERGE } from "./operations.js";
5
+ import { workflowPath } from "./scope.js";
6
+ import { ConnectorCallError } from "../../../errors.js";
7
+ /** Only the documented contents path can consume several literal URL segments. */
8
+ export function contentsPath(path) {
9
+ // Preserve the shared refusal of URL suffixes and unfilled placeholders.
10
+ if (/[?#{}]/.test(path))
11
+ return path;
12
+ const match = /^(\/repos\/[^/]+\/[^/]+\/contents\/)(.+)$/.exec(path);
13
+ if (!match)
14
+ return path;
15
+ let relative;
16
+ try {
17
+ relative = decodeURIComponent(match[2]);
18
+ }
19
+ catch {
20
+ // Keep malformed encodings for the index's standard refusal.
21
+ return path;
22
+ }
23
+ workflowPath(relative);
24
+ return match[1] + encodeURIComponent(relative);
25
+ }
26
+ // Prefer the deployed coverage for natural queries. Explicit paths and queries
27
+ // without reviewed matches retain full-pin refusal discovery. Metadata, contract
28
+ // lookup, validation and the manifest still use the complete immutable pin.
29
+ class RepositoryIndex extends OperationIndex {
30
+ resolve(method, path) {
31
+ if (method === "GET" && /^\/repos\/[^/]+\/[^/]+\/contents$/.test(path)) {
32
+ // GitHub documents omitted path as the root directory. Reuse the pinned
33
+ // contents contract; validate owner/repo normally, and never send this
34
+ // placeholder. The actual resource request keeps the /contents URL.
35
+ const match = super.resolve(method, `${path}/root`);
36
+ return { ...match, params: { ...match.params, path: "" } };
37
+ }
38
+ try {
39
+ return super.resolve(method, contentsPath(path));
40
+ }
41
+ catch (error) {
42
+ if (method === "GET" &&
43
+ error instanceof ConnectorCallError &&
44
+ error.code === "invalid_args" &&
45
+ error.message.includes(" operation in the pinned API index ") &&
46
+ /^\/repos\/[^/]+\/[^/]+\/(?:commits|compare)\/[^/]+\/.+/.test(path))
47
+ throw new ConnectorCallError("invalid_args", `${error.message} Encode '/' inside refs as %2F.`);
48
+ throw error;
49
+ }
50
+ }
51
+ contract(op, only) {
52
+ const contract = super.contract(op, only);
53
+ if (op.path === "/repos/{owner}/{repo}/contents/{path}")
54
+ for (const param of contract.parameters)
55
+ if (param.name === "path")
56
+ param.description =
57
+ "Canonical relative file or directory path; nested paths such as src/index.ts are accepted. For the root directory use /repos/{owner}/{repo}/contents without a final path.";
58
+ if (["/repos/{owner}/{repo}/commits/{ref}", "/repos/{owner}/{repo}/compare/{basehead}"].includes(op.path))
59
+ for (const param of contract.parameters)
60
+ if (param.name === "ref" || param.name === "basehead")
61
+ param.description =
62
+ "Repository-local ref or SHA; encode a slash inside a branch name as %2F. Compare uses BASE...HEAD. Owner-prefixed refs containing a colon are refused.";
63
+ return contract;
64
+ }
65
+ search(query, options) {
66
+ const all = super.search(query, { ...options, limit: this.ops.length });
67
+ if (query.trim().startsWith("/"))
68
+ return all.slice(0, options.limit);
69
+ const preferred = all.filter((op) => {
70
+ const key = `${op.method} ${op.path}`;
71
+ return READ_PERMISSIONS[key] || RELEASE_PERMISSIONS[key] || INTERNAL_READS.has(key) || key === MERGE;
72
+ });
73
+ // The shared lexical framing drops "latest". Bare release discovery
74
+ // therefore leads with the collection and latest read; explicit actions,
75
+ // method filters and paths still discover every reviewed release write.
76
+ const found = /^releases?$/i.test(query.trim()) && (options.method === undefined || options.method === "GET")
77
+ ? preferred.filter((op) => op.method === "GET" &&
78
+ ["/repos/{owner}/{repo}/releases", "/repos/{owner}/{repo}/releases/latest"].includes(op.path))
79
+ : preferred;
80
+ return (found.length ? found : all).slice(0, options.limit);
81
+ }
82
+ }
83
+ export const githubIndex = new RepositoryIndex({
84
+ ...openapi,
85
+ ops: openapi.ops.map((row) => {
86
+ const [method, path, id, summary, tag, ...server] = row;
87
+ const alias = method === "PATCH" && path === "/repos/{owner}/{repo}/releases/{release_id}"
88
+ ? " (Publish a release by updating draft to false)"
89
+ : path === "/repos/{owner}/{repo}/releases/latest"
90
+ ? " (Latest published release)"
91
+ : path.includes("/pulls")
92
+ ? " (PR pull request)"
93
+ : path.includes("/contents/")
94
+ ? " (Read file or directory contents)"
95
+ : "";
96
+ return [method, path, id, summary + alias, tag, ...server];
97
+ }),
98
+ }, { vendor: "github", title: "GitHub", slashParams: ["path", "ref", "basehead"] });
99
+ for (const key of [...Object.keys(READ_PERMISSIONS), ...Object.keys(RELEASE_PERMISSIONS), ...INTERNAL_READS, MERGE]) {
100
+ if (!githubIndex.ops.some((op) => `${op.method} ${op.path}` === key))
101
+ throw new Error(`GitHub reviewed operation is absent from the pin: ${key}`);
102
+ }
103
+ export const GITHUB_VERDICTS = {
104
+ ...Object.fromEntries(Object.keys(READ_PERMISSIONS).map((key) => [key, "read"])),
105
+ ...Object.fromEntries(Object.keys(RELEASE_PERMISSIONS).map((key) => [key, "destructive"])),
106
+ [MERGE]: "refuse",
107
+ ...Object.fromEntries([...INTERNAL_READS].map((key) => [key, "refuse"])),
108
+ };
109
+ export const GITHUB_NAMED = {
110
+ [MERGE]: "merge_pull_request",
111
+ "GET /installation/repositories": "list_scopes",
112
+ "GET /search/repositories": "search_scoped",
113
+ "GET /search/issues": "search_scoped",
114
+ "GET /search/code": "search_scoped",
115
+ };
116
+ const adapter = githubPage("https://api.github.com");
117
+ export const GITHUB_PAGES = Object.fromEntries(githubIndex.ops
118
+ .filter((op) => {
119
+ const key = `${op.method} ${op.path}`;
120
+ return (READ_PERMISSIONS[key] && githubIndex.contract(op).parameters.some((p) => p.in === "query" && p.name === "page"));
121
+ })
122
+ .map((op) => [`${op.method} ${op.path}`, adapter]));
123
+ export const GITHUB_HATCH = {
124
+ name: "github",
125
+ title: "GitHub",
126
+ index: githubIndex,
127
+ verdicts: GITHUB_VERDICTS,
128
+ named: GITHUB_NAMED,
129
+ pages: GITHUB_PAGES,
130
+ pageCursor: "argument",
131
+ pathExample: "/repos/alice/widget/issues",
132
+ };