@zackbart/connecta 0.34.1 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (441) hide show
  1. package/CHANGELOG.md +418 -0
  2. package/README.md +65 -105
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2044 -1161
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +751 -281
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +29 -7
  53. package/dist/connectors/api-connector.js +145 -57
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/remote-mcp.d.ts +10 -30
  58. package/dist/connectors/remote-mcp.js +955 -563
  59. package/dist/d1.js +10 -243
  60. package/dist/derived-context.js +5 -0
  61. package/dist/describe-config.d.ts +3 -1
  62. package/dist/describe-config.js +2 -0
  63. package/dist/downstream-input.js +347 -260
  64. package/dist/errors.d.ts +87 -6
  65. package/dist/errors.js +114 -4
  66. package/dist/execute.js +87 -50
  67. package/dist/executor-admission.js +3 -0
  68. package/dist/executors/quickjs.js +163 -112
  69. package/dist/guarded-transport.js +50 -0
  70. package/dist/guest-runtime.js +1 -1
  71. package/dist/http/client.js +439 -0
  72. package/dist/http/errors.js +558 -0
  73. package/dist/http/fields.js +49 -0
  74. package/dist/http/hatch-paging.js +318 -0
  75. package/dist/http/hatch.js +1279 -0
  76. package/dist/http/json-schema.js +267 -0
  77. package/dist/http/node-transport.js +241 -0
  78. package/dist/http/oauth.js +162 -0
  79. package/dist/http/paging.js +227 -0
  80. package/dist/http/provider.js +221 -0
  81. package/dist/http/safety.js +82 -0
  82. package/dist/http/services.js +79 -0
  83. package/dist/http/tools.js +379 -0
  84. package/dist/http/vendor-index.js +138 -0
  85. package/dist/http/vendor.js +448 -0
  86. package/dist/http/write-request.js +66 -0
  87. package/dist/http-policy.d.ts +11 -0
  88. package/dist/http-policy.js +45 -0
  89. package/dist/inbound-credential.js +1 -1
  90. package/dist/index.d.ts +2 -2
  91. package/dist/index.js +4 -0
  92. package/dist/invocation-auth.js +30 -19
  93. package/dist/invocation.js +218 -85
  94. package/dist/mcp-result.js +0 -4
  95. package/dist/membership.d.ts +4 -0
  96. package/dist/meta-output.js +1 -1
  97. package/dist/meta-tools.js +531 -406
  98. package/dist/native-recovery.js +52 -0
  99. package/dist/native-tools.js +382 -0
  100. package/dist/node.d.ts +4 -3
  101. package/dist/node.js +45 -8
  102. package/dist/oauth-handoff.js +177 -104
  103. package/dist/oauth-partition.js +6 -20
  104. package/dist/oauth-sealing.js +6 -7
  105. package/dist/operation-vocabulary.js +101 -0
  106. package/dist/operator-record.d.ts +2 -2
  107. package/dist/operator-record.js +17 -4
  108. package/dist/operator-ui/contract.d.ts +8 -3
  109. package/dist/operator-ui/generated.js +4 -4
  110. package/dist/operator-ui/model.d.ts +2 -3
  111. package/dist/program-writes.js +47 -26
  112. package/dist/provider-call-facts.d.ts +115 -0
  113. package/dist/provider-call-facts.js +182 -0
  114. package/dist/provider-call.d.ts +112 -0
  115. package/dist/provider-call.js +271 -0
  116. package/dist/provider.d.ts +65 -31
  117. package/dist/provider.js +116 -39
  118. package/dist/providers/_shared/google/hatch.js +91 -0
  119. package/dist/providers/_shared/google/kit.js +427 -0
  120. package/dist/providers/_shared/google/result-size.js +15 -2
  121. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  122. package/dist/providers/_shared/google/service-account.js +8 -4
  123. package/dist/providers/_shared/google/workspace.d.ts +6 -210
  124. package/dist/providers/_shared/google/workspace.js +6 -425
  125. package/dist/providers/_shared/rest/compact-index.js +86 -0
  126. package/dist/providers/_shared/rest/kit.js +146 -0
  127. package/dist/providers/_shared/rest/operation-index.js +230 -14
  128. package/dist/providers/_shared/rest/response-media.js +11 -0
  129. package/dist/providers/_shared/rest/value-safety.js +353 -195
  130. package/dist/providers/_shared/sensitive-fields.js +27 -0
  131. package/dist/providers/breeze/api.js +584 -0
  132. package/dist/providers/breeze/index.d.ts +1 -3
  133. package/dist/providers/breeze/index.js +67 -1420
  134. package/dist/providers/breeze/openapi.generated.js +60 -0
  135. package/dist/providers/breeze/skill.generated.js +2 -6
  136. package/dist/providers/breeze/tools.js +696 -0
  137. package/dist/providers/ccb/api.js +496 -0
  138. package/dist/providers/ccb/index.d.ts +15 -37
  139. package/dist/providers/ccb/index.js +77 -1702
  140. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  141. package/dist/providers/ccb/lib/constants.js +74 -0
  142. package/dist/providers/ccb/lib/guide.js +9 -0
  143. package/dist/providers/ccb/lib/verdicts.js +387 -0
  144. package/dist/providers/ccb/openapi.generated.js +397 -0
  145. package/dist/providers/ccb/safety.js +295 -0
  146. package/dist/providers/ccb/skill.generated.js +2 -6
  147. package/dist/providers/ccb/tools.js +853 -0
  148. package/dist/providers/cloudflare/api.js +1066 -0
  149. package/dist/providers/cloudflare/index.d.ts +5 -22
  150. package/dist/providers/cloudflare/index.js +79 -197
  151. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  152. package/dist/providers/cloudflare/lib/config.js +2 -0
  153. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  154. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  155. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  156. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  157. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  158. package/dist/providers/cloudflare/openapi.generated.js +4 -3
  159. package/dist/providers/cloudflare/{value-safety.js → safety.js} +487 -0
  160. package/dist/providers/cloudflare/skill.generated.js +2 -10
  161. package/dist/providers/cloudflare/tools.js +360 -0
  162. package/dist/providers/docs/api.js +51 -0
  163. package/dist/providers/docs/index.d.ts +1 -12
  164. package/dist/providers/docs/index.js +53 -1165
  165. package/dist/providers/docs/lib/constants.d.ts +18 -0
  166. package/dist/providers/docs/lib/constants.js +18 -0
  167. package/dist/providers/docs/lib/discovery.js +26 -0
  168. package/dist/providers/docs/lib/requests.js +48 -0
  169. package/dist/providers/docs/lib/schemas.js +168 -0
  170. package/dist/providers/docs/openapi.generated.js +16 -0
  171. package/dist/providers/docs/safety.js +54 -0
  172. package/dist/providers/docs/skill.generated.js +2 -6
  173. package/dist/providers/docs/tools.js +801 -0
  174. package/dist/providers/drive/api.js +177 -0
  175. package/dist/providers/drive/index.d.ts +1 -12
  176. package/dist/providers/drive/index.js +38 -1448
  177. package/dist/providers/drive/lib/constants.d.ts +6 -0
  178. package/dist/providers/drive/lib/constants.js +6 -0
  179. package/dist/providers/drive/lib/contracts.js +532 -0
  180. package/dist/providers/drive/lib/hatch.js +197 -0
  181. package/dist/providers/drive/openapi.generated.js +77 -0
  182. package/dist/providers/drive/safety.js +90 -0
  183. package/dist/providers/drive/skill.generated.js +2 -6
  184. package/dist/providers/drive/tools.js +1290 -0
  185. package/dist/providers/forms/api.js +71 -0
  186. package/dist/providers/forms/index.d.ts +1 -12
  187. package/dist/providers/forms/index.js +49 -1145
  188. package/dist/providers/forms/lib/constants.d.ts +14 -0
  189. package/dist/providers/forms/lib/constants.js +19 -0
  190. package/dist/providers/forms/lib/hatch.js +72 -0
  191. package/dist/providers/forms/openapi.generated.js +23 -0
  192. package/dist/providers/forms/safety.js +34 -0
  193. package/dist/providers/forms/skill.generated.js +2 -8
  194. package/dist/providers/forms/tools.js +1023 -0
  195. package/dist/providers/github/api.js +150 -0
  196. package/dist/providers/github/index.d.ts +4 -5
  197. package/dist/providers/github/index.js +30 -87
  198. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  199. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  200. package/dist/providers/github/lib/discovery.js +132 -0
  201. package/dist/providers/github/lib/operations.js +58 -0
  202. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  203. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  204. package/dist/providers/github/openapi.generated.js +1216 -0
  205. package/dist/providers/github/safety.js +216 -0
  206. package/dist/providers/github/skill.generated.js +2 -5
  207. package/dist/providers/github/tools.js +506 -0
  208. package/dist/providers/gmail/api.js +114 -0
  209. package/dist/providers/gmail/index.d.ts +1 -12
  210. package/dist/providers/gmail/index.js +73 -1621
  211. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  212. package/dist/providers/gmail/lib/constants.js +16 -0
  213. package/dist/providers/gmail/lib/index.js +173 -0
  214. package/dist/providers/gmail/lib/schemas.js +176 -0
  215. package/dist/providers/gmail/lib/threading.js +120 -0
  216. package/dist/providers/gmail/openapi.generated.js +92 -0
  217. package/dist/providers/gmail/safety.js +21 -0
  218. package/dist/providers/gmail/skill.generated.js +2 -6
  219. package/dist/providers/gmail/tools.js +1435 -0
  220. package/dist/providers/overflow/api.js +1008 -0
  221. package/dist/providers/overflow/index.d.ts +1 -17
  222. package/dist/providers/overflow/index.js +60 -1488
  223. package/dist/providers/overflow/skill.generated.js +2 -5
  224. package/dist/providers/overflow/tools.js +873 -0
  225. package/dist/providers/planning-center/api.js +467 -0
  226. package/dist/providers/planning-center/index.d.ts +4 -35
  227. package/dist/providers/planning-center/index.js +69 -2445
  228. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  229. package/dist/providers/planning-center/lib/constants.js +83 -0
  230. package/dist/providers/planning-center/lib/discovery.js +40 -0
  231. package/dist/providers/planning-center/lib/guide.js +39 -0
  232. package/dist/providers/planning-center/lib/json-api.js +83 -0
  233. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  234. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  235. package/dist/providers/planning-center/safety.js +188 -0
  236. package/dist/providers/planning-center/skill.generated.js +2 -27
  237. package/dist/providers/planning-center/tools.js +1010 -0
  238. package/dist/providers/quickbooks/api.js +299 -0
  239. package/dist/providers/quickbooks/index.d.ts +13 -0
  240. package/dist/providers/quickbooks/index.js +93 -0
  241. package/dist/providers/quickbooks/lib/query.js +118 -0
  242. package/dist/providers/quickbooks/lib/writes.js +168 -0
  243. package/dist/providers/quickbooks/safety.js +222 -0
  244. package/dist/providers/quickbooks/skill.generated.js +5 -0
  245. package/dist/providers/quickbooks/tools.js +117 -0
  246. package/dist/providers/sheets/api.js +133 -0
  247. package/dist/providers/sheets/index.d.ts +4 -16
  248. package/dist/providers/sheets/index.js +61 -1172
  249. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  250. package/dist/providers/sheets/lib/constants.js +14 -0
  251. package/dist/providers/sheets/lib/hatch.js +163 -0
  252. package/dist/providers/sheets/lib/requests.js +105 -0
  253. package/dist/providers/sheets/lib/schemas.js +138 -0
  254. package/dist/providers/sheets/openapi.generated.js +30 -0
  255. package/dist/providers/sheets/safety.js +27 -0
  256. package/dist/providers/sheets/skill.generated.js +2 -7
  257. package/dist/providers/sheets/tools.js +733 -0
  258. package/dist/providers/slides/api.js +147 -0
  259. package/dist/providers/slides/index.d.ts +2 -10
  260. package/dist/providers/slides/index.js +48 -2555
  261. package/dist/providers/slides/lib/constants.d.ts +11 -0
  262. package/dist/providers/slides/lib/constants.js +11 -0
  263. package/dist/providers/slides/lib/requests.js +60 -0
  264. package/dist/providers/slides/lib/schemas.js +565 -0
  265. package/dist/providers/slides/openapi.generated.js +18 -0
  266. package/dist/providers/slides/skill.generated.js +2 -6
  267. package/dist/providers/slides/tools.js +1968 -0
  268. package/dist/providers/stripe/api.js +401 -0
  269. package/dist/providers/stripe/index.d.ts +5 -27
  270. package/dist/providers/stripe/index.js +74 -210
  271. package/dist/providers/stripe/lib/config.d.ts +4 -0
  272. package/dist/providers/stripe/lib/config.js +2 -0
  273. package/dist/providers/stripe/openapi.generated.js +4 -3
  274. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  275. package/dist/providers/stripe/skill.generated.js +2 -11
  276. package/dist/providers/stripe/tools.js +77 -0
  277. package/dist/providers/tithely/api.js +531 -0
  278. package/dist/providers/tithely/index.d.ts +17 -0
  279. package/dist/providers/tithely/index.js +86 -965
  280. package/dist/providers/tithely/skill.generated.js +2 -5
  281. package/dist/providers/tithely/tools.js +426 -0
  282. package/dist/providers/vercel/api.js +551 -0
  283. package/dist/providers/vercel/index.d.ts +9 -25
  284. package/dist/providers/vercel/index.js +65 -260
  285. package/dist/providers/vercel/lib/config.d.ts +2 -0
  286. package/dist/providers/vercel/lib/config.js +2 -0
  287. package/dist/providers/vercel/lib/index.js +117 -0
  288. package/dist/providers/vercel/lib/logs.js +100 -0
  289. package/dist/providers/vercel/lib/pin.js +270 -0
  290. package/dist/providers/vercel/openapi.generated.js +10 -5
  291. package/dist/providers/vercel/{value-safety.js → safety.js} +247 -38
  292. package/dist/providers/vercel/skill.generated.js +2 -7
  293. package/dist/providers/vercel/tools.js +642 -0
  294. package/dist/redaction-identity.js +47 -0
  295. package/dist/redaction-marker.js +125 -0
  296. package/dist/registry.d.ts +21 -15
  297. package/dist/registry.js +409 -376
  298. package/dist/routes/access-tokens.js +1 -1
  299. package/dist/routes/actor-labels.js +1 -1
  300. package/dist/routes/connect.js +1 -1
  301. package/dist/routes/dispatch.js +103 -0
  302. package/dist/routes/mcp.js +170 -79
  303. package/dist/routes/oauth.js +6 -1
  304. package/dist/routes/operator.js +2 -2
  305. package/dist/routes/shared.d.ts +5 -4
  306. package/dist/routes/shared.js +244 -177
  307. package/dist/routes/skills.js +10 -8
  308. package/dist/routes/ui-config.js +27 -3
  309. package/dist/routes/ui-data.js +21 -20
  310. package/dist/routes/ui.js +1 -1
  311. package/dist/runtime/call-admission.js +0 -26
  312. package/dist/runtime/call-entry.js +30 -0
  313. package/dist/runtime/call.js +552 -0
  314. package/dist/runtime/connector-scope.js +7 -0
  315. package/dist/runtime/credential-probe.js +34 -0
  316. package/dist/runtime/executor.js +40 -0
  317. package/dist/runtime/native-storage.js +63 -0
  318. package/dist/runtime/registry.js +27 -0
  319. package/dist/runtime/request-scope.js +72 -0
  320. package/dist/runtime/run.js +15 -7
  321. package/dist/runtime/shared-read.js +34 -5
  322. package/dist/runtime/storage.js +34 -21
  323. package/dist/sent-secrets.d.ts +194 -37
  324. package/dist/sent-secrets.js +1743 -340
  325. package/dist/server.js +5 -56
  326. package/dist/skills.js +322 -223
  327. package/dist/sqlite.js +15 -14
  328. package/dist/storage/d1-copy.js +255 -0
  329. package/dist/storage/d1-driver.js +15 -0
  330. package/dist/storage/keys.js +28 -0
  331. package/dist/storage/sql-driver.js +88 -0
  332. package/dist/storage/sql-native.js +544 -0
  333. package/dist/storage/sql-schema.d.ts +6 -0
  334. package/dist/storage/sql-schema.js +15 -0
  335. package/dist/storage/sql.d.ts +14 -20
  336. package/dist/storage/sql.js +29 -535
  337. package/dist/timeout.js +0 -26
  338. package/dist/tool-safety.js +20 -10
  339. package/dist/types.d.ts +9 -109
  340. package/dist/ui.d.ts +1 -1
  341. package/dist/ui.js +0 -1
  342. package/dist/upward.js +3 -0
  343. package/dist/usage-guide.js +3 -1
  344. package/dist/validate.d.ts +4 -2
  345. package/dist/validate.js +86 -9
  346. package/dist/version.d.ts +1 -1
  347. package/dist/version.js +1 -1
  348. package/dist/worker.js +312 -292
  349. package/dist/workspace-subject.js +5 -1
  350. package/dist/write-outcome.js +454 -34
  351. package/documentation/README.md +28 -7
  352. package/documentation/architecture.md +2409 -255
  353. package/documentation/auth.md +867 -114
  354. package/documentation/code-mode.md +49 -16
  355. package/documentation/deploying.md +164 -20
  356. package/documentation/hosted-mcp-migration.md +460 -0
  357. package/documentation/integrating.md +129 -144
  358. package/documentation/meta-tools.md +409 -32
  359. package/documentation/operating.md +27 -3
  360. package/documentation/operator-tests.md +3 -0
  361. package/documentation/operator-ui.md +84 -48
  362. package/documentation/provider-auth-migration.md +16 -63
  363. package/documentation/provider-migration-0.29.md +10 -5
  364. package/documentation/provider-migration-0.35.md +975 -0
  365. package/documentation/providers.md +1347 -0
  366. package/examples/worker/AGENTS.md +23 -9
  367. package/examples/worker/README.md +254 -135
  368. package/examples/worker/alchemy.run.ts +116 -0
  369. package/examples/worker/gitignore +10 -0
  370. package/examples/worker/src/connecta.config.ts +23 -21
  371. package/examples/worker/wrangler.jsonc +14 -5
  372. package/guides/connecting-agents.md +157 -0
  373. package/guides/how-it-works.md +156 -0
  374. package/guides/safety-and-trust.md +153 -0
  375. package/package.json +30 -50
  376. package/templates/node/.env.example +3 -0
  377. package/templates/node/README.md +22 -2
  378. package/templates/node/docker-compose.yml +1 -0
  379. package/templates/node/package.json +3 -2
  380. package/templates/node/src/connecta.config.ts +8 -0
  381. package/dist/catalog-drift.d.ts +0 -138
  382. package/dist/catalog-drift.js +0 -578
  383. package/dist/operator-ui/agents.d.ts +0 -74
  384. package/dist/operator-ui/agents.js +0 -104
  385. package/dist/operator-ui/config-summary.js +0 -565
  386. package/dist/operator-ui/connection-map.js +0 -376
  387. package/dist/operator-ui/endpoints.js +0 -221
  388. package/dist/operator-ui/fix-prompts.d.ts +0 -18
  389. package/dist/operator-ui/fix-prompts.js +0 -87
  390. package/dist/operator-ui/health.js +0 -52
  391. package/dist/operator-ui/member-page.js +0 -97
  392. package/dist/operator-ui/overview.js +0 -123
  393. package/dist/operator-ui/setup-commands.js +0 -51
  394. package/dist/operator-ui/view.d.ts +0 -401
  395. package/dist/operator-ui/view.js +0 -705
  396. package/dist/providers/_shared/request-token.js +0 -83
  397. package/dist/providers/_shared/rest/dispatch.js +0 -41
  398. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  399. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  400. package/dist/providers/_shared/rest/tools.js +0 -569
  401. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  402. package/dist/providers/basecamp/index.d.ts +0 -45
  403. package/dist/providers/basecamp/index.js +0 -997
  404. package/dist/providers/basecamp/skill.generated.js +0 -9
  405. package/dist/providers/cloudflare/rest.d.ts +0 -37
  406. package/dist/providers/cloudflare/rest.js +0 -1097
  407. package/dist/providers/github/hosted.js +0 -218
  408. package/dist/providers/github/rest.js +0 -321
  409. package/dist/providers/infisical/index.d.ts +0 -7
  410. package/dist/providers/infisical/index.js +0 -713
  411. package/dist/providers/infisical/skill.generated.js +0 -8
  412. package/dist/providers/intercom/index.d.ts +0 -24
  413. package/dist/providers/intercom/index.js +0 -121
  414. package/dist/providers/intercom/skill.generated.js +0 -8
  415. package/dist/providers/linear/index.d.ts +0 -55
  416. package/dist/providers/linear/index.js +0 -537
  417. package/dist/providers/linear/skill.generated.js +0 -8
  418. package/dist/providers/mixpanel/index.d.ts +0 -59
  419. package/dist/providers/mixpanel/index.js +0 -472
  420. package/dist/providers/mixpanel/operations.js +0 -20
  421. package/dist/providers/mixpanel/rest.js +0 -603
  422. package/dist/providers/mixpanel/skill.generated.js +0 -10
  423. package/dist/providers/mixpanel/value-safety.js +0 -16
  424. package/dist/providers/notion/index.d.ts +0 -67
  425. package/dist/providers/notion/index.js +0 -368
  426. package/dist/providers/notion/openapi.generated.js +0 -75
  427. package/dist/providers/notion/rest.d.ts +0 -24
  428. package/dist/providers/notion/rest.js +0 -1226
  429. package/dist/providers/notion/skill.generated.js +0 -11
  430. package/dist/providers/notion/value-safety.js +0 -56
  431. package/dist/providers/revenuecat/index.d.ts +0 -51
  432. package/dist/providers/revenuecat/index.js +0 -697
  433. package/dist/providers/revenuecat/skill.generated.js +0 -11
  434. package/dist/providers/stripe/rest.d.ts +0 -14
  435. package/dist/providers/stripe/rest.js +0 -402
  436. package/dist/providers/vercel/rest.d.ts +0 -20
  437. package/dist/providers/vercel/rest.js +0 -1020
  438. package/dist/providers/wispr-flow/index.d.ts +0 -14
  439. package/dist/providers/wispr-flow/index.js +0 -117
  440. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  441. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -1,578 +0,0 @@
1
- // Web-API only, like the rest of the core: a manifest comparison that ran on
2
- // Node but not on Workers would leave half the deployments unable to tell a
3
- // stale allowlist from a current one.
4
- import { classifyTool } from "./tool-safety.js";
5
- import { failureRecord, logFailure } from "./operator-record.js";
6
- /** A count, or 0 when the seam returned something that is not one. */
7
- function boundedCount(value) {
8
- return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
9
- }
10
- /** An ISO-8601 date-time with a zone, as `Date.parse` reads it on every runtime. */
11
- const ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:\d{2})$/;
12
- /**
13
- * The report's time, re-serialized from the instant it names, so the string
14
- * that leaves is always connecta's own ISO-8601 UTC form, never the seam's.
15
- */
16
- function observationTime(value) {
17
- if (typeof value !== "string" || !ISO_INSTANT.test(value))
18
- return undefined;
19
- const time = Date.parse(value);
20
- return Number.isFinite(time) ? new Date(time).toISOString() : undefined;
21
- }
22
- /**
23
- * Rebuild a drift report as bounded counts, closed verification facts, and a timestamp.
24
- *
25
- * `Connector.catalogDrift()` sits on the open plugin seam, and what it returns
26
- * lands on authenticated connector status and the operator page. TypeScript
27
- * constrains neither extra enumerable properties nor `observedAt` at runtime.
28
- * Counts, closed verification facts, and a time are rebuilt at the boundary where
29
- * third-party output becomes a response — rather than trusted. A report whose
30
- * `observedAt` names no instant is no observation connecta can date, and is
31
- * dropped whole (INV-6): a plugin forwarding a downstream's report could
32
- * otherwise put any text there. The activity path reconstructs its five
33
- * fields for the same reason.
34
- */
35
- export function boundedCatalogDrift(report) {
36
- if (!report || typeof report !== "object")
37
- return undefined;
38
- const observedAt = observationTime(report.observedAt);
39
- if (observedAt === undefined)
40
- return undefined;
41
- return {
42
- observedAt,
43
- ...(typeof report.reviewedBaseline === "boolean" ? { reviewedBaseline: report.reviewedBaseline } : {}),
44
- ...(report.verification === "complete" || report.verification === "unavailable"
45
- ? { verification: report.verification }
46
- : {}),
47
- ...(report.schemaCoverage && typeof report.schemaCoverage === "object"
48
- ? {
49
- schemaCoverage: {
50
- pinned: boundedCount(report.schemaCoverage.pinned),
51
- unpinned: boundedCount(report.schemaCoverage.unpinned),
52
- },
53
- }
54
- : {}),
55
- unclassifiedTools: boundedCount(report.unclassifiedTools),
56
- unservedTools: boundedCount(report.unservedTools),
57
- annotationConflicts: boundedCount(report.annotationConflicts),
58
- schemaChanges: boundedCount(report.schemaChanges),
59
- ...(boundedCount(report.droppedTools ?? 0) > 0 ? { droppedTools: boundedCount(report.droppedTools ?? 0) } : {}),
60
- };
61
- }
62
- const encoder = new TextEncoder();
63
- /**
64
- * Most JSON values one tool's schemas may hold before its digest refuses to
65
- * compute. A digest vouches for a whole schema or for nothing, so a schema
66
- * past the bound is not hashed in part: the computation throws, and the
67
- * caller serves every digested review unverified (INV-1).
68
- */
69
- const MAX_SCHEMA_DIGEST_NODES = 100_000;
70
- /** Object keys in the order `JSON.stringify` emits a key-sorted object. */
71
- function canonicalKeys(value) {
72
- const entries = Object.entries(value).filter(([, item]) => item !== undefined && typeof item !== "function" && typeof item !== "symbol");
73
- entries.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
74
- // A plain object enumerates integer-like keys first, in numeric order.
75
- // Recorded digests were taken from a key-sorted object, so reproduce its
76
- // enumeration rather than the sort alone.
77
- const sorted = Object.fromEntries(entries);
78
- return Object.keys(sorted).map((key) => [key, sorted[key]]);
79
- }
80
- const SCHEMA_MAPS = new Set([
81
- "properties",
82
- "patternProperties",
83
- "$defs",
84
- "definitions",
85
- "dependentSchemas",
86
- "dependencies",
87
- ]);
88
- const SCHEMA_ARRAYS = new Set(["allOf", "anyOf", "oneOf", "prefixItems"]);
89
- const SCHEMA_CHILDREN = new Set([
90
- "items",
91
- "additionalItems",
92
- "additionalProperties",
93
- "unevaluatedProperties",
94
- "unevaluatedItems",
95
- "contains",
96
- "propertyNames",
97
- "not",
98
- "if",
99
- "then",
100
- "else",
101
- "contentSchema",
102
- ]);
103
- function childMode(mode, key, value) {
104
- if (mode === "root" || mode === "map")
105
- return "schema";
106
- if (mode !== "schema")
107
- return "data";
108
- if (key === "required" || key === "enum" || key === "type")
109
- return "set";
110
- if (SCHEMA_MAPS.has(key))
111
- return "map";
112
- if (SCHEMA_ARRAYS.has(key) || (key === "items" && Array.isArray(value)))
113
- return "schema-array";
114
- return SCHEMA_CHILDREN.has(key) ? "schema" : "data";
115
- }
116
- function canonicalJson(root, sets) {
117
- const out = [];
118
- const stack = [{ value: root, mode: sets ? "root" : "data", out }];
119
- let nodes = 0;
120
- while (stack.length > 0) {
121
- const task = stack.pop();
122
- const out = task.out;
123
- if ("text" in task) {
124
- out.push(task.text);
125
- continue;
126
- }
127
- if ("members" in task) {
128
- out.push("[", task.members
129
- .map((member) => member.join(""))
130
- .sort()
131
- .join(","), "]");
132
- continue;
133
- }
134
- if (++nodes > MAX_SCHEMA_DIGEST_NODES)
135
- throw new Error(`schema has more than ${MAX_SCHEMA_DIGEST_NODES} values; refusing to digest it in part.`);
136
- const { value, mode } = task;
137
- if (value === null || value === undefined)
138
- out.push("null");
139
- else if (typeof value === "string" || typeof value === "boolean")
140
- out.push(JSON.stringify(value));
141
- else if (typeof value === "number")
142
- out.push(Number.isFinite(value) ? JSON.stringify(value) : "null");
143
- else if (typeof value === "function" || typeof value === "symbol")
144
- out.push("null");
145
- else if (typeof value !== "object")
146
- throw new Error(`schema holds a ${typeof value}, which JSON cannot carry.`);
147
- else if (Array.isArray(value)) {
148
- if (mode === "set") {
149
- const members = Array.from({ length: value.length }, () => []);
150
- stack.push({ members, out });
151
- for (let index = value.length - 1; index >= 0; index--)
152
- stack.push({ value: value[index], mode: "data", out: members[index] });
153
- }
154
- else {
155
- out.push("[");
156
- stack.push({ text: "]", out });
157
- for (let index = value.length - 1; index >= 0; index--) {
158
- stack.push({ value: value[index], mode: mode === "schema-array" ? "schema" : "data", out });
159
- if (index > 0)
160
- stack.push({ text: ",", out });
161
- }
162
- }
163
- }
164
- else {
165
- out.push("{");
166
- stack.push({ text: "}", out });
167
- const entries = canonicalKeys(value);
168
- for (let index = entries.length - 1; index >= 0; index--) {
169
- const [key, item] = entries[index];
170
- stack.push({ value: item, mode: childMode(mode, key, item), out });
171
- stack.push({ text: `${index > 0 ? "," : ""}${JSON.stringify(key)}:`, out });
172
- }
173
- }
174
- }
175
- return out.join("");
176
- }
177
- /**
178
- * Digest the schemas of one downstream tool.
179
- *
180
- * Canonical rather than literal, unlike the catalog fingerprint in
181
- * `src/catalog-fingerprint.ts`: that one is deliberately conservative because a
182
- * spurious cache write is cheap, while a spurious drift finding spends a
183
- * maintainer's attention on a downstream that reordered its JSON keys.
184
- * New pins use `sha256-sets-v1:` and sort required, enum, and type arrays only
185
- * at schema keyword locations. Tuple arrays and JSON data keep their order.
186
- * Legacy `sha256:` pins use the original literal-array form, so an upgrade
187
- * cannot silently invalidate a reviewed provider manifest.
188
- * Description and annotations are excluded — a reworded description is P1's
189
- * business, and an annotation change is already its own drift category.
190
- *
191
- * Rejects rather than digesting part of a schema: a digest that ignored some
192
- * leaf would let a reviewed read keep its verdict after that leaf changed.
193
- */
194
- export async function vettedSchemaDigest(tool, format = "sets-v1") {
195
- const bytes = encoder.encode(canonicalJson({
196
- inputSchema: tool.inputSchema ?? null,
197
- outputSchema: tool.outputSchema ?? null,
198
- }, format === "sets-v1"));
199
- const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
200
- return `${format === "sets-v1" ? "sha256-sets-v1" : "sha256"}:${[...digest].map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
201
- }
202
- /**
203
- * Build a provider's manifest from the lists it already maintains.
204
- *
205
- * Throws when a name is classified twice, because a tool that is both a read
206
- * and a write is a review mistake that must not boot: the annotation the
207
- * connector would apply depends on which branch runs first, and "safe by
208
- * default" cannot be decided by ordering.
209
- */
210
- export function vettedCatalog(input) {
211
- const tools = new Map();
212
- const digestFor = (name) => input.schemaDigests?.[name];
213
- for (const name of input.reads) {
214
- const digest = digestFor(name);
215
- tools.set(name, {
216
- verdict: "read-only",
217
- ...(input.optionalTools?.has(name) ? { optional: true } : {}),
218
- ...(digest !== undefined ? { schemaDigest: digest } : {}),
219
- });
220
- }
221
- for (const [name, verdict] of input.writes) {
222
- if (tools.has(name)) {
223
- throw new Error(`vettedCatalog() classified "${name}" as both a read and a write.`);
224
- }
225
- const digest = digestFor(name);
226
- tools.set(name, {
227
- verdict,
228
- ...(input.optionalTools?.has(name) ? { optional: true } : {}),
229
- ...(digest !== undefined ? { schemaDigest: digest } : {}),
230
- });
231
- }
232
- for (const name of Object.keys(input.schemaDigests ?? {})) {
233
- if (!tools.has(name)) {
234
- throw new Error(`vettedCatalog() recorded a schema digest for unclassified tool "${name}".`);
235
- }
236
- }
237
- for (const name of input.optionalTools ?? []) {
238
- if (!tools.has(name))
239
- throw new Error(`vettedCatalog() marked unclassified tool "${name}" optional.`);
240
- }
241
- return { version: 1, tools };
242
- }
243
- const VERDICTS = {
244
- read: "read-only",
245
- write: "additive",
246
- destructive: "destructive",
247
- };
248
- const PUBLIC_VERDICTS = {
249
- "read-only": "read",
250
- additive: "write",
251
- destructive: "destructive",
252
- };
253
- const SCHEMA_DIGEST = /^sha256(?:-sets-v1)?:[0-9a-f]{64}$/;
254
- const REVIEWED_TOOL_KEYS = new Set(["verdict", "reason", "schemaDigest", "optional"]);
255
- function isRecord(value) {
256
- return typeof value === "object" && value !== null && !Array.isArray(value);
257
- }
258
- /**
259
- * Validate a public {@link ToolClassification} once, reading every value a
260
- * single time, into the manifest the registry classifies with and a
261
- * deep-frozen copy of the record.
262
- *
263
- * Every structural mistake throws, naming `owner`, because a classification
264
- * that half-applies is worse than one that refuses to boot (INV-11). Unknown
265
- * keys throw too: a misspelled `verdict` must not quietly leave a write
266
- * unclassified.
267
- */
268
- function parseClassification(classification, owner) {
269
- function fail(detail) {
270
- throw new Error(`[connecta] ${owner} classify ${detail}`);
271
- }
272
- if (!isRecord(classification))
273
- fail("must be an object with a tools record.");
274
- for (const key of Object.keys(classification)) {
275
- if (key !== "tools" && key !== "unlisted")
276
- fail(`has unknown key "${key}"; only "tools" and "unlisted" are accepted.`);
277
- }
278
- const unlisted = classification.unlisted;
279
- if (unlisted !== undefined && unlisted !== "hide")
280
- fail('unlisted must be "hide" when set.');
281
- const input = classification.tools;
282
- if (!isRecord(input))
283
- fail("tools must be a record of tool name to verdict.");
284
- const tools = new Map();
285
- const frozen = {};
286
- for (const [name, entry] of Object.entries(input)) {
287
- if (!name || name.trim() !== name) {
288
- fail(`tool name "${name}" is empty or has surrounding whitespace.`);
289
- }
290
- const record = typeof entry === "string" ? { verdict: entry } : isRecord(entry) ? { ...entry } : {};
291
- for (const key of Object.keys(record)) {
292
- if (!REVIEWED_TOOL_KEYS.has(key))
293
- fail(`tool "${name}" has unknown key "${key}".`);
294
- }
295
- const { verdict: publicVerdict, reason, schemaDigest: digest, optional } = record;
296
- const verdict = typeof publicVerdict === "string" && Object.hasOwn(VERDICTS, publicVerdict) ? VERDICTS[publicVerdict] : undefined;
297
- if (verdict === undefined) {
298
- fail(`tool "${name}" needs verdict "read", "write", or "destructive".`);
299
- }
300
- if (reason !== undefined && (typeof reason !== "string" || !reason.trim())) {
301
- fail(`tool "${name}" reason must be a non-empty string.`);
302
- }
303
- if (digest !== undefined && (typeof digest !== "string" || !SCHEMA_DIGEST.test(digest))) {
304
- fail(`tool "${name}" schemaDigest must be "sha256:" or "sha256-sets-v1:" and 64 lowercase hex digits.`);
305
- }
306
- if (optional !== undefined && typeof optional !== "boolean")
307
- fail(`tool "${name}" optional must be a boolean.`);
308
- tools.set(name, {
309
- verdict,
310
- ...(typeof optional === "boolean" ? { optional } : {}),
311
- ...(typeof digest === "string" ? { schemaDigest: digest } : {}),
312
- });
313
- frozen[name] =
314
- typeof entry === "string"
315
- ? PUBLIC_VERDICTS[verdict]
316
- : Object.freeze({
317
- verdict: PUBLIC_VERDICTS[verdict],
318
- ...(typeof reason === "string" ? { reason } : {}),
319
- ...(typeof optional === "boolean" ? { optional } : {}),
320
- ...(typeof digest === "string" ? { schemaDigest: digest } : {}),
321
- });
322
- }
323
- return {
324
- catalog: { version: 1, tools, ...(unlisted ? { unlisted } : {}) },
325
- frozen: Object.freeze({ tools: Object.freeze(frozen), ...(unlisted ? { unlisted } : {}) }),
326
- };
327
- }
328
- /** Validate a {@link ToolClassification} and build the manifest it describes. */
329
- export function reviewedCatalog(classification, owner) {
330
- return parseClassification(classification, owner).catalog;
331
- }
332
- /**
333
- * Validate a {@link ToolClassification} and return a deep-frozen copy of it:
334
- * what a connector carries as `classification`, so neither the caller's
335
- * original object nor a write through the connector can change a verdict
336
- * after review.
337
- */
338
- export function reviewedClassification(classification, owner) {
339
- return parseClassification(classification, owner).frozen;
340
- }
341
- /**
342
- * One reviewed tool as served: a fresh object, never one a connector, a
343
- * cache, or an earlier read holds.
344
- *
345
- * A listed read fills downstream silence, and an explicit write annotation on
346
- * it wins: `destructiveHint: true` or `readOnlyHint: false` on a classified
347
- * read is the downstream telling us the review is stale. A listed write or
348
- * destructive tool stays a write whatever the downstream claims; there
349
- * connecta knows what the tool does, and a claim to the contrary is a
350
- * downstream bug rather than news
351
- * ([#310](https://github.com/zackbart/connecta/issues/310),
352
- * [#315](https://github.com/zackbart/connecta/issues/315)). A tool no review
353
- * lists keeps only an explicit read annotation, the downstream's own word
354
- * being the only evidence there is. A reviewed tool whose recorded schema
355
- * digest the live tool no longer matches, or could not be checked against,
356
- * keeps no reviewed verdict and is a write.
357
- */
358
- function servedTool(catalog, fact, lapsed, override) {
359
- const definition = structuredClone(fact);
360
- const reviewed = catalog.tools.get(fact.name);
361
- definition.classification = classifyTool(fact, override, reviewed
362
- ? {
363
- verdict: PUBLIC_VERDICTS[reviewed.verdict],
364
- stale: lapsed.has(fact.name),
365
- }
366
- : undefined);
367
- const downstream = definition.annotations ?? {};
368
- const record = catalog.tools.get(definition.name);
369
- const annotate = (annotations) => ({
370
- ...definition,
371
- annotations: override === undefined
372
- ? annotations
373
- : { ...annotations, readOnlyHint: override === "read", destructiveHint: override === "write" },
374
- });
375
- if (record?.verdict === "destructive") {
376
- return annotate({ ...downstream, readOnlyHint: false, destructiveHint: true });
377
- }
378
- if (record && lapsed.has(definition.name)) {
379
- // A review vouches for the schema it read. When the live schema no longer
380
- // matches that digest, or the digest could not be checked, the verdict is
381
- // about some other tool: the read becomes a write until a release reviews
382
- // it again (INV-1).
383
- return annotate({ ...downstream, readOnlyHint: false });
384
- }
385
- if (record?.verdict === "read-only") {
386
- if (downstream.destructiveHint === true || downstream.readOnlyHint === false) {
387
- return annotate(downstream);
388
- }
389
- return annotate({
390
- ...downstream,
391
- readOnlyHint: true,
392
- destructiveHint: downstream.destructiveHint ?? false,
393
- });
394
- }
395
- if (record?.verdict === "additive") {
396
- return annotate({ ...downstream, readOnlyHint: false });
397
- }
398
- // Fill-in only: a silent tool is not read-only, so drift fails closed onto
399
- // `call_destructive_tool`, and it gets no `destructiveHint` it has not
400
- // earned. An explicit read claim on a name no review lists is believed.
401
- return annotate({ ...downstream, readOnlyHint: downstream.readOnlyHint ?? false });
402
- }
403
- /**
404
- * Whether the downstream's own annotation contradicts what a release reviewed.
405
- *
406
- * Only an *explicit* contradiction counts. Silence is the ordinary case the
407
- * classification exists to fill, and an unclassified tool is already counted
408
- * as an addition rather than twice.
409
- */
410
- function contradicts(record, definition) {
411
- const downstream = definition.annotations ?? {};
412
- if (record.verdict === "read-only") {
413
- return downstream.readOnlyHint === false || downstream.destructiveHint === true;
414
- }
415
- return downstream.readOnlyHint === true;
416
- }
417
- /**
418
- * Names of served tools whose schemas no longer match the digest a release
419
- * recorded for them. A manifest that recorded no digest for a tool cannot have
420
- * an opinion about its schema, so it does not pay for a hash either. Throws
421
- * when a digest cannot be computed; the caller decides what that means.
422
- */
423
- async function changedSchemas(catalog, tools) {
424
- const changed = new Set();
425
- for (const definition of tools) {
426
- const recorded = catalog.tools.get(definition.name)?.schemaDigest;
427
- if (recorded !== undefined &&
428
- recorded !== (await vettedSchemaDigest(definition, recorded.startsWith("sha256:") ? "legacy" : "sets-v1"))) {
429
- changed.add(definition.name);
430
- }
431
- }
432
- return changed;
433
- }
434
- /** Every served tool whose review recorded a digest: what cannot be verified. */
435
- function digestedTools(catalog, tools) {
436
- return new Set(tools
437
- .filter((definition) => catalog.tools.get(definition.name)?.schemaDigest !== undefined)
438
- .map((definition) => definition.name));
439
- }
440
- function countDrift(catalog, tools, changed) {
441
- let unclassifiedTools = 0;
442
- let annotationConflicts = 0;
443
- const served = new Set();
444
- for (const definition of tools) {
445
- served.add(definition.name);
446
- const record = catalog.tools.get(definition.name);
447
- if (!record) {
448
- unclassifiedTools += 1;
449
- continue;
450
- }
451
- if (contradicts(record, definition))
452
- annotationConflicts += 1;
453
- }
454
- let unservedTools = 0;
455
- for (const [name, record] of catalog.tools) {
456
- if (!record.optional && !served.has(name))
457
- unservedTools += 1;
458
- }
459
- return {
460
- unclassifiedTools,
461
- unservedTools,
462
- annotationConflicts,
463
- schemaChanges: changed.size,
464
- };
465
- }
466
- /**
467
- * Compare a live catalog with the manifest and count what moved.
468
- *
469
- * Counts only, and by construction: there is nowhere here to put a tool name,
470
- * a schema, or a downstream string, so no later surface has to remember to
471
- * strip one. Reads nothing but the tools it was handed — the caller already
472
- * fetched them to serve a request, and this function never fetches anything.
473
- */
474
- export async function detectCatalogDrift(catalog, tools) {
475
- return countDrift(catalog, tools, await changedSchemas(catalog, tools));
476
- }
477
- /**
478
- * Each connector object's review, validated the first time a registry reads
479
- * it. Read once per object, so a getter or a record mutated later cannot
480
- * hand a later registry (a principal's, say) a different review.
481
- */
482
- const reviews = new WeakMap();
483
- /**
484
- * The review `connector.classification` declares, or undefined when it
485
- * declares none. Throws on a malformed one (INV-11).
486
- */
487
- export function catalogReviewOf(connector) {
488
- let review = reviews.get(connector);
489
- if (review === undefined) {
490
- const classification = connector.classification;
491
- review = classification === undefined ? null : reviewedCatalog(classification, `connector "${connector.id}"`);
492
- reviews.set(connector, review);
493
- }
494
- return review ?? undefined;
495
- }
496
- /**
497
- * Classify downstream facts with a review: what the registry serves on every
498
- * read, from whichever cache layer the facts came from.
499
- *
500
- * Every tool returned is fresh. The registry supplies the same whole-schema
501
- * verification it observed for this listing, including failures. Standalone
502
- * callers verify here. No failed verification survives onto a later listing,
503
- * and meanwhile no digested review vouches for a read (INV-1).
504
- */
505
- export async function classifyCatalog(catalog, connectorId, facts, logger, overrides, verification) {
506
- let lapsed = verification
507
- ? verification.available
508
- ? verification.changed
509
- : digestedTools(catalog, facts)
510
- : undefined;
511
- if (!lapsed) {
512
- try {
513
- lapsed = await changedSchemas(catalog, facts);
514
- }
515
- catch (error) {
516
- lapsed = digestedTools(catalog, facts);
517
- logFailure(logger, "schema digest check failed; serving digested reviews as writes", failureRecord({ connector: connectorId }, error));
518
- }
519
- }
520
- const unverified = lapsed;
521
- return facts
522
- .filter((fact) => catalog.unlisted !== "hide" || catalog.tools.has(fact.name))
523
- .map((fact) => servedTool(catalog, fact, unverified, overrides?.[fact.name]));
524
- }
525
- /** Counts only, retained weakly by connector and an explicit runtime/catalog partition. */
526
- const observations = new WeakMap();
527
- /**
528
- * Observe tools already fetched by a listing. No probe, persistence, or catalog
529
- * payload: registry-owned partition tokens isolate deployment and subject.
530
- * A digest failure replaces old success, while classification fails closed.
531
- */
532
- export async function observeReviewedDrift(connector, catalog, listed, logger, partition = connector, droppedTools = 0) {
533
- let verification;
534
- let report = {
535
- observedAt: new Date().toISOString(),
536
- reviewedBaseline: catalog !== undefined,
537
- unclassifiedTools: 0,
538
- unservedTools: 0,
539
- annotationConflicts: 0,
540
- schemaChanges: 0,
541
- ...(droppedTools > 0 ? { droppedTools } : {}),
542
- };
543
- if (catalog) {
544
- const reviewed = listed.filter((tool) => catalog.tools.has(tool.name));
545
- const pinned = digestedTools(catalog, reviewed).size;
546
- const schemaCoverage = { pinned, unpinned: reviewed.length - pinned };
547
- try {
548
- verification = { changed: await changedSchemas(catalog, listed), available: true };
549
- report = {
550
- ...report,
551
- ...countDrift(catalog, listed, verification.changed),
552
- schemaCoverage,
553
- verification: "complete",
554
- };
555
- }
556
- catch (error) {
557
- verification = { changed: new Set(), available: false };
558
- report = {
559
- ...report,
560
- ...countDrift(catalog, listed, verification.changed),
561
- schemaCoverage,
562
- verification: "unavailable",
563
- };
564
- logFailure(logger, "catalog drift check failed", failureRecord({ connector: connector.id }, error));
565
- }
566
- }
567
- let partitions = observations.get(connector);
568
- if (!partitions) {
569
- partitions = new WeakMap();
570
- observations.set(connector, partitions);
571
- }
572
- partitions.set(partition, report);
573
- return verification;
574
- }
575
- /** Look up only this runtime/catalog partition; never start a listing. */
576
- export function observedCatalogDrift(connector, partition = connector) {
577
- return observations.get(connector)?.get(partition);
578
- }
@@ -1,74 +0,0 @@
1
- import type { OperatorUiContractV2 } from "./contract.js";
2
- import { type Notice, type RequestFailureFacts, type Tone } from "./view.js";
3
- /**
4
- * The Tokens page's rows, computed from the slot list and contract v2 alone.
5
- * Agents are declared in code: a row's only controls are its token's issue,
6
- * rotate and revoke, so nothing here creates, renames or rebinds one.
7
- */
8
- /** One declared agent's token slot, as `GET /ui/access-tokens` returns it. */
9
- export type AgentSlot = ({
10
- name: string;
11
- state: "none";
12
- } | {
13
- name: string;
14
- state: "issued";
15
- issuedAt: string;
16
- } | {
17
- name: string;
18
- state: "revoked";
19
- revokedAt: string;
20
- }) & {
21
- /**
22
- * The route's opaque slot revision; it changes on every slot commit (P3b,
23
- * #837). A slot read without one is unresolved and never acted on.
24
- */
25
- revision?: string;
26
- };
27
- /** Issue and rotate are the same request; the slot's state names it. */
28
- export type SlotAction = "issue" | "rotate" | "revoke";
29
- export interface AgentRow {
30
- name: string;
31
- /** Pools it belongs to, from `agents[].pools`; empty when the contract does not list it. */
32
- pools: string[];
33
- slot: AgentSlot;
34
- /**
35
- * Whether `slot` comes from the live slot list. Only a live slot can be
36
- * acted on: one known only from the contract may be stale, so its controls
37
- * are disabled until a refresh lists it.
38
- */
39
- live: boolean;
40
- /** Why its controls are off, or null when they work. */
41
- blocked: string | null;
42
- /** Its latest activity row; null is "never" (or history that is off). */
43
- lastSeenAt: string | null;
44
- actions: SlotAction[];
45
- }
46
- export declare function slotActions(slot: Pick<AgentSlot, "state">): SlotAction[];
47
- /**
48
- * One agent's slot, resolved once for both what the row shows and what an
49
- * action may do. The live slot list is authoritative; the contract's copy is
50
- * shown only for an agent the list does not have, and is never acted on.
51
- */
52
- export declare function resolveSlot(contract: OperatorUiContractV2 | null, slots: AgentSlot[], name: string): {
53
- slot: AgentSlot;
54
- live: boolean;
55
- } | null;
56
- /**
57
- * One row per declared agent, in the slot list's order, then any agent only
58
- * the contract lists. The contract adds pools and last seen.
59
- */
60
- export declare function agentRows(contract: OperatorUiContractV2 | null, slots: AgentSlot[], unresolved?: readonly string[]): AgentRow[];
61
- export declare function slotBadge(slot: Pick<AgentSlot, "state">): {
62
- label: string;
63
- tone: Tone;
64
- };
65
- /** When the slot last changed, issued or revoked (its badge says which); a dash when it never has. */
66
- export declare function slotSince(slot: AgentSlot, format: (value: string) => string): string;
67
- export declare function lastSeenLabel(lastSeenAt: string | null, format: (value: string) => string): string;
68
- /**
69
- * Why a token operation did not land, in fixed sentences keyed by status.
70
- * `outcome_unknown` (503) and `aborted` (499) are failures like any other and
71
- * are never retried for the operator: an unknown rotation returned no secret,
72
- * and only a new, deliberate rotation produces one.
73
- */
74
- export declare function tokenFailureNotice(action: SlotAction, name: string, facts: RequestFailureFacts, productName: string): Notice;