@zackbart/connecta 0.28.1 → 0.30.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 (332) hide show
  1. package/CHANGELOG.md +855 -5
  2. package/README.md +125 -116
  3. package/bin/connecta.mjs +121 -139
  4. package/bin/meta-tool-names.d.mts +2 -0
  5. package/bin/meta-tool-names.mjs +9 -0
  6. package/bin/version.mjs +3 -0
  7. package/dist/access-tokens.js +53 -63
  8. package/dist/activity-request.js +8 -0
  9. package/dist/activity.d.ts +76 -42
  10. package/dist/activity.js +110 -42
  11. package/dist/argument-redaction.js +230 -0
  12. package/dist/auth/clerk-sdk/client.d.ts +65 -0
  13. package/dist/auth/clerk-sdk/client.js +5 -0
  14. package/dist/auth/clerk-sdk/generated.js +1845 -0
  15. package/dist/auth/clerk-transport.js +19 -0
  16. package/dist/auth/clerk.d.ts +17 -7
  17. package/dist/auth/clerk.js +189 -107
  18. package/dist/auth/cloudflare-access.js +25 -26
  19. package/dist/auth/downstream-client-metadata.d.ts +29 -0
  20. package/dist/auth/downstream-client-metadata.js +133 -0
  21. package/dist/auth/downstream-oauth.js +1584 -1580
  22. package/dist/auth/downstream-revocation.js +106 -0
  23. package/dist/auth/oauth-token-response.js +231 -0
  24. package/dist/auth/oauth-v2-migration.js +116 -0
  25. package/dist/auth/static-oauth.js +93 -71
  26. package/dist/auth-elicitation.js +288 -0
  27. package/dist/authorization-handoff.js +111 -0
  28. package/dist/branding.d.ts +8 -16
  29. package/dist/branding.js +26 -59
  30. package/dist/byte-read-response.js +39 -0
  31. package/dist/call-admission.js +12 -16
  32. package/dist/catalog-cache.js +739 -0
  33. package/dist/catalog-drift.d.ts +50 -15
  34. package/dist/catalog-drift.js +365 -128
  35. package/dist/catalog-fingerprint.js +2 -4
  36. package/dist/catalog-freshness.js +13 -0
  37. package/dist/catalog-limits.js +2 -2
  38. package/dist/catalog-service.js +409 -225
  39. package/dist/catalog.js +43 -84
  40. package/dist/concurrency.js +3 -4
  41. package/dist/config-defaults.d.ts +39 -0
  42. package/dist/config-defaults.js +46 -0
  43. package/dist/config-schema.d.ts +181 -0
  44. package/dist/config-schema.js +435 -0
  45. package/dist/config-value-sources.js +102 -0
  46. package/dist/config.d.ts +633 -0
  47. package/dist/config.js +508 -0
  48. package/dist/connector-access.d.ts +1 -0
  49. package/dist/connector-access.js +13 -15
  50. package/dist/connector-caller.d.ts +8 -0
  51. package/dist/connector-caller.js +15 -6
  52. package/dist/connector-scope.js +1 -1
  53. package/dist/connectors/api-connector.d.ts +59 -7
  54. package/dist/connectors/api-connector.js +106 -19
  55. package/dist/connectors/api.js +4 -1
  56. package/dist/connectors/guarded-fetch.d.ts +144 -0
  57. package/dist/connectors/guarded-fetch.js +87 -38
  58. package/dist/connectors/negotiation-cache.js +46 -0
  59. package/dist/connectors/option-shapes.js +27 -0
  60. package/dist/connectors/remote-mcp.d.ts +30 -4
  61. package/dist/connectors/remote-mcp.js +1774 -320
  62. package/dist/connectors/resource-uri.js +335 -0
  63. package/dist/credential-contract.d.ts +10 -0
  64. package/dist/credential-rules.js +1 -3
  65. package/dist/credential-url.js +108 -0
  66. package/dist/credentials.d.ts +6 -1
  67. package/dist/credentials.js +27 -18
  68. package/dist/d1.d.ts +130 -0
  69. package/dist/d1.js +290 -0
  70. package/dist/describe-config.d.ts +165 -0
  71. package/dist/describe-config.js +315 -0
  72. package/dist/described.js +106 -0
  73. package/dist/downstream-input-context.js +128 -0
  74. package/dist/downstream-input.js +325 -0
  75. package/dist/errors.d.ts +132 -31
  76. package/dist/errors.js +175 -87
  77. package/dist/execute.js +798 -318
  78. package/dist/executor-admission.d.ts +1 -0
  79. package/dist/executor-admission.js +11 -15
  80. package/dist/executor-contract.d.ts +20 -0
  81. package/dist/executor-contract.js +48 -0
  82. package/dist/executor-result.js +30 -13
  83. package/dist/executors/quickjs-child.js +15 -9
  84. package/dist/executors/quickjs-protocol.js +5 -6
  85. package/dist/executors/quickjs-runtime.js +152 -59
  86. package/dist/executors/quickjs.js +49 -39
  87. package/dist/favicon.js +1 -2
  88. package/dist/fix-prompt.js +1 -3
  89. package/dist/guest-runtime.js +238 -0
  90. package/dist/guest-types.d.ts +218 -0
  91. package/dist/guest-types.js +1 -0
  92. package/dist/html-security.js +24 -0
  93. package/dist/identity.js +1 -3
  94. package/dist/inbound-credential.js +52 -0
  95. package/dist/index.d.ts +24 -256
  96. package/dist/index.js +65 -478
  97. package/dist/invocation-auth.js +69 -0
  98. package/dist/invocation.js +262 -79
  99. package/dist/json-schema.d.ts +1 -1
  100. package/dist/mcp-client-context.js +35 -0
  101. package/dist/mcp-result.js +11 -7
  102. package/dist/meta-output.js +61 -0
  103. package/dist/meta-tool-names.d.ts +2 -0
  104. package/dist/meta-tool-names.js +3 -0
  105. package/dist/meta-tools.js +419 -272
  106. package/dist/module-contracts.d.ts +8 -23
  107. package/dist/node.d.ts +0 -2
  108. package/dist/node.js +2 -2
  109. package/dist/oauth-callback-outcome.js +1 -3
  110. package/dist/oauth-handoff.js +194 -0
  111. package/dist/oauth-sealing.js +20 -0
  112. package/dist/operator-record.d.ts +137 -0
  113. package/dist/operator-record.js +420 -0
  114. package/dist/operator-ui/assets.js +31 -0
  115. package/dist/operator-ui/contract.d.ts +72 -0
  116. package/dist/operator-ui/contract.js +1 -0
  117. package/dist/operator-ui/fix-prompts.d.ts +18 -0
  118. package/dist/operator-ui/generated.js +5 -4
  119. package/dist/operator-ui/model.d.ts +12 -87
  120. package/dist/operator-ui/model.js +2 -9
  121. package/dist/operator-ui/setup-commands.js +1 -3
  122. package/dist/operator-ui/view.d.ts +323 -0
  123. package/dist/operator-ui/view.js +62 -189
  124. package/dist/page-styles.js +2 -3
  125. package/dist/program-result.js +5 -0
  126. package/dist/program-source.js +14 -2
  127. package/dist/{exempt-writes.js → program-writes.js} +60 -19
  128. package/dist/provider.d.ts +142 -0
  129. package/dist/provider.js +187 -0
  130. package/dist/providers/_shared/google/result-size.js +57 -0
  131. package/dist/providers/_shared/google/service-account.d.ts +58 -0
  132. package/dist/providers/_shared/google/service-account.js +500 -0
  133. package/dist/providers/_shared/google/workspace.d.ts +276 -0
  134. package/dist/providers/_shared/google/workspace.js +518 -0
  135. package/dist/providers/_shared/request-token.js +83 -0
  136. package/dist/providers/{basecamp.d.ts → basecamp/index.d.ts} +6 -28
  137. package/dist/providers/basecamp/index.js +997 -0
  138. package/dist/providers/basecamp/skill.generated.js +9 -0
  139. package/dist/providers/{breeze.d.ts → breeze/index.d.ts} +2 -2
  140. package/dist/providers/{breeze.js → breeze/index.js} +184 -140
  141. package/dist/providers/breeze/skill.generated.js +9 -0
  142. package/dist/providers/{ccb.d.ts → ccb/index.d.ts} +2 -2
  143. package/dist/providers/{ccb.js → ccb/index.js} +271 -116
  144. package/dist/providers/ccb/skill.generated.js +9 -0
  145. package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
  146. package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
  147. package/dist/providers/cloudflare/skill.generated.js +10 -0
  148. package/dist/providers/docs/index.d.ts +54 -0
  149. package/dist/providers/docs/index.js +1237 -0
  150. package/dist/providers/docs/skill.generated.js +9 -0
  151. package/dist/providers/drive/index.d.ts +53 -0
  152. package/dist/providers/drive/index.js +1523 -0
  153. package/dist/providers/drive/skill.generated.js +9 -0
  154. package/dist/providers/forms/index.d.ts +54 -0
  155. package/dist/providers/forms/index.js +1217 -0
  156. package/dist/providers/forms/skill.generated.js +11 -0
  157. package/dist/providers/github/auth.d.ts +32 -0
  158. package/dist/providers/github/auth.js +361 -0
  159. package/dist/providers/github/hosted.js +218 -0
  160. package/dist/providers/github/index.d.ts +13 -0
  161. package/dist/providers/github/index.js +140 -0
  162. package/dist/providers/github/key.js +100 -0
  163. package/dist/providers/github/rest.js +321 -0
  164. package/dist/providers/github/scope.d.ts +29 -0
  165. package/dist/providers/github/scope.js +124 -0
  166. package/dist/providers/github/skill.generated.js +8 -0
  167. package/dist/providers/gmail/index.d.ts +51 -0
  168. package/dist/providers/gmail/index.js +1436 -0
  169. package/dist/providers/gmail/skill.generated.js +9 -0
  170. package/dist/providers/infisical/index.d.ts +7 -0
  171. package/dist/providers/infisical/index.js +713 -0
  172. package/dist/providers/infisical/skill.generated.js +8 -0
  173. package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
  174. package/dist/providers/linear/index.js +352 -0
  175. package/dist/providers/linear/skill.generated.js +8 -0
  176. package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
  177. package/dist/providers/mixpanel/index.js +416 -0
  178. package/dist/providers/mixpanel/skill.generated.js +9 -0
  179. package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
  180. package/dist/providers/{notion.js → notion/index.js} +226 -239
  181. package/dist/providers/notion/skill.generated.js +10 -0
  182. package/dist/providers/{overflow.d.ts → overflow/index.d.ts} +2 -2
  183. package/dist/providers/{overflow.js → overflow/index.js} +74 -111
  184. package/dist/providers/overflow/skill.generated.js +8 -0
  185. package/dist/providers/{planning-center.d.ts → planning-center/index.d.ts} +2 -2
  186. package/dist/providers/{planning-center.js → planning-center/index.js} +264 -104
  187. package/dist/providers/planning-center/skill.generated.js +10 -0
  188. package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
  189. package/dist/providers/revenuecat/index.js +557 -0
  190. package/dist/providers/revenuecat/skill.generated.js +11 -0
  191. package/dist/providers/sheets/index.d.ts +54 -0
  192. package/dist/providers/sheets/index.js +1237 -0
  193. package/dist/providers/sheets/skill.generated.js +10 -0
  194. package/dist/providers/slides/index.d.ts +53 -0
  195. package/dist/providers/slides/index.js +2645 -0
  196. package/dist/providers/slides/skill.generated.js +9 -0
  197. package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
  198. package/dist/providers/stripe/index.js +266 -0
  199. package/dist/providers/stripe/skill.generated.js +11 -0
  200. package/dist/providers/{tithely.d.ts → tithely/index.d.ts} +2 -2
  201. package/dist/providers/{tithely.js → tithely/index.js} +60 -91
  202. package/dist/providers/tithely/skill.generated.js +8 -0
  203. package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
  204. package/dist/providers/vercel/index.js +1038 -0
  205. package/dist/providers/vercel/mcp-ownership.js +212 -0
  206. package/dist/providers/vercel/skill.generated.js +11 -0
  207. package/dist/registry.d.ts +110 -171
  208. package/dist/registry.js +588 -927
  209. package/dist/request-state.js +21 -0
  210. package/dist/resource-read.js +103 -0
  211. package/dist/result-shapes.js +17 -49
  212. package/dist/retired-toolkits.js +1 -1
  213. package/dist/routes/access-tokens.js +3 -6
  214. package/dist/routes/activity-context.js +21 -0
  215. package/dist/routes/activity-disclosure.js +40 -0
  216. package/dist/routes/activity.js +59 -21
  217. package/dist/routes/actor-labels.js +3 -50
  218. package/dist/routes/connect.js +221 -0
  219. package/dist/routes/credentials.js +15 -27
  220. package/dist/routes/mcp.js +365 -130
  221. package/dist/routes/oauth-client-metadata.js +15 -0
  222. package/dist/routes/oauth-management.js +45 -107
  223. package/dist/routes/oauth.js +110 -57
  224. package/dist/routes/operator.js +3 -3
  225. package/dist/routes/shared.d.ts +25 -64
  226. package/dist/routes/shared.js +160 -80
  227. package/dist/routes/skills.js +30 -0
  228. package/dist/routes/ui-config.js +225 -0
  229. package/dist/routes/ui-data.js +40 -35
  230. package/dist/routes/ui.js +66 -56
  231. package/dist/runtime/admission.js +4 -2
  232. package/dist/runtime/call-admission.js +3 -1
  233. package/dist/runtime/connector-scope.js +1 -4
  234. package/dist/runtime/run.js +10 -39
  235. package/dist/runtime/services.js +12 -117
  236. package/dist/runtime/shared-read.js +1 -3
  237. package/dist/runtime/storage.js +8 -1
  238. package/dist/sent-secrets.d.ts +93 -0
  239. package/dist/sent-secrets.js +1013 -0
  240. package/dist/server.js +28 -71
  241. package/dist/skills.js +416 -174
  242. package/dist/sqlite.d.ts +48 -0
  243. package/dist/sqlite.js +181 -0
  244. package/dist/storage/keys.js +443 -0
  245. package/dist/storage/memory.js +16 -4
  246. package/dist/storage/sql.d.ts +66 -0
  247. package/dist/storage/sql.js +543 -0
  248. package/dist/timeout.js +4 -2
  249. package/dist/tool-name.js +17 -0
  250. package/dist/tool-safety.d.ts +9 -35
  251. package/dist/tool-safety.js +20 -40
  252. package/dist/types.d.ts +336 -56
  253. package/dist/types.js +0 -1
  254. package/dist/ui.d.ts +7 -19
  255. package/dist/ui.js +76 -90
  256. package/dist/url-safety.js +3 -6
  257. package/dist/usage-guide.js +146 -0
  258. package/dist/validate.d.ts +7 -0
  259. package/dist/validate.js +309 -47
  260. package/dist/version.d.ts +1 -7
  261. package/dist/version.js +3 -7
  262. package/dist/worker.d.ts +11 -0
  263. package/dist/worker.js +435 -0
  264. package/documentation/README.md +63 -0
  265. package/documentation/architecture.md +696 -231
  266. package/documentation/auth.md +1069 -546
  267. package/documentation/code-mode.md +662 -356
  268. package/documentation/deploying.md +146 -0
  269. package/documentation/integrating.md +159 -0
  270. package/documentation/meta-tools.md +570 -216
  271. package/documentation/operating.md +135 -0
  272. package/documentation/operator-tests.md +97 -0
  273. package/documentation/operator-ui.md +132 -0
  274. package/documentation/provider-migration-0.29.md +65 -0
  275. package/examples/worker/AGENTS.md +34 -12
  276. package/examples/worker/README.md +293 -255
  277. package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
  278. package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
  279. package/examples/worker/src/connecta.config.ts +151 -0
  280. package/examples/worker/src/index.ts +14 -197
  281. package/examples/worker/wrangler.jsonc +15 -35
  282. package/package.json +126 -54
  283. package/templates/node/.dockerignore +1 -2
  284. package/templates/node/.env.example +20 -21
  285. package/templates/node/AGENTS.md +21 -17
  286. package/templates/node/Dockerfile +3 -5
  287. package/templates/node/README.md +140 -58
  288. package/templates/node/docker-compose.yml +11 -12
  289. package/templates/node/package.json +4 -2
  290. package/templates/node/src/connecta.config.ts +119 -0
  291. package/templates/node/src/index.ts +9 -154
  292. package/templates/node/src/provision-token.ts +17 -0
  293. package/AGENTS.md +0 -170
  294. package/dist/artifacts/connector.d.ts +0 -58
  295. package/dist/artifacts/connector.js +0 -730
  296. package/dist/artifacts/document.js +0 -86
  297. package/dist/artifacts/guide.js +0 -140
  298. package/dist/artifacts/html-scan.js +0 -329
  299. package/dist/artifacts/json.js +0 -78
  300. package/dist/artifacts/kv-store.d.ts +0 -20
  301. package/dist/artifacts/kv-store.js +0 -140
  302. package/dist/artifacts/markdown.js +0 -478
  303. package/dist/artifacts/module.d.ts +0 -37
  304. package/dist/artifacts/module.js +0 -66
  305. package/dist/artifacts/operations.d.ts +0 -197
  306. package/dist/artifacts/operations.js +0 -1002
  307. package/dist/artifacts/refresh.d.ts +0 -55
  308. package/dist/artifacts/refresh.js +0 -236
  309. package/dist/artifacts/routes.js +0 -206
  310. package/dist/artifacts/types.d.ts +0 -214
  311. package/dist/artifacts/types.js +0 -22
  312. package/dist/artifacts/validate.d.ts +0 -62
  313. package/dist/artifacts/validate.js +0 -651
  314. package/dist/artifacts.d.ts +0 -6
  315. package/dist/artifacts.js +0 -9
  316. package/dist/auth/bearer.d.ts +0 -11
  317. package/dist/auth/bearer.js +0 -50
  318. package/dist/providers/basecamp.js +0 -445
  319. package/dist/providers/linear.js +0 -217
  320. package/dist/providers/mixpanel.js +0 -247
  321. package/dist/providers/revenuecat.js +0 -317
  322. package/dist/providers/stripe.js +0 -253
  323. package/dist/providers/vercel.js +0 -1253
  324. package/dist/storage/file.d.ts +0 -15
  325. package/dist/storage/file.js +0 -455
  326. package/ethos.md +0 -93
  327. package/examples/worker/src/cloudflare-kv.ts +0 -43
  328. package/examples/worker/src/d1-activity-row.ts +0 -155
  329. package/examples/worker/src/d1-activity.ts +0 -147
  330. package/examples/worker/src/d1-storage.ts +0 -138
  331. package/examples/worker/src/r2-artifact-blobs.ts +0 -29
  332. package/templates/node/src/file-activity.ts +0 -182
@@ -1,7 +1,6 @@
1
+ import type { CatalogDriftActivityContext } from "./activity.js";
1
2
  import type { CredentialVault } from "./credential-contract.js";
2
- import type { CatalogDriftReport, Connector, ConnectorContext, ConnectorStatus, KVStorage, Logger, ToolDef } from "./types.js";
3
- import { type DeferredWork } from "./connector-scope.js";
4
- import { type CatalogDriftActivityContext } from "./activity.js";
3
+ import type { Connector, ConnectorContext, ConnectorStatus, KVStorage, Logger, ToolDef } from "./types.js";
5
4
  import { type CallAdmissionPermit, type ConnectorCallAdmissionSnapshot } from "./call-admission.js";
6
5
  import { type ConnectorCaller } from "./connector-caller.js";
7
6
  /**
@@ -26,7 +25,7 @@ export declare const MIN_MAX_RESULT_BYTES = 1;
26
25
  /**
27
26
  * The one definition of a usable `maxResultBytes`: a finite whole number of at
28
27
  * least {@link MIN_MAX_RESULT_BYTES} bytes. Shared by all three intake points
29
- * — `calls.maxResultBytes`, the per-connector override, and `get_result`'s
28
+ * — `calls.maxResultBytes`, the per-connector override, and `connecta.result`'s
30
29
  * `maxBytes` argument — so a value that is valid at one is valid at all.
31
30
  *
32
31
  * Everything else is rejected rather than coerced, because each rejected shape
@@ -38,14 +37,17 @@ export declare const MIN_MAX_RESULT_BYTES = 1;
38
37
  export declare function isValidMaxResultBytes(value: number): boolean;
39
38
  /**
40
39
  * Resolve a configured cap against the value it inherits, dropping anything
41
- * `isValidMaxResultBytes` rejects. Operator-facing surfaces pair this with a
42
- * startup warning (see `Registry.checkResultCaps`) so the fallback is never
43
- * silent; the resolution itself stays total so no call site has to cope with
44
- * a broken cap.
40
+ * `isValidMaxResultBytes` rejects. Construction already refuses an unusable
41
+ * cap (`Registry.assertResultCaps`); the resolution stays total so no call
42
+ * site has to cope with a broken one.
45
43
  */
46
44
  export declare function resolveMaxResultBytes(value: number | undefined, inherited: number): number;
47
45
  export interface RegistryOptions {
46
+ publicUrl?: string | undefined;
47
+ oauthClientName?: string | undefined;
48
+ classification?: Readonly<Record<string, Readonly<Record<string, "read" | "write">>>> | undefined;
48
49
  storage: KVStorage;
50
+ catalogStorage?: KVStorage;
49
51
  logger: Logger;
50
52
  credentialVault?: CredentialVault | undefined;
51
53
  credentialUi?: boolean | undefined;
@@ -53,33 +55,22 @@ export interface RegistryOptions {
53
55
  credentialOwner?: string | undefined;
54
56
  /** Internal child registries skip deployment-wide construction warnings. */
55
57
  constructionChecks?: boolean | undefined;
58
+ catalogDriftActivity?: Omit<CatalogDriftActivityContext, "logger"> | undefined;
56
59
  toolCacheTtlSeconds?: number | undefined;
57
- persistToolCatalog?: boolean | undefined;
58
- toolCatalogStaleSeconds?: number | undefined;
60
+ catalogMinTtlSeconds?: number | undefined;
61
+ catalogMaxTtlSeconds?: number | undefined;
59
62
  /**
60
- * Cap on inline result size before truncation + get_result paging. Must be a
61
- * whole number of bytes >= 1; anything else warns at startup and falls back
62
- * to the default 24_000.
63
+ * Cap on inline result size before truncation + connecta.result paging. Must be a
64
+ * whole number of bytes >= 1; anything else throws at construction. Default
65
+ * 24_000.
63
66
  */
64
67
  maxResultBytes?: number | undefined;
65
68
  results?: {
66
69
  maxStashBytes?: number;
67
70
  maxStashEntries?: number;
68
71
  } | undefined;
69
- /**
70
- * Where payload-free catalog-drift observations go. Present only when the
71
- * deployment configured an activity store; drift is reported through
72
- * connector status either way.
73
- */
74
- catalogDriftActivity?: Omit<CatalogDriftActivityContext, "logger"> | undefined;
75
- }
76
- export type ConnectorOperationOptions = Pick<ConnectorContext, "signal" | "timeoutMs">;
77
- /** Agent-only catalog behavior. This never enters a ConnectorContext. */
78
- export interface CatalogReadOptions {
79
- defer?: DeferredWork;
80
- /** Fresh deadline for a deferred refresh; never an inbound signal. */
81
- refreshTimeoutMs: number;
82
72
  }
73
+ export type ConnectorOperationOptions = Pick<ConnectorContext, "signal" | "timeoutMs" | "defer">;
83
74
  /**
84
75
  * The registry surface a per-connection MCP server consumes: every meta-tool
85
76
  * (`src/meta-tools.ts`) and the `execute_code` sandbox bridge (`src/execute.ts`)
@@ -89,17 +80,28 @@ export interface CatalogReadOptions {
89
80
  * consume registry behavior without depending on the concrete implementation
90
81
  * or its construction-only methods.
91
82
  */
83
+ /** Host-admitted identity and endpoint bindings for result paging. */
84
+ export interface ResultIdentity {
85
+ subject: string | null;
86
+ principal: string | null;
87
+ endpoint: string;
88
+ origin: string | null;
89
+ }
92
90
  export interface RegistryView {
93
91
  credentialUiAvailable(): boolean;
94
92
  /** Deployment-wide result-size cap threaded to the meta-tools. */
95
93
  readonly maxResultBytes: number;
96
94
  listConnectors(): Connector[];
95
+ /** Whole-connector permission for downstream skill files, which have no tool grants. */
96
+ canReadConnectorSkills(id: string): boolean;
97
97
  getConnector(id: string): Connector | undefined;
98
+ /** Only whole-connector grants authorize resource reads. */
99
+ getResourceConnector(id: string): Connector | undefined;
98
100
  resolveAddress(address: string): {
99
101
  connector: Connector;
100
102
  toolName: string;
101
103
  } | null;
102
- getTools(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions, readOptions?: CatalogReadOptions): Promise<ToolDef[]>;
104
+ getTools(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): Promise<ToolDef[]>;
103
105
  contextFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): ConnectorContext;
104
106
  /** Acquire the connector's shared downstream-call permit. */
105
107
  admitCall(id: string, input: {
@@ -108,18 +110,23 @@ export interface RegistryView {
108
110
  signal?: AbortSignal;
109
111
  }): Promise<CallAdmissionPermit>;
110
112
  resultsStorage(): KVStorage;
111
- /** Reserve runtime-wide capacity before writing a paging envelope's chunks. */
112
- stashResult(key: string, chunks: readonly string[], ttlSeconds: number): Promise<boolean>;
113
+ resultIdentity(): ResultIdentity;
114
+ /** Recheck live auth/grants and pool admission before exposing stored data. */
115
+ recheckResultAccess(address: string | undefined, classification: "read" | "write", signal?: AbortSignal, access?: "catalog"): Promise<boolean>;
116
+ /** Reserve deployment-wide capacity before writing a paging envelope's chunks. */
117
+ stashResult(id: string, chunks: readonly string[], ttlSeconds: number): Promise<boolean>;
113
118
  /** Local declared-vs-stored credential mismatch, with no downstream I/O. */
114
119
  credentialDriftFor(id: string): Promise<string | undefined>;
115
120
  /** Value-free shape learned from successful calls, never a provider declaration. */
116
121
  observedOutputSchema(connectorId: string, definition: ToolDef): ToolDef["outputSchema"] | undefined;
117
122
  /** Passively learn one successful unwrapped result; failures stay isolated. */
118
123
  observeOutputShape(connectorId: string, definition: ToolDef, value: unknown): void;
124
+ /** Age of the complete cached catalog; null for static or unobserved catalogs. */
125
+ catalogAgeMs(id: string): number | null;
119
126
  statusFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): Promise<ConnectorStatus>;
120
127
  invalidateStored(id: string): Promise<void>;
121
- /** Bind returned OAuth state to this view's personal storage partition. */
122
- bindOAuthHandoff(id: string, authorizationUrl: string): Promise<void>;
128
+ /** Bind returned OAuth state to its initiating user for either owner scope. */
129
+ bindOAuthHandoff(id: string, authorizationUrl: string, principalKey?: string): Promise<void>;
123
130
  }
124
131
  /**
125
132
  * Connector id → the only tool names this view may see on it. A connector
@@ -133,42 +140,37 @@ export interface RegistryScope {
133
140
  guardedToolAccess?: ToolAccess;
134
141
  subjectKey?: string;
135
142
  principalKey?: string;
143
+ endpoint?: string;
144
+ origin?: string | null;
145
+ currentResultAccess?: (address: string | undefined, classification: "read" | "write", signal?: AbortSignal, access?: "catalog") => Promise<boolean>;
136
146
  /** The admitted caller, readable only by built-in connectors; see connector-caller.ts. */
137
147
  caller?: ConnectorCaller;
138
148
  }
139
149
  /**
140
- * Holds the connector set, resolves addresses, and caches per-connector tool
141
- * lists in memory with a TTL. Connector failures are isolated: a broken
150
+ * Holds the connector set, resolves addresses, and coalesces tool listings
151
+ * within one request. Remote MCP clients own persisted response caching. Connector failures are isolated: a broken
142
152
  * connector surfaces status "error"; the rest keep working.
143
153
  */
144
154
  export declare class Registry implements RegistryView {
145
155
  private readonly opts;
146
156
  private readonly connectors;
147
157
  private readonly callAdmission;
148
- private readonly cache;
149
- private readonly invalidated;
150
- /** Per-connector epoch preventing a pre-invalidation refresh from publishing. */
151
- private readonly catalogGenerations;
152
- /** Serialize persisted catalog set/delete operations within this isolate. */
153
- private readonly catalogMutations;
154
- /** Same-request cold loads share one read without retaining the request.
155
- * See documentation/architecture.md#the-two-lifetimes. */
158
+ /** Coalesce listings only within one request and authorization partition. */
156
159
  private readonly requestCatalogLoads;
157
- /** One live refresh per connector across agent and operator requests. */
158
- private readonly catalogRefreshes;
160
+ private readonly catalogObservedAt;
159
161
  /** Last payload-free agent catalog access in this runtime. */
160
162
  private readonly catalogAccess;
161
- /** Last drift counts reported to activity, per connector, in this runtime. */
162
- private readonly reportedDrift;
163
+ /** Count-only intake findings, including catalogs loaded from storage. */
164
+ private droppedToolNames;
165
+ /**
166
+ * Schema digest verification per reviewed facts array. Only the registry's
167
+ * own deep-frozen arrays are keys, so an entry stays true while they live.
168
+ */
169
+ private readonly verifiedFacts;
163
170
  private readonly observedOutputSchemas;
164
- private readonly ttlMs;
165
- private readonly staleMs;
166
- private readonly persistToolCatalog;
167
171
  /** Result-size guard cap threaded to the meta-tools. */
168
172
  readonly maxResultBytes: number;
169
- /** Only keys, byte counts, and expiry survive requests; never write promises. */
170
- private readonly resultStash;
171
- private resultStashBytes;
173
+ private readonly classification;
172
174
  private readonly configuredConnectors;
173
175
  private readonly personalRegistries;
174
176
  private readonly oauthPartition;
@@ -187,22 +189,20 @@ export declare class Registry implements RegistryView {
187
189
  * cannot check it, and a catalog that drifts later cannot widen a grant.
188
190
  */
189
191
  noteAbsentGrant(connectorId: string, toolName: string): void;
190
- private oauthHandoffKey;
191
192
  storeOAuthHandoff(connectorId: string, state: string, principalKey: string): Promise<void>;
192
193
  oauthCallbackView(connectorId: string, state: string | null): Promise<{
193
194
  registry: RegistryView;
194
195
  principalKey?: string;
195
196
  } | null>;
196
- clearOAuthHandoff(connectorId: string, state: string | null): Promise<void>;
197
+ consumeOAuthHandoff(connectorId: string, state: string | null, principalKey: string): Promise<boolean>;
197
198
  /**
198
- * Warn once per unusable result cap, at construction time — the same
199
- * "runs fine but is surely unintended" channel as the insecure-config
200
- * warnings in `createConnecta`. A rejected cap can't be honoured, and
201
- * honouring it *approximately* is exactly the inversion issue #32 is about,
202
- * so the value is dropped in favour of what it inherits and the operator is
203
- * told which one is actually in force.
199
+ * Refuse an unusable result cap at construction, like every other
200
+ * structural mistake (INV-11). A rejected cap can't be honoured, and
201
+ * honouring it *approximately* is exactly the inversion issue #32 is about;
202
+ * falling back with a warning let a deployment boot on a value nobody
203
+ * chose.
204
204
  */
205
- private checkResultCaps;
205
+ private assertResultCaps;
206
206
  /**
207
207
  * Warn once per convention violation at construction time. Static only —
208
208
  * never calls listTools() (remote connectors are lazy/network); tool-level
@@ -211,7 +211,9 @@ export declare class Registry implements RegistryView {
211
211
  private checkConventions;
212
212
  listConnectors(): Connector[];
213
213
  getConnector(id: string): Connector | undefined;
214
- contextFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): ConnectorContext;
214
+ getResourceConnector(id: string): Connector | undefined;
215
+ canReadConnectorSkills(id: string): boolean;
216
+ contextFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions, scope?: RegistryScope): ConnectorContext;
215
217
  admitCall(id: string, input: {
216
218
  toolName: string;
217
219
  args: unknown;
@@ -220,48 +222,41 @@ export declare class Registry implements RegistryView {
220
222
  /** Connector totals across root and personal controllers; health removes ids. */
221
223
  callAdmissionSnapshot(): Record<string, ConnectorCallAdmissionSnapshot>;
222
224
  /**
223
- * Payload-free drift counts for the open health endpoint, so `connecta
224
- * doctor` can report a stale allowlist without asking any downstream
225
- * anything. Only connectors that ship a vetted manifest *and* have already
226
- * served a refresh *in this runtime* appear — a process or isolate that has
227
- * answered no catalog request yet honestly reports nothing, and drift is not
228
- * persisted the way the catalog itself is.
229
- *
230
- * Every report is rebuilt by {@link boundedCatalogDrift} on the way out:
231
- * `Connector.catalogDrift()` is the open plugin seam, and this snapshot is
232
- * serialized into an unauthenticated response.
225
+ * The drift a connector last showed in this runtime: the registry's own
226
+ * observation against a connector's `classification`, otherwise whatever
227
+ * the connector's `catalogDrift()` seam reports, bounded either way.
233
228
  */
234
- catalogDriftSnapshot(): Record<string, CatalogDriftReport>;
235
- /**
236
- * Turn the observation a refresh just took into at most one activity event.
237
- *
238
- * Emitted on change rather than on every refresh: an identical report every
239
- * TTL is a heartbeat, not news, and the current counts are already on
240
- * connector status. A first observation that is clean is not an event
241
- * either — nothing moved — but a later return to clean is, because "the
242
- * drift is gone" is exactly what an operator watching the timeline is
243
- * waiting for.
244
- */
245
- private observeCatalogDrift;
229
+ private catalogDriftOf;
246
230
  /** Reject queued/future downstream admission; active permits release safely. */
247
231
  closeCallAdmission(): void;
248
232
  /**
249
- * Reserve capacity and write one ASCII paging envelope in this runtime.
233
+ * Reserve capacity and write one ASCII paging envelope.
234
+ *
235
+ * `chunks[n]` lands on `resultKeys.chunk(id, n)` inside `partition` — the
236
+ * layout connecta.result reads back, so a page fetches only the chunks it covers
237
+ * instead of the whole stored result (issue #540). Chunking is a read-cost
238
+ * decision, not a capacity one: however many keys an envelope occupies, it
239
+ * is one stash entry charged its total ASCII length.
250
240
  *
251
- * `chunks[0]` lands on `<prefix><key>` and `chunks[n]` on `<prefix><key>#<n>`
252
- * — the layout get_result reads back, so a page fetches only the chunks it
253
- * covers instead of the whole stored result (issue #540). Chunking is a
254
- * read-cost decision, not a capacity one: however many keys an envelope
255
- * occupies, it is one stash entry charged its total ASCII length.
241
+ * The bounds are the deployment's, not this isolate's. Every charge is a
242
+ * row in one ledger record in storage, booked by compare-and-set before any
243
+ * chunk is written, so every isolate and process sharing the store sees the
244
+ * same entries and bytes. A pending write keeps its finite charge reserved.
245
+ * Writes stop after 30 seconds; absolute chunk expiries cannot pass the
246
+ * booked deadline even on late commit. Rejected responses leave writes
247
+ * unconfirmed and retain their charge. Cleanup/release and settlement each
248
+ * stop waiting after 15 seconds. Storage TTL reclaims the rows.
256
249
  */
257
- stashResult(key: string, chunks: readonly string[], ttlSeconds: number, prefix?: string): Promise<boolean>;
250
+ stashResult(id: string, chunks: readonly string[], ttlSeconds: number, partition?: string): Promise<boolean>;
258
251
  /**
259
- * Storage namespaced to the meta-tool result store (`results:` prefix), kept
260
- * separate from any connector's `conn:<id>:` namespace. Backs get_result.
252
+ * Storage namespaced to the root result partition, kept separate from any
253
+ * connector's namespace. Backs connecta.result.
261
254
  */
255
+ resultIdentity(): ResultIdentity;
256
+ recheckResultAccess(_address: string | undefined, _classification: "read" | "write", _signal?: AbortSignal, _access?: "catalog"): Promise<boolean>;
262
257
  resultsStorage(): KVStorage;
263
258
  credentialUiAvailable(): boolean;
264
- bindOAuthHandoff(): Promise<void>;
259
+ bindOAuthHandoff(id: string, authorizationUrl: string, principalKey?: string): Promise<void>;
265
260
  observedOutputSchema(connectorId: string, definition: ToolDef): ToolDef["outputSchema"] | undefined;
266
261
  observeOutputShape(connectorId: string, definition: ToolDef, value: unknown): void;
267
262
  /** Resolve "<connectorId>.<toolName>" → connector + tool name. */
@@ -269,89 +264,33 @@ export declare class Registry implements RegistryView {
269
264
  connector: Connector;
270
265
  toolName: string;
271
266
  } | null;
272
- private catalogKey;
273
- private catalogChunkKey;
274
- private validCatalogTools;
275
- private validCatalogManifest;
276
- private parseCatalogManifest;
277
- private splitCatalogChunks;
278
- private readCatalog;
279
- private storeCatalog;
280
- private deleteCatalog;
281
- private catalogGeneration;
282
- private advanceCatalogGeneration;
267
+ /** Compare only the fingerprints accepted in this exact cache partition. */
268
+ private recordCatalogDrift;
269
+ private loadDownstreamTools;
270
+ /** The served catalog excludes control-character names; raw caches stay complete. */
271
+ private acceptToolNames;
272
+ /** Observe intake once, never while serving an older cached listing. */
273
+ private observeDroppedToolNames;
283
274
  /**
284
- * Keep this isolate's writes and invalidations ordered. Without the queue, an
285
- * old refresh can finish its storage.set after a credential change deletes
286
- * the catalog and resurrect the pre-change listing.
275
+ * One connector's catalog as served: the cached downstream facts, classified
276
+ * on every read by the connector's `classification`, into fresh objects.
277
+ * Safety is derived here and nowhere else, so no cache layer can carry a
278
+ * stale verdict — from an older review, an older release, or a stale
279
+ * fallback — and nothing a caller or decorator does to a served tool reaches
280
+ * the next read.
287
281
  */
288
- private enqueueCatalogMutation;
289
- private refreshToolsWithContext;
290
- /**
291
- * Whether a refresh may still enter the shared cache layers: its generation
292
- * is current, and the flight it runs in has been neither abandoned nor
293
- * outlived its bound. Asked at each publication point, since listing and
294
- * snapshotting both yield, and a late result must never overwrite the one a
295
- * fresh attempt published in the meantime.
296
- */
297
- private mayPublish;
298
- /**
299
- * Publish one shared refresh before starting its connector work. The first
300
- * caller owns the scope and signal, and the flight lives `boundMs` from now
301
- * at most; every later caller joins the result without gaining access to
302
- * that context. A flight found past its bound is abandoned here, and this
303
- * caller starts the fresh attempt.
304
- */
305
- private startCatalogRefresh;
306
- /**
307
- * Give up on a flight that outlived its bound. Later readers start a fresh
308
- * attempt, its joiners are told to, and nothing its owner lists from now on
309
- * reaches a cache. The owner's work is left alone: it belongs to another
310
- * request, which nothing here may reach into, and it can no longer publish.
311
- */
312
- private abandonCatalogRefresh;
313
- /**
314
- * Wait on another caller's flight, no longer than its bound. Succeeds with
315
- * its tools, or with `undefined` when it will not answer for this caller —
316
- * past its bound, when this waiter abandons it, or failed for its owner
317
- * alone — so the caller makes a fresh attempt. The timer is this waiter's
318
- * own: on workerd it is what keeps a request that waits on another alive,
319
- * and bounded.
320
- */
321
- private joinCatalogRefresh;
322
- /** Force a live listTools refresh and replace both catalog cache layers. */
323
- private refreshTools;
324
- private observeCatalogAccess;
325
- /**
326
- * Start or join one shared refresh. A newly deferred task owns its scope,
327
- * deadline, and teardown; no inbound signal or request scope crosses into it.
328
- */
329
- private deferCatalogRefresh;
330
- /** Cached listTools with in-memory + persisted serializable catalog layers. */
331
282
  private loadTools;
332
- /**
333
- * Coalesce one connector's catalog traversal inside one inbound request. The
334
- * WeakMap neither roots the request scope nor lets its connector context
335
- * escape into another request; settled entries are also removed eagerly.
336
- *
337
- * The read owns its signal, and each caller waits under its own: one that
338
- * is cancelled while others wait leaves with its own failure, and the read
339
- * is cancelled only when every caller has gone (src/runtime/shared-read.ts).
340
- *
341
- * The deployment-wide flight below this layer coalesces the actual live
342
- * refresh across requests. Its owner's context governs the listing, and its
343
- * owner's deadline bounds it; later callers join only its result, never its
344
- * request scope, and a failure that was the owner's alone sends them to a
345
- * fresh attempt rather than to them.
346
- */
347
- getTools(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions, readOptions?: CatalogReadOptions): Promise<ToolDef[]>;
283
+ private publishUnreviewedTool;
284
+ /** Construction-only view for the secret-free static config description. */
285
+ describeStaticTools(id: string): ToolDef[] | undefined;
286
+ private validateClassification;
287
+ getTools(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions, scope?: RegistryScope): Promise<ToolDef[]>;
348
288
  credentialDriftFor(id: string): Promise<string | undefined>;
289
+ /** Age of a complete cache entry; reads never refresh it. */
290
+ catalogAgeMs(id: string): number | null;
349
291
  /** Best-effort connector status for the operator UI. */
350
- statusFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions): Promise<ConnectorStatus>;
351
- private markCatalogInvalid;
352
- private deleteStoredCatalog;
353
- /** Drop a connector's cached tool list (e.g. after auth completes). */
292
+ statusFor(id: string, baseUrl: string, requestScope?: object, callOptions?: ConnectorOperationOptions, scope?: RegistryScope): Promise<ConnectorStatus>;
293
+ /** Rotate the storage generation; in-flight old readers cannot republish it. */
354
294
  invalidate(id: string): void;
355
- /** Drop both in-memory and persisted tool catalogs. */
356
295
  invalidateStored(id: string): Promise<void>;
357
296
  }