@zackbart/connecta 0.34.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +62 -105
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2051 -1160
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +663 -271
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +15 -7
  53. package/dist/connectors/api-connector.js +147 -57
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/option-shapes.js +1 -1
  58. package/dist/connectors/remote-mcp.d.ts +12 -30
  59. package/dist/connectors/remote-mcp.js +960 -564
  60. package/dist/d1.js +10 -243
  61. package/dist/derived-context.js +5 -0
  62. package/dist/describe-config.d.ts +5 -1
  63. package/dist/describe-config.js +3 -0
  64. package/dist/downstream-input.js +347 -260
  65. package/dist/errors.d.ts +87 -6
  66. package/dist/errors.js +114 -4
  67. package/dist/execute.js +87 -50
  68. package/dist/executor-admission.js +3 -0
  69. package/dist/executors/quickjs.js +163 -112
  70. package/dist/guarded-transport.js +50 -0
  71. package/dist/guest-runtime.js +1 -1
  72. package/dist/http/client.js +439 -0
  73. package/dist/http/errors.js +558 -0
  74. package/dist/http/fields.js +49 -0
  75. package/dist/http/hatch-paging.js +318 -0
  76. package/dist/http/hatch.js +1279 -0
  77. package/dist/http/json-schema.js +267 -0
  78. package/dist/http/node-transport.js +241 -0
  79. package/dist/http/oauth.js +162 -0
  80. package/dist/http/paging.js +228 -0
  81. package/dist/http/provider.js +221 -0
  82. package/dist/http/safety.js +82 -0
  83. package/dist/http/services.js +79 -0
  84. package/dist/http/tools.js +383 -0
  85. package/dist/http/vendor-index.js +138 -0
  86. package/dist/http/vendor.js +448 -0
  87. package/dist/http/write-request.js +66 -0
  88. package/dist/http-policy.d.ts +11 -0
  89. package/dist/http-policy.js +45 -0
  90. package/dist/inbound-credential.js +1 -1
  91. package/dist/index.d.ts +2 -2
  92. package/dist/index.js +4 -0
  93. package/dist/invocation-auth.js +30 -19
  94. package/dist/invocation.js +221 -87
  95. package/dist/mcp-result.js +0 -4
  96. package/dist/membership.d.ts +4 -0
  97. package/dist/meta-output.js +1 -1
  98. package/dist/meta-tools.js +534 -408
  99. package/dist/native-recovery.js +52 -0
  100. package/dist/native-tools.js +382 -0
  101. package/dist/node.d.ts +4 -3
  102. package/dist/node.js +45 -8
  103. package/dist/oauth-handoff.js +177 -104
  104. package/dist/oauth-partition.js +6 -20
  105. package/dist/oauth-sealing.js +6 -7
  106. package/dist/operation-vocabulary.js +101 -0
  107. package/dist/operator-record.d.ts +2 -2
  108. package/dist/operator-record.js +17 -4
  109. package/dist/operator-ui/agents.d.ts +5 -4
  110. package/dist/operator-ui/agents.js +17 -7
  111. package/dist/operator-ui/config-summary.js +8 -4
  112. package/dist/operator-ui/connection-map.js +9 -6
  113. package/dist/operator-ui/contract.d.ts +7 -3
  114. package/dist/operator-ui/endpoints.js +5 -14
  115. package/dist/operator-ui/fix-prompts.d.ts +1 -1
  116. package/dist/operator-ui/fix-prompts.js +0 -8
  117. package/dist/operator-ui/generated.js +3 -3
  118. package/dist/operator-ui/health.js +52 -0
  119. package/dist/operator-ui/model.d.ts +2 -3
  120. package/dist/operator-ui/overview.js +11 -19
  121. package/dist/operator-ui/setup-commands.js +0 -4
  122. package/dist/operator-ui/view.d.ts +5 -29
  123. package/dist/operator-ui/view.js +3 -59
  124. package/dist/program-writes.js +47 -26
  125. package/dist/provider-call-facts.d.ts +115 -0
  126. package/dist/provider-call-facts.js +182 -0
  127. package/dist/provider-call.d.ts +112 -0
  128. package/dist/provider-call.js +271 -0
  129. package/dist/provider.d.ts +71 -32
  130. package/dist/provider.js +134 -40
  131. package/dist/providers/_shared/google/hatch.js +91 -0
  132. package/dist/providers/_shared/google/kit.js +537 -0
  133. package/dist/providers/_shared/google/result-size.js +15 -2
  134. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  135. package/dist/providers/_shared/google/service-account.js +8 -4
  136. package/dist/providers/_shared/google/workspace.d.ts +8 -209
  137. package/dist/providers/_shared/google/workspace.js +7 -426
  138. package/dist/providers/_shared/rest/compact-index.js +86 -0
  139. package/dist/providers/_shared/rest/dispatch.js +3 -23
  140. package/dist/providers/_shared/rest/kit.js +546 -0
  141. package/dist/providers/_shared/rest/operation-index.js +230 -14
  142. package/dist/providers/_shared/rest/response-media.js +11 -0
  143. package/dist/providers/_shared/rest/tools.js +101 -78
  144. package/dist/providers/_shared/rest/value-safety.js +353 -195
  145. package/dist/providers/_shared/sensitive-fields.js +27 -0
  146. package/dist/providers/breeze/api.js +584 -0
  147. package/dist/providers/breeze/index.d.ts +3 -3
  148. package/dist/providers/breeze/index.js +67 -1420
  149. package/dist/providers/breeze/openapi.generated.js +60 -0
  150. package/dist/providers/breeze/skill.generated.js +2 -6
  151. package/dist/providers/breeze/tools.js +696 -0
  152. package/dist/providers/ccb/api.js +496 -0
  153. package/dist/providers/ccb/index.d.ts +17 -37
  154. package/dist/providers/ccb/index.js +77 -1702
  155. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  156. package/dist/providers/ccb/lib/constants.js +74 -0
  157. package/dist/providers/ccb/lib/guide.js +9 -0
  158. package/dist/providers/ccb/lib/verdicts.js +387 -0
  159. package/dist/providers/ccb/openapi.generated.js +397 -0
  160. package/dist/providers/ccb/safety.js +295 -0
  161. package/dist/providers/ccb/skill.generated.js +2 -6
  162. package/dist/providers/ccb/tools.js +853 -0
  163. package/dist/providers/cloudflare/api.js +1066 -0
  164. package/dist/providers/cloudflare/index.d.ts +7 -22
  165. package/dist/providers/cloudflare/index.js +80 -194
  166. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  167. package/dist/providers/cloudflare/lib/config.js +2 -0
  168. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  169. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  170. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  171. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  172. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  173. package/dist/providers/cloudflare/openapi.generated.js +3299 -3208
  174. package/dist/providers/cloudflare/{value-safety.js → safety.js} +538 -18
  175. package/dist/providers/cloudflare/skill.generated.js +2 -10
  176. package/dist/providers/cloudflare/tools.js +360 -0
  177. package/dist/providers/docs/api.js +51 -0
  178. package/dist/providers/docs/index.d.ts +1 -12
  179. package/dist/providers/docs/index.js +53 -1165
  180. package/dist/providers/docs/lib/constants.d.ts +18 -0
  181. package/dist/providers/docs/lib/constants.js +18 -0
  182. package/dist/providers/docs/lib/discovery.js +26 -0
  183. package/dist/providers/docs/lib/requests.js +48 -0
  184. package/dist/providers/docs/lib/schemas.js +168 -0
  185. package/dist/providers/docs/openapi.generated.js +16 -0
  186. package/dist/providers/docs/safety.js +54 -0
  187. package/dist/providers/docs/skill.generated.js +2 -6
  188. package/dist/providers/docs/tools.js +802 -0
  189. package/dist/providers/drive/api.js +177 -0
  190. package/dist/providers/drive/index.d.ts +1 -12
  191. package/dist/providers/drive/index.js +38 -1448
  192. package/dist/providers/drive/lib/constants.d.ts +6 -0
  193. package/dist/providers/drive/lib/constants.js +6 -0
  194. package/dist/providers/drive/lib/contracts.js +532 -0
  195. package/dist/providers/drive/lib/hatch.js +197 -0
  196. package/dist/providers/drive/openapi.generated.js +77 -0
  197. package/dist/providers/drive/safety.js +90 -0
  198. package/dist/providers/drive/skill.generated.js +2 -6
  199. package/dist/providers/drive/tools.js +1290 -0
  200. package/dist/providers/forms/api.js +71 -0
  201. package/dist/providers/forms/index.d.ts +1 -12
  202. package/dist/providers/forms/index.js +49 -1145
  203. package/dist/providers/forms/lib/constants.d.ts +14 -0
  204. package/dist/providers/forms/lib/constants.js +19 -0
  205. package/dist/providers/forms/lib/hatch.js +72 -0
  206. package/dist/providers/forms/openapi.generated.js +23 -0
  207. package/dist/providers/forms/safety.js +34 -0
  208. package/dist/providers/forms/skill.generated.js +2 -8
  209. package/dist/providers/forms/tools.js +1024 -0
  210. package/dist/providers/github/api.js +150 -0
  211. package/dist/providers/github/index.d.ts +4 -5
  212. package/dist/providers/github/index.js +30 -87
  213. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  214. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  215. package/dist/providers/github/lib/discovery.js +132 -0
  216. package/dist/providers/github/lib/operations.js +58 -0
  217. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  218. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  219. package/dist/providers/github/openapi.generated.js +1216 -0
  220. package/dist/providers/github/safety.js +216 -0
  221. package/dist/providers/github/skill.generated.js +2 -5
  222. package/dist/providers/github/tools.js +506 -0
  223. package/dist/providers/gmail/api.js +114 -0
  224. package/dist/providers/gmail/index.d.ts +1 -12
  225. package/dist/providers/gmail/index.js +73 -1621
  226. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  227. package/dist/providers/gmail/lib/constants.js +16 -0
  228. package/dist/providers/gmail/lib/index.js +173 -0
  229. package/dist/providers/gmail/lib/schemas.js +176 -0
  230. package/dist/providers/gmail/lib/threading.js +120 -0
  231. package/dist/providers/gmail/openapi.generated.js +92 -0
  232. package/dist/providers/gmail/safety.js +21 -0
  233. package/dist/providers/gmail/skill.generated.js +2 -6
  234. package/dist/providers/gmail/tools.js +1435 -0
  235. package/dist/providers/overflow/api.js +1008 -0
  236. package/dist/providers/overflow/index.d.ts +3 -17
  237. package/dist/providers/overflow/index.js +60 -1488
  238. package/dist/providers/overflow/skill.generated.js +2 -5
  239. package/dist/providers/overflow/tools.js +873 -0
  240. package/dist/providers/planning-center/api.js +467 -0
  241. package/dist/providers/planning-center/index.d.ts +6 -35
  242. package/dist/providers/planning-center/index.js +69 -2445
  243. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  244. package/dist/providers/planning-center/lib/constants.js +83 -0
  245. package/dist/providers/planning-center/lib/discovery.js +40 -0
  246. package/dist/providers/planning-center/lib/guide.js +39 -0
  247. package/dist/providers/planning-center/lib/json-api.js +83 -0
  248. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  249. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  250. package/dist/providers/planning-center/safety.js +188 -0
  251. package/dist/providers/planning-center/skill.generated.js +2 -27
  252. package/dist/providers/planning-center/tools.js +1010 -0
  253. package/dist/providers/sheets/api.js +133 -0
  254. package/dist/providers/sheets/index.d.ts +4 -16
  255. package/dist/providers/sheets/index.js +61 -1172
  256. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  257. package/dist/providers/sheets/lib/constants.js +14 -0
  258. package/dist/providers/sheets/lib/hatch.js +163 -0
  259. package/dist/providers/sheets/lib/requests.js +105 -0
  260. package/dist/providers/sheets/lib/schemas.js +138 -0
  261. package/dist/providers/sheets/openapi.generated.js +30 -0
  262. package/dist/providers/sheets/safety.js +27 -0
  263. package/dist/providers/sheets/skill.generated.js +2 -7
  264. package/dist/providers/sheets/tools.js +734 -0
  265. package/dist/providers/slides/api.js +147 -0
  266. package/dist/providers/slides/index.d.ts +2 -10
  267. package/dist/providers/slides/index.js +48 -2555
  268. package/dist/providers/slides/lib/constants.d.ts +11 -0
  269. package/dist/providers/slides/lib/constants.js +11 -0
  270. package/dist/providers/slides/lib/requests.js +60 -0
  271. package/dist/providers/slides/lib/schemas.js +565 -0
  272. package/dist/providers/slides/openapi.generated.js +18 -0
  273. package/dist/providers/slides/skill.generated.js +2 -6
  274. package/dist/providers/slides/tools.js +1968 -0
  275. package/dist/providers/stripe/api.js +401 -0
  276. package/dist/providers/stripe/index.d.ts +7 -27
  277. package/dist/providers/stripe/index.js +75 -191
  278. package/dist/providers/stripe/lib/config.d.ts +4 -0
  279. package/dist/providers/stripe/lib/config.js +2 -0
  280. package/dist/providers/stripe/openapi.generated.js +4 -3
  281. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  282. package/dist/providers/stripe/skill.generated.js +2 -10
  283. package/dist/providers/stripe/tools.js +77 -0
  284. package/dist/providers/tithely/api.js +531 -0
  285. package/dist/providers/tithely/index.d.ts +19 -0
  286. package/dist/providers/tithely/index.js +86 -965
  287. package/dist/providers/tithely/skill.generated.js +2 -5
  288. package/dist/providers/tithely/tools.js +426 -0
  289. package/dist/providers/vercel/api.js +551 -0
  290. package/dist/providers/vercel/index.d.ts +11 -25
  291. package/dist/providers/vercel/index.js +67 -261
  292. package/dist/providers/vercel/lib/config.d.ts +2 -0
  293. package/dist/providers/vercel/lib/config.js +2 -0
  294. package/dist/providers/vercel/lib/index.js +117 -0
  295. package/dist/providers/vercel/lib/logs.js +100 -0
  296. package/dist/providers/vercel/lib/pin.js +270 -0
  297. package/dist/providers/vercel/openapi.generated.js +398 -376
  298. package/dist/providers/vercel/{value-safety.js → safety.js} +261 -42
  299. package/dist/providers/vercel/skill.generated.js +2 -7
  300. package/dist/providers/vercel/tools.js +642 -0
  301. package/dist/redaction-identity.js +47 -0
  302. package/dist/redaction-marker.js +125 -0
  303. package/dist/registry.d.ts +30 -28
  304. package/dist/registry.js +446 -413
  305. package/dist/routes/access-tokens.js +1 -1
  306. package/dist/routes/actor-labels.js +1 -1
  307. package/dist/routes/connect.js +1 -1
  308. package/dist/routes/dispatch.js +103 -0
  309. package/dist/routes/mcp.js +170 -79
  310. package/dist/routes/oauth.js +3 -1
  311. package/dist/routes/operator.js +2 -2
  312. package/dist/routes/shared.d.ts +5 -4
  313. package/dist/routes/shared.js +244 -177
  314. package/dist/routes/skills.js +10 -8
  315. package/dist/routes/ui-config.js +27 -3
  316. package/dist/routes/ui-data.js +29 -22
  317. package/dist/routes/ui.js +1 -1
  318. package/dist/runtime/call-admission.js +0 -26
  319. package/dist/runtime/call-entry.js +30 -0
  320. package/dist/runtime/call.js +556 -0
  321. package/dist/runtime/connector-scope.js +7 -0
  322. package/dist/runtime/credential-probe.js +34 -0
  323. package/dist/runtime/executor.js +40 -0
  324. package/dist/runtime/native-storage.js +63 -0
  325. package/dist/runtime/registry.js +27 -0
  326. package/dist/runtime/request-scope.js +72 -0
  327. package/dist/runtime/run.js +15 -7
  328. package/dist/runtime/shared-read.js +34 -5
  329. package/dist/runtime/storage.js +34 -21
  330. package/dist/sent-secrets.d.ts +194 -37
  331. package/dist/sent-secrets.js +1743 -340
  332. package/dist/server.js +5 -56
  333. package/dist/skills.js +330 -224
  334. package/dist/sqlite.js +15 -14
  335. package/dist/storage/d1-copy.js +255 -0
  336. package/dist/storage/d1-driver.js +15 -0
  337. package/dist/storage/keys.js +28 -0
  338. package/dist/storage/sql-driver.js +88 -0
  339. package/dist/storage/sql-native.js +544 -0
  340. package/dist/storage/sql-schema.d.ts +6 -0
  341. package/dist/storage/sql-schema.js +15 -0
  342. package/dist/storage/sql.d.ts +14 -20
  343. package/dist/storage/sql.js +29 -535
  344. package/dist/timeout.js +0 -26
  345. package/dist/tool-safety.js +20 -10
  346. package/dist/types.d.ts +11 -99
  347. package/dist/upward.js +3 -0
  348. package/dist/usage-guide.js +3 -1
  349. package/dist/validate.d.ts +4 -2
  350. package/dist/validate.js +86 -9
  351. package/dist/version.d.ts +1 -1
  352. package/dist/version.js +1 -1
  353. package/dist/worker.js +312 -292
  354. package/dist/workspace-subject.js +5 -1
  355. package/dist/write-outcome.js +454 -34
  356. package/documentation/README.md +27 -7
  357. package/documentation/architecture.md +2550 -186
  358. package/documentation/auth.md +821 -98
  359. package/documentation/code-mode.md +56 -21
  360. package/documentation/deploying.md +164 -20
  361. package/documentation/hosted-mcp-migration.md +460 -0
  362. package/documentation/integrating.md +144 -105
  363. package/documentation/meta-tools.md +411 -34
  364. package/documentation/operating.md +28 -4
  365. package/documentation/operator-tests.md +11 -2
  366. package/documentation/operator-ui.md +103 -33
  367. package/documentation/provider-auth-migration.md +38 -63
  368. package/documentation/provider-migration-0.29.md +10 -5
  369. package/documentation/provider-migration-0.35.md +975 -0
  370. package/documentation/providers.md +965 -0
  371. package/examples/worker/AGENTS.md +23 -9
  372. package/examples/worker/README.md +254 -135
  373. package/examples/worker/alchemy.run.ts +116 -0
  374. package/examples/worker/gitignore +10 -0
  375. package/examples/worker/src/connecta.config.ts +23 -21
  376. package/examples/worker/wrangler.jsonc +14 -5
  377. package/guides/connecting-agents.md +157 -0
  378. package/guides/how-it-works.md +156 -0
  379. package/guides/safety-and-trust.md +153 -0
  380. package/package.json +27 -42
  381. package/templates/node/.env.example +3 -0
  382. package/templates/node/README.md +22 -2
  383. package/templates/node/docker-compose.yml +1 -0
  384. package/templates/node/package.json +3 -2
  385. package/templates/node/src/connecta.config.ts +8 -0
  386. package/dist/catalog-drift.d.ts +0 -134
  387. package/dist/catalog-drift.js +0 -493
  388. package/dist/providers/_shared/request-token.js +0 -83
  389. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  390. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  391. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  392. package/dist/providers/basecamp/index.d.ts +0 -43
  393. package/dist/providers/basecamp/index.js +0 -997
  394. package/dist/providers/basecamp/skill.generated.js +0 -9
  395. package/dist/providers/cloudflare/rest.d.ts +0 -37
  396. package/dist/providers/cloudflare/rest.js +0 -1078
  397. package/dist/providers/github/hosted.js +0 -218
  398. package/dist/providers/github/rest.js +0 -321
  399. package/dist/providers/infisical/index.d.ts +0 -7
  400. package/dist/providers/infisical/index.js +0 -713
  401. package/dist/providers/infisical/skill.generated.js +0 -8
  402. package/dist/providers/linear/index.d.ts +0 -55
  403. package/dist/providers/linear/index.js +0 -352
  404. package/dist/providers/linear/skill.generated.js +0 -8
  405. package/dist/providers/mixpanel/index.d.ts +0 -57
  406. package/dist/providers/mixpanel/index.js +0 -468
  407. package/dist/providers/mixpanel/operations.js +0 -20
  408. package/dist/providers/mixpanel/rest.js +0 -603
  409. package/dist/providers/mixpanel/skill.generated.js +0 -10
  410. package/dist/providers/mixpanel/value-safety.js +0 -16
  411. package/dist/providers/notion/index.d.ts +0 -65
  412. package/dist/providers/notion/index.js +0 -368
  413. package/dist/providers/notion/openapi.generated.js +0 -75
  414. package/dist/providers/notion/rest.d.ts +0 -24
  415. package/dist/providers/notion/rest.js +0 -1226
  416. package/dist/providers/notion/skill.generated.js +0 -11
  417. package/dist/providers/notion/value-safety.js +0 -56
  418. package/dist/providers/revenuecat/index.d.ts +0 -49
  419. package/dist/providers/revenuecat/index.js +0 -557
  420. package/dist/providers/revenuecat/skill.generated.js +0 -11
  421. package/dist/providers/stripe/rest.d.ts +0 -14
  422. package/dist/providers/stripe/rest.js +0 -402
  423. package/dist/providers/vercel/rest.d.ts +0 -20
  424. package/dist/providers/vercel/rest.js +0 -1020
  425. package/dist/providers/wispr-flow/index.d.ts +0 -14
  426. package/dist/providers/wispr-flow/index.js +0 -117
  427. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  428. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
package/dist/skills.js CHANGED
@@ -1,3 +1,7 @@
1
+ import { duringViewEffect } from "./runtime/call.js";
2
+ import { RequestScope, requestOwner } from "./runtime/request-scope.js";
3
+ import { upwardStep } from "./upward.js";
4
+ import { authCall, authInvoke, authFlow, authMethod, registerAuth, registerAuthMethod, authOwnMethod, } from "./auth/native.js";
1
5
  import { USAGE_SKILL } from "./usage-guide.js";
2
6
  import { boundedEchoText, ConnectorCallError } from "./errors.js";
3
7
  import { Effect } from "effect";
@@ -20,8 +24,13 @@ export const CONNECTA_INSTRUCTIONS = `${ROUTE} On a writable endpoint, programs
20
24
  * comes from deployment config for the pool the request was admitted through;
21
25
  * nothing a request sends reaches it.
22
26
  */
23
- export function endpointInstructions(description) {
24
- return description === undefined ? CONNECTA_INSTRUCTIONS : `${CONNECTA_INSTRUCTIONS} This endpoint: ${description}`;
27
+ export function endpointInstructions(description, native) {
28
+ const instructions = native ? nativeInstructions(native.executeCode) : CONNECTA_INSTRUCTIONS;
29
+ return description === undefined ? instructions : `${instructions} This endpoint: ${description}`;
30
+ }
31
+ /** Instructions for pools whose host searches the listed native tools. */
32
+ export function nativeInstructions(executeCode) {
33
+ return `Each tool here is one operation; annotations classify reads/writes. Call known tools directly; ${executeCode ? "combine work in execute_code using the program addresses in tool descriptions." : "find tools with your host's search."} Read-only endpoints omit and refuse writes. Never repeat a write for output. Give auth handoffs to the user/operator. Follow nextAction to page with ${executeCode ? "connecta.result in execute_code" : "read_result"}. skills lists guidance.`;
25
34
  }
26
35
  export { USAGE_SKILL } from "./usage-guide.js";
27
36
  /** True when at least one of `connectors` carries a usage guide. */
@@ -86,7 +95,11 @@ export function connectorSkillName(connectorId) {
86
95
  export function connectorGuide(connector) {
87
96
  const guide = connector.usageGuide;
88
97
  const content = typeof guide === "string" ? guide : guide?.content;
89
- return content && content.trim() !== "" ? content : undefined;
98
+ if (!content || content.trim() === "")
99
+ return undefined;
100
+ return connector.readOnly === true
101
+ ? `Read-only connection: only read-classified tools are available. Write calls are refused, including tools named in this guide.\n\n${content}`
102
+ : content;
90
103
  }
91
104
  /** Discovery budget for one connector-guide summary, including an ellipsis. */
92
105
  export const GUIDE_SUMMARY_LENGTH = 120;
@@ -298,7 +311,9 @@ export function connectorGuideSummary(connector) {
298
311
  // normalization here so direct Connector callers see the same text.
299
312
  boundedSummary(connector.usageGuide.summary ?? "")
300
313
  : undefined;
301
- return configured ?? summarizeGuide(connector, guide);
314
+ const original = typeof connector.usageGuide === "string" ? connector.usageGuide : connector.usageGuide?.content;
315
+ const summary = configured ?? summarizeGuide(connector, original ?? guide);
316
+ return connector.readOnly === true ? boundedSummary(`Read-only. ${summary}`) : summary;
302
317
  }
303
318
  /** Whether correct use always depends on conventions outside the tool schema. */
304
319
  export function connectorGuideRequired(connector) {
@@ -340,38 +355,44 @@ function localRecord(name, uri, description, content, aliases) {
340
355
  function validSkillName(name) {
341
356
  return name.length <= 64 && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name);
342
357
  }
343
- async function localRecords(connectors) {
344
- const builtIns = AVAILABLE_SKILLS.map((skill) => localRecord(skill.name, `skill://connecta/${skill.name}/SKILL.md`, skill.description, skill.content(), [
345
- skill.name,
346
- `skill://connecta/${skill.name}`,
347
- ]));
348
- const guides = await Promise.all(connectors
349
- .filter((connector) => connectorGuide(connector) !== undefined)
350
- .sort((a, b) => Number(connectorGuideRequired(b)) - Number(connectorGuideRequired(a)) ||
351
- (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
352
- .map(async (connector) => {
353
- const name = validSkillName(connector.id)
354
- ? connector.id
355
- : `connector-${[...new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(connector.id)))]
356
- .map((byte) => byte.toString(16).padStart(2, "0"))
357
- .join("")
358
- .slice(0, 48)}`;
359
- const description = connectorGuideSummary(connector);
360
- const root = `skill://connecta/connectors/${encodeURIComponent(name)}`;
361
- const content = `---\n${JSON.stringify({ name, description }, null, 2)}\n---\n\n${connectorGuide(connector)}`;
362
- return {
363
- ...localRecord(name, `${root}/SKILL.md`, description, content, [
364
- connectorSkillName(connector.id),
365
- `skill://connecta/connectors/${encodeURIComponent(connector.id)}`,
366
- root,
367
- ]),
368
- connector,
369
- };
370
- }));
371
- if (new Set(guides.map((guide) => guide.entry.uri)).size !== guides.length)
372
- throw new ConnectorCallError("unavailable", "Connector skill slugs collide.");
373
- return [builtIns[0], ...guides, ...builtIns.slice(1)];
358
+ function localRecords(connectors) {
359
+ return runEdge(localRecordsNative(connectors));
374
360
  }
361
+ const localRecordsNative = /* @__PURE__ */ registerAuth(localRecords, function (connectors) {
362
+ return authFlow(function* () {
363
+ const builtIns = AVAILABLE_SKILLS.map((skill) => localRecord(skill.name, `skill://connecta/${skill.name}/SKILL.md`, skill.description, skill.content(), [
364
+ skill.name,
365
+ `skill://connecta/${skill.name}`,
366
+ ]));
367
+ const guides = yield* upwardStep(Effect.forEach(connectors
368
+ .filter((connector) => connectorGuide(connector) !== undefined)
369
+ .sort((a, b) => Number(connectorGuideRequired(b)) - Number(connectorGuideRequired(a)) ||
370
+ (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)), (connector) => authFlow(function* () {
371
+ const name = validSkillName(connector.id)
372
+ ? connector.id
373
+ : `connector-${[
374
+ ...new Uint8Array(yield* upwardStep(authInvoke(crypto.subtle, "digest", ["SHA-256", encoder.encode(connector.id)]))),
375
+ ]
376
+ .map((byte) => byte.toString(16).padStart(2, "0"))
377
+ .join("")
378
+ .slice(0, 48)}`;
379
+ const description = connectorGuideSummary(connector);
380
+ const root = `skill://connecta/connectors/${encodeURIComponent(name)}`;
381
+ const content = `---\n${JSON.stringify({ name, description }, null, 2)}\n---\n\n${connectorGuide(connector)}`;
382
+ return {
383
+ ...localRecord(name, `${root}/SKILL.md`, description, content, [
384
+ connectorSkillName(connector.id),
385
+ `skill://connecta/connectors/${encodeURIComponent(connector.id)}`,
386
+ root,
387
+ ]),
388
+ connector,
389
+ };
390
+ }), { concurrency: "unbounded" }));
391
+ if (new Set(guides.map((guide) => guide.entry.uri)).size !== guides.length)
392
+ throw new ConnectorCallError("unavailable", "Connector skill slugs collide.");
393
+ return [builtIns[0], ...guides, ...builtIns.slice(1)];
394
+ });
395
+ });
375
396
  /** Keep the downstream path tree, so relative supporting-file references still resolve. */
376
397
  export function downstreamSkillUri(connectorId, uri) {
377
398
  if (uri.length > 32_768)
@@ -446,18 +467,28 @@ function validateEntry(entry) {
446
467
  if (!files.has(entry.uri) || bytes > MAX_SKILL_BYTES)
447
468
  throw new ConnectorCallError("unavailable", "Downstream skill manifest is incomplete or oversized.");
448
469
  }
449
- async function withManifest(record) {
450
- const bytes = encoder.encode(record.content);
451
- if (bytes.length > MAX_SKILL_BYTES)
452
- throw new ConnectorCallError("unavailable", "Local skill exceeds the byte bound.");
453
- const digest = [...new Uint8Array(await crypto.subtle.digest("SHA-256", bytes))]
454
- .map((byte) => byte.toString(16).padStart(2, "0"))
455
- .join("");
456
- return {
457
- ...record,
458
- entry: { ...record.entry, resources: [{ uri: record.entry.uri, digest: `sha256:${digest}`, size: bytes.length }] },
459
- };
470
+ function withManifest(record) {
471
+ return runEdge(withManifestNative(record));
460
472
  }
473
+ const withManifestNative = /* @__PURE__ */ registerAuth(withManifest, function (record) {
474
+ return authFlow(function* () {
475
+ const bytes = encoder.encode(record.content);
476
+ if (bytes.length > MAX_SKILL_BYTES)
477
+ throw new ConnectorCallError("unavailable", "Local skill exceeds the byte bound.");
478
+ const digest = [
479
+ ...new Uint8Array(yield* upwardStep(authInvoke(crypto.subtle, "digest", ["SHA-256", bytes]))),
480
+ ]
481
+ .map((byte) => byte.toString(16).padStart(2, "0"))
482
+ .join("");
483
+ return {
484
+ ...record,
485
+ entry: {
486
+ ...record.entry,
487
+ resources: [{ uri: record.entry.uri, digest: `sha256:${digest}`, size: bytes.length }],
488
+ },
489
+ };
490
+ });
491
+ });
461
492
  /**
462
493
  * One caller-view registry for native methods, the meta-tool and the guest API.
463
494
  * No content reaches storage or operator sinks. Downstream skills use uncached
@@ -475,42 +506,15 @@ export class SkillsRegistry {
475
506
  this.registry = registry;
476
507
  this.baseUrl = baseUrl;
477
508
  this.options = options;
509
+ void SkillsRegistry.nativePrograms;
478
510
  this.scope = options.requestScope ?? {};
479
- this.local = localRecords(registry.listConnectors());
511
+ this.local = authCall(localRecords, [registry.listConnectors()]);
480
512
  }
481
513
  operation(connector, read) {
482
- const timeoutMs = this.options.probeTimeoutMs ?? 20_000;
483
- const operationScope = {};
484
- sentSecretsForRequest(this.scope).include(sentSecretsForRequest(operationScope));
485
- return runEdge(withDeadlineEffect((signal) => Effect.scoped(Effect.gen({ self: this }, function* () {
486
- const ctx = this.registry.contextFor(connector.id, this.baseUrl, operationScope, {
487
- signal,
488
- timeoutMs,
489
- ...(this.options.defer ? { defer: this.options.defer } : {}),
490
- });
491
- yield* closeScopeOnExit(connector, ctx, this.options.defer);
492
- return yield* Effect.tryPromise({
493
- try: () => read(ctx),
494
- catch: (error) => error instanceof ConnectorCallError && error.code === "auth_required"
495
- ? new ConnectorCallError("auth_required", "Downstream skills require authorization.")
496
- : new ConnectorCallError("unavailable", "Downstream skills are unavailable."),
497
- });
498
- })), {
499
- timeoutMs,
500
- ...(this.options.requestSignal ? { signal: this.options.requestSignal } : {}),
501
- timeoutError: new ConnectorCallError("unavailable", "Downstream skills timed out."),
502
- }), { signal: this.options.requestSignal });
514
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "operation", [connector, read]));
503
515
  }
504
- async records() {
505
- if (!this.snapshot) {
506
- this.snapshot = this.build();
507
- this.snapshot.catch(() => {
508
- this.snapshot = undefined;
509
- });
510
- }
511
- const records = await this.snapshot;
512
- this.assertSafe(records);
513
- return records;
516
+ records() {
517
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "records", []));
514
518
  }
515
519
  /** Later catalog/read operations can add credentials to this request. */
516
520
  assertSafe(records) {
@@ -530,71 +534,11 @@ export class SkillsRegistry {
530
534
  }
531
535
  }
532
536
  }
533
- async build() {
534
- const records = await Promise.all((await this.local).map(withManifest));
535
- let catalogBytes = jsonBytes(records.map((record) => record.entry));
536
- // Bounded sequential connector reads avoid unbounded fan-out and finish
537
- // cleanup before a later connector's failure can end the whole listing.
538
- for (const connector of this.registry.listConnectors()) {
539
- if (!connector.downstreamSkills || !this.registry.canReadConnectorSkills(connector.id))
540
- continue;
541
- const entries = await this.operation(connector, (ctx) => connector.downstreamSkills.list(ctx));
542
- if (!Array.isArray(entries) || records.length + entries.length > MAX_SKILLS)
543
- throw new ConnectorCallError("unavailable", "Downstream skills listing exceeds its bound.");
544
- for (const original of entries) {
545
- if (catalogBytes + jsonBytes(original) + 1 > MAX_SKILL_CATALOG_BYTES)
546
- throw new ConnectorCallError("unavailable", "Skills listing exceeds its byte bound.");
547
- const entry = structuredClone(original);
548
- validateEntry(entry);
549
- const files = new Map();
550
- const uri = downstreamSkillUri(connector.id, entry.uri);
551
- const secrets = sentSecretsForRequest(this.scope);
552
- if (secrets.containsUrl(entry.uri))
553
- throw new ConnectorCallError("unavailable", "Downstream skill URI contains sent credentials.");
554
- files.set(uri, entry.uri);
555
- const resources = entry.resources === "dynamic"
556
- ? "dynamic"
557
- : entry.resources.map((file) => {
558
- const uri = downstreamSkillUri(connector.id, file.uri);
559
- if (secrets.containsUrl(file.uri))
560
- throw new ConnectorCallError("unavailable", "Downstream skill URI contains sent credentials.");
561
- files.set(uri, file.uri);
562
- return { ...file, uri };
563
- });
564
- if (records.some((record) => record.entry.uri === uri))
565
- throw new ConnectorCallError("unavailable", "Downstream skills listing contains duplicate entries.");
566
- const mapped = { ...entry, uri, resources };
567
- catalogBytes += jsonBytes(mapped) + 1;
568
- if (catalogBytes > MAX_SKILL_CATALOG_BYTES)
569
- throw new ConnectorCallError("unavailable", "Skills listing exceeds its byte bound.");
570
- records.push({ entry: mapped, aliases: [], connector, files });
571
- }
572
- }
573
- if (records.length > MAX_SKILLS || jsonBytes(records.map((record) => record.entry)) > MAX_SKILL_CATALOG_BYTES) {
574
- throw new ConnectorCallError("unavailable", "Skills listing exceeds its byte or entry bound.");
575
- }
576
- // Keep the old investigation guide behind every connector and downstream
577
- // guide, where it cannot consume one of the first five import slots.
578
- const investigate = records.findIndex((record) => record.aliases.includes("investigate"));
579
- if (investigate >= 0)
580
- records.push(records.splice(investigate, 1)[0]);
581
- this.assertSafe(records);
582
- return records;
537
+ build() {
538
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "build", []));
583
539
  }
584
- async lookup(uri) {
585
- const local = (await this.local).find((record) => record.entry.uri === uri || record.aliases.includes(uri));
586
- if (local) {
587
- const record = await withManifest(local);
588
- this.assertSafe([record]);
589
- return record;
590
- }
591
- // A non-skill URI never starts a downstream resource request or listing.
592
- if (!uri.startsWith("skill://downstream/"))
593
- throw this.missing(uri);
594
- const record = (await this.records()).find((record) => record.entry.uri === uri);
595
- if (!record)
596
- throw this.missing(uri);
597
- return record;
540
+ lookup(uri) {
541
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "lookup", [uri]));
598
542
  }
599
543
  missing(name) {
600
544
  const guides = this.registry.listConnectors().filter((connector) => connectorGuide(connector) !== undefined);
@@ -618,92 +562,254 @@ export class SkillsRegistry {
618
562
  : `Unknown skill "${boundedEchoText(name)}".`;
619
563
  return new ConnectorCallError("not_found", `${message} Available skills: ${available}.`);
620
564
  }
621
- async list(cursor) {
622
- const records = await this.records();
623
- const offset = cursor === undefined ? 0 : /^skills:[1-9][0-9]*$/.test(cursor) ? Number(cursor.slice(7)) : NaN;
624
- if (!Number.isSafeInteger(offset) || offset % SKILL_PAGE_SIZE !== 0 || offset >= records.length)
625
- throw new ConnectorCallError("invalid_args", "Invalid skills cursor.");
626
- return {
627
- ...PRIVATE,
628
- skills: records.slice(offset, offset + SKILL_PAGE_SIZE).map((record) => record.entry),
629
- ...(offset + SKILL_PAGE_SIZE < records.length ? { nextCursor: `skills:${offset + SKILL_PAGE_SIZE}` } : {}),
630
- };
565
+ list(cursor) {
566
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "list", [cursor]));
631
567
  }
632
- async get(uri) {
633
- return { ...PRIVATE, skill: (await this.lookup(uri)).entry };
568
+ get(uri) {
569
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "get", [uri]));
634
570
  }
635
- async resources(cursor) {
636
- const page = await this.list(cursor);
637
- return {
638
- ...PRIVATE,
639
- resources: page.skills.flatMap((skill) => (skill.resources === "dynamic" ? [{ uri: skill.uri }] : skill.resources).map((file) => ({
640
- uri: file.uri,
641
- name: file.uri === skill.uri ? String(skill.frontmatter.name) : file.uri.slice(file.uri.lastIndexOf("/") + 1),
642
- ...(file.uri === skill.uri
643
- ? { description: String(skill.frontmatter.description), mimeType: "text/markdown" }
644
- : {}),
645
- ...("size" in file ? { size: file.size } : {}),
646
- }))),
647
- ...(page.nextCursor ? { nextCursor: page.nextCursor } : {}),
648
- };
571
+ resources(cursor) {
572
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "resources", [cursor]));
649
573
  }
650
- async read(uri) {
651
- const local = (await this.local).find((record) => record.entry.uri === uri || record.aliases.includes(uri));
652
- if (local) {
653
- const record = await withManifest(local);
654
- this.assertSafe([record]);
655
- if (record.connector)
656
- this.options.onRead?.(record.connector, "local");
657
- // A connector guide is operator-authored payload, like a downstream file; built-in guides are Connecta's own.
658
- const text = record.connector ? sentSecretsForRequest(this.scope).redact(record.content) : record.content;
659
- return { ...PRIVATE, contents: [{ uri: record.entry.uri, mimeType: "text/markdown", text }] };
660
- }
661
- if (!uri.startsWith("skill://downstream/"))
662
- throw this.missing(uri);
663
- const record = (await this.records()).find((record) => record.files?.has(uri));
664
- if (!record?.connector || !record.files || !this.registry.canReadConnectorSkills(record.connector.id))
665
- throw this.missing(uri);
666
- const originalUri = record.files.get(uri);
667
- const contents = await this.operation(record.connector, (ctx) => record.connector.downstreamSkills.read(originalUri, ctx));
668
- // Structural fields and preserved digests cannot be repaired by the
669
- // output boundary after this read has sent another credential.
670
- await this.records();
671
- if (!Array.isArray(contents) || contents.length !== 1 || contents[0]?.uri !== originalUri)
672
- throw new ConnectorCallError("unavailable", "Downstream skill read returned unexpected files.");
673
- const content = contents[0];
674
- if (!content || (typeof content.text === "string") === (typeof content.blob === "string"))
675
- throw new ConnectorCallError("unavailable", "Downstream skill read did not return one file.");
676
- let bytes;
677
- try {
678
- bytes = typeof content.text === "string" ? encoder.encode(content.text).length : atob(content.blob).length;
679
- }
680
- catch {
681
- throw new ConnectorCallError("unavailable", "Downstream skill file is not valid base64.");
682
- }
683
- if (bytes > MAX_SKILL_BYTES)
684
- throw new ConnectorCallError("unavailable", "Downstream skill file exceeds the byte bound.");
685
- this.options.onRead?.(record.connector, "downstream");
686
- // Downstream file contents take the request's full payload rules before any reader sees them.
687
- const clean = sentSecretsForRequest(this.scope).redact(content);
688
- return { ...PRIVATE, contents: [{ ...clean, uri }] };
574
+ read(uri) {
575
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "read", [uri]));
689
576
  }
690
- async text(name) {
691
- const record = await this.lookup(name);
692
- const content = (await this.read(record.entry.uri)).contents[0];
693
- if (typeof content.text === "string")
694
- return content.text;
695
- try {
696
- return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(Uint8Array.from(atob(content.blob), (char) => char.charCodeAt(0)));
697
- }
698
- catch {
699
- throw new ConnectorCallError("unavailable", "Skill instructions are not UTF-8 text.");
700
- }
577
+ text(name) {
578
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "text", [name]));
701
579
  }
702
- async summaries() {
703
- return (await this.records()).map((record) => ({
704
- name: record.aliases[0] ?? record.entry.uri,
705
- uri: record.entry.uri,
706
- description: String(record.entry.frontmatter.description),
707
- }));
580
+ summaries() {
581
+ return runEdge(authOwnMethod(SkillsRegistry.prototype, this, "summaries", []));
708
582
  }
583
+ static nativePrograms = /* @__PURE__ */ (() => {
584
+ registerAuthMethod(SkillsRegistry.prototype, "summaries", function () {
585
+ const self = this;
586
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => authFlow(function* () {
587
+ return (yield* upwardStep(authInvoke(self, "records", []))).map((record) => ({
588
+ name: record.aliases[0] ?? record.entry.uri,
589
+ uri: record.entry.uri,
590
+ description: String(record.entry.frontmatter.description),
591
+ }));
592
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
593
+ }, SkillsRegistry.prototype.summaries);
594
+ registerAuthMethod(SkillsRegistry.prototype, "text", function (name) {
595
+ const self = this;
596
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => authFlow(function* () {
597
+ const record = yield* upwardStep(authInvoke(self, "lookup", [name]));
598
+ const content = (yield* upwardStep(authInvoke(self, "read", [record.entry.uri]))).contents[0];
599
+ if (typeof content.text === "string")
600
+ return content.text;
601
+ try {
602
+ return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(Uint8Array.from(atob(content.blob), (char) => char.charCodeAt(0)));
603
+ }
604
+ catch {
605
+ throw new ConnectorCallError("unavailable", "Skill instructions are not UTF-8 text.");
606
+ }
607
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
608
+ }, SkillsRegistry.prototype.text);
609
+ registerAuthMethod(SkillsRegistry.prototype, "read", function (uri) {
610
+ const self = this;
611
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => authFlow(function* () {
612
+ const local = (yield* upwardStep(self.local)).find((record) => record.entry.uri === uri || record.aliases.includes(uri));
613
+ if (local) {
614
+ const record = yield* upwardStep(authCall(withManifest, [local]));
615
+ self.assertSafe([record]);
616
+ if (record.connector)
617
+ self.options.onRead?.(record.connector, "local");
618
+ // A connector guide is operator-authored payload, like a downstream file; built-in guides are Connecta's own.
619
+ const text = record.connector
620
+ ? sentSecretsForRequest(self.scope).redact(record.content)
621
+ : record.content;
622
+ return { ...PRIVATE, contents: [{ uri: record.entry.uri, mimeType: "text/markdown", text }] };
623
+ }
624
+ if (!uri.startsWith("skill://downstream/"))
625
+ throw self.missing(uri);
626
+ const record = (yield* upwardStep(authInvoke(self, "records", []))).find((record) => record.files?.has(uri));
627
+ if (!record?.connector || !record.files || !self.registry.canReadConnectorSkills(record.connector.id))
628
+ throw self.missing(uri);
629
+ const originalUri = record.files.get(uri);
630
+ const contents = yield* upwardStep(authInvoke(self, "operation", [
631
+ record.connector,
632
+ authMethod((ctx) => authInvoke(record.connector.downstreamSkills, "read", [
633
+ originalUri,
634
+ ctx,
635
+ ])),
636
+ ]));
637
+ // Structural fields and preserved digests cannot be repaired by the
638
+ // output boundary after this read has sent another credential.
639
+ yield* upwardStep(authInvoke(self, "records", []));
640
+ if (!Array.isArray(contents) || contents.length !== 1 || contents[0]?.uri !== originalUri)
641
+ throw new ConnectorCallError("unavailable", "Downstream skill read returned unexpected files.");
642
+ const content = contents[0];
643
+ if (!content || (typeof content.text === "string") === (typeof content.blob === "string"))
644
+ throw new ConnectorCallError("unavailable", "Downstream skill read did not return one file.");
645
+ let bytes;
646
+ try {
647
+ bytes =
648
+ typeof content.text === "string" ? encoder.encode(content.text).length : atob(content.blob).length;
649
+ }
650
+ catch {
651
+ throw new ConnectorCallError("unavailable", "Downstream skill file is not valid base64.");
652
+ }
653
+ if (bytes > MAX_SKILL_BYTES)
654
+ throw new ConnectorCallError("unavailable", "Downstream skill file exceeds the byte bound.");
655
+ self.options.onRead?.(record.connector, "downstream");
656
+ // Downstream file contents take the request's full payload rules before any reader sees them.
657
+ const clean = sentSecretsForRequest(self.scope).redact(content);
658
+ return { ...PRIVATE, contents: [{ ...clean, uri }] };
659
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
660
+ }, SkillsRegistry.prototype.read);
661
+ registerAuthMethod(SkillsRegistry.prototype, "resources", function (cursor) {
662
+ const self = this;
663
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => authFlow(function* () {
664
+ const page = yield* upwardStep(authInvoke(self, "list", [cursor]));
665
+ return {
666
+ ...PRIVATE,
667
+ resources: page.skills.flatMap((skill) => (skill.resources === "dynamic" ? [{ uri: skill.uri }] : skill.resources).map((file) => ({
668
+ uri: file.uri,
669
+ name: file.uri === skill.uri
670
+ ? String(skill.frontmatter.name)
671
+ : file.uri.slice(file.uri.lastIndexOf("/") + 1),
672
+ ...(file.uri === skill.uri
673
+ ? { description: String(skill.frontmatter.description), mimeType: "text/markdown" }
674
+ : {}),
675
+ ...("size" in file ? { size: file.size } : {}),
676
+ }))),
677
+ ...(page.nextCursor ? { nextCursor: page.nextCursor } : {}),
678
+ };
679
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
680
+ }, SkillsRegistry.prototype.resources);
681
+ registerAuthMethod(SkillsRegistry.prototype, "get", function (uri) {
682
+ const self = this;
683
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => authFlow(function* () {
684
+ return { ...PRIVATE, skill: (yield* upwardStep(authInvoke(self, "lookup", [uri]))).entry };
685
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
686
+ }, SkillsRegistry.prototype.get);
687
+ registerAuthMethod(SkillsRegistry.prototype, "list", function (cursor) {
688
+ const self = this;
689
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => authFlow(function* () {
690
+ const records = yield* upwardStep(authInvoke(self, "records", []));
691
+ const offset = cursor === undefined ? 0 : /^skills:[1-9][0-9]*$/.test(cursor) ? Number(cursor.slice(7)) : NaN;
692
+ if (!Number.isSafeInteger(offset) || offset % SKILL_PAGE_SIZE !== 0 || offset >= records.length)
693
+ throw new ConnectorCallError("invalid_args", "Invalid skills cursor.");
694
+ return {
695
+ ...PRIVATE,
696
+ skills: records.slice(offset, offset + SKILL_PAGE_SIZE).map((record) => record.entry),
697
+ ...(offset + SKILL_PAGE_SIZE < records.length
698
+ ? { nextCursor: `skills:${offset + SKILL_PAGE_SIZE}` }
699
+ : {}),
700
+ };
701
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
702
+ }, SkillsRegistry.prototype.list);
703
+ registerAuthMethod(SkillsRegistry.prototype, "lookup", function (uri) {
704
+ const self = this;
705
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => authFlow(function* () {
706
+ const local = (yield* upwardStep(self.local)).find((record) => record.entry.uri === uri || record.aliases.includes(uri));
707
+ if (local) {
708
+ const record = yield* upwardStep(authCall(withManifest, [local]));
709
+ self.assertSafe([record]);
710
+ return record;
711
+ }
712
+ // A non-skill URI never starts a downstream resource request or listing.
713
+ if (!uri.startsWith("skill://downstream/"))
714
+ throw self.missing(uri);
715
+ const record = (yield* upwardStep(authInvoke(self, "records", []))).find((record) => record.entry.uri === uri);
716
+ if (!record)
717
+ throw self.missing(uri);
718
+ return record;
719
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
720
+ }, SkillsRegistry.prototype.lookup);
721
+ registerAuthMethod(SkillsRegistry.prototype, "build", function () {
722
+ const self = this;
723
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => authFlow(function* () {
724
+ const records = yield* upwardStep(Effect.forEach(yield* upwardStep(self.local), (record) => authCall(withManifest, [record]), {
725
+ concurrency: "unbounded",
726
+ }));
727
+ let catalogBytes = jsonBytes(records.map((record) => record.entry));
728
+ // Bounded sequential connector reads avoid unbounded fan-out and finish
729
+ // cleanup before a later connector's failure can end the whole listing.
730
+ for (const connector of self.registry.listConnectors()) {
731
+ if (!connector.downstreamSkills || !self.registry.canReadConnectorSkills(connector.id))
732
+ continue;
733
+ const entries = yield* upwardStep(authInvoke(self, "operation", [
734
+ connector,
735
+ authMethod((ctx) => authInvoke(connector.downstreamSkills, "list", [ctx])),
736
+ ]));
737
+ if (!Array.isArray(entries) || records.length + entries.length > MAX_SKILLS)
738
+ throw new ConnectorCallError("unavailable", "Downstream skills listing exceeds its bound.");
739
+ for (const original of entries) {
740
+ if (catalogBytes + jsonBytes(original) + 1 > MAX_SKILL_CATALOG_BYTES)
741
+ throw new ConnectorCallError("unavailable", "Skills listing exceeds its byte bound.");
742
+ const entry = structuredClone(original);
743
+ validateEntry(entry);
744
+ const files = new Map();
745
+ const uri = downstreamSkillUri(connector.id, entry.uri);
746
+ const secrets = sentSecretsForRequest(self.scope);
747
+ if (secrets.containsUrl(entry.uri))
748
+ throw new ConnectorCallError("unavailable", "Downstream skill URI contains sent credentials.");
749
+ files.set(uri, entry.uri);
750
+ const resources = entry.resources === "dynamic"
751
+ ? "dynamic"
752
+ : entry.resources.map((file) => {
753
+ const uri = downstreamSkillUri(connector.id, file.uri);
754
+ if (secrets.containsUrl(file.uri))
755
+ throw new ConnectorCallError("unavailable", "Downstream skill URI contains sent credentials.");
756
+ files.set(uri, file.uri);
757
+ return { ...file, uri };
758
+ });
759
+ if (records.some((record) => record.entry.uri === uri))
760
+ throw new ConnectorCallError("unavailable", "Downstream skills listing contains duplicate entries.");
761
+ const mapped = { ...entry, uri, resources };
762
+ catalogBytes += jsonBytes(mapped) + 1;
763
+ if (catalogBytes > MAX_SKILL_CATALOG_BYTES)
764
+ throw new ConnectorCallError("unavailable", "Skills listing exceeds its byte bound.");
765
+ records.push({ entry: mapped, aliases: [], connector, files });
766
+ }
767
+ }
768
+ if (records.length > MAX_SKILLS ||
769
+ jsonBytes(records.map((record) => record.entry)) > MAX_SKILL_CATALOG_BYTES) {
770
+ throw new ConnectorCallError("unavailable", "Skills listing exceeds its byte or entry bound.");
771
+ }
772
+ // Keep the old investigation guide behind every connector and downstream
773
+ // guide, where it cannot consume one of the first five import slots.
774
+ const investigate = records.findIndex((record) => record.aliases.includes("investigate"));
775
+ if (investigate >= 0)
776
+ records.push(records.splice(investigate, 1)[0]);
777
+ self.assertSafe(records);
778
+ return records;
779
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
780
+ }, SkillsRegistry.prototype.build);
781
+ registerAuthMethod(SkillsRegistry.prototype, "records", function () {
782
+ const instance = this;
783
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => Effect.gen(function* () {
784
+ if (!instance.snapshot)
785
+ instance.snapshot = yield* Effect.cached(authInvoke(instance, "build", []).pipe(Effect.onError(() => Effect.sync(() => {
786
+ instance.snapshot = undefined;
787
+ }))));
788
+ const records = yield* instance.snapshot;
789
+ instance.assertSafe(records);
790
+ return records;
791
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
792
+ }, SkillsRegistry.prototype.records);
793
+ registerAuthMethod(SkillsRegistry.prototype, "operation", function (connector, read) {
794
+ const self = this;
795
+ const timeoutMs = self.options.probeTimeoutMs ?? 20_000;
796
+ const operationScope = {};
797
+ sentSecretsForRequest(self.scope).include(sentSecretsForRequest(operationScope));
798
+ return duringViewEffect({ requestScope: this.scope, signal: this.options.requestSignal }, () => withDeadlineEffect((signal) => Effect.scoped(Effect.gen(function* () {
799
+ const ctx = self.registry.contextFor(connector.id, self.baseUrl, operationScope, {
800
+ signal,
801
+ timeoutMs,
802
+ ...(self.options.defer ? { defer: self.options.defer } : {}),
803
+ });
804
+ yield* closeScopeOnExit(connector, ctx, self.options.defer);
805
+ return yield* authCall(read, [ctx]).pipe(Effect.mapError((error) => error instanceof ConnectorCallError && error.code === "auth_required"
806
+ ? new ConnectorCallError("auth_required", "Downstream skills require authorization.")
807
+ : new ConnectorCallError("unavailable", "Downstream skills are unavailable.")));
808
+ })), {
809
+ timeoutMs,
810
+ ...(self.options.requestSignal ? { signal: self.options.requestSignal } : {}),
811
+ timeoutError: new ConnectorCallError("unavailable", "Downstream skills timed out."),
812
+ })).pipe(Effect.provideService(RequestScope, requestOwner(this.scope)));
813
+ }, SkillsRegistry.prototype.operation);
814
+ })();
709
815
  }