@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/types.d.ts CHANGED
@@ -1,37 +1,69 @@
1
+ import type { CallErrorDetails } from "./errors.js";
1
2
  /** A JSON Schema object describing a tool's input. */
2
3
  export type JsonSchema = Record<string, unknown>;
3
- /** Minimal key/value store — the only state connecta needs. */
4
+ /**
5
+ * Minimal key/value store — the only state connecta needs. Keys and list
6
+ * prefixes must not contain U+0000 (NUL); adapters reject them with TypeError
7
+ * before accessing storage. SQL TEXT results truncate at NUL on Node 22.
8
+ */
4
9
  export interface KVStorage {
10
+ /**
11
+ * Explicit adapter opt-in: both `set` and `compareAndSet` honor
12
+ * `expiresAtMs`, including delayed commits. `createConnecta` rejects adapters
13
+ * without this capability. Declare it only after implementing that contract.
14
+ */
15
+ readonly capabilities: {
16
+ readonly absoluteExpiry: true;
17
+ };
18
+ /** The live value at `key`; null when absent or expired. */
5
19
  get(key: string): Promise<string | null>;
20
+ /**
21
+ * Write `value`. With `opts.ttlSeconds` the entry reads as absent once that
22
+ * many seconds pass; omitted or zero means no expiry. Shared stores must
23
+ * create and check relative expiry with a storage-owned clock. `expiresAtMs`
24
+ * instead sets an absolute, safe-integer epoch-millisecond expiry, including
25
+ * for a delayed commit. Adapters must honor it without restarting a TTL at
26
+ * commit time. Supply at most one of these options; a past absolute expiry
27
+ * writes an already-expired value.
28
+ */
6
29
  set(key: string, value: string, opts?: {
7
30
  ttlSeconds?: number;
31
+ expiresAtMs?: number;
8
32
  }): Promise<void>;
9
33
  delete(key: string): Promise<void>;
10
- /**
11
- * Sorted keys beginning with `prefix`. Optional for existing adapters;
12
- * subsystems that need independent, enumerable records require it explicitly.
13
- */
14
- list?(prefix: string): Promise<string[]>;
34
+ /** Live keys beginning with `prefix`, sorted by UTF-16 code unit. */
35
+ list(prefix: string): Promise<string[]>;
15
36
  /**
16
37
  * Atomic compare-and-set: write `next` only if the key's current value is
17
38
  * exactly `expected`, and report whether the write happened. `expected:
18
39
  * null` means "absent", and an expired entry is absent. `next: null`
19
- * deletes; otherwise `next` is stored with `options.ttlSeconds`, or with no
20
- * expiry when that is omitted, exactly as `set` would. On `false` nothing
40
+ * deletes; otherwise `next` takes the relative or absolute expiry options
41
+ * exactly as `set` would, or no expiry when both are omitted. On `false` nothing
21
42
  * changed.
22
43
  *
23
44
  * Atomic means linearizable against every other operation on the same
24
45
  * store, `set` and `delete` included: of N concurrent `compareAndSet(key,
25
46
  * null, value)` claims on an absent key, exactly one returns true.
26
47
  *
27
- * Optional, because not every backend can promise it: an eventually
28
- * consistent store such as Cloudflare Workers KV must omit the method
29
- * rather than emulate it with a read followed by a write. Subsystems that
30
- * need an atomic claim require it explicitly.
31
- */
32
- compareAndSet?(key: string, expected: string | null, next: string | null, options?: {
48
+ * Required. Every subsystem that must claim a key exactly once relies on
49
+ * it, and none of them carries a read-then-write fallback. The shipped
50
+ * adapters are `memoryStorage()`, `d1Storage()` from
51
+ * `@zackbart/connecta/d1`, and `sqliteStorage()` from
52
+ * `@zackbart/connecta/sqlite`; an eventually consistent store such as
53
+ * Cloudflare Workers KV cannot implement it and is not supported.
54
+ */
55
+ compareAndSet(key: string, expected: string | null, next: string | null, options?: {
33
56
  ttlSeconds?: number;
57
+ expiresAtMs?: number;
34
58
  }): Promise<boolean>;
59
+ /**
60
+ * Which adapter this is, for `Connecta.describeConfig()`. The shipped
61
+ * adapters answer `"memory"`, `"d1"`, or `"sqlite"`; any other answer, or
62
+ * none, is described as `"custom"`. Never a path, binding, or value.
63
+ */
64
+ describe?(): {
65
+ kind: string;
66
+ };
35
67
  }
36
68
  export interface Logger {
37
69
  debug(...args: unknown[]): void;
@@ -40,16 +72,30 @@ export interface Logger {
40
72
  error(...args: unknown[]): void;
41
73
  }
42
74
  export interface ToolDef {
75
+ /** Final verdict on a request-scoped published catalog entry. Never persisted. */
76
+ classification?: "read" | "write";
43
77
  name: string;
44
78
  description?: string;
79
+ /** Downstream display metadata retained with the catalog. */
80
+ title?: string;
81
+ icons?: Array<{
82
+ src: string;
83
+ mimeType?: string;
84
+ sizes?: string[];
85
+ theme?: "light" | "dark";
86
+ }>;
87
+ /** Downstream execution requirements, enforced even on a cached catalog. */
88
+ execution?: {
89
+ taskSupport?: "required" | "optional" | "forbidden";
90
+ };
45
91
  inputSchema?: JsonSchema;
46
92
  /** Optional JSON Schema describing the tool's structured result. */
47
93
  outputSchema?: JsonSchema;
48
94
  /**
49
95
  * Standard MCP tool behavior hints plus provider-specific extensions.
50
- * Connecta fails closed: only readOnlyHint === true (without a contradictory
51
- * destructiveHint) may use call_tool or execute_code. Every other tool must
52
- * cross the call_destructive_tool approval boundary.
96
+ * The registry classifies these after deployment overrides and provider
97
+ * review. Only a stored read verdict may use call_tool; program writes
98
+ * require a trusted pool. Approval belongs to the host.
53
99
  */
54
100
  annotations?: ToolAnnotations;
55
101
  }
@@ -82,7 +128,7 @@ export interface ConnectorRollingWindowBudget {
82
128
  * pretending multi-rule admission is already atomic.
83
129
  */
84
130
  export interface ConnectorCallAdmissionRule {
85
- /** Maximum simultaneous Connector.callTool attempts in one partition. */
131
+ /** Maximum simultaneous tool calls and resource reads in one partition. */
86
132
  maxConcurrency?: number;
87
133
  /** Callers allowed to wait behind the concurrency bound. Default 32. */
88
134
  maxQueueSize?: number;
@@ -150,9 +196,9 @@ export interface ConnectorCredentialConfig {
150
196
  export interface CredentialTestResult {
151
197
  ok: boolean;
152
198
  /**
153
- * Detail for the deployment's log. The operator page shows fixed copy for
154
- * `ok` and never this text, since a downstream's reply quoted here can
155
- * quote the credential it rejected.
199
+ * Shown and logged nowhere: a downstream's reply quoted here can quote the
200
+ * credential it rejected (INV-6). The operator page shows fixed copy for
201
+ * `ok`, and the log records only that a test failed.
156
202
  */
157
203
  message?: string;
158
204
  }
@@ -164,6 +210,10 @@ export interface ConnectorContext {
164
210
  logger: Logger;
165
211
  /** Public base URL of this deployment (origin), used for OAuth callbacks. */
166
212
  baseUrl: string;
213
+ /** Fixed deployment configuration, independent of the request Host. */
214
+ publicUrl?: string;
215
+ /** Deployment name used in downstream client metadata. */
216
+ oauthClientName?: string;
167
217
  /**
168
218
  * Read-only access to this connector's human-managed credential. Present
169
219
  * only when the connector declares `credential` and the deployment configures
@@ -182,17 +232,59 @@ export interface ConnectorContext {
182
232
  requestScope?: object;
183
233
  /** Best-effort cancellation signal for this connector operation. */
184
234
  signal?: AbortSignal;
235
+ /** Runtime hook keeping a dispatched OAuth refresh alive through its commit. */
236
+ defer?: (promise: Promise<unknown>) => void;
185
237
  /** Requested connector-operation deadline in milliseconds. */
186
238
  timeoutMs?: number;
187
239
  }
188
- type ConnectorStatusState = "ok" | "auth_required" | "error";
240
+ type ConnectorStatusState = "ok" | "auth_required" | "credential_required" | "error";
241
+ /**
242
+ * What a reviewed downstream tool does. `"read"` is observational. `"write"`
243
+ * changes state without destroying any that already exists, such as a create.
244
+ * `"destructive"` modifies or removes existing state, including an upsert that
245
+ * can overwrite. Both writes leave the read-only path; `"destructive"` also
246
+ * asserts `destructiveHint`, which shapes the approval copy a human reads.
247
+ */
248
+ export type ToolVerdict = "read" | "write" | "destructive";
249
+ /** One reviewed tool, with the evidence that justifies its verdict. */
250
+ export interface ReviewedTool {
251
+ readonly verdict: ToolVerdict;
252
+ /** Why the verdict holds when the name or downstream annotations do not say. */
253
+ readonly reason?: string;
254
+ /**
255
+ * `sha256:<hex>` digest of the input and output schemas the review read.
256
+ * Omit until a review has actually read them; an invented digest reports
257
+ * drift that never happened. When the live schema no longer matches it, or
258
+ * it cannot be checked, the verdict lapses and the tool is served as a write.
259
+ */
260
+ readonly schemaDigest?: string;
261
+ }
262
+ /**
263
+ * A reviewed classification of a downstream MCP catalog, keyed by exact tool
264
+ * name. Plain data, validated at construction, so the same record classifies
265
+ * live tools and feeds the drift check. A connector carries it as
266
+ * `Connector.classification`, and the registry applies it on every read.
267
+ *
268
+ * It fails closed. A name it does not list keeps only an explicit downstream
269
+ * read annotation; silence and contradiction classify as writes. A listed read
270
+ * fills downstream silence but never overrules an explicit write annotation.
271
+ * A listed write or destructive tool stays a write whatever the downstream
272
+ * claims. A listed tool whose `schemaDigest` no longer matches is a write.
273
+ */
274
+ export interface ToolClassification {
275
+ /** Hide every name absent from tools, including tools claiming to be reads. */
276
+ readonly unlisted?: "hide";
277
+ readonly tools: Readonly<Record<string, ToolVerdict | ReviewedTool>>;
278
+ }
189
279
  /**
190
280
  * How far a downstream catalog has moved away from the manifest a release
191
- * reviewed. Four numbers and nothing else: names, schemas, and prose stay out
281
+ * reviewed. Counts and nothing else: names, schemas, and prose stay out
192
282
  * of every surface this rides on, so a drift report can never become a payload
193
283
  * ([#343](https://github.com/zackbart/connecta/issues/343)).
194
284
  */
195
285
  export interface CatalogDriftCounts {
286
+ /** Downstream tools dropped because their names contain C0, DEL, or C1. */
287
+ droppedTools?: number;
196
288
  /** Live tools no release classified. Each one fails closed at call time. */
197
289
  unclassifiedTools: number;
198
290
  /** Classified names this catalog no longer serves — plan gating included. */
@@ -213,7 +305,10 @@ export interface CatalogAccessObservation {
213
305
  state: "fresh" | "stale";
214
306
  observedAt: string;
215
307
  }
308
+ export type ResourceTemplateRefusalCode = "resource_template_ambiguous" | "resource_match_budget_exceeded";
216
309
  export interface ConnectorStatus {
310
+ /** Distinct host-observed refusal codes, without URI or template text. */
311
+ resourceTemplateRefusals?: ResourceTemplateRefusalCode[];
217
312
  state: ConnectorStatusState;
218
313
  /** When state === "auth_required", the URL the operator should open. */
219
314
  authorizationUrl?: string;
@@ -222,6 +317,15 @@ export interface ConnectorStatus {
222
317
  * authorization URL instead of starting a new flow. Absent otherwise.
223
318
  */
224
319
  authorizationReused?: boolean;
320
+ /** The client registration mechanism actually selected for this grant. */
321
+ registrationPath?: "cimd" | "dcr" | "static";
322
+ /**
323
+ * From `startAuth()`, the message reaches the agent. From `status()`, it is
324
+ * never logged, and `Registry.statusFor` keeps it only when connecta wrote
325
+ * it: a custom connector's `status()` contributes its state alone, since
326
+ * its text can quote a downstream (INV-6). Connecta's connectors describe a
327
+ * failed status from its typed record.
328
+ */
225
329
  message?: string;
226
330
  /**
227
331
  * Drift observed the last time this connector served a catalog refresh *in
@@ -237,6 +341,27 @@ export interface ConnectorStatus {
237
341
  */
238
342
  catalogAccess?: CatalogAccessObservation;
239
343
  }
344
+ /** A downstream skill's verbatim frontmatter and complete file manifest. */
345
+ export interface ConnectorSkill {
346
+ uri: string;
347
+ frontmatter: Record<string, unknown>;
348
+ resources: "dynamic" | Array<{
349
+ uri: string;
350
+ digest: string;
351
+ size: number;
352
+ }>;
353
+ }
354
+ /** Resource bytes before the agent boundary, with exactly one encoding. */
355
+ export type ConnectorSkillResourceContents = {
356
+ uri: string;
357
+ mimeType?: string;
358
+ } & ({
359
+ text: string;
360
+ blob?: never;
361
+ } | {
362
+ blob: string;
363
+ text?: never;
364
+ });
240
365
  /** The whole plugin contract — the one open seam. */
241
366
  export interface Connector {
242
367
  id: string;
@@ -250,29 +375,17 @@ export interface Connector {
250
375
  title?: string;
251
376
  /** How call_tool wraps results. "mcp" passes the content array through; anything else is JSON-wrapped. */
252
377
  kind?: "mcp" | "api";
253
- /**
254
- * This connector's own default for its tools that are not explicitly
255
- * read-only, inside `execute_code`: `"never"` lets a program call them
256
- * without asking for approval. Reserved for connectors connecta ships
257
- * whose writes are cheap to undo (the artifacts connector, whose
258
- * every write is a new immutable version); a deployment's own connectors
259
- * leave it unset and exempt through `execute.approval`, which overrides
260
- * this either way. Never read from a downstream catalog — a server cannot
261
- * exempt its own tools — and never makes a tool read-only anywhere else.
262
- */
263
- approval?: "never";
264
378
  description?: string;
265
379
  /**
266
380
  * Max inline result size (bytes) for this connector's tools before
267
- * call_tool truncates and stashes the full text for get_result
381
+ * call_tool truncates and stashes the full text for connecta.result
268
382
  * paging. Overrides `ConnectaConfig.calls.maxResultBytes`;
269
383
  * omit to inherit it (which itself defaults to 24_000). Must be a whole
270
- * number of bytes >= 1; anything else warns at startup and is ignored, so
271
- * the connector inherits the deployment-wide cap.
384
+ * number of bytes >= 1; anything else refuses to construct.
272
385
  */
273
386
  maxResultBytes?: number;
274
387
  /**
275
- * Optional per-runtime admission policy for downstream tool calls. It covers
388
+ * Optional per-runtime admission policy for downstream tool calls and resource reads. It covers
276
389
  * call_tool, call_destructive_tool, and every execute_code host call, but
277
390
  * not catalog/status/auth operations.
278
391
  */
@@ -284,11 +397,22 @@ export interface Connector {
284
397
  * cannot describe correct use (for example a generic API wrapper or a
285
398
  * cross-operation sequencing rule).
286
399
  *
287
- * Listed by `skills` as `connector:<id>` and returned verbatim by
288
- * `skills({ name: "connector:<id>" })`. The guide remains deployment-owned
289
- * configuration; no runtime registration or shared mutable copy exists.
400
+ * Served as `skill://connecta/connectors/<slug>/SKILL.md`, with generated
401
+ * frontmatter followed by the unchanged guide body. `connector:<id>` is a
402
+ * one-release lookup alias. The guide remains deployment-owned configuration;
403
+ * no runtime registration or shared mutable copy exists.
290
404
  */
291
405
  usageGuide?: string | ConnectorUsageGuide;
406
+ /**
407
+ * Opted-in downstream Skills transport. The registry validates advertised
408
+ * URIs and manifest bounds before exposing these bytes to an agent. The host
409
+ * verifies preserved digests against the returned bytes. Neither
410
+ * operation registers tools or retains a catalog across requests.
411
+ */
412
+ downstreamSkills?: {
413
+ list(ctx: ConnectorContext): Promise<ConnectorSkill[]>;
414
+ read(uri: string, ctx: ConnectorContext): Promise<ConnectorSkillResourceContents[]>;
415
+ };
292
416
  /** Optional human-managed credential slot rendered in the connection in the operator UI. */
293
417
  credential?: ConnectorCredentialConfig;
294
418
  /** Optional server-side check used by the connection's Test action in the operator UI. */
@@ -301,21 +425,69 @@ export interface Connector {
301
425
  * fetched lazily over the network and are not known at construction time.
302
426
  */
303
427
  staticTools?: ToolDef[];
428
+ /**
429
+ * Optional reviewed classification of the tools `listTools` returns: data
430
+ * the registry applies, never something the connector applies itself.
431
+ * `remoteMcp({ classify })` and maintained providers set it to a
432
+ * deep-frozen record; a custom connector may set one too. It is validated
433
+ * when a registry first reads it (INV-11), and read once per connector
434
+ * object. A connector that sets it lists raw downstream tools; the
435
+ * registry caches and persists only that listing, and classifies it on
436
+ * every read with this record, so no cache layer carries a verdict.
437
+ * Connectors with `staticTools` cannot set it: annotate those directly.
438
+ *
439
+ * A wrapper that rebuilds a connector must forward this field to keep the
440
+ * review. `{ ...connector }`, `Object.assign`, and `Object.create` keep it;
441
+ * a forwarding class that omits it serves an unreviewed connector, whose
442
+ * downstream annotations are its own claims and fail closed when absent.
443
+ * Deployment-level classifier overrides, keyed by connector id
444
+ * and tool ([#706](https://github.com/zackbart/connecta/issues/706)), apply
445
+ * regardless of wrapping.
446
+ */
447
+ readonly classification?: ToolClassification | undefined;
304
448
  /**
305
449
  * Optional: the drift this connector saw the last time it listed tools,
306
- * or undefined when it has not listed any yet. Implemented by maintained
307
- * hosted-MCP proxies, which compare the live catalog with the manifest a
308
- * release reviewed *while* serving a refresh the deployment already asked
309
- * for. It is a getter over an observation, never a probe: calling it makes
310
- * no request, touches no credential, and returns counts only.
450
+ * or undefined when it has not listed any yet. A getter over an
451
+ * observation, never a probe: calling it makes no request, touches no
452
+ * credential, and returns counts only. Ignored for a connector with a
453
+ * `classification`, whose drift the registry observes itself, against
454
+ * that record, while serving a refresh the deployment already asked for.
311
455
  */
312
456
  catalogDrift?(): CatalogDriftReport | undefined;
457
+ /**
458
+ * Optional: what this connector is, for `Connecta.describeConfig()` and the
459
+ * operator surfaces built on it — where it points, how it authenticates,
460
+ * and its static tools. Never a probe and never a secret: header names but
461
+ * no values, a credential slot's labels but never its contents, an
462
+ * endpoint's origin and path but no query or userinfo. `remoteMcp()`,
463
+ * `api()` and the maintained providers implement
464
+ * it; a custom connector without it is described as `{ source: { kind:
465
+ * "custom" } }`. Core copies only the fields named in
466
+ * `ConnectorDescription`, so anything else returned is dropped.
467
+ */
468
+ describe?(): ConnectorDescription;
313
469
  listTools(ctx: ConnectorContext): Promise<ToolDef[]>;
314
- callTool(name: string, args: unknown, ctx: ConnectorContext): Promise<unknown>;
470
+ callTool(name: string, args: unknown, ctx: ConnectorContext,
471
+ /** A fresh deep copy of the catalog definition for this dispatch. */
472
+ options?: {
473
+ definition?: ToolDef;
474
+ /** Verified direct-call continuation, never populated by a program. */
475
+ input?: {
476
+ requestState?: string;
477
+ inputResponses: Record<string, unknown>;
478
+ } | undefined;
479
+ }): Promise<unknown>;
480
+ /**
481
+ * Optional read-only downstream resource operation. The URI is an opaque
482
+ * argument to this configured connector, never a destination to fetch.
483
+ * Return the MCP-shaped `{ contents }` result. Programs require a grant to
484
+ * the whole connector; an exact-tool grant does not authorize resources.
485
+ */
486
+ readResource?(uri: string, ctx: ConnectorContext): Promise<unknown>;
315
487
  /**
316
488
  * Optional best-effort teardown for resources retained under
317
- * `ctx.requestScope`. The core calls this at most once when a scope it created
318
- * solely for probing ends, and never uses that scope again. Teardown gets a
489
+ * `ctx.requestScope`. The core calls this at most once when a probe or
490
+ * execute_code scope ends, and never uses that scope again. Teardown gets a
319
491
  * small, fixed best-effort completion window; a missing, rejected, or
320
492
  * never-settling hook cannot change or hold open the operation's result
321
493
  * beyond that bound.
@@ -349,12 +521,88 @@ export interface Connector {
349
521
  * pending URL could complete consent with their own account.
350
522
  */
351
523
  verifyState?(state: string | null, ctx: ConnectorContext): Promise<boolean>;
524
+ /** Validate a callback issuer against its verified consent, including error responses. */
525
+ verifyCallbackIssuer?(issuer: string | null, ctx: ConnectorContext): Promise<boolean>;
526
+ /**
527
+ * Atomically terminate the consent verified in this context, discarding its
528
+ * verifier. Required to accept error callbacks; must share finishAuth's
529
+ * single-use claim so concurrent error and code callbacks have one winner.
530
+ */
531
+ consumeAuthError?(ctx: ConnectorContext): Promise<void>;
352
532
  /**
353
533
  * Optional: complete a downstream OAuth flow (called by
354
534
  * /oauth/callback/<id>). `callbackParams` preserves the authorization
355
- * server's RFC 9207 `iss` response parameter for SDK validation.
535
+ * server's RFC 9207 `iss` response parameter for validation. Built-in
536
+ * OAuth adapters require a nonempty `state` in this parameter, including
537
+ * programmatic calls and `api()` flows with PKCE disabled. Missing state
538
+ * is refused before any downstream request.
356
539
  */
357
- finishAuth?(code: string, ctx: ConnectorContext, callbackParams?: URLSearchParams): Promise<void>;
540
+ finishAuth?(code: string, ctx: ConnectorContext, callbackParams: URLSearchParams): Promise<void>;
541
+ }
542
+ /** An endpoint as `describeConfig()` shows it: never a query, fragment, or userinfo. */
543
+ export interface DescribedEndpoint {
544
+ origin: string;
545
+ path: string;
546
+ }
547
+ /** A connector's downstream authentication, without a single secret. */
548
+ export interface ConnectorAuthDescription {
549
+ /** `none` when the connector authenticates nothing itself. */
550
+ mode: "none" | "headers" | "credential" | "oauth" | "request";
551
+ /** Names of deployment-owned static headers; their values never appear. */
552
+ headerNames?: string[];
553
+ /** Header a stored credential rides. */
554
+ header?: string;
555
+ /** Framing placed before a stored credential; null sends it verbatim. */
556
+ scheme?: string | null;
557
+ /** Requested OAuth scopes. */
558
+ scope?: string;
559
+ /** Public CIMD client metadata document. */
560
+ clientMetadataUrl?: string;
561
+ /** A declared authorization endpoint (`api()` OAuth). */
562
+ authorizationEndpoint?: DescribedEndpoint;
563
+ /** A declared token endpoint (`api()` OAuth). */
564
+ tokenEndpoint?: DescribedEndpoint;
565
+ /** Origins `ctx.oauth.fetch` sends the access token to. */
566
+ apiOrigins?: string[];
567
+ /** Token-endpoint client authentication method. */
568
+ tokenEndpointAuthMethod?: string;
569
+ /** Whether the client authenticates with a secret; the secret never appears. */
570
+ confidentialClient?: boolean;
571
+ /** Whether PKCE is used. */
572
+ pkce?: boolean;
573
+ /** Names of extra authorization-request parameters; values never appear. */
574
+ authorizationParamNames?: string[];
575
+ /** Names of extra token-request headers; values never appear. */
576
+ tokenRequestHeaderNames?: string[];
577
+ }
578
+ /** One statically known tool, with the classification core will apply. */
579
+ export interface ConnectorToolDescription {
580
+ name: string;
581
+ description?: string;
582
+ annotations?: ToolAnnotations;
583
+ inputSchema?: JsonSchema;
584
+ outputSchema?: JsonSchema;
585
+ /** Present on registry descriptions after overrides and provider review (INV-1). */
586
+ classification?: "read" | "write";
587
+ }
588
+ /** What `Connector.describe()` reports. Every field is optional but `source`. */
589
+ export interface ConnectorDescription {
590
+ /** Construction-time presence for described fields, keyed by relative dot path. Never option values. */
591
+ optionSources?: Readonly<Record<string, "default" | "config">>;
592
+ source: {
593
+ kind: "remote-mcp" | "api" | "custom";
594
+ /** The maintained provider or built-in module that built the connector. */
595
+ provider?: string;
596
+ };
597
+ endpoint?: DescribedEndpoint;
598
+ auth?: ConnectorAuthDescription;
599
+ transport?: {
600
+ versionNegotiation?: "auto" | "legacy";
601
+ redirects?: "none" | "same-origin";
602
+ requireHttps?: boolean;
603
+ };
604
+ /** Static tools; omitted for a catalog that loads from the network. */
605
+ tools?: ConnectorToolDescription[];
358
606
  }
359
607
  export interface ConnectorUsageGuide {
360
608
  /** Markdown returned verbatim by `skills({ name: "connector:<id>" })`. */
@@ -377,6 +625,17 @@ export interface ConnectorUsageGuide {
377
625
  export interface ExecuteResult {
378
626
  result: unknown;
379
627
  error?: string;
628
+ /** Host-owned sandbox facts. Never derive these from guest result values or logs. */
629
+ failure?: {
630
+ name: string;
631
+ /** An uncaught typed host rejection, retained by guest Error identity. */
632
+ call?: CallErrorDetails;
633
+ line?: number;
634
+ timeout?: {
635
+ elapsedMs: number;
636
+ deadlineMs: number;
637
+ };
638
+ };
380
639
  logs?: string[];
381
640
  }
382
641
  /** A named group of host functions exposed to sandboxed code as a global. */
@@ -385,7 +644,7 @@ export interface ExecutorProvider {
385
644
  fns: Record<string, (...args: unknown[]) => Promise<unknown>>;
386
645
  /**
387
646
  * Optional trusted sandbox-side setup run after provider globals exist.
388
- * Connecta uses this to restore typed host errors. This is host-authored code, never
647
+ * Connecta uses this for the immutable namespace and emission acknowledgements. This is host-authored code, never
389
648
  * model input. See documentation/code-mode.md#what-an-executor-must-implement.
390
649
  */
391
650
  prelude?: string;
@@ -393,8 +652,13 @@ export interface ExecutorProvider {
393
652
  /**
394
653
  * Runs model-written JavaScript in a sandbox where the ONLY capabilities are
395
654
  * the provider functions — no network, filesystem, env, or timers. Structurally
396
- * compatible with `DynamicWorkerExecutor` from `@cloudflare/codemode` (Workers);
655
+ * compatible with the upstream `DynamicWorkerExecutor` result/provider seam;
656
+ * Workers must use `workerExecutor()` from "@zackbart/connecta/worker" so each
657
+ * run owns and releases its Worker Loader and RPC handles. Direct upstream
658
+ * construction is rejected by `createConnecta()`.
397
659
  * `quickJsExecutor()` from "@zackbart/connecta/quickjs" is the Node implementation.
660
+ * Custom implementations must explicitly opt in with
661
+ * `customExecutor(executor, { lifecycle: "self-managed" })` from the root entry.
398
662
  * NEVER back this with an unsandboxed eval — the code is untrusted.
399
663
  */
400
664
  export interface Executor {
@@ -436,11 +700,13 @@ export interface AdmissionSnapshot {
436
700
  /**
437
701
  * Optional admission capability used by bounded executors. The acquired lease
438
702
  * carries execution so an already-admitted caller cannot accidentally acquire
439
- * a second slot and deadlock a pool of one.
703
+ * a second slot and deadlock a pool of one. `wait: false` must refuse with
704
+ * executor_overloaded immediately when no slot is free; never queue it.
440
705
  */
441
706
  export interface AdmittingExecutor extends Executor {
442
707
  acquire(options?: {
443
708
  signal?: AbortSignal;
709
+ wait?: boolean;
444
710
  }): Promise<ExecutorLease>;
445
711
  /** Payload-free health/metrics view when the executor exposes one. */
446
712
  admissionSnapshot?(): AdmissionSnapshot;
@@ -457,6 +723,8 @@ export type AuthResult = {
457
723
  ok: true;
458
724
  userId?: string;
459
725
  subjectId?: string;
726
+ /** Browser session cookies refreshed by an interactive provider. */
727
+ sessionCookies?: readonly string[];
460
728
  /** Human owner represented by a non-interactive access credential. */
461
729
  principal?: IdentityReference;
462
730
  } | {
@@ -600,11 +868,21 @@ export interface ConnectaTheme {
600
868
  */
601
869
  colorScheme?: "system" | "light" | "dark";
602
870
  }
603
- /** An inbound authentication provider (bearer token, interactive identity, ...). */
871
+ /** An inbound authentication provider (machine token or interactive identity). */
604
872
  export interface InboundAuth {
605
873
  kind: string;
606
874
  /** This provider may admit a human identity to operator mutation routes. */
607
875
  interactiveOperator?: true;
876
+ /**
877
+ * Recognize credential syntax or trusted runtime context, without verifying
878
+ * it or doing I/O. The first recognizing provider owns the verdict, including
879
+ * refusals. Human routes reject recognized machine credentials without
880
+ * consulting storage or another identity. A throw fails closed.
881
+ * Explicit Authorization headers are normalized and exclude cookies and
882
+ * Access context. Without recognition, the first eligible provider owns
883
+ * that header's verdict; a refusal never falls back to another provider.
884
+ */
885
+ recognizesCredential?(request: Request, runtimeContext?: InboundAuthRuntimeContext): boolean;
608
886
  /**
609
887
  * Stable, non-secret namespace of the identity directory behind
610
888
  * `activityActorLabel`. Stored with new activity actors so two providers with
@@ -622,11 +900,13 @@ export interface InboundAuth {
622
900
  activityActorLabel?(subjectId: string): string | undefined | Promise<string | undefined>;
623
901
  /**
624
902
  * Optional browser sign-in configuration. When present, operator pages use
625
- * the provider instead of asking the operator to paste a static bearer secret.
903
+ * the provider's interactive sign-in flow.
626
904
  */
627
905
  uiAuth?: UiAuthConfig;
628
906
  /** Serve/short-circuit .well-known + OPTIONS. Return null when not handled. */
629
907
  handleMetadata?(request: Request, baseUrl: string): Response | null | Promise<Response | null>;
908
+ /** 401 challenge, selected only when this provider serves the resource metadata. */
909
+ challenge?(request: Request, baseUrl: string): string;
630
910
  /** Attempt to authorize a request. */
631
911
  authorize(request: Request, baseUrl: string, runtimeContext?: InboundAuthRuntimeContext): AuthResult | Promise<AuthResult>;
632
912
  }
package/dist/types.js CHANGED
@@ -1,2 +1 @@
1
- // Core contracts for connecta. Web-API only — no node: imports here.
2
1
  export {};
package/dist/ui.d.ts CHANGED
@@ -2,21 +2,15 @@ import type { OperatorSurface } from "./module-contracts.js";
2
2
  import type { CredentialVault } from "./credential-contract.js";
3
3
  import { type DeferredWork } from "./connector-scope.js";
4
4
  import { type CredentialManagementCapability, type UiData, type UiProblem, type UiToolSafety } from "./operator-ui/model.js";
5
- import { type ApprovalPolicy } from "./tool-safety.js";
6
5
  import type { RegistryView } from "./registry.js";
7
6
  import type { ConnectaBranding, Connector, ConnectorStatus, ToolDef, UiAuthConfig } from "./types.js";
8
7
  export { filterUiConnectors, type CredentialManagementCapability, type UiConnector, type UiData, } from "./operator-ui/model.js";
9
8
  export { CONNECTA_FAVICON_SVG, resolveBranding, isSafeHttpUrl, isSafeHttpsUrl, isSafeIconHref } from "./branding.js";
10
- export type OperatorPage = "tokens" | "connections" | "activity" | "artifacts" | "artifact";
9
+ export type OperatorPage = import("./operator-ui/view.js").OperatorPage;
11
10
  export declare function operatorPageForPath(path: string): OperatorPage | undefined;
12
11
  export declare function operatorPageTitle(page: OperatorPage, configuredTitle: string): string;
13
- /**
14
- * The badge a tool earns, from the predicates core enforces with. Computed
15
- * here so the page reports the rule rather than restating it. `exempt` is the
16
- * config exemption (#566), which `isApprovalExempt` already refuses to grant
17
- * a read-only tool.
18
- */
19
- export declare function uiToolSafety(definition: ToolDef, exempt?: boolean): UiToolSafety;
12
+ /** Report the verdict the registry stored, independent of pool trust. */
13
+ export declare function uiToolSafety(definition: ToolDef): UiToolSafety;
20
14
  /**
21
15
  * The fix-prompt key for a connector that is not usable. Chosen from the
22
16
  * status state and the connector's declared auth shape — configuration, never
@@ -43,22 +37,16 @@ export declare function buildUiData(registry: RegistryView, baseUrl: string, ser
43
37
  mayManage?: (id: string) => boolean;
44
38
  timeoutMs?: number;
45
39
  signal?: AbortSignal;
46
- approval?: ApprovalPolicy;
47
40
  }): Promise<UiData>;
48
41
  /**
49
42
  * Every operator page serves this same data-free shell. Connector, credential,
50
43
  * and activity data arrives only through the authenticated `/ui/*` APIs.
51
44
  */
52
- export declare function renderUiHtml(uiAuth?: UiAuthConfig, mcpUrl?: string, branding?: ConnectaBranding, nonce?: string, page?: OperatorPage, options?: {
53
- /** Where the Connections page lives, when this shell is on another origin. */
54
- homeUrl?: string;
55
- /**
56
- * The origin that serves `/favicon.*`, when this shell is on another one:
57
- * an artifact host answers those paths with 404. See `PageLayout.iconOrigin`.
58
- */
59
- iconOrigin?: string | undefined;
60
- }): string;
45
+ export declare function renderUiHtml(uiAuth?: UiAuthConfig, mcpUrl?: string, branding?: ConnectaBranding,
46
+ /** @deprecated Scripts load from same-origin assets; ignored. */
47
+ _nonce?: string, page?: OperatorPage): string;
61
48
  /** Mount the connection UI without enabling any storage or activity module. */
62
49
  export declare function operatorUi(options?: {
63
50
  branding?: ConnectaBranding;
64
51
  }): OperatorSurface;
52
+ export type { OperatorUiContract, OperatorConnectorOverlay, OperatorTool, OperatorViewer, OperatorGrant, OperatorPool, OperatorLastCall, } from "./operator-ui/contract.js";