@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
@@ -15,11 +15,13 @@ import { fork } from "node:child_process";
15
15
  import { existsSync } from "node:fs";
16
16
  import { fileURLToPath } from "node:url";
17
17
  import { Deferred, Duration, Effect, Exit, Schedule, Scope } from "effect";
18
- import { AdmissionController, ExecutorAdmissionError, ExecutorExecutionError, } from "../executor-admission.js";
18
+ import { AdmissionController, ExecutorAdmissionError, ExecutorExecutionError } from "../executor-admission.js";
19
19
  import { msg } from "../errors.js";
20
+ import { InvocationFailure } from "../invocation.js";
21
+ import { brandExecutor } from "../executor-contract.js";
20
22
  import { MAX_EXECUTE_LOG_CHARS } from "../executor-result.js";
21
23
  import { detach, fromSignal, runEdge } from "../runtime/run.js";
22
- import { hostCallLabel, MAX_QUICKJS_IPC_BYTES, MAX_QUICKJS_HOST_RPC_BYTES, serializedBytes, stringifyBounded, } from "./quickjs-protocol.js";
24
+ import { hostCallLabel, MAX_QUICKJS_IPC_BYTES, MAX_QUICKJS_RESULT_BYTES, QUICKJS_RESULT_CHUNK_CHARS, MAX_QUICKJS_HOST_RPC_BYTES, serializedBytes, stringifyBounded, } from "./quickjs-protocol.js";
23
25
  export { normalizeCode } from "./quickjs-runtime.js";
24
26
  const DEFAULT_TIMEOUT_MS = 30_000;
25
27
  const DEFAULT_CPU_TIME_MS = 250;
@@ -36,10 +38,7 @@ const MAX_CHILD_STDERR_BYTES = 8 * 1024;
36
38
  const MAX_ERROR_CHARS = 4_000;
37
39
  // Respawn backoff after consecutive crashes: 100 ms, doubling, capped at 5 s.
38
40
  // A value, not a running effect: stepping it happens inside a request's fiber.
39
- const CRASH_BACKOFF = Schedule.min([
40
- Schedule.exponential(Duration.millis(100)),
41
- Schedule.spaced(Duration.seconds(5)),
42
- ]);
41
+ const CRASH_BACKOFF = Schedule.min([Schedule.exponential(Duration.millis(100)), Schedule.spaced(Duration.seconds(5))]);
43
42
  const crashBackoff = Effect.map(Schedule.toStep(CRASH_BACKOFF), (step) => (crashedAt) => step(crashedAt, undefined).pipe(Effect.map(([, delay]) => crashedAt + Duration.toMillis(delay)),
44
43
  // Neither schedule ever halts; a halt here would be a broken invariant.
45
44
  Effect.orDie));
@@ -56,36 +55,27 @@ function retainStderrTail(current, chunk) {
56
55
  function childExitError(message, stderrTail) {
57
56
  if (stderrTail.length === 0)
58
57
  return new Error(message);
59
- return new Error(`${message}\nRecent child stderr (last ${stderrTail.length} bytes):\n` +
60
- stderrTail.toString("utf8"));
58
+ return new Error(`${message}\nRecent child stderr (last ${stderrTail.length} bytes):\n` + stderrTail.toString("utf8"));
61
59
  }
62
60
  function positiveWhole(value, fallback, name) {
63
61
  const resolved = value ?? fallback;
64
- if (!Number.isFinite(resolved) ||
65
- !Number.isInteger(resolved) ||
66
- resolved < 1) {
62
+ if (!Number.isFinite(resolved) || !Number.isInteger(resolved) || resolved < 1) {
67
63
  throw new TypeError(`${name} must be a positive whole number.`);
68
64
  }
69
65
  return resolved;
70
66
  }
71
67
  function nonNegativeWhole(value, fallback, name) {
72
68
  const resolved = value ?? fallback;
73
- if (!Number.isFinite(resolved) ||
74
- !Number.isInteger(resolved) ||
75
- resolved < 0) {
69
+ if (!Number.isFinite(resolved) || !Number.isInteger(resolved) || resolved < 0) {
76
70
  throw new TypeError(`${name} must be a non-negative whole number.`);
77
71
  }
78
72
  return resolved;
79
73
  }
80
74
  function errorPayload(error) {
81
- // X11: a partial authenticated frame exposes its secret instead of decoding.
82
- // Refuse it whole if a host ever bypasses execute.ts's framing bound.
83
- const message = error.length > MAX_ERROR_CHARS && error.includes("\u001econnecta-error:")
84
- ? `Host failure exceeded the ${MAX_ERROR_CHARS}-character bridge limit.`
85
- : error.slice(0, MAX_ERROR_CHARS);
86
75
  return JSON.stringify({
87
76
  ok: false,
88
- error: message,
77
+ error: msg(error).slice(0, MAX_ERROR_CHARS),
78
+ ...(error instanceof InvocationFailure ? { call: error.details } : {}),
89
79
  });
90
80
  }
91
81
  function cancelled(message) {
@@ -104,10 +94,7 @@ function unlessCancelled(effect, signal, message) {
104
94
  return effect;
105
95
  if (signal.aborted)
106
96
  return Effect.fail(cancelled(message));
107
- return Effect.raceAllFirst([
108
- effect,
109
- fromSignal(signal).pipe(Effect.mapError(() => cancelled(message))),
110
- ]);
97
+ return Effect.raceAllFirst([effect, fromSignal(signal).pipe(Effect.mapError(() => cancelled(message)))]);
111
98
  }
112
99
  /**
113
100
  * The child's release: SIGTERM, then wait for the exit, bounded — a child
@@ -257,6 +244,8 @@ class QuickJsChildPool {
257
244
  id,
258
245
  logs: [],
259
246
  logChars: 0,
247
+ resultChunks: [],
248
+ resultBytes: 0,
260
249
  providers: providerMap,
261
250
  outcome: Deferred.makeUnsafe(),
262
251
  };
@@ -282,9 +271,19 @@ class QuickJsChildPool {
282
271
  this.rejectActive(slot, error);
283
272
  this.recycle(slot);
284
273
  }).pipe(Effect.andThen(Effect.never));
274
+ const started = Date.now();
285
275
  const contenders = [
286
276
  Deferred.await(active.outcome),
287
- Effect.sleep(Duration.millis(this.runtimeOptions.timeoutMs + CHILD_EXIT_GRACE_MS)).pipe(Effect.andThen(endWith(new Error(`QuickJS child exceeded the ${this.runtimeOptions.timeoutMs}ms wall budget and was terminated.`)))),
277
+ Effect.sleep(Duration.millis(this.runtimeOptions.timeoutMs + CHILD_EXIT_GRACE_MS)).pipe(Effect.andThen(Effect.suspend(() => {
278
+ const elapsedMs = Date.now() - started;
279
+ const deadlineMs = this.runtimeOptions.timeoutMs;
280
+ return endWith(new InvocationFailure({
281
+ code: "timeout",
282
+ message: `Operation "execute_code" timed out during sandbox termination after ${elapsedMs}ms (effective deadline ${deadlineMs}ms).`,
283
+ retryable: false,
284
+ details: { operation: "execute_code", stage: "sandbox termination", elapsedMs, deadlineMs },
285
+ }));
286
+ }))),
288
287
  ];
289
288
  if (signal) {
290
289
  contenders.push(fromSignal(signal).pipe(Effect.catch(() => endWith(cancelled("Execution was cancelled.")))));
@@ -448,7 +447,9 @@ class QuickJsChildPool {
448
447
  active.logs.push(retained);
449
448
  active.logChars += separator + retained.length;
450
449
  }
451
- catch { /* Malformed log messages carry no output. */ }
450
+ catch {
451
+ /* Malformed log messages carry no output. */
452
+ }
452
453
  return;
453
454
  }
454
455
  if (message.type === "host-call") {
@@ -457,15 +458,29 @@ class QuickJsChildPool {
457
458
  await this.handleHostCall(slot, child.process, active, message);
458
459
  return;
459
460
  }
460
- if (message.type !== "result" || message.jobId !== active.id)
461
+ if ((message.type !== "result" && message.type !== "result-chunk") || message.jobId !== active.id)
461
462
  return;
462
- if (serializedBytes(message.payloadJson) > MAX_QUICKJS_IPC_BYTES) {
463
+ if (message.payloadJson.length > QUICKJS_RESULT_CHUNK_CHARS ||
464
+ (message.type === "result-chunk" && message.payloadJson.length !== QUICKJS_RESULT_CHUNK_CHARS) ||
465
+ message.payloadJson.length === 0) {
466
+ this.rejectActive(slot, new Error("QuickJS execution result exceeded the IPC limit."));
467
+ this.recycle(slot);
468
+ return;
469
+ }
470
+ const bytes = serializedBytes(message.payloadJson);
471
+ if (active.resultBytes + bytes > MAX_QUICKJS_RESULT_BYTES) {
463
472
  this.rejectActive(slot, new Error("QuickJS execution result exceeded the IPC limit."));
464
473
  this.recycle(slot);
465
474
  return;
466
475
  }
467
476
  try {
468
- const payload = JSON.parse(message.payloadJson);
477
+ stringifyBounded(message, "QuickJS result IPC envelope");
478
+ active.resultBytes += bytes;
479
+ active.resultChunks.push(message.payloadJson);
480
+ if (message.type === "result-chunk")
481
+ return;
482
+ const payload = JSON.parse(active.resultChunks.join(""));
483
+ active.resultChunks.length = 0;
469
484
  // A result ends any crash streak: the next crash backs off from 100 ms.
470
485
  slot.crashes.length = 0;
471
486
  slot.backoff = undefined;
@@ -487,8 +502,7 @@ class QuickJsChildPool {
487
502
  async handleHostCall(slot, child, active, message) {
488
503
  let payloadJson;
489
504
  try {
490
- if (serializedBytes(message.payloadJson) >
491
- MAX_QUICKJS_HOST_RPC_BYTES) {
505
+ if (serializedBytes(message.payloadJson) > MAX_QUICKJS_HOST_RPC_BYTES) {
492
506
  // Refused before parsing, so there is no address to name here: parsing
493
507
  // an over-limit payload to improve its error message would spend the
494
508
  // work the limit exists to refuse.
@@ -496,9 +510,7 @@ class QuickJsChildPool {
496
510
  }
497
511
  const payload = JSON.parse(message.payloadJson);
498
512
  const provider = active.providers.get(payload.namespace);
499
- const fn = provider && Object.hasOwn(provider.fns, payload.functionName)
500
- ? provider.fns[payload.functionName]
501
- : undefined;
513
+ const fn = provider && Object.hasOwn(provider.fns, payload.functionName) ? provider.fns[payload.functionName] : undefined;
502
514
  if (!fn) {
503
515
  throw new Error(`Unknown function ${payload.namespace}.${payload.functionName}`);
504
516
  }
@@ -517,7 +529,7 @@ class QuickJsChildPool {
517
529
  }
518
530
  }
519
531
  catch (err) {
520
- payloadJson = errorPayload(msg(err));
532
+ payloadJson = errorPayload(err);
521
533
  }
522
534
  if (!child.connected || slot.active !== active)
523
535
  return;
@@ -554,9 +566,7 @@ class QuickJsChildPool {
554
566
  return;
555
567
  // Never concatenate the stream with the final reply: those entries are
556
568
  // the same logs. A normal reply retains its existing full log contract.
557
- const resolved = outcome.logs === undefined && active.logs.length > 0
558
- ? { ...outcome, logs: active.logs }
559
- : outcome;
569
+ const resolved = outcome.logs === undefined && active.logs.length > 0 ? { ...outcome, logs: active.logs } : outcome;
560
570
  this.clearActive(slot);
561
571
  Deferred.doneUnsafe(active.outcome, Exit.succeed(resolved));
562
572
  }
@@ -621,5 +631,5 @@ class QuickJsChildPool {
621
631
  * double-acquire deadlock at concurrency 1.
622
632
  */
623
633
  export function quickJsExecutor(options = {}) {
624
- return new QuickJsChildPool(options);
634
+ return brandExecutor(new QuickJsChildPool(options), "leased");
625
635
  }
package/dist/favicon.js CHANGED
@@ -32,8 +32,7 @@ function buildIco() {
32
32
  const dx = x - 15.5;
33
33
  const dy = y - 15.5;
34
34
  const radius = Math.sqrt(dx * dx + dy * dy);
35
- const opaque = radius >= 8 && radius <= 13 &&
36
- (x <= 18 || Math.abs(dy) >= 7);
35
+ const opaque = radius >= 8 && radius <= 13 && (x <= 18 || Math.abs(dy) >= 7);
37
36
  const row = size - 1 - y;
38
37
  const pixel = pixels + (row * size + x) * 4;
39
38
  ico[pixel + 3] = opaque ? 255 : 0;
@@ -18,9 +18,7 @@ const CONNECTOR_ID_RE = /^[a-z0-9_-]+$/;
18
18
  * than escaped, since a value that is not a connector id is not config.
19
19
  */
20
20
  export function renderFixPrompt(spec, connectorId) {
21
- const id = connectorId !== undefined && CONNECTOR_ID_RE.test(connectorId)
22
- ? connectorId
23
- : undefined;
21
+ const id = connectorId !== undefined && CONNECTOR_ID_RE.test(connectorId) ? connectorId : undefined;
24
22
  return [
25
23
  "Diagnose and fix a problem in this connecta deployment (the @zackbart/connecta package). " +
26
24
  "It is configured as code: connectors, credential slots, OAuth clients, pools, and inbound auth " +
@@ -0,0 +1,238 @@
1
+ /** Capture the single-use runner before evaluating the guest expression. */
2
+ export function wrapGuestProgram(code) {
3
+ return `async () => globalThis.__connecta_run()(async (connecta) => await (\n${code}\n)())`;
4
+ }
5
+ /** Separate user source from the trusted wrapper before publishing Worker modules. */
6
+ export function isolateGuestProgram(code) {
7
+ const prefix = "async () => globalThis.__connecta_run()(";
8
+ const callback = "async (connecta) => await (\n";
9
+ const suffix = "\n)())";
10
+ if (!code.startsWith(prefix + callback) || !code.endsWith(suffix))
11
+ return undefined;
12
+ return {
13
+ program: code.slice(prefix.length, -1),
14
+ // Only this fixed wrapper enters the private runner module. Matching text
15
+ // inside an arbitrary body/string is guest data, never a trusted wrapper.
16
+ wrapper: `${prefix}__connecta_user_program)`,
17
+ };
18
+ }
19
+ /**
20
+ * Emissions are acknowledged before success, even when the guest omits await.
21
+ * Capture intrinsics before user code can replace them.
22
+ */
23
+ export function guestPrelude() {
24
+ return `${guestInitializer()}(connecta);`;
25
+ }
26
+ /** Protect completion promises before any Worker or QuickJS guest runs. */
27
+ export function guestPromiseInitializer() {
28
+ return `(() => {
29
+ const NativePromise = Promise;
30
+ const nativeResolve = Function.prototype.call.bind(NativePromise.resolve);
31
+ const nativeRace = Function.prototype.call.bind(NativePromise.race);
32
+ const isArray = Array.isArray;
33
+ const iteratorKey = Symbol.iterator;
34
+ const arrayValues = Function.prototype.call.bind(Array.prototype.values);
35
+ const arrayNext = Function.prototype.call.bind(Object.getPrototypeOf([][Symbol.iterator]()).next);
36
+ function safeRace(values) {
37
+ // Upstream constructs its completion array after the program starts.
38
+ // Use captured array iteration, with private own methods, so neither a
39
+ // replaced iterator factory nor iterator.next can observe its promises.
40
+ if (isArray(values)) {
41
+ const iterator = arrayValues(values);
42
+ values = { __proto__: null, [iteratorKey]: () => ({ __proto__: null,
43
+ next: () => arrayNext(iterator) }) };
44
+ }
45
+ return nativeRace(HostPromise, values);
46
+ }
47
+ // The upstream Worker starts its Promise.race after invoking the program.
48
+ // Its deadline must not use a resolve function replaced during that invocation.
49
+ class HostPromise extends NativePromise {}
50
+ Object.defineProperties(HostPromise, {
51
+ resolve: { value: value => nativeResolve(HostPromise, value) },
52
+ [Symbol.species]: { value: HostPromise }
53
+ });
54
+ Object.freeze(HostPromise.prototype);
55
+ Object.freeze(HostPromise);
56
+ Object.defineProperties(NativePromise, {
57
+ race: { value: safeRace, writable: false, configurable: false },
58
+ [Symbol.species]: { value: NativePromise, configurable: false }
59
+ });
60
+ // Async return values are adopted through their prototype's then method.
61
+ // Guest callbacks must not change host completion.
62
+ Object.freeze(NativePromise.prototype);
63
+ })()`;
64
+ }
65
+ /** Capture a private initializer before a Worker evaluates its guest module. */
66
+ export function guestInitializer() {
67
+ return `(() => {
68
+ ${guestPromiseInitializer()};
69
+ const NativePromise = Promise;
70
+ const freeze = Object.freeze;
71
+ const defineProperties = Object.defineProperties;
72
+ // Protect the bridge codec and its object prototypes from guest hooks.
73
+ freeze(JSON);
74
+ freeze(Object.prototype);
75
+ defineProperties(globalThis, {
76
+ JSON: { value: JSON, writable: false, configurable: false },
77
+ Promise: { value: NativePromise, writable: false, configurable: false }
78
+ });
79
+ const promiseThen = Function.prototype.call.bind(NativePromise.prototype.then);
80
+ const promiseCatch = Function.prototype.call.bind(NativePromise.prototype.catch);
81
+ const promiseFinally = Function.prototype.call.bind(NativePromise.prototype.finally);
82
+ const push = Function.prototype.call.bind(Array.prototype.push);
83
+ const apply = Function.prototype.call.bind(Function.prototype.apply);
84
+ const NativeError = Error;
85
+ const NativeWeakMap = WeakMap;
86
+ const isArray = Array.isArray;
87
+ const weakGet = Function.prototype.call.bind(WeakMap.prototype.get);
88
+ const weakSet = Function.prototype.call.bind(WeakMap.prototype.set);
89
+ return freeze((provider) => {
90
+ const pending = [];
91
+ const emit = provider.emit;
92
+ const hostCall = provider.call;
93
+ const hostResult = provider.result;
94
+ const nativeRefs = new NativeWeakMap();
95
+ async function inline(value) {
96
+ if (!value || typeof value.transfer !== "string" || !value.handle) return value;
97
+ // A completed downstream call stays successful if transfer storage fails.
98
+ // Preserve its handle so the caller can page later, without repeating a write.
99
+ try {
100
+ let text = "", page;
101
+ do {
102
+ page = await hostResult(value.transfer);
103
+ text += page.text;
104
+ } while (page.hasMore);
105
+ return { data: value.handle.valueFormat === "json" ? JSON.parse(text) : text,
106
+ format: value.handle.valueFormat };
107
+ } catch { return value.handle; }
108
+ }
109
+ async function call() {
110
+ const reply = await apply(hostCall, undefined, arguments);
111
+ if (!reply || !reply.native) return inline(reply);
112
+ const native = await inline(reply.native.value);
113
+ if (native.format === "paged" && !reply.value) return native;
114
+ const value = reply.value ? await inline(reply.value) : {
115
+ data: reply.native.dataKey ? native.data[reply.native.dataKey] : native.data, format: "json"
116
+ };
117
+ if (value.format === "paged") return value;
118
+ if (native.format === "paged") {
119
+ value.contentResult = native;
120
+ return value;
121
+ }
122
+ if (native.format === "json" && native.data && isArray(native.data.content)) {
123
+ const content = native.data.content;
124
+ // Only host-issued refs cross back. Binary data never needs a second
125
+ // guest-to-host transfer, and guest edits cannot mint native pointers.
126
+ for (let i = 0; i < content.length; i++) {
127
+ weakSet(nativeRefs, content[i], { ref: reply.native.ref, index: i });
128
+ }
129
+ value.content = content;
130
+ weakSet(nativeRefs, value, { ref: reply.native.ref });
131
+ }
132
+ return value;
133
+ }
134
+ function trackEmission(task) {
135
+ const entry = { handled: false, settled: promiseThen(task,
136
+ () => ({ ok: true }), error => ({ ok: false, error })) };
137
+ push(pending, entry);
138
+ // Every derived promise owns propagated rejection; only an unhandled
139
+ // leaf fails the run, so a later catch also handles its ancestors.
140
+ return freeze({
141
+ then(resolve, reject) {
142
+ entry.handled = true;
143
+ return trackEmission(promiseThen(task, resolve, reject));
144
+ },
145
+ catch(reject) {
146
+ entry.handled = true;
147
+ return trackEmission(promiseCatch(task, reject));
148
+ },
149
+ finally(callback) {
150
+ entry.handled = true;
151
+ return trackEmission(promiseFinally(task, callback));
152
+ }
153
+ });
154
+ }
155
+ const namespace = freeze({
156
+ __proto__: null,
157
+ search: provider.search,
158
+ describe: provider.describe,
159
+ call,
160
+ read: provider.read,
161
+ result: provider.result,
162
+ skill: provider.skill,
163
+ emit(block) {
164
+ const ref = block && typeof block === "object" ? weakGet(nativeRefs, block) : undefined;
165
+ return trackEmission(emit(ref || block));
166
+ }
167
+ });
168
+ globalThis.connecta = namespace;
169
+ defineProperties(globalThis, {
170
+ Error: { value: NativeError, writable: false, configurable: false },
171
+ __connecta_run: { configurable: true, value: () => {
172
+ delete globalThis.__connecta_run;
173
+ let used = false;
174
+ return async (program) => {
175
+ if (used) throw new NativeError("Guest runner initialization is single-use.");
176
+ used = true;
177
+ const result = await program(namespace);
178
+ for (let i = 0; i < pending.length; i++) {
179
+ const report = await pending[i].settled;
180
+ if (!report.ok && !pending[i].handled) throw report.error;
181
+ }
182
+ return result;
183
+ };
184
+ }}
185
+ });
186
+ });
187
+ })()`;
188
+ }
189
+ const ERROR_NAMES = new Set([
190
+ "Error",
191
+ "TypeError",
192
+ "SyntaxError",
193
+ "ReferenceError",
194
+ "RangeError",
195
+ "EvalError",
196
+ "URIError",
197
+ "AggregateError",
198
+ ]);
199
+ /** Fixed repair guidance, used only in agent-facing results. */
200
+ export function programError(raw, code) {
201
+ const message = typeof raw.message === "string" ? raw.message : "Program failed.";
202
+ const name = typeof raw.name === "string" && ERROR_NAMES.has(raw.name) ? raw.name : "Error";
203
+ const stack = typeof raw.stack === "string" ? raw.stack : "";
204
+ // Compare QuickJS/V8 locations to the wrapper baseline after the source.
205
+ const location = /:(\d+)(?::\d+)?\)?(?:\n|$)/.exec(stack);
206
+ const baseline = typeof raw.baseline === "string" ? /:(\d+)(?::\d+)?\)?(?:\n|$)/.exec(raw.baseline) : null;
207
+ // Workers publish only the user callback in this module, with one prefix line.
208
+ // Its trusted wrapper and baseline live in a separate, private module scope.
209
+ const workerLocation = /connecta-guest\.js:(\d+):\d+/.exec(stack);
210
+ const line = typeof raw.line === "number" && Number.isFinite(raw.line)
211
+ ? Math.max(1, raw.line)
212
+ : workerLocation
213
+ ? Math.max(1, Number(workerLocation[1]) - 1)
214
+ : location && baseline
215
+ ? Math.max(1, Number(location[1]) - Number(baseline[1]) + code.split("\n").length + 1)
216
+ : null;
217
+ let hint = "Use plain JavaScript in one async () => { ... } expression and the connecta global.";
218
+ if (/\brequire\b|\b[Ii]mports?\b|\bfs\b|filesystem|node:/.test(message) ||
219
+ (name === "SyntaxError" && /\bimport\b/.test(code))) {
220
+ hint =
221
+ "Imports, require, and filesystem access are outside the guest API. Use connecta.call to access configured services.";
222
+ }
223
+ else if (["TypeError", "ReferenceError"].includes(name) &&
224
+ /(?:const|let|var|function|\()\s*connecta\b/.test(code)) {
225
+ hint = "Do not shadow connecta. Use the host-provided connecta global.";
226
+ }
227
+ else if (/callTool|mixpanel|\bskills\b|connecta\.(?:guide|skills)/.test(message) ||
228
+ (["TypeError", "ReferenceError"].includes(name) && /connecta\.(?:guide|skills)\b/.test(code))) {
229
+ hint =
230
+ "Use connecta.call(address, args), connecta.search, connecta.describe, connecta.result, and connecta.skill(name). Services are addressed by connector.tool, never guest globals.";
231
+ }
232
+ return {
233
+ code: "program_error",
234
+ message: `Program ${name}: ${message}`,
235
+ retryable: false,
236
+ details: { name, line, hint },
237
+ };
238
+ }
@@ -0,0 +1,218 @@
1
+ import type { ToolDef } from "./types.js";
2
+ import type { CallErrorDetails } from "./errors.js";
3
+ /** TypeScript notation for the JavaScript guest global; programs receive no arguments. */
4
+ export interface GuestApi {
5
+ search(args?: CatalogSearchArgs): Promise<CatalogSearchResult>;
6
+ describe(args?: CatalogDescribeArgs): Promise<{
7
+ tools: CatalogDescription[];
8
+ }>;
9
+ call(address: string, args?: unknown, options?: {
10
+ timeoutMs?: number;
11
+ }): Promise<GuestResult>;
12
+ call(request: {
13
+ address: string;
14
+ args?: unknown;
15
+ timeoutMs?: number;
16
+ }): Promise<GuestResult>;
17
+ read(uri: string): Promise<GuestResourceResult>;
18
+ result(id: string | GuestResultHandle, options?: {
19
+ page?: number;
20
+ offset?: number;
21
+ maxBytes?: number;
22
+ }): Promise<GuestResultPage>;
23
+ skill(name: string): Promise<{
24
+ name: string;
25
+ text: string;
26
+ format: "text";
27
+ }>;
28
+ emit(block: GuestNativeBlock | GuestResult): PromiseLike<void>;
29
+ }
30
+ export interface GuestResourceResult {
31
+ contents: Array<{
32
+ uri: string;
33
+ mimeType?: string;
34
+ } & ({
35
+ text: string;
36
+ } | {
37
+ blob: string;
38
+ })>;
39
+ }
40
+ export interface GuestResultHandle {
41
+ format: "paged";
42
+ valueFormat: "json" | "text";
43
+ resultId?: string;
44
+ totalBytes: number;
45
+ truncated: true;
46
+ hint: string;
47
+ }
48
+ /** Inline MCP rich results expose original blocks; emit(result) forwards all of them. */
49
+ export type GuestResult = ({
50
+ data: unknown;
51
+ format: "json";
52
+ } | {
53
+ data: string;
54
+ format: "text";
55
+ } | GuestResultHandle) & {
56
+ content?: GuestNativeBlock[];
57
+ /** Paging handle when native content exceeds the inline cap or transfer fails. */
58
+ contentResult?: GuestResultHandle;
59
+ };
60
+ /** Native call blocks can be forwarded unchanged, including annotations and metadata. */
61
+ export type GuestNativeBlock = (GuestBlock | {
62
+ type: "resource";
63
+ resource: {
64
+ uri: string;
65
+ mimeType?: string;
66
+ } & ({
67
+ text: string;
68
+ } | {
69
+ blob: string;
70
+ });
71
+ } | {
72
+ type: "resource_link";
73
+ uri: string;
74
+ name: string;
75
+ title?: string;
76
+ description?: string;
77
+ mimeType?: string;
78
+ size?: number;
79
+ }) & {
80
+ annotations?: {
81
+ audience?: Array<"user" | "assistant">;
82
+ priority?: number;
83
+ lastModified?: string;
84
+ };
85
+ _meta?: Record<string, unknown>;
86
+ };
87
+ export interface GuestResultPage {
88
+ resultId: string;
89
+ offset: number;
90
+ bytes: number;
91
+ totalBytes: number;
92
+ hasMore: boolean;
93
+ nextOffset?: number;
94
+ format: "text";
95
+ text: string;
96
+ }
97
+ export type GuestBlock = {
98
+ type: "text";
99
+ text: string;
100
+ } | {
101
+ type: "image" | "audio";
102
+ data: string;
103
+ mimeType: string;
104
+ };
105
+ type SchemaFormat = "json" | "compact" | "typescript";
106
+ export interface CatalogSearchArgs {
107
+ query?: string;
108
+ connector?: string;
109
+ safety?: "readOnly" | "approvalRequired" | "all";
110
+ limit?: number;
111
+ offset?: number;
112
+ fullDescriptions?: boolean;
113
+ includeSchemas?: SchemaFormat;
114
+ includeSchemaKeys?: boolean;
115
+ }
116
+ export interface CatalogDescribeArgs {
117
+ address?: unknown;
118
+ addresses?: unknown;
119
+ format?: SchemaFormat;
120
+ fullDescriptions?: boolean;
121
+ }
122
+ type GuideRequiredReason = "connector_required" | "approval_required" | "schema_truncated";
123
+ interface CatalogFailureDetail extends Partial<import("./errors.js").AuthorizationHandoff> {
124
+ nextAction?: CallErrorDetails["nextAction"];
125
+ retry?: string;
126
+ code: string;
127
+ message: string;
128
+ retryable: boolean;
129
+ retryAfterMs?: number;
130
+ }
131
+ interface CatalogDescriptionFailureDetail extends CatalogFailureDetail {
132
+ configuredConnectors?: string[];
133
+ nextAction?: NonNullable<CallErrorDetails["nextAction"]>;
134
+ suggestions?: string[];
135
+ }
136
+ interface CatalogSearchFailure extends CatalogFailureDetail {
137
+ connector: string;
138
+ nextAction?: Extract<NonNullable<CallErrorDetails["nextAction"]>, {
139
+ tool: "authorize_connector";
140
+ }>;
141
+ retry?: string;
142
+ }
143
+ export interface CatalogSearchPage {
144
+ catalogErrors: CatalogSearchFailure[];
145
+ absence?: {
146
+ service: string;
147
+ message: string;
148
+ configuredConnectors: string[];
149
+ };
150
+ total: number;
151
+ offset: number;
152
+ limit: number;
153
+ hasMore: boolean;
154
+ nextOffset?: number;
155
+ matchMode?: "partial";
156
+ queryAnalysis?: {
157
+ representedTerms: string[];
158
+ otherResultTerms: string[];
159
+ unmatchedTerms: string[];
160
+ truncated?: true;
161
+ connectorScope?: string;
162
+ unknownConnector?: true;
163
+ configuredConnectors?: string[];
164
+ unavailableConnectorCount?: number;
165
+ catalogError?: CatalogFailureDetail;
166
+ guide?: string;
167
+ guideSummary?: string;
168
+ guideRequired?: true;
169
+ guideRequiredReasons?: GuideRequiredReason[];
170
+ guidance?: string;
171
+ };
172
+ }
173
+ export type CatalogSearchResult = CatalogSearchPage & {
174
+ tools: Array<CatalogSearchTool & {
175
+ connectorTitle?: string;
176
+ guide?: string;
177
+ guideSummary?: string;
178
+ }>;
179
+ };
180
+ export interface CatalogDescription {
181
+ address: string;
182
+ schemaFormat?: "json" | "text";
183
+ name?: string;
184
+ description?: string;
185
+ guide?: string;
186
+ guideSummary?: string;
187
+ guideRequired?: true;
188
+ guideRequiredReasons?: GuideRequiredReason[];
189
+ inputSchema?: unknown;
190
+ outputSchema?: unknown;
191
+ signature?: string;
192
+ outputSchemaSource?: "observed";
193
+ inputSchemaTruncated?: true;
194
+ outputSchemaTruncated?: true;
195
+ annotations?: ToolDef["annotations"];
196
+ error?: string;
197
+ errorDetails?: CatalogDescriptionFailureDetail;
198
+ }
199
+ type CatalogSearchTool = {
200
+ name: string;
201
+ address: string;
202
+ description?: string;
203
+ inputSchema?: unknown;
204
+ outputSchema?: unknown;
205
+ signature?: string;
206
+ schemaFormat?: "json" | "text";
207
+ outputSchemaSource?: "observed";
208
+ inputSchemaTruncated?: true;
209
+ outputSchemaTruncated?: true;
210
+ inputKeys?: string[];
211
+ requiredInputKeys?: string[];
212
+ outputKeys?: string[];
213
+ annotations?: ToolDef["annotations"];
214
+ classification?: ToolDef["classification"];
215
+ guideRequired?: true;
216
+ guideRequiredReasons?: GuideRequiredReason[];
217
+ };
218
+ export {};
@@ -0,0 +1 @@
1
+ export {};