@zackbart/connecta 0.37.1 → 0.39.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 (265) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +5 -4
  3. package/bin/connecta.mjs +1 -39
  4. package/bin/version.mjs +1 -1
  5. package/dist/access-tokens.js +2 -4
  6. package/dist/agent-identity.js +1 -1
  7. package/dist/agent-routes.js +231 -0
  8. package/dist/auth/clerk-sdk/generated.js +2 -1
  9. package/dist/auth/downstream-oauth/consent.js +519 -0
  10. package/dist/auth/downstream-oauth/grant-store.js +439 -0
  11. package/dist/auth/downstream-oauth/refresh-coordinator.js +562 -0
  12. package/dist/auth/downstream-oauth/refresh-records.js +447 -0
  13. package/dist/auth/downstream-oauth/sdk-hooks.js +242 -0
  14. package/dist/auth/downstream-oauth.js +66 -2516
  15. package/dist/auth/downstream-revocation.js +1 -1
  16. package/dist/auth/native.js +27 -0
  17. package/dist/auth/oauth-grant.js +24 -0
  18. package/dist/auth/oauth-token-response.js +1 -1
  19. package/dist/auth/static-oauth.js +153 -131
  20. package/dist/auth/vercel-agent.js +2 -1
  21. package/dist/auth-elicitation.js +9 -3
  22. package/dist/authorization-handoff.js +11 -5
  23. package/dist/branding.d.ts +1 -15
  24. package/dist/branding.js +2 -2
  25. package/dist/bytes.js +42 -0
  26. package/dist/call-admission-context.js +2 -5
  27. package/dist/call-recovery.js +0 -3
  28. package/dist/catalog-cache.js +130 -43
  29. package/dist/catalog-fingerprint.js +2 -18
  30. package/dist/catalog-policy.js +18 -0
  31. package/dist/catalog-service.js +285 -48
  32. package/dist/catalog.js +18 -2
  33. package/dist/config-defaults.d.ts +1 -0
  34. package/dist/config-defaults.js +1 -0
  35. package/dist/config-schema.d.ts +1 -1
  36. package/dist/config-schema.js +6 -2
  37. package/dist/config.d.ts +57 -25
  38. package/dist/config.js +30 -77
  39. package/dist/connector-caller.d.ts +1 -1
  40. package/dist/connector-health.js +59 -0
  41. package/dist/connector-status.js +117 -0
  42. package/dist/connectors/api-connector.d.ts +7 -2
  43. package/dist/connectors/api-connector.js +11 -7
  44. package/dist/connectors/guarded-fetch.d.ts +0 -6
  45. package/dist/connectors/guarded-fetch.js +1 -11
  46. package/dist/connectors/negotiation-cache.js +22 -4
  47. package/dist/connectors/remote-mcp/call.js +164 -0
  48. package/dist/connectors/remote-mcp/catalog.js +278 -0
  49. package/dist/connectors/remote-mcp/config.js +263 -0
  50. package/dist/connectors/remote-mcp/connection.js +671 -0
  51. package/dist/connectors/remote-mcp/errors.js +488 -0
  52. package/dist/connectors/remote-mcp/oauth.js +469 -0
  53. package/dist/connectors/remote-mcp/resources.js +473 -0
  54. package/dist/connectors/remote-mcp/runtime.js +1 -0
  55. package/dist/connectors/remote-mcp/transport.js +544 -0
  56. package/dist/connectors/remote-mcp.js +61 -2898
  57. package/dist/connectors/resource-uri.js +0 -4
  58. package/dist/credential-contract.d.ts +23 -0
  59. package/dist/credential-reads.js +17 -0
  60. package/dist/credential-verification.js +53 -0
  61. package/dist/credentials.d.ts +7 -0
  62. package/dist/credentials.js +60 -25
  63. package/dist/d1.d.ts +0 -89
  64. package/dist/d1.js +0 -34
  65. package/dist/describe-config.d.ts +12 -2
  66. package/dist/describe-config.js +2 -0
  67. package/dist/discovery-health.js +199 -0
  68. package/dist/downstream-input.js +4 -2
  69. package/dist/errors.d.ts +55 -17
  70. package/dist/errors.js +95 -41
  71. package/dist/execute.js +172 -125
  72. package/dist/executor-result.js +5 -2
  73. package/dist/executors/quickjs-runtime.js +2 -25
  74. package/dist/executors/quickjs.js +1 -1
  75. package/dist/guest-functions.js +83 -0
  76. package/dist/guest-runtime.js +63 -20
  77. package/dist/guest-types.d.ts +24 -10
  78. package/dist/http/argument-problems.js +35 -0
  79. package/dist/http/client.js +1 -1
  80. package/dist/http/errors.js +7 -6
  81. package/dist/http/fields.js +192 -13
  82. package/dist/http/hatch-response.js +73 -0
  83. package/dist/http/hatch.js +88 -23
  84. package/dist/http/json-schema.js +1 -1
  85. package/dist/http/node-transport.js +0 -1
  86. package/dist/http/oauth.js +4 -3
  87. package/dist/http/paging.js +6 -9
  88. package/dist/http/provider.js +33 -5
  89. package/dist/http/safety.js +9 -1
  90. package/dist/http/services.js +1 -8
  91. package/dist/http/tools.js +45 -30
  92. package/dist/http/vendor.js +7 -7
  93. package/dist/identity.js +2 -6
  94. package/dist/index.d.ts +1 -1
  95. package/dist/index.js +9 -2
  96. package/dist/invocation-auth.js +2 -1
  97. package/dist/invocation.js +21 -6
  98. package/dist/membership.d.ts +13 -5
  99. package/dist/membership.js +34 -2
  100. package/dist/meta-tools.js +50 -35
  101. package/dist/native-recovery.js +4 -16
  102. package/dist/native-tools.js +6 -2
  103. package/dist/oauth-handoff.js +2 -2
  104. package/dist/oauth-sealing.js +10 -0
  105. package/dist/operation-vocabulary.js +136 -14
  106. package/dist/operator-record.d.ts +2 -2
  107. package/dist/operator-record.js +2 -49
  108. package/dist/operator-ui/contract.d.ts +12 -2
  109. package/dist/operator-ui/generated.js +3 -3
  110. package/dist/operator-ui/model.d.ts +22 -1
  111. package/dist/program-writes.js +3 -8
  112. package/dist/provider-call.js +0 -7
  113. package/dist/provider.d.ts +1 -1
  114. package/dist/providers/_shared/google/kit.js +1 -6
  115. package/dist/providers/_shared/google/service-account.js +1 -3
  116. package/dist/providers/_shared/google/workspace.d.ts +1 -1
  117. package/dist/providers/_shared/guide.js +3 -0
  118. package/dist/providers/_shared/json.js +12 -0
  119. package/dist/providers/_shared/rest/compact-index.js +1 -1
  120. package/dist/providers/_shared/rest/kit.js +1 -3
  121. package/dist/providers/_shared/rest/operation-index.js +49 -53
  122. package/dist/providers/_shared/rest/value-safety.js +106 -28
  123. package/dist/providers/breeze/api.js +9 -8
  124. package/dist/providers/breeze/index.js +4 -2
  125. package/dist/providers/breeze/skill.generated.js +1 -1
  126. package/dist/providers/breeze/tools.js +7 -7
  127. package/dist/providers/ccb/api.js +3 -7
  128. package/dist/providers/ccb/index.js +7 -1
  129. package/dist/providers/ccb/skill.generated.js +1 -1
  130. package/dist/providers/ccb/tools.js +1 -6
  131. package/dist/providers/cloudflare/api.js +10 -3
  132. package/dist/providers/cloudflare/index.js +2 -1
  133. package/dist/providers/cloudflare/safety.js +3 -3
  134. package/dist/providers/cloudflare/skill.generated.js +1 -1
  135. package/dist/providers/docs/lib/schemas.js +24 -22
  136. package/dist/providers/docs/safety.js +2 -0
  137. package/dist/providers/docs/skill.generated.js +1 -1
  138. package/dist/providers/docs/tools.js +4 -14
  139. package/dist/providers/drive/api.js +1 -0
  140. package/dist/providers/drive/lib/contracts.js +8 -5
  141. package/dist/providers/drive/skill.generated.js +1 -1
  142. package/dist/providers/drive/tools.js +23 -41
  143. package/dist/providers/forms/api.js +1 -0
  144. package/dist/providers/forms/skill.generated.js +1 -1
  145. package/dist/providers/forms/tools.js +11 -16
  146. package/dist/providers/github/api.js +1 -0
  147. package/dist/providers/github/lib/discovery.js +1 -1
  148. package/dist/providers/github/skill.generated.js +1 -1
  149. package/dist/providers/github/tools.js +61 -17
  150. package/dist/providers/gmail/lib/schemas.js +60 -50
  151. package/dist/providers/gmail/skill.generated.js +1 -1
  152. package/dist/providers/gmail/tools.js +12 -26
  153. package/dist/providers/granola/index.js +2 -0
  154. package/dist/providers/granola/skill.generated.js +1 -1
  155. package/dist/providers/overflow/api.js +8 -4
  156. package/dist/providers/overflow/index.js +2 -1
  157. package/dist/providers/overflow/skill.generated.js +1 -1
  158. package/dist/providers/overflow/tools.js +3 -7
  159. package/dist/providers/planning-center/api.js +5 -2
  160. package/dist/providers/planning-center/lib/constants.d.ts +1 -1
  161. package/dist/providers/planning-center/lib/json-api.js +1 -9
  162. package/dist/providers/planning-center/skill.generated.js +1 -1
  163. package/dist/providers/planning-center/tools.js +2 -1
  164. package/dist/providers/quickbooks/safety.js +80 -39
  165. package/dist/providers/quickbooks/skill.generated.js +1 -1
  166. package/dist/providers/sheets/api.js +1 -0
  167. package/dist/providers/sheets/skill.generated.js +1 -1
  168. package/dist/providers/sheets/tools.js +14 -23
  169. package/dist/providers/slides/skill.generated.js +1 -1
  170. package/dist/providers/slides/tools.js +19 -26
  171. package/dist/providers/stripe/index.js +2 -1
  172. package/dist/providers/stripe/safety.js +2 -2
  173. package/dist/providers/stripe/skill.generated.js +1 -1
  174. package/dist/providers/tithely/api.js +5 -8
  175. package/dist/providers/tithely/index.js +3 -2
  176. package/dist/providers/tithely/skill.generated.js +1 -1
  177. package/dist/providers/tithely/tools.js +7 -5
  178. package/dist/providers/vercel/api.js +2 -7
  179. package/dist/providers/vercel/lib/pin.js +1 -1
  180. package/dist/providers/vercel/safety.js +1 -1
  181. package/dist/providers/vercel/skill.generated.js +1 -1
  182. package/dist/providers/vercel/tools.js +6 -4
  183. package/dist/redaction-marker.js +2 -2
  184. package/dist/registry.d.ts +11 -5
  185. package/dist/registry.js +46 -20
  186. package/dist/request-principal.js +1 -1
  187. package/dist/request-state.js +2 -2
  188. package/dist/routes/access-tokens.js +1 -1
  189. package/dist/routes/activity-disclosure.js +1 -1
  190. package/dist/routes/connect.js +2 -2
  191. package/dist/routes/credentials.js +130 -61
  192. package/dist/routes/dispatch.js +5 -1
  193. package/dist/routes/mcp.js +34 -17
  194. package/dist/routes/oauth-management.js +1 -1
  195. package/dist/routes/operator.js +6 -5
  196. package/dist/routes/shared.d.ts +13 -8
  197. package/dist/routes/shared.js +15 -9
  198. package/dist/routes/ui-config.js +3 -3
  199. package/dist/routes/ui-data.js +126 -20
  200. package/dist/routes/ui.js +17 -1
  201. package/dist/runtime/call-admission.js +1 -1
  202. package/dist/runtime/call.js +8 -3
  203. package/dist/runtime/native-storage.js +9 -0
  204. package/dist/runtime/request-reads.js +182 -0
  205. package/dist/runtime/request-scope.js +16 -0
  206. package/dist/runtime/settlement.js +1 -1
  207. package/dist/runtime/shared-read.js +2 -15
  208. package/dist/runtime/storage.js +12 -0
  209. package/dist/sent-secrets.d.ts +1 -2
  210. package/dist/sent-secrets.js +3 -8
  211. package/dist/server.js +4 -4
  212. package/dist/skills.js +44 -54
  213. package/dist/sqlite.d.ts +0 -19
  214. package/dist/sqlite.js +2 -83
  215. package/dist/storage/keys.js +69 -128
  216. package/dist/storage/memory.js +8 -2
  217. package/dist/storage/sql-native.js +27 -101
  218. package/dist/storage/sql.d.ts +1 -24
  219. package/dist/storage/sql.js +13 -14
  220. package/dist/storage-digest.js +32 -0
  221. package/dist/timeout.js +8 -0
  222. package/dist/tool-error.js +4 -0
  223. package/dist/types.d.ts +33 -0
  224. package/dist/url-safety.js +0 -4
  225. package/dist/usage-guide.js +18 -37
  226. package/dist/validate.d.ts +3 -0
  227. package/dist/validate.js +220 -158
  228. package/dist/version.d.ts +1 -1
  229. package/dist/version.js +1 -1
  230. package/dist/worker.js +1 -1
  231. package/dist/write-outcome.js +0 -3
  232. package/documentation/README.md +19 -55
  233. package/documentation/architecture.md +436 -515
  234. package/documentation/auth.md +229 -88
  235. package/documentation/code-mode.md +201 -94
  236. package/documentation/deploying.md +25 -43
  237. package/documentation/integrating.md +18 -19
  238. package/documentation/meta-tools.md +225 -51
  239. package/documentation/migration-0.33.md +10 -6
  240. package/documentation/migration-0.34.md +5 -5
  241. package/documentation/migration-retired-layouts.md +74 -0
  242. package/documentation/operator-tests.md +20 -120
  243. package/documentation/operator-ui.md +108 -16
  244. package/documentation/pool-membership-upgrade.md +44 -0
  245. package/documentation/provider-auth-migration.md +4 -10
  246. package/documentation/provider-migration-0.29.md +4 -15
  247. package/documentation/providers.md +105 -0
  248. package/examples/worker/AGENTS.md +14 -16
  249. package/examples/worker/README.md +24 -118
  250. package/examples/worker/src/connecta.config.ts +1 -0
  251. package/guides/connecting-agents.md +9 -31
  252. package/guides/how-it-works.md +6 -4
  253. package/guides/safety-and-trust.md +4 -1
  254. package/package.json +19 -19
  255. package/templates/node/AGENTS.md +13 -12
  256. package/templates/node/README.md +9 -26
  257. package/templates/node/package.json +1 -1
  258. package/templates/node/src/connecta.config.ts +1 -0
  259. package/dist/auth/oauth-v2-migration.js +0 -135
  260. package/dist/provider-call-facts.d.ts +0 -115
  261. package/dist/provider-call.d.ts +0 -112
  262. package/dist/storage/d1-copy.js +0 -255
  263. package/dist/storage/sql-schema.d.ts +0 -6
  264. package/examples/worker/kv-to-d1.wrangler.jsonc +0 -26
  265. package/examples/worker/scripts/copy-kv-to-d1.mjs +0 -162
@@ -360,6 +360,67 @@ discovery for your deployment's catalog.
360
360
 
361
361
  <!-- provider-inventory:end -->
362
362
 
363
+ ## Field selection with `fields`
364
+
365
+ Every maintained read that projects a result takes an optional `fields`
366
+ argument: up to 50 dot paths, each 1 to 200 characters, that narrow the
367
+ returned data. Selection runs after value safety and privacy filtering, so it
368
+ can only remove values. `a.b` and `a[].b` are equivalent; a list on the way is
369
+ narrowed item by item.
370
+
371
+ Where paths start, the anchor, depends on the tool and is stated in each
372
+ `fields` schema description with one valid example:
373
+
374
+ | Tool | Paths start at | Example |
375
+ | ------------------------------------------ | ---------------------------------- | -------------------------------------------- |
376
+ | A named read (`get_*` and similar) | The result | `["id"]`, `["owner.name"]` |
377
+ | A named list or search (`{ items, page }`) | Each item in `items` | `["id"]`, not `["items.id"]` |
378
+ | `*_api_read` and `*_api_write` | The vendor response body in `data` | `["projects.name"]`, not `["data.projects"]` |
379
+
380
+ A hatch body that is a list is narrowed item by item, so its paths start at
381
+ each item. An enveloping vendor nests records under a root, such as
382
+ `{ "projects": [...] }`; select `projects.name`, not `name`. Copy hatch paths
383
+ from the operation's `*_api_details` `response.fields`, which are already in
384
+ these coordinates. Paging, cut and recovery metadata (`page`, `truncated`)
385
+ remain outside the selection where a tool says so.
386
+
387
+ **Refused before dispatch.** A path outside the declared contract returns
388
+ `invalid_args` before any request. Each finding names the entry position
389
+ (`/fields/1`), the segment where the path left the contract and the properties
390
+ declared there, never the submitted path:
391
+
392
+ - Named tools check the first segment against the properties their published
393
+ output schema declares for the result or item. Deeper segments follow JSON
394
+ Schema's default: an object is closed only where the schema says
395
+ `additionalProperties: false`, and only such an object refuses an undeclared
396
+ property. Paths through other objects, open values such as GitHub
397
+ `search_scoped` rows' `item`, and paths past a scalar are accepted; a miss
398
+ there is omitted from the selection.
399
+ - Hatch reads and writes check the first segment against the operation's
400
+ declared response roots. An operation that declares no response properties
401
+ refuses `fields`. The pinned index does not establish whether deeper levels
402
+ are complete, so deeper segments are not refused.
403
+
404
+ **Declared but absent is not an error.** Optional values, empty lists and
405
+ values that value safety or privacy filtering removed are ordinary. A declared
406
+ path the current response lacks is never refused, and the selection omits it.
407
+
408
+ **Hatch miss warnings.** A hatch answer adds `warnings: string[]` when a
409
+ `fields` entry matched nothing anywhere in a nonempty response. Each warning
410
+ names the entry position, the segment where matching stopped and the
411
+ properties the operation's contract declares there, for example
412
+ `fields/1 matched nothing in this response after value safety and privacy
413
+ filtering, at segment 2; declared there: id, name.` Where the contract
414
+ declares none, such as inside an open map, it says so. A warning never lists
415
+ the response's own keys, which in an open map such as `metadata` are data, and
416
+ never repeats the submitted path. A path that matched in any listed item, a
417
+ path that runs past a scalar (selection keeps the scalar), and any path of an
418
+ empty body (`null`, `[]` or `{}`) produce no warning. Warnings are bounded: each
419
+ is at most 512 characters, at most 10 are kept within 4,096 characters
420
+ together, reviewed vendor warnings included, and a final entry counts the rest
421
+ (`3 more warnings omitted.`). Treat a warning as a repair hint for the next
422
+ call, not as a failure.
423
+
363
424
  ## API operation discovery and boundaries
364
425
 
365
426
  Standard API operation search accepts resource nouns, actions and conversational
@@ -418,6 +479,50 @@ then follow `page.nextCursor` to reach operations beyond the leading profile
418
479
  results. Responses contain at most eight compact hits within 16 KiB; fetch
419
480
  operation details separately and keep the same query when continuing.
420
481
 
482
+ Operation details return the request contract and, for an operation that is
483
+ not refused and declares success-response properties, a `response` section.
484
+ Write `fields` filters and reductions from it without a sampling read:
485
+
486
+ - `anchor` is `data` when paths start at the read result's `data`, or `data[]`
487
+ when the body is a list and each path applies to every item.
488
+ - `fields` lists the declared paths a read can select, in the read and write
489
+ tools' `fields` coordinates; pass them unchanged, such as
490
+ `fields: ["data[].id"]`.
491
+ - `withheld` is a best-effort, incomplete hint: the listed paths whose
492
+ non-null values value safety always withholds or redacts, by a reviewed
493
+ redaction path, a credential name, the deployment's sensitive-field choice
494
+ or a closed projection. A rule that can leave some value unchanged is never
495
+ a hint. Examples are URL sanitizing, reduction to an origin, which returns a
496
+ bare origin unchanged, redaction by a key, type or label, and a credential
497
+ suffix rule that scrubs only strings. A container above a hinted path is
498
+ not hinted either. Every hinted path also appears in `fields`.
499
+ - `omitted` counts declared paths not listed.
500
+
501
+ **`response` promises no readability.** Value safety runs on every read. A
502
+ value at any listed path, hinted or not, may still be withheld or redacted at
503
+ read time. An unlisted path may be too, so never treat it as safe. Many rules
504
+ depend on the values a vendor returns, which no index knows in advance:
505
+
506
+ - An expanded or polymorphic object is redacted by its type: for example, a
507
+ Stripe event's `data` or a Checkout Session's expanded `payment_intent`
508
+ loses a payment intent's `client_secret`.
509
+ - An opaque container is redacted by its contents: Google Docs
510
+ `inlineObjects` loses image `contentUri` capabilities, and Vercel drain
511
+ `headers`, deployment `env` and `protectionBypass` keys are withheld.
512
+ - A labelled or typed record is redacted by its label or type.
513
+ - URLs carrying credentials are sanitized. QuickBooks replaces every http(s)
514
+ URL in a returned string, including ordinary text such as a Customer
515
+ `DisplayName` or `CompanyName`, with `[redacted]`.
516
+ - A value echoing a secret the request sent is redacted.
517
+
518
+ Paths list shallowest first, in index order, up to 100 paths and 4,096
519
+ characters of path JSON, the hint included; a path over 200 characters is
520
+ never listed. The pinned index carries names only, never response types or
521
+ example values. Only the first page of a whole-operation answer carries
522
+ `response`; `param` answers and continuation pages omit it. An operation
523
+ without declared response properties has no `response`, and its reads refuse
524
+ `fields`.
525
+
421
526
  Maintained REST hatches validate path parameters against their pinned contracts
422
527
  before dispatch. Integer ids use canonical ASCII decimal notation within the
423
528
  safe-integer range and obey the operation's declared bounds; for example,
@@ -67,12 +67,10 @@ tokens, upgrading, and diagnosis with `connecta doctor` to their procedures.
67
67
  - All state lives in the one D1 database bound as `CONNECTA_DB`, through
68
68
  `d1Storage` (and `d1ActivityStore`) from `@zackbart/connecta/d1`. Do not add
69
69
  a KV namespace, a second database, or a copied storage adapter; connecta
70
- creates its own tables. The only KV binding is in `kv-to-d1.wrangler.jsonc`,
71
- which is never deployed. It exists for the one-shot copy from a 0.28 Workers
72
- KV deployment (README.md § "Upgrading from 0.28"). Back up, block traffic
73
- and background writers, drain, wait for stable KV, copy and verify, deploy
74
- while maintenance remains, then mark cutover before reopening traffic. Never
75
- rerun stale KV after cutover. Retain backups before removing KV.
70
+ creates its own tables. Pre-0.29 Workers KV state must be copied on
71
+ Connecta 0.37.1 before upgrading past that bridge release; follow the installed
72
+ package's `documentation/migration-retired-layouts.md`. The current example
73
+ includes no KV copy script or binding.
76
74
  - Add application logic only inside deliberate `api()` connector handlers.
77
75
  Do not copy or modify Connecta package internals here.
78
76
  - Prefer `api()` when the agent must see an exact reviewed capability set;
@@ -97,16 +95,16 @@ tokens, upgrading, and diagnosis with `connecta doctor` to their procedures.
97
95
  Each agent keeps one Connecta connection whose harness, never the model,
98
96
  picks the pool per turn. Tiers are nested pools of shared connectors with
99
97
  no `owner`, each spreading the tool list below. Recommended names are
100
- `<agent>` for the lowest and `<agent>-<tier>` above it; any named pool,
101
- including an existing `team` or `leadership` pool, may be a tier if all its
102
- human members are cleared for it. A chat gets the most capable tier everyone
103
- present is cleared for, and the lowest when anyone present is unknown.
104
- `<agent>-<user>` (that user's highest tier plus their own connector ids,
105
- `owner` set to their Workspace address) is used only in a one-on-one with
106
- that user. List only cleared people in a tier, and never another person in
107
- a `<agent>-<user>` pool: its per-user connectors act as that user for every
108
- member. Never add a second Connecta connection or mount downstream tools
109
- directly.
98
+ `<agent>` for the lowest and `<agent>-<tier>` above it. Every pool lists
99
+ only people or only `agent:` references; mixing them throws at
100
+ construction. Tiers and `<agent>-<user>` pools list only the agent. People
101
+ with a tier's reach get their own people-only pool (for example `team`
102
+ beside `assistant-team`) spreading the same tool-list constant. A chat gets
103
+ the most capable tier everyone present is cleared for, and the lowest when
104
+ anyone present is unknown. `<agent>-<user>` (that user's highest tier plus
105
+ their own connector ids, `owner` set to their Workspace address) is used
106
+ only in a one-on-one with that user. Never add a second Connecta connection
107
+ or mount downstream tools directly.
110
108
  - Brand the operator UI in `operatorUi({ branding })`: product and owner names,
111
109
  description, favicon, and `theme` (`accent`, `radius`, `fontFamily`,
112
110
  `monoFamily`, `colorScheme`). Ask the deployment's owner for their brand
@@ -21,14 +21,13 @@ migrations, and secrets.
21
21
 
22
22
  ## Files
23
23
 
24
- | File | What it is |
25
- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
- | `src/index.ts` | the Worker entrypoint — starts the configuration, under 30 lines |
27
- | `src/connecta.config.ts` | connectors, auth, storage, and optional modules, as `defineConfig((env) => …)` |
28
- | `alchemy.run.ts` | the deployment: Worker, vars, secrets, D1, Worker Loader, and both Access applications |
29
- | `wrangler.jsonc` | local `wrangler dev` only, with a simulated Access identity; never used to deploy |
30
- | `gitignore` | the copied deployment's `.gitignore`, shipped under this name because npm strips `.gitignore` ([Copied into its own repository](#copied-into-its-own-repository)) |
31
- | `scripts/copy-kv-to-d1.mjs`, `kv-to-d1.wrangler.jsonc` | one-shot copy of a 0.28 Workers KV deployment's state into D1, run once and deleted ([Upgrading from 0.28](#upgrading-from-028)) |
24
+ | File | What it is |
25
+ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
+ | `src/index.ts` | the Worker entrypoint — starts the configuration, under 30 lines |
27
+ | `src/connecta.config.ts` | connectors, auth, storage, and optional modules, as `defineConfig((env) => …)` |
28
+ | `alchemy.run.ts` | the deployment: Worker, vars, secrets, D1, Worker Loader, and both Access applications |
29
+ | `wrangler.jsonc` | local `wrangler dev` only, with a simulated Access identity; never used to deploy |
30
+ | `gitignore` | the copied deployment's `.gitignore`, shipped under this name because npm strips `.gitignore` ([Copied into its own repository](#copied-into-its-own-repository)) |
32
31
 
33
32
  Construct Connecta once per isolate and pass `ctx` through to `fetch`, as the
34
33
  example entrypoint does.
@@ -261,31 +260,10 @@ the Access policy or application.
261
260
 
262
261
  ### Let agents through Access
263
262
 
264
- `ConnectaAgents` in `alchemy.run.ts` is a second self-hosted Access
265
- application whose destination is `<PUBLIC_URL host>/agent/*`, with a single
266
- policy whose action is **Bypass** and whose include rule is **Everyone**. The
267
- Worker-level application still protects every other path. Never bypass any
268
- other path. To serve agents on another hostname too, add a destination for it,
269
- for example `{ type: "public", uri: "agents.example.com/agent/*" }`. Through the
270
- Access API, the application is:
271
-
272
- ```json
273
- {
274
- "type": "self_hosted",
275
- "name": "connecta agents",
276
- "destinations": [{ "type": "public", "uri": "connecta.example.com/agent/*" }],
277
- "policies": [{ "name": "agents bypass", "decision": "bypass", "include": [{ "everyone": {} }] }]
278
- }
279
- ```
280
-
281
- It must be a hostname-and-path (`public`) destination: a second Worker
282
- destination is refused because the Worker-level application owns it. Changes
283
- took 15–19 seconds to settle when probed, occasionally longer, with transient
284
- edge errors meanwhile. Do not rely on a fixed wait; repeat
285
- [Verify after deploying](#verify-after-deploying). Connecta ignores Access
286
- context on `/agent/*` and refuses every other spelling of that namespace before
287
- auth. [Deploying Connecta](https://github.com/zackbart/connecta/blob/main/documentation/deploying.md#agent-endpoints-behind-cloudflare-access)
288
- records the untested cases and the propagation details.
263
+ `ConnectaAgents` in `alchemy.run.ts` declares the agent bypass. Follow
264
+ [Agent endpoints behind Cloudflare Access](https://github.com/zackbart/connecta/blob/main/documentation/deploying.md#agent-endpoints-behind-cloudflare-access)
265
+ for the hostname-and-path application, API JSON, matching rules and controls.
266
+ Repeat [Verify after deploying](#verify-after-deploying) after Access changes.
289
267
 
290
268
  ### Moving a Wrangler-deployed Worker to Alchemy
291
269
 
@@ -357,7 +335,7 @@ it reports, run Alchemy and Wrangler only on a trusted machine, keep
357
335
  `alchemy dev` and `wrangler dev` bound to localhost, and give the API token
358
336
  only the four permissions in [Deploy](#deploy) and a short expiry.
359
337
 
360
- `wrangler` serves only `wrangler dev` and `scripts/copy-kv-to-d1.mjs`. A
338
+ `wrangler` serves local `wrangler dev`. A
361
339
  `tsconfig.json` like the following lets `tsc --noEmit`
362
340
  resolve `D1Database`, `WorkerLoader`, and `ExecutionContext`, and checks the
363
341
  stack:
@@ -402,9 +380,10 @@ declared agent, is available to signed-in maintainers.
402
380
  ## Select optional modules
403
381
 
404
382
  `cloudflareAccessAuth()` reads trusted identity after Access admits the Worker
405
- request. Maintainers use plain `/mcp` and the operator pages; people in a pool
406
- use `/mcp/<pool>`, and agents in it `/agent/<pool>`, which serve exactly that
407
- pool's tools. Agents authenticate with `accessTokens(storage)` over the same D1
383
+ request. Maintainers use plain `/mcp` and the operator pages; people in a
384
+ people pool use `/mcp/<pool>` (or plain `/mcp` when it is their only pool), and
385
+ agents in an agent pool use `/agent/<pool>`; each serves exactly that pool's
386
+ tools. Agents authenticate with `accessTokens(storage)` over the same D1
408
387
  database; human endpoints refuse their tokens, and Access service headers alone
409
388
  never grant MCP access or interactive authority.
410
389
  Keep users, groups, and admission in Access. Connector visibility and management
@@ -623,87 +602,14 @@ Each shape moves to the one `CONNECTA_DB` binding:
623
602
 
624
603
  #### Copying Workers KV state into D1
625
604
 
626
- Storage keys did not change in 0.29. `copyKvToD1(kv, db, { source })` from
627
- `@zackbart/connecta/d1` preserves live keys, exact values including vault
628
- ciphertext, and absolute expiries. The source is the KV namespace id. Counts
629
- and failures name only families, never keys or values. Oversized UTF-8 strings
630
- or rows are skipped and counted as invalid against D1's
631
- [2,000,000-byte limit](https://developers.cloudflare.com/d1/platform/limits/).
632
- A different live D1 value or expiry is a conflict, kept by default.
633
-
634
- Use a maintenance window. Copying while either deployment serves can restore
635
- revoked tokens, stale refresh tokens, or disconnected connectors. A rerun is
636
- safe only while the source remains stable and D1 has no new application writes.
637
- The script reads the source id from `kv-to-d1.wrangler.jsonc` and checks two
638
- consecutive listing/hash passes before a copy or verification pass. The config
639
- uses remote KV and D1 bindings and is never deployed.
640
-
641
- Prepare the new configuration without deploying it. Use the existing activity
642
- D1 database as `CONNECTA_DB`, keeping its name and id; otherwise create one
643
- with `wrangler d1 create connecta`. Remove `kv_namespaces` and copied adapters.
644
- Configuration lives in `src/connecta.config.ts` and
645
- `src/index.ts` is the entry point. Set the plain var `CONNECTA_ACTIVITY = "on"`
646
- so preserved activity remains visible. Bind only `CONNECTA_DB` and `LOADER` for storage/execution;
647
- keep existing auth vars and the credential secret.
648
- Fill in the copy config's namespace id and the same D1 database name/id,
649
- then `wrangler login` and check the prepared deployment with a dry run.
650
-
651
- 1. Back up KV with a bulk export including values and expiration metadata.
652
- Export D1 with `wrangler d1 export <db> --remote --output before-cutover.sql`.
653
- Store backups securely and preserve the exact credential encryption key,
654
- whatever secret name the deployment stores it under.
655
- 2. Block traffic using maintenance mode or turn the route off. Stop cron,
656
- queue consumers, scheduled jobs, and every other KV/D1 writer. Drain all
657
- in-flight requests, including OAuth callbacks and token refreshes.
658
- 3. Wait at least **60 seconds after the last write**, or the longest configured
659
- KV `cacheTtl`, whichever is greater. KV propagation can take longer, so this
660
- is a minimum, not proof of consistency. See
661
- [KV consistency](https://developers.cloudflare.com/kv/concepts/how-kv-works/).
662
- Confirm a stable source with two consecutive listing/hash passes that match;
663
- the script performs this check. If they differ, stay in maintenance, wait
664
- longer, and repeat. Expiring entries may also require another pass.
665
- 4. Copy **before switching traffic** with
666
- `node scripts/copy-kv-to-d1.mjs --maintenance`. Resolve all `invalid` and
667
- `conflicts` counts under maintenance; either makes the script exit non-zero.
668
- An oversized entry requires a deliberate per-family remediation, not a
669
- retry of the same value. Overwrite only families explicitly reviewed as
670
- stale in D1, for example `--maintenance --overwrite-family catalog`.
671
- Token/OAuth/vault families require the operator to confirm D1 rows are stale
672
- and also pass `--confirm-stale-d1`; never infer this from a conflict alone.
673
- There is no blanket `--overwrite`. Then run
674
- `node scripts/copy-kv-to-d1.mjs --maintenance --verify`. It compares SHA-256
675
- hashes of exact values and absolute expiries for live source keys, reports
676
- `verified` / `mismatches` counts by family only, and exits non-zero on any
677
- invalid entry or mismatch. Keep traffic and writers stopped until these
678
- counts are resolved. A verification pass does not rewrite copied entries.
679
- 5. Deploy the D1 configuration with the deployment's `wrangler deploy` while maintenance remains.
680
- Run `connecta doctor --pool <pool>` using Access service credentials plus a
681
- stored `cta_` bearer through `CONNECTA_TOKEN`. Verify an existing
682
- OAuth connector without re-consent, an existing `cta_` token, a connector
683
- using a vault credential, and prior activity in the Activity view. Run
684
- these controlled checks with other traffic and background writers blocked.
685
- 6. Seal the source with
686
- `node scripts/copy-kv-to-d1.mjs --maintenance --mark-live`, then reopen
687
- traffic and background writers. The permanent D1 marker refuses later
688
- copies. Never rerun after traffic resumes. `--i-know-this-is-stale` is only
689
- an emergency override after stopping writers again and assessing stale KV;
690
- it does not make stale tokens or credentials safe to restore.
691
- Retain backups before deleting the KV namespace. After a clean observation
692
- period, remove the copy script/config and delete KV with
693
- `wrangler kv namespace delete --namespace-id <id>`.
694
-
695
- An in-Worker copy can call
696
- `copyKvToD1(env.CONNECTA_KV, env.CONNECTA_DB, { source: namespaceId, cursor })`
697
- from a guarded one-off route under the same maintenance procedure. Each call
698
- reads at most `maxKeys` keys, default 500. For near-limit rows use 200 or fewer
699
- so additional byte-bounded D1 batches fit the invocation's query budget.
700
- Loop until `done`, passing each returned cursor. Tokens keep KV's raw cursor
701
- in D1 for seven days, are bound to the source id, and are atomically consumed.
702
- Unknown, spent, or foreign-source tokens are refused without echoing them.
703
- On failure, use the error's replacement token or restart under maintenance.
704
- Call `markKvToD1Live(db, namespaceId)` before reopening traffic, and remove the
705
- route and KV binding. The source stability check is the operator's duty when
706
- using the API directly. Remote bindings remain unverified until deploy day.
605
+ Complete this conversion on Connecta 0.37.1 before installing the release
606
+ that removes migrations. The current `/d1` subpath provides `d1Storage` and
607
+ `d1ActivityStore`; it no longer exports `copyKvToD1`, `markKvToD1Live`, or
608
+ migration types, and this example no longer includes the copy script/config.
609
+ Use the 0.37.1 package's Worker example under maintenance, verify the copy,
610
+ mark cutover, and open every owner's OAuth grant on that bridge release.
611
+ Follow [Retired layout migrations](../../documentation/migration-retired-layouts.md)
612
+ for the required order and recovery. Never copy stale KV into a live database.
707
613
 
708
614
  ## Activity history (optional)
709
615
 
@@ -111,6 +111,7 @@ export default defineConfig((env: Env) => {
111
111
  // Access user ids or "agent:<name>". The starter pool is the agent's base
112
112
  // pool (shared connectors, no owner), named after the agent as the agent
113
113
  // pool layout requires.
114
+ // Each pool lists only people or only agents; share tool lists across separate pools.
114
115
  pools: { ci: { tools: ["echo"], members: ["agent:ci"] } },
115
116
  // Connectors that declare a `credential` slot become editable by a
116
117
  // maintainer (shared) or by the member it belongs to (personal),
@@ -11,7 +11,8 @@ has exact setup and verification steps.
11
11
 
12
12
  Imagine an agent named `assistant` that helps with CRM records and tickets.
13
13
  Its operator creates a pool with the actions needed for that job and adds
14
- the agent as a member. The pool can be read-only if updates must be impossible.
14
+ the agent as a member. Agent pools contain only agents; people use separate
15
+ pools that can share the same tool list. The pool can be read-only if updates must be impossible.
15
16
 
16
17
  ```mermaid
17
18
  flowchart LR
@@ -68,14 +69,11 @@ sequenceDiagram
68
69
  C-->>H: Serve the pool's permitted tools
69
70
  ```
70
71
 
71
- Anyone who obtains either token can act as the agent. Trust the Vercel
72
- project code and build steps that can obtain its tokens, and enable only
73
- environments that should have the pool's access.
74
-
75
- The [token management guide](../documentation/auth.md#issue-rotate-or-revoke-an-agent-token)
72
+ [Safety and trust](./safety-and-trust.md#a-credential-proves-an-agent-not-a-person)
73
+ explains who can act with these credentials. The
74
+ [token management guide](../documentation/auth.md#issue-rotate-or-revoke-an-agent-token)
76
75
  and [Vercel identity guide](../documentation/auth.md#vercel-workload-credentials)
77
- own availability, setup, rotation, and revocation. If both methods are
78
- enabled, stopping one does not stop the other.
76
+ own setup, rotation, and revocation.
79
77
 
80
78
  ## An optional integration for Eve
81
79
 
@@ -114,29 +112,9 @@ identity. Instructions help the model use tools; they grant no permissions.
114
112
 
115
113
  ## Decide whether writes need a person
116
114
 
117
- The helper defaults to unattended execution of authorized writes. Connecting
118
- an agent does not automatically add an approval step.
119
-
120
- ```mermaid
121
- flowchart TB
122
- Call["Agent requests a change"] --> Ask{"App asks for approval?"}
123
- Ask -->|Yes| Approved{"Person approves?"}
124
- Approved -->|No| Stop["Stop"]
125
- Approved -->|Yes| Pool{"Connecta allows this write?"}
126
- Ask -->|No| Pool
127
- Pool -->|No| Refuse["Refuse before sending"]
128
- Pool -->|Yes| Send["Send the change"]
129
- ```
130
-
131
- For an interactive Eve agent, `gateWrites: true` asks before tools not marked
132
- read-only. An explicit Eve approval policy takes precedence. If the agent
133
- must never update data, use a read-only pool.
134
-
135
- Approval may rely on an earlier tool label. A writable pool can execute a
136
- newly classified write without a fresh approval; a read-only pool refuses it.
137
- [Safety and trust](./safety-and-trust.md) explains the boundary, and the
138
- [helper guide](https://github.com/zackbart/connecta/blob/main/packages/connecta-eve/README.md#approval-and-writes)
139
- explains the policy mechanics.
115
+ Agree on an approval policy before enabling writes. See
116
+ [approval boundaries](./safety-and-trust.md#read-only-blocks-actions-that-change-data)
117
+ and the [Eve helper's approval setup](https://github.com/zackbart/connecta/blob/main/packages/connecta-eve/README.md#approval-and-writes).
140
118
 
141
119
  ## When accounts or audiences differ
142
120
 
@@ -41,7 +41,7 @@ For setup and migrations, see [Integrating services](../documentation/integratin
41
41
 
42
42
  A **pool** is a named selection of tools and the people or agents allowed
43
43
  to use them. The operator creates it and gives it an **endpoint**: a
44
- connection address for that pool.
44
+ connection address for that pool. Each pool lists only people or only agents.
45
45
 
46
46
  One pool might let the assistant read CRM records. Another might let a
47
47
  person update tickets. Tools and accounts are separate choices: a pool
@@ -65,7 +65,9 @@ choose the right one for the conversation. The model does not choose its
65
65
  own access level.
66
66
 
67
67
  Maintainers run the deployment and can reach its whole tool list through
68
- the main human endpoint. Other people use their assigned pools.
68
+ the main human endpoint, `/mcp`. Other people use their assigned pools. A
69
+ person in exactly one pool can use that same `/mcp` address: their sign-in
70
+ selects the pool, and they get only its tools.
69
71
  Agents use shared accounts selected by the operator. They do not inherit
70
72
  the account of the person chatting with them.
71
73
 
@@ -115,8 +117,8 @@ unbounded data.
115
117
 
116
118
  With meta-tools, one discovered read can use a direct call. Finding an unfamiliar
117
119
  action, combining several calls, or reducing a large answer belongs in a program.
118
- On a writable endpoint, a program may also change data. The AI app decides
119
- whether to ask for approval before running it.
120
+ On a writable endpoint, a program may also change data; see
121
+ [approval boundaries](./safety-and-trust.md#read-only-blocks-actions-that-change-data).
120
122
 
121
123
  The [endpoint workflow](../documentation/operating.md) and
122
124
  [code reference](../documentation/code-mode.md) explain the mechanics.
@@ -71,7 +71,10 @@ or contradictory read hints count as writes, but a service can mislabel an
71
71
  action and an operator can override its label. Use restricted service
72
72
  credentials as another boundary where possible.
73
73
 
74
- The AI app owns approvals. It may ask based on an earlier tool label. If a
74
+ The Eve helper defaults to unattended authorized writes. For interactive use,
75
+ `gateWrites: true` asks before tools not marked read-only; an explicit Eve
76
+ approval policy takes precedence. The AI app owns approvals. It may ask based
77
+ on an earlier tool label. If a
75
78
  read becomes a write, a writable pool can execute it without a fresh
76
79
  approval; a read-only pool refuses it. Connecta does not pause a program to
77
80
  ask a person partway through.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zackbart/connecta",
3
- "version": "0.37.1",
3
+ "version": "0.39.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "One MCP to rule them all — a single MCP endpoint aggregating many downstream connectors behind a code-first surface of six meta-tools.",
@@ -191,7 +191,6 @@
191
191
  "check:declarations": "node scripts/check-declarations.mjs --dist .",
192
192
  "check:bundle": "node scripts/bundle-size.mjs",
193
193
  "providers:check": "tsx scripts/drift-check.mjs --specs --manual",
194
- "drift:check": "tsx scripts/drift-check.mjs",
195
194
  "eval:selftest": "tsx eval/selftest.ts",
196
195
  "eval:agent": "tsx eval/run-agent.ts",
197
196
  "eval:smoke": "tsx eval/run-smoke.ts",
@@ -257,31 +256,32 @@
257
256
  "devDependencies": {
258
257
  "@clerk/backend": "3.12.0",
259
258
  "@cloudflare/codemode": "^0.5.0",
260
- "@cloudflare/vitest-pool-workers": "^0.18.8",
261
- "@cloudflare/workers-types": "^4.20250101.0 || ^5.0.0",
259
+ "@cloudflare/vitest-plugin": "^1.4.3",
260
+ "@cloudflare/workers-types": "5.20260804.1",
262
261
  "@effect/platform-node": "4.0.5",
263
262
  "@fontsource-variable/hanken-grotesk": "^5.3.0",
264
263
  "@fontsource-variable/jetbrains-mono": "^5.3.0",
265
- "@playwright/test": "^1.62.0",
266
- "@radix-ui/react-dialog": "^1.2.0",
267
- "@radix-ui/react-tabs": "^1.1.22",
268
- "@tanstack/react-router": "^1.170.41",
269
- "@types/node": "^22.0.0",
264
+ "@playwright/test": "^1.64.1",
265
+ "@radix-ui/react-dialog": "^1.3.1",
266
+ "@radix-ui/react-tabs": "^1.2.1",
267
+ "@tanstack/react-router": "^1.170.44",
268
+ "@types/node": "^22.20.5",
270
269
  "@types/react": "^19.3.0",
271
270
  "@types/react-dom": "^19.3.0",
272
271
  "alchemy": "2.0.0-beta.83",
273
272
  "cmdk": "^1.1.1",
274
- "esbuild": "^0.28.0",
275
- "knip": "^6.29.0",
276
- "oxfmt": "0.72.0",
277
- "oxlint": "^1.76.0",
273
+ "esbuild": "^0.28.2",
274
+ "knip": "^6.41.0",
275
+ "oxfmt": "0.73.0",
276
+ "oxlint": "^1.88.0",
278
277
  "quickjs-emscripten": "^0.32.0",
279
- "react": "^19.3.0",
280
- "react-dom": "^19.3.0",
281
- "tsx": "^4.23.1",
282
- "typescript": "^5.9.3",
278
+ "react": "^19.3.1",
279
+ "react-dom": "^19.3.1",
280
+ "tsx": "^4.23.15",
281
+ "typescript": "^6.0.3",
283
282
  "undici": "6.29.1",
284
- "vitest": "^4.1.6",
285
- "wrangler": "^4.114.0"
283
+ "vite": "^8.3.4",
284
+ "vitest": "^5.0.4",
285
+ "wrangler": "^4.151.0"
286
286
  }
287
287
  }
@@ -33,8 +33,9 @@ tokens, upgrading, and diagnosis with `connecta doctor` to their procedures.
33
33
  Issue or rotate an agent's token with `npm run --silent rotate-token -- <agent>`
34
34
  against the same configuration and database the server uses; bind a token
35
35
  from before agents once with `npm run adopt-token -- <token-id> <agent>`.
36
- Plain `/mcp` serves `maintainers` only; other people reach `/mcp/<pool>` and
37
- agents `/agent/<pool>` for a pool listing them in `members` (`npm run doctor`
36
+ Plain `/mcp` serves `maintainers` the whole catalog and each other person
37
+ in exactly one pool that pool; people also reach `/mcp/<pool>` and agents
38
+ `/agent/<pool>` for a pool listing them in `members` (`npm run doctor`
38
39
  checks `/agent/local-machine`). Human endpoints refuse `cta_` tokens. `CONNECTA_TOKEN` is only for clients and doctor; never add a configured
39
40
  static bearer or an open startup mode.
40
41
  All state, activity included, lives in the one SQLite file `CONNECTA_DATABASE`
@@ -45,16 +46,16 @@ tokens, upgrading, and diagnosis with `connecta doctor` to their procedures.
45
46
  Each agent keeps one Connecta connection whose harness, never the model,
46
47
  picks the pool per turn. Tiers are nested pools of shared connectors with
47
48
  no `owner`, each spreading the tool list below. Recommended names are
48
- `<agent>` for the lowest and `<agent>-<tier>` above it; any named pool,
49
- including an existing `team` or `leadership` pool, may be a tier if all its
50
- human members are cleared for it. A chat gets the most capable tier everyone
51
- present is cleared for, and the lowest when anyone present is unknown.
52
- `<agent>-<user>` (that user's highest tier plus their own connector ids,
53
- `owner` set to their Workspace address) is used only in a one-on-one with
54
- that user. List only cleared people in a tier, and never another person in
55
- a `<agent>-<user>` pool: its per-user connectors act as that user for every
56
- member. Never add a second Connecta connection or mount downstream tools
57
- directly.
49
+ `<agent>` for the lowest and `<agent>-<tier>` above it. Every pool lists
50
+ only people or only `agent:` references; mixing them throws at
51
+ construction. Tiers and `<agent>-<user>` pools list only the agent. People
52
+ with a tier's reach get their own people-only pool (for example `team`
53
+ beside `assistant-team`) spreading the same tool-list constant. A chat gets
54
+ the most capable tier everyone present is cleared for, and the lowest when
55
+ anyone present is unknown. `<agent>-<user>` (that user's highest tier plus
56
+ their own connector ids, `owner` set to their Workspace address) is used
57
+ only in a one-on-one with that user. Never add a second Connecta connection
58
+ or mount downstream tools directly.
58
59
  - Brand the operator UI in `operatorUi({ branding })`: product and owner names,
59
60
  description, favicon, and `theme` (`accent`, `radius`, `fontFamily`,
60
61
  `monoFamily`, `colorScheme`). Ask the deployment's owner for their brand
@@ -19,19 +19,9 @@ npm start
19
19
  ```
20
20
 
21
21
  Keep the template's pinned `undici` dependency and its `listen` import from
22
- `@zackbart/connecta/node`. `listen` installs the owned HTTP transport used by
23
- every maintained-provider request, reads included, remote MCP writes, and
24
- downstream OAuth token, registration and revocation POSTs.
25
- Without `listen()`, maintained-provider writes, reviewed POST reads and remote
26
- MCP writes are refused before sending; downstream OAuth credential POSTs also
27
- require the owned sender. It connects directly by default. For an HTTP(S) CONNECT
28
- proxy, configure `listen(connecta, { port, proxy: "http://proxy.example.com:8080" })`
29
- in `src/index.ts`. Ambient proxy variables and host dispatchers do not configure
30
- the owned sender. Remote MCP reads and OAuth discovery GETs retain native fetch
31
- and need their own host proxy policy. An uncertain refresh requires fresh
32
- authorization rather than replaying the spent token. See
33
- [Node transport requirements](https://github.com/zackbart/connecta/blob/main/documentation/deploying.md#start-on-node)
34
- for proxy credentials and TLS trust.
22
+ `@zackbart/connecta/node`. Follow the
23
+ [Node transport and proxy requirements](https://github.com/zackbart/connecta/blob/main/documentation/deploying.md#start-on-node)
24
+ when changing `src/index.ts` or configuring egress.
35
25
 
36
26
  The manifest approves only `esbuild@0.28.2` to run its install script. `tsx`
37
27
  uses esbuild to run this TypeScript source, so that script is part of the
@@ -128,19 +118,12 @@ first use, and commits one row per write. Back it up as one file, together
128
118
  with its `-wal` file while the server runs. Node 22 and 23 print an
129
119
  experimental-feature warning for `node:sqlite` once at startup.
130
120
 
131
- Upgrading from 0.28, which kept state in `.connecta-state.json`: stop the
132
- server, then copy the old file into the database once, before the first start:
133
-
134
- ```sh
135
- npx connecta migrate-state .connecta-state.json .connecta.sqlite
136
- ```
137
-
138
- In the container, mount the old file and import it into the volume:
139
- `docker compose run --rm -v "$PWD/.connecta-state.json:/import/state.json:ro"
140
- connecta npx connecta migrate-state /import/state.json /data/connecta.sqlite`. It copies every live entry with its expiry, keeps any
141
- key the database already holds, and never changes the old file; delete that
142
- once the deployment is verified. The 0.28 activity log
143
- (`.connecta-activity.jsonl`) is not imported; history starts fresh.
121
+ Upgrading from the pre-SQLite JSON state format requires importing it with
122
+ Connecta 0.37.1 before installing the release that removes migrations. The
123
+ current package has no `importStateFile` or `connecta migrate-state`; SQLite
124
+ never reads `.connecta-state.json`. Follow the installed package's
125
+ `documentation/migration-retired-layouts.md`, including opening every OAuth
126
+ grant on 0.37.1, before changing the pin.
144
127
 
145
128
  A build with no lockfile in the context resolves the pinned Connecta version
146
129
  itself, and a lockfile npm writes inside the image never reaches this project.