@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
package/dist/index.js CHANGED
@@ -1,232 +1,14 @@
1
- import { credentialTestRule, describeCredentialTestMismatch, } from "./credential-rules.js";
1
+ import { describeConfigSources } from "./config-value-sources.js";
2
+ import { credentialTestRule, describeCredentialTestMismatch } from "./credential-rules.js";
2
3
  import { Registry } from "./registry.js";
3
- import { intersectAccess, parseConnectorAccess, POOL_NAME_RE } from "./connector-access.js";
4
+ import { parseConnectorAccess, POOL_NAME_RE } from "./connector-access.js";
4
5
  import { createFetchHandler } from "./server.js";
5
- import { createExecuteTool, runClaimMs } from "./execute.js";
6
- import { droppedBrandingUrls, droppedThemeTokens, droppedUiAuthUrls, } from "./branding.js";
7
- import { memoryStorage } from "./storage/memory.js";
8
- import { CONNECTA_VERSION } from "./version.js";
9
- import { AdmissionController, executorName, isAdmittingExecutor, withExecutorAdmission, } from "./executor-admission.js";
10
- import { DEFAULT_MAX_WRITES } from "./exempt-writes.js";
11
- import { disposeEdgeRuntime } from "./runtime/run.js";
12
- import { NO_EXEMPTIONS } from "./tool-safety.js";
13
- import { createCoreRuntime, resolveLogger } from "./runtime/services.js";
14
- const REQUEST_ADMISSION_DEFAULTS = {
15
- concurrency: 16,
16
- maxQueueSize: 32,
17
- queueTimeoutMs: 5_000,
18
- retryAfterMs: 1_000,
19
- };
20
- const DEFAULT_REQUEST_MAX_DURATION_MS = 300_000;
21
- const CODE_ADMISSION_DEFAULTS = {
22
- concurrency: 2,
23
- maxQueueSize: 8,
24
- queueTimeoutMs: 5_000,
25
- retryAfterMs: 1_000,
26
- };
27
- function admissionController(options, defaults, maxDurationMs) {
28
- return new AdmissionController({
29
- concurrency: options?.concurrency ?? defaults.concurrency,
30
- maxQueueSize: options?.maxQueueSize ?? defaults.maxQueueSize,
31
- queueTimeoutMs: options?.queueTimeoutMs ?? defaults.queueTimeoutMs,
32
- retryAfterMs: options?.retryAfterMs ?? defaults.retryAfterMs,
33
- ...(maxDurationMs !== undefined ? { maxDurationMs } : {}),
34
- });
35
- }
36
- /** Bearer providers are checked before Clerk (per spec). */
37
- function normalizeAuth(auth) {
38
- const list = auth ? (Array.isArray(auth) ? auth : [auth]) : [];
39
- return [...list].sort((a, b) => {
40
- const rank = (x) => (x.kind === "bearer" ? 0 : 1);
41
- return rank(a) - rank(b);
42
- });
43
- }
44
- const admissionPoolSchema = {
45
- concurrency: null,
46
- maxQueueSize: null,
47
- queueTimeoutMs: null,
48
- retryAfterMs: null,
49
- };
50
- const requestAdmissionSchema = {
51
- ...admissionPoolSchema,
52
- maxDurationMs: null,
53
- };
54
- const CONFIG_SCHEMA = {
55
- connectors: null,
56
- auth: null,
57
- identity: {
58
- connectorAccess: null,
59
- activityAccess: null,
60
- credentialAdministration: null,
61
- personalConnection: null,
62
- accessTokenManagement: null,
63
- },
64
- pools: null,
65
- storage: null,
66
- publicUrl: null,
67
- allowedOrigins: null,
68
- activity: null,
69
- vault: null,
70
- ui: null,
71
- artifacts: null,
72
- accessTokens: null,
73
- artifactOrigin: null,
74
- discovery: {
75
- concurrency: null,
76
- catalogTtlSeconds: null,
77
- persistCatalog: null,
78
- staleCatalogSeconds: null,
79
- probeTimeoutMs: null,
80
- },
81
- results: {
82
- maxStashBytes: null,
83
- maxStashEntries: null,
84
- },
85
- calls: {
86
- defaultTimeoutMs: null,
87
- maxResultBytes: null,
88
- },
89
- execute: {
90
- maxEmittedBytes: null,
91
- maxEmittedBlocks: null,
92
- maxHostCalls: null,
93
- hostCallTimeoutMs: null,
94
- watchdogMs: null,
95
- maxWrites: null,
96
- approval: null,
97
- },
98
- admission: {
99
- requests: requestAdmissionSchema,
100
- code: admissionPoolSchema,
101
- },
102
- logger: null,
103
- serverInfo: {
104
- name: null,
105
- version: null,
106
- title: null,
107
- websiteUrl: null,
108
- icons: [
109
- {
110
- src: null,
111
- mimeType: null,
112
- sizes: null,
113
- },
114
- ],
115
- },
116
- deploymentInfo: null,
117
- executor: null,
118
- };
119
- function unknownOptionPaths(value, path, schema) {
120
- if (schema === null)
121
- return [];
122
- if (Array.isArray(schema)) {
123
- if (!Array.isArray(value))
124
- return [];
125
- return value.flatMap((entry, index) => unknownOptionPaths(entry, `${path}[${index}]`, schema[0]));
126
- }
127
- if (typeof value !== "object" || value === null)
128
- return [];
129
- const known = new Set(Object.keys(schema));
130
- const unknown = Reflect.ownKeys(value)
131
- .filter((key) => typeof key !== "string" || !known.has(key))
132
- .map((key) => `${path}.${String(key)}`)
133
- .sort();
134
- if (unknown.length > 0)
135
- return unknown;
136
- for (const [key, childSchema] of Object.entries(schema)) {
137
- unknown.push(...unknownOptionPaths(value[key], `${path}.${key}`, childSchema));
138
- }
139
- return unknown;
140
- }
141
- /** Pause-only options #672 removed with `resume_execution`. */
142
- const RETIRED_PAUSE_OPTIONS = [
143
- "ConnectaConfig.execute.resumableWrites",
144
- "ConnectaConfig.execute.pausedRunTtlSeconds",
145
- ];
146
- function rejectUnknownOptions(paths) {
147
- if (paths.length === 0)
148
- return;
149
- throw new Error(`Unknown Connecta configuration option${paths.length === 1 ? "" : "s"}:\n` +
150
- paths.map((path) => `- ${path}`).join("\n") +
151
- (paths.includes("ConnectaConfig.credentials") ? "\nUse vault: encryptedCredentialVault(storage, key) from @zackbart/connecta/credentials." : "") +
152
- (paths.includes("ConnectaConfig.branding") ? "\nMove branding into ui: operatorUi({ branding }) from @zackbart/connecta/ui." : "") +
153
- (paths.some((path) => RETIRED_PAUSE_OPTIONS.includes(path))
154
- ? "\nPrograms no longer pause at writes, so there is nothing to configure: execute_code runs read-only and config-exempt tools, and every other write goes through call_destructive_tool (issue #672). Delete the option."
155
- : ""));
156
- }
157
- /** Reject JavaScript typos and removed options before construction does work. */
158
- function assertKnownConfig(config) {
159
- rejectUnknownOptions(unknownOptionPaths(config, "ConnectaConfig", CONFIG_SCHEMA));
160
- if (config.results !== undefined) {
161
- if (!config.results || typeof config.results !== "object" || Array.isArray(config.results)) {
162
- throw new Error("ConnectaConfig.results must be an object");
163
- }
164
- for (const key of ["maxStashBytes", "maxStashEntries"]) {
165
- const value = config.results[key];
166
- if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {
167
- throw new Error(`ConnectaConfig.results.${key} must be a non-negative safe integer`);
168
- }
169
- }
170
- }
171
- if (config.vault && (["get", "getAll", "set", "setAll", "metadata", "delete"].some(key => typeof config.vault[key] !== "function") || ["seal", "open"].some(key => !["undefined", "function"].includes(typeof config.vault[key]))))
172
- throw new Error("ConnectaConfig.vault must implement CredentialVault");
173
- if (config.ui && (typeof config.ui.handle !== "function" || typeof config.ui.credentialHandoffUrl !== "function" || !Array.isArray(config.ui.reservedPaths)))
174
- throw new Error("ConnectaConfig.ui must be created with operatorUi(...)");
175
- const activity = config.activity;
176
- if (activity !== undefined &&
177
- (typeof activity !== "object" ||
178
- activity === null ||
179
- typeof activity.recordTool !== "function")) {
180
- throw new Error("ConnectaConfig.activity must be created with activityHistory(...)");
181
- }
182
- if (config.accessTokens !== undefined && (!config.accessTokens ||
183
- typeof config.accessTokens.auth?.authorize !== "function" ||
184
- config.accessTokens.auth.interactiveOperator ||
185
- typeof config.accessTokens.handle !== "function")) {
186
- throw new Error("ConnectaConfig.accessTokens must be created with accessTokens(storage) from @zackbart/connecta/auth/access-tokens; reuse your existing storage to preserve tokens");
187
- }
188
- const artifacts = config.artifacts;
189
- if (artifacts !== undefined) {
190
- const connector = artifacts?.connector;
191
- if (typeof artifacts !== "object" ||
192
- artifacts === null ||
193
- !connector ||
194
- connector.id !== "artifacts" ||
195
- typeof connector.callTool !== "function" ||
196
- typeof artifacts.handle !== "function") {
197
- throw new Error("ConnectaConfig.artifacts must be created with artifacts(...) from @zackbart/connecta/artifacts");
198
- }
199
- if (config.connectors?.some((candidate) => candidate?.id === "artifacts")) {
200
- throw new Error('Connector id "artifacts" is reserved by the artifacts module; rename ' +
201
- "your connector or drop the artifacts option");
202
- }
203
- if (!config.publicUrl) {
204
- throw new Error("ConnectaConfig.artifacts needs publicUrl: artifact links are shared " +
205
- "with teammates, so they must name the deployment's own origin, never " +
206
- "one taken from a request's Host header");
207
- }
208
- }
209
- if (config.artifactOrigin !== undefined) {
210
- if (!config.artifacts || !config.ui || !config.publicUrl) {
211
- throw new Error("ConnectaConfig.artifactOrigin needs artifacts, ui, and publicUrl");
212
- }
213
- if (typeof config.artifactOrigin !== "string") {
214
- throw new Error("ConnectaConfig.artifactOrigin must be an HTTPS origin");
215
- }
216
- let origin;
217
- try {
218
- origin = new URL(config.artifactOrigin);
219
- }
220
- catch {
221
- throw new Error("ConnectaConfig.artifactOrigin must be an HTTPS origin");
222
- }
223
- if (origin.protocol !== "https:" ||
224
- origin.toString() !== `${origin.origin}/` ||
225
- origin.origin === new URL(config.publicUrl).origin) {
226
- throw new Error("ConnectaConfig.artifactOrigin must be a distinct HTTPS origin");
227
- }
228
- }
229
- }
6
+ import { droppedBrandingUrls, droppedThemeTokens, droppedUiAuthUrls } from "./branding.js";
7
+ import { readConfig } from "./config.js";
8
+ import { describeConfig } from "./describe-config.js";
9
+ export { customExecutor } from "./executor-contract.js";
10
+ import { AdmissionController, executorName, isAdmittingExecutor, withExecutorAdmission } from "./executor-admission.js";
11
+ export { defineConfig } from "./config.js";
230
12
  /**
231
13
  * Validate declared pools against the connector set. Everything checkable at
232
14
  * construction throws here: a malformed name, an unparseable grant, an
@@ -238,27 +20,13 @@ function resolvePools(pools, registry) {
238
20
  const resolved = new Map();
239
21
  if (!pools)
240
22
  return resolved;
241
- if (typeof pools !== "object" || Array.isArray(pools)) {
242
- throw new Error("ConnectaConfig.pools must be an object keyed by pool name");
243
- }
23
+ // The schema has already refused a pool that is not an object, a missing or
24
+ // non-array `tools`, a non-function `grant`, and a misspelled key — a
25
+ // misspelled `grant` would otherwise boot as a deny-all pool.
244
26
  for (const [name, pool] of Object.entries(pools)) {
245
27
  if (!POOL_NAME_RE.test(name)) {
246
28
  throw new Error(`ConnectaConfig.pools: pool name "${name}" must match [a-z0-9_-]+`);
247
29
  }
248
- if (!pool || typeof pool !== "object" || !Array.isArray(pool.tools)) {
249
- throw new Error(`ConnectaConfig.pools.${name}: tools must be an array of connector ids or connector.tool addresses`);
250
- }
251
- if (pool.grant !== undefined && typeof pool.grant !== "function") {
252
- throw new Error(`ConnectaConfig.pools.${name}: grant must be a function`);
253
- }
254
- // A misspelled `grant` would otherwise boot as a deny-all pool with only a
255
- // per-request log line to say so; that is fail-closed, but the rule here
256
- // is that structural mistakes refuse to boot.
257
- for (const key of Object.keys(pool)) {
258
- if (key !== "tools" && key !== "grant") {
259
- throw new Error(`ConnectaConfig.pools.${name}: unknown option "${key}"`);
260
- }
261
- }
262
30
  let access;
263
31
  try {
264
32
  access = parseConnectorAccess(pool.tools);
@@ -284,92 +52,24 @@ function resolvePools(pools, registry) {
284
52
  }
285
53
  }
286
54
  }
287
- resolved.set(name, { access, grant: pool.grant ?? (() => false) });
55
+ resolved.set(name, { access, trust: pool.trust, grant: pool.grant ?? (() => false) });
288
56
  }
289
57
  return resolved;
290
58
  }
291
- /**
292
- * Validate `execute.approval` against the connector set, like the pools: a
293
- * malformed key or value, an unknown connector, and an `api()` address its
294
- * tools do not include all throw. Remote catalogs load lazily, so an address
295
- * on one is kept and simply never matches a tool it does not serve.
296
- */
297
- function resolveApprovalPolicy(approval, registry) {
298
- for (const connector of registry.listConnectors()) {
299
- if (connector.approval !== undefined && connector.approval !== "never") {
300
- throw new Error(`Connector "${connector.id}": approval must be "never" or omitted`);
301
- }
302
- }
303
- if (approval === undefined)
304
- return NO_EXEMPTIONS;
305
- if (!approval || typeof approval !== "object" || Array.isArray(approval)) {
306
- throw new Error("ConnectaConfig.execute.approval must be an object keyed by connector ids and connector.tool addresses");
307
- }
308
- const connectors = new Map();
309
- const tools = new Map();
310
- for (const [key, value] of Object.entries(approval)) {
311
- const where = `ConnectaConfig.execute.approval[${JSON.stringify(key)}]`;
312
- if (value !== "never" && value !== "ask") {
313
- throw new Error(`${where} must be "never" or "ask"`);
314
- }
315
- const dot = key.indexOf(".");
316
- const id = dot === -1 ? key : key.slice(0, dot);
317
- const tool = dot === -1 ? undefined : key.slice(dot + 1);
318
- if (!id || tool === "") {
319
- throw new Error(`${where}: keys are connector ids or connector.tool addresses`);
320
- }
321
- const connector = registry.getConnector(id);
322
- if (!connector)
323
- throw new Error(`${where}: unknown connector "${id}"`);
324
- if (tool === undefined) {
325
- connectors.set(id, value);
326
- continue;
327
- }
328
- if (connector.staticTools &&
329
- !connector.staticTools.some((candidate) => candidate.name === tool)) {
330
- throw new Error(`${where}: connector "${id}" has no tool "${tool}"`);
331
- }
332
- tools.set(key, value);
333
- }
334
- return { connectors, tools };
335
- }
336
- /** A positive whole number, or the default when the value is unusable. */
337
- function positiveWhole(value, fallback) {
338
- return typeof value === "number" && Number.isFinite(value) && value >= 1
339
- ? Math.trunc(value)
340
- : fallback;
341
- }
342
- /**
343
- * One-time construction warnings for deployment shapes that run fine but are
344
- * usually unintended. Warning-only — never throws and never changes behavior;
345
- * each deployment-wide condition emits at most one `logger.warn`, and each
346
- * per-connector condition at most one per connector it names.
347
- */
348
- function warnInsecureConfig(config, inboundAuth, logger) {
59
+ /** Construction warnings for valid but usually unintended deployment choices. */
60
+ function warnInsecureConfig(config) {
61
+ const { auth: inboundAuth, logger } = config;
349
62
  const oauthConnectors = config.connectors.filter((c) => c.finishAuth);
350
63
  const hasCredentialConnector = config.connectors.some((c) => c.credential);
351
64
  // Static API headers can carry secrets without declaring credential hooks.
352
65
  // Any configured connector warrants the open-deployment warning.
353
- if (inboundAuth.length === 0 &&
354
- (config.connectors.length > 0 || config.artifacts)) {
66
+ if (inboundAuth.length === 0 && config.connectors.length > 0) {
355
67
  logger.warn("[connecta] running with no inbound authentication: any caller can " +
356
68
  "invoke every shared connector. " +
357
69
  (hasCredentialConnector || oauthConnectors.length > 0
358
70
  ? "Configured credentials and downstream OAuth grants are exposed to those calls. "
359
71
  : "") +
360
- "Configure `auth` (for example bearerToken(...) or Clerk) to gate access.");
361
- }
362
- // Artifact pages mount inside the operator UI and open only for an
363
- // authenticated viewer; either missing leaves the connector with no page.
364
- if (config.artifacts && !config.ui) {
365
- logger.warn("[connecta] artifacts is configured without ui: agents can publish and " +
366
- "read artifacts, but there is no viewer, so their links answer 404. " +
367
- "Add ui: operatorUi() to serve artifact pages.");
368
- }
369
- else if (config.artifacts && inboundAuth.length === 0) {
370
- logger.warn("[connecta] artifacts is configured with no inbound authentication: " +
371
- "artifact pages refuse every request, because there is no team to " +
372
- "show them to. Configure `auth` to open them.");
72
+ "Configure Clerk, Cloudflare Access on Workers, or accessTokens(storage) to gate access.");
373
73
  }
374
74
  // Unset publicUrl with OAuth connectors: the downstream redirect_uri is
375
75
  // derived per-request from the attacker-influenced inbound Host header.
@@ -463,177 +163,68 @@ function warnInsecureConfig(config, inboundAuth, logger) {
463
163
  }
464
164
  }
465
165
  export function createConnecta(config) {
466
- assertKnownConfig(config);
467
- if (!config.executor) {
468
- throw new Error("ConnectaConfig.executor is required. Configure quickJsExecutor() from " +
469
- '"@zackbart/connecta/quickjs" on Node, or ' +
470
- "new DynamicWorkerExecutor({ loader: env.LOADER }) from " +
471
- '"@cloudflare/codemode" on Workers.');
472
- }
473
- const storage = config.storage ?? memoryStorage();
474
- const logger = resolveLogger(config.logger);
475
- const credentialVault = config.vault;
476
- const configuredAuth = normalizeAuth([
477
- ...(config.accessTokens ? [config.accessTokens.auth] : []),
478
- ...normalizeAuth(config.auth),
479
- ]);
480
- const serverInfo = {
481
- ...config.serverInfo,
482
- name: config.serverInfo?.name ?? "connecta",
483
- version: config.serverInfo?.version ?? CONNECTA_VERSION,
484
- };
485
- // The artifacts module contributes one prebuilt connector, appended like any
486
- // configured one: same catalog, invocation, admission, and activity.
487
- const connectors = config.artifacts
488
- ? [...config.connectors, config.artifacts.connector]
489
- : config.connectors;
490
- const registry = new Registry(connectors, {
166
+ // Every structural check runs here, before any work: what comes back is the
167
+ // configuration the deployment runs with, defaults applied once.
168
+ const { input, resolved } = readConfig(config);
169
+ const { logger } = resolved;
170
+ const storage = resolved.storage;
171
+ const registry = new Registry([...resolved.connectors], {
491
172
  storage,
492
173
  logger,
493
- credentialVault,
494
- credentialUi: Boolean(config.ui),
495
- catalogDriftActivity: config.activity?.store
174
+ publicUrl: resolved.publicUrl,
175
+ oauthClientName: resolved.serverInfo.name,
176
+ credentialVault: resolved.vault,
177
+ credentialUi: Boolean(resolved.ui),
178
+ catalogDriftActivity: resolved.activity?.store
496
179
  ? {
497
- sink: config.activity.store,
498
- recordDrift: config.activity.recordDrift,
499
- serverInfo,
500
- ...(config.activity.deploymentId !== undefined
501
- ? { deploymentId: config.activity.deploymentId }
502
- : {}),
180
+ sink: resolved.activity.store,
181
+ recordChange: resolved.activity.recordChange,
182
+ serverInfo: resolved.serverInfo,
183
+ ...(resolved.activity.deploymentId !== undefined ? { deploymentId: resolved.activity.deploymentId } : {}),
503
184
  }
504
185
  : undefined,
505
- toolCacheTtlSeconds: config.discovery?.catalogTtlSeconds,
506
- persistToolCatalog: config.discovery?.persistCatalog,
507
- toolCatalogStaleSeconds: config.discovery?.staleCatalogSeconds,
508
- maxResultBytes: config.calls?.maxResultBytes,
509
- results: config.results,
186
+ toolCacheTtlSeconds: resolved.discovery.catalogTtlSeconds,
187
+ catalogMinTtlSeconds: resolved.discovery.catalogMinTtlSeconds,
188
+ catalogMaxTtlSeconds: resolved.discovery.catalogMaxTtlSeconds,
189
+ maxResultBytes: resolved.calls.maxResultBytes,
190
+ results: resolved.results,
191
+ classification: resolved.classification,
510
192
  });
511
- const inboundAuth = configuredAuth;
512
- const pools = resolvePools(config.pools, registry);
513
- const approval = resolveApprovalPolicy(config.execute?.approval, registry);
514
- const maxWrites = positiveWhole(config.execute?.maxWrites, DEFAULT_MAX_WRITES);
515
- warnInsecureConfig(config, inboundAuth, logger);
516
- const requestAdmission = admissionController(config.admission?.requests, REQUEST_ADMISSION_DEFAULTS, config.admission?.requests?.maxDurationMs ?? DEFAULT_REQUEST_MAX_DURATION_MS);
517
- const configuredCodeAdmission = admissionController(config.admission?.code, CODE_ADMISSION_DEFAULTS);
193
+ const pools = resolvePools(resolved.pools, registry);
194
+ warnInsecureConfig(resolved);
195
+ const requestAdmission = new AdmissionController(resolved.admission.requests);
518
196
  let codeAdmission;
519
- let executor = config.executor;
197
+ let executor = resolved.executor;
520
198
  // Read the identity off the configured executor, before any wrapper hides
521
199
  // it behind an anonymous object literal.
522
200
  const configuredExecutorName = executorName(executor);
523
- if (!isAdmittingExecutor(executor)) {
524
- codeAdmission = configuredCodeAdmission;
201
+ const executorAdmits = isAdmittingExecutor(executor);
202
+ if (!executorAdmits) {
203
+ codeAdmission = new AdmissionController(resolved.admission.code);
525
204
  executor = withExecutorAdmission(executor, codeAdmission);
526
205
  }
527
- else if (config.admission?.code) {
206
+ else if (input.admission?.code) {
528
207
  logger.warn("[connecta] admission.code is ignored because the configured executor " +
529
208
  "implements acquire() and owns its admission pool; configure that " +
530
209
  "executor's concurrency and queue options instead.");
531
210
  }
532
- if (config.artifacts?.bindRefresh) {
533
- const sharedIds = registry.listConnectors()
534
- .filter((connector) => connector.id !== "artifacts" && connector.authScope !== "personal")
535
- .map((connector) => connector.id);
536
- const refreshConfig = {
537
- discoveryConcurrency: config.discovery?.concurrency,
538
- probeTimeoutMs: config.discovery?.probeTimeoutMs,
539
- maxEmittedBytes: config.execute?.maxEmittedBytes,
540
- maxEmittedBlocks: config.execute?.maxEmittedBlocks,
541
- maxHostCalls: config.execute?.maxHostCalls,
542
- hostCallTimeoutMs: config.execute?.hostCallTimeoutMs,
543
- watchdogMs: config.execute?.watchdogMs,
544
- failOnInvocationFailure: true,
545
- // A connector's own `approval: "never"` still applies when policy maps
546
- // are empty. Override every shared connector explicitly for refresh.
547
- approval: {
548
- connectors: new Map(sharedIds.map((id) => [id, "ask"])),
549
- tools: new Map(),
550
- },
551
- };
552
- config.artifacts.bindRefresh({
553
- ...(config.ui?.branding ? { branding: config.ui.branding } : {}),
554
- claimMs: runClaimMs(refreshConfig),
555
- execute: async (program, owner, signal) => {
556
- if (!owner)
557
- throw new Error("Refresh owner is missing; reconfigure this program.");
558
- let access = parseConnectorAccess(config.identity?.connectorAccess
559
- ? await config.identity.connectorAccess(owner.identity) : "all", { allowReadOnly: true });
560
- if (owner.pool) {
561
- const pool = pools.get(owner.pool);
562
- if (!pool || await pool.grant(owner.identity) !== true) {
563
- throw new Error("Refresh owner's pool grant is no longer available.");
564
- }
565
- access = intersectAccess(access, pool.access);
566
- }
567
- if (access.connectorIds !== "all" && !access.connectorIds.includes("artifacts")) {
568
- throw new Error("Refresh owner no longer has artifact publishing access.");
569
- }
570
- if (access.toolAccess?.get("artifacts") &&
571
- !access.toolAccess.get("artifacts").has("set_refresh")) {
572
- throw new Error("Refresh owner no longer has refresh configuration access.");
573
- }
574
- if (access.guardedToolAccess?.get("artifacts")?.has("set_refresh")) {
575
- throw new Error("A read-only guarded grant cannot configure refresh.");
576
- }
577
- access = intersectAccess(access, { connectorIds: sharedIds });
578
- if (signal.aborted)
579
- throw new Error("Refresh deadline expired before execution.");
580
- const view = registry.scoped({ connectorIds: access.connectorIds,
581
- ...(access.toolAccess ? { toolAccess: access.toolAccess } : {}),
582
- ...(access.guardedToolAccess ? { guardedToolAccess: access.guardedToolAccess } : {}) });
583
- const execute = createExecuteTool(view, config.publicUrl, executor, logger, undefined, refreshConfig);
584
- return execute({ code: program }, { signal });
585
- },
586
- });
587
- }
588
- // Every structural check has passed, so this is the configuration the
589
- // deployment runs with. Creating the runtime builds nothing — a Worker may
590
- // construct its Connecta at global scope, where no fiber may start.
591
- const runtime = createCoreRuntime(registry, {
592
- storage,
593
- logger,
594
- vault: credentialVault,
595
- activity: config.activity,
596
- config: {
597
- config,
598
- serverInfo,
599
- auth: inboundAuth,
600
- pools,
601
- executorName: configuredExecutorName,
602
- },
211
+ // Built once, from values construction already validated; never per call.
212
+ const description = describeConfig({
213
+ registry,
214
+ raw: input,
215
+ config: resolved,
216
+ executorName: configuredExecutorName,
217
+ executorAdmits,
603
218
  });
604
219
  const handler = createFetchHandler({
220
+ config: resolved,
221
+ configDescription: description,
222
+ configValueSources: describeConfigSources(description, input),
605
223
  registry,
606
- auth: inboundAuth,
607
- identity: config.identity,
608
224
  pools,
609
- publicUrl: config.publicUrl,
610
- artifactOrigin: config.artifactOrigin,
611
- allowedOrigins: config.allowedOrigins,
612
- serverInfo,
613
- logger,
614
- activity: config.activity?.store,
615
- activityModule: config.activity,
616
- artifactsModule: config.artifacts,
617
- accessTokens: config.accessTokens,
618
- activityReadGate: config.activity?.readGate,
619
- activityDeploymentId: config.activity?.deploymentId,
620
225
  executor,
621
226
  executorName: configuredExecutorName,
622
227
  requestAdmission,
623
- defaultToolTimeoutMs: config.calls?.defaultTimeoutMs,
624
- probeTimeoutMs: config.discovery?.probeTimeoutMs,
625
- discoveryConcurrency: config.discovery?.concurrency,
626
- maxEmittedBytes: config.execute?.maxEmittedBytes,
627
- maxEmittedBlocks: config.execute?.maxEmittedBlocks,
628
- maxHostCalls: config.execute?.maxHostCalls,
629
- hostCallTimeoutMs: config.execute?.hostCallTimeoutMs,
630
- watchdogMs: config.execute?.watchdogMs,
631
- approval,
632
- maxWrites,
633
- credentialVault,
634
- ui: config.ui,
635
- deploymentInfo: config.deploymentInfo,
636
- branding: config.ui?.branding,
637
228
  });
638
229
  let closePromise;
639
230
  return {
@@ -641,20 +232,13 @@ export function createConnecta(config) {
641
232
  ? ctx
642
233
  : undefined),
643
234
  registry,
235
+ describeConfig: () => description,
644
236
  close: async () => {
645
237
  closePromise ??= Promise.resolve().then(async () => {
646
- try {
647
- requestAdmission.close();
648
- codeAdmission?.close();
649
- registry.closeCallAdmission();
650
- await config.executor?.close?.();
651
- }
652
- finally {
653
- // Last, and whether or not the executor closed cleanly. A fiber
654
- // already running keeps the services it was given; only a run
655
- // started after this is refused.
656
- await disposeEdgeRuntime(runtime);
657
- }
238
+ requestAdmission.close();
239
+ codeAdmission?.close();
240
+ registry.closeCallAdmission();
241
+ await resolved.executor.close?.();
658
242
  });
659
243
  await closePromise;
660
244
  },
@@ -662,6 +246,8 @@ export function createConnecta(config) {
662
246
  }
663
247
  export { remoteMcp } from "./connectors/remote-mcp.js";
664
248
  export { api } from "./connectors/api.js";
249
+ export { keys, optionsOf, array, opaque, instance, strings, variants } from "./config-schema.js";
250
+ export { defineProvider, PROVIDER_COMMON } from "./provider.js";
665
251
  export { ConnectorCallError } from "./errors.js";
666
252
  // The same argument validation api() performs, usable by connectors that
667
253
  // implement the Connector interface directly. Returns the error rather than
@@ -669,3 +255,4 @@ export { ConnectorCallError } from "./errors.js";
669
255
  export { validateToolInput } from "./validate.js";
670
256
  export { memoryStorage } from "./storage/memory.js";
671
257
  export { CONNECTA_VERSION } from "./version.js";
258
+ export { META_TOOL_NAMES } from "./meta-tool-names.js";