@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
@@ -0,0 +1,135 @@
1
+ # Operating an endpoint
2
+
3
+ Use this guide as an agent connected to an existing Connecta endpoint. Setup
4
+ and credentials are the deployment operator's responsibility; use
5
+ [Deploying Connecta](./deploying.md) if you are that operator.
6
+ [All agent routes](./README.md) are in the index.
7
+
8
+ ## Choose the call path
9
+
10
+ Connecta exposes six top-level tools. Read [the tool table](./meta-tools.md#the-six-tools)
11
+ for exact arguments and result envelopes. Follow the endpoint's supplied
12
+ instructions and `skills` usage guide for deployment-specific context.
13
+
14
+ | Work | Use |
15
+ | ------------------------------------------------------------------ | --------------------------------------------------------- |
16
+ | One known read, with usable arguments and a small result | `call_tool` |
17
+ | Discover a tool, chain calls, combine services, or reduce a result | `execute_code` |
18
+ | One write on a read-only endpoint | `call_destructive_tool` |
19
+ | Obtain connector instructions | `skills` with the returned guide name |
20
+ | Start a required authentication handoff | `authorize_connector`, using the returned recovery action |
21
+
22
+ The endpoint's trust is part of its tool descriptions. On a `trusted` endpoint,
23
+ programs may write within the caller's grants, and `execute_code` is annotated
24
+ as a write. On `read-only`, every write is a separate top-level call. The host
25
+ controls approval. Never change pool, identity, or trust to work around a refusal.
26
+ [Routing between the call surfaces](./meta-tools.md#routing-between-the-call-surfaces)
27
+ owns the full decision rules.
28
+
29
+ ## Discover before guessing
30
+
31
+ Use two to four distinctive action/object terms for each operation, and name
32
+ the connector when it is obvious. Read `catalogErrors`, `absence`, classification,
33
+ and required inputs before selecting a result. An empty search may mean a
34
+ failed catalog or a service outside the caller's grants.
35
+
36
+ For normal reads, keep discovery, calls, and reduction in one program when the
37
+ schemas suffice; return the answer rather than catalog matches. Use top-level
38
+ `search_tools` for catalog inspection or to discover a write on a read-only
39
+ endpoint, then dispatch each write with `call_destructive_tool`. An unfamiliar
40
+ read result may return a bounded sample for inspection before the next program.
41
+
42
+ Use the exact returned `address`, including punctuation. A TypeScript signature
43
+ is guidance for writing JavaScript; do not paste types into executable code.
44
+ If a schema is truncated or exact constraints matter, describe the address with
45
+ `format: "json"`. Read a returned `guide` through `skills` or
46
+ `connecta.skill` before relying on provider-specific conventions.
47
+ [Discovery context](./meta-tools.md#discovery-context) and
48
+ [guest search](./code-mode.md#connectasearch) define these results.
49
+
50
+ ## Call, combine, and reduce
51
+
52
+ A program is one JavaScript `async` arrow expression. It has the `connecta`
53
+ guest API and captured console output, with no portable imports, filesystem,
54
+ network access, or credentials. Downstream calls return an envelope; read its
55
+ `data` rather than treating the envelope as the provider's result.
56
+
57
+ This illustrative tracker has a `list_issues` read accepting `state` and
58
+ returning `data.nodes`. Discover its address, call it, and group the identifiers
59
+ in one program:
60
+
61
+ ```js
62
+ async () => {
63
+ const page = await connecta.search({
64
+ connector: "tracker",
65
+ query: "list issues",
66
+ safety: "readOnly",
67
+ });
68
+ if (page.catalogErrors.length || page.absence) {
69
+ return { gap: page.catalogErrors, absence: page.absence };
70
+ }
71
+ const tool = page.tools.find(t => t.name === "list_issues");
72
+ if (!tool) return { gap: "list_issues unavailable" };
73
+ const { data, format } = await connecta.call(tool.address, {
74
+ state: "started",
75
+ });
76
+ if (format !== "json" || !Array.isArray(data?.nodes)) {
77
+ return { gap: "Expected a JSON issues collection" };
78
+ }
79
+ const byOwner = Object.create(null);
80
+ for (const issue of data.nodes) {
81
+ const owner = issue.assignee?.name ?? "unassigned";
82
+ (byOwner[owner] ??= []).push(issue.identifier);
83
+ }
84
+ return byOwner;
85
+ }
86
+ ```
87
+
88
+ `tracker.list_issues` is illustrative, not a built-in address. Discover the real
89
+ connector's schemas and pagination before adapting this program. Keep loops and
90
+ parallel work bounded. [Parallel calls](./code-mode.md#parallel-calls),
91
+ [results and projection](./code-mode.md#results-and-projection), and
92
+ [cancellation and limits](./code-mode.md#cancellation-and-limits) own those rules.
93
+
94
+ Discovery may label an output schema `observed`. It records field names and
95
+ broad types from successful reads in bounded runtime memory, with no scalar
96
+ values. Treat it as evidence, not a provider contract; handle missing fields.
97
+
98
+ ## Large results and resources
99
+
100
+ Direct calls may return a preview and a result handle. Page the handle through
101
+ `connecta.result` in a program using the returned offset and byte limits, or
102
+ reduce the data in the original program. Handles are short-lived and bound to
103
+ the admitted caller, endpoint/pool, and current grants. Never invent one or pass
104
+ it between identities. [Paging](./meta-tools.md#paging-with-connectaresult)
105
+ owns the envelope and expiry rules.
106
+
107
+ For resources, use the exposed resource inventory and `connecta.read`; do not
108
+ fetch an arbitrary URL. [Resource reads](./code-mode.md#connectaread) describe
109
+ which URIs may be read. Connector guides and native skills are described in
110
+ [skills](./meta-tools.md#connector-guides-and-skills).
111
+
112
+ ## Recover without replaying a write
113
+
114
+ Read typed failures and their `nextAction`. Authorization recovery can point
115
+ to consent, operator credential setup, or deployment configuration. Discovery
116
+ and status do not begin consent on their own. Follow
117
+ [authorization recovery](./meta-tools.md#authorization-recovery),
118
+ [routing recovery](./meta-tools.md#routing-recovery), and
119
+ [argument recovery](./meta-tools.md#argument-recovery) for the specific failure.
120
+
121
+ A dispatched write is never automatically replayed. An ambiguous timeout may
122
+ mean the provider applied it; inspect state or ask for the missing decision
123
+ before issuing it again. [Retry semantics](./code-mode.md#retry-semantics) and
124
+ [writes](./code-mode.md#writes) describe program outcomes and write accounting.
125
+
126
+ ## Implementation and evidence
127
+
128
+ The endpoint's built-in [usage skill](https://github.com/zackbart/connecta/blob/main/src/skills.ts)
129
+ is maintained alongside [meta-tools](https://github.com/zackbart/connecta/blob/main/src/meta-tools.ts)
130
+ and [execution](https://github.com/zackbart/connecta/blob/main/src/execute.ts).
131
+ [Usage-guide tests](https://github.com/zackbart/connecta/blob/main/test/usage-guide.test.ts),
132
+ [direct-call tests](https://github.com/zackbart/connecta/blob/main/test/meta-tools-call.test.ts),
133
+ and [guest-contract tests](https://github.com/zackbart/connecta/blob/main/test/guest-api-contract.test.ts)
134
+ check the contracts. Executor-specific evidence is indexed in
135
+ [code-mode verification](./code-mode.md#verification).
@@ -0,0 +1,97 @@
1
+ # Operator UI tests
2
+
3
+ Use this repository-maintenance guide when changing operator pages, data routes,
4
+ or browser evidence. Read the [operator UI contract](./operator-ui.md) first.
5
+ [The agent index](./README.md) routes deployment and endpoint tasks.
6
+
7
+ `test/fixtures/operator-visual.ts` owns the visual data. It builds the config,
8
+ live overlay, viewer, and legacy auth details through the current server routes,
9
+ using the types in `src/operator-ui/contract.ts` and `model.ts`. Collections use
10
+ their corresponding browser types. `test/operator-visual-fixtures.test.ts`
11
+ validates contract versions, connector IDs, granted tools, classification,
12
+ permissions, provenance, and secret exclusion on Node and Workers. A fixture's
13
+ config cannot silently become a stale copy of the server serializer.
14
+
15
+ `test/browser/operator-visual.spec.ts` intercepts API reads and serves the real
16
+ hashed assets and HTML with the production CSP. Loading responses wait on an
17
+ explicit gate. Error responses use fixed HTTP failures. Screenshots use a fixed
18
+ clock, UTC, en-US, locally hosted fonts, disabled animations, hidden carets,
19
+ and a 1280 × 900 viewport. Narrow fixtures use 390 × 844. Every test waits for
20
+ its state and fonts before capturing.
21
+
22
+ ## Page and state matrix
23
+
24
+ Each row runs empty, loading, error, populated, and restricted-viewer fixtures
25
+ in both light and dark themes, for 120 screenshots.
26
+
27
+ | Page or tab | Empty state | Loading/error request | Restricted viewer |
28
+ | --------------------- | ------------------------------------ | --------------------- | --------------------------------------------------- |
29
+ | Overview | No connectors or attention items | Config | Scoped connectors, no privileged navigation |
30
+ | Connectors | No connectors | Config | Read grant and credential slot, no other connectors |
31
+ | Connector Config | Zero-tool connector | Config | Scoped connector snapshot |
32
+ | Connector Tools | Empty catalog | Config | Read tool only |
33
+ | Connector Auth | Deployment-managed auth | Config | Visible slot, deployment-managed auth |
34
+ | Connector Activity | No calls | Activity | Unavailable |
35
+ | Connector Diagnostics | No observed drift/call | Config | Scoped diagnostics |
36
+ | Tools | Empty catalog | Config | Read tool only |
37
+ | Access | No pools or client tokens | Config | No token management |
38
+ | Access tokens | No client tokens | Token list | No token management |
39
+ | Activity | No calls | Activity | Unavailable |
40
+ | Config | Snapshot without connectors or pools | Config | Scoped snapshot |
41
+
42
+ Another 36 screenshots cover configured, mismatched, unreadable and multifield
43
+ credentials; all three OAuth client mechanisms; clean and unobserved drift;
44
+ historical Activity; client setup; schema dialog; read/write filters; expanded
45
+ config provenance; narrow sign-in and Auth; and deployment branding. The base
46
+ populated Activity fixture includes grouped calls, an ungrouped legacy row,
47
+ classification/result size/client facts, and a catalog-change event.
48
+
49
+ Screenshots cover presentation. Keep unit and server tests for INV-6 sentinels,
50
+ secret disclosure, auth and grant boundaries, CSRF, identity fences, cancellation,
51
+ request lifetime, and error sanitization. Keep browser tests for keyboard/focus,
52
+ XSS, real CSP enforcement, and popup lifetimes. A screenshot
53
+ cannot prove these rules.
54
+
55
+ ## Updating Linux snapshots
56
+
57
+ The source of truth is `*-linux.png`, produced on `ubuntu-latest` with the
58
+ lockfile's Playwright Chromium. Both CI workflows use the same runner, Node 22,
59
+ and `npm run test:browser:install -- --with-deps`. macOS runs fixture routing and
60
+ readiness checks but omits screenshot comparison. The update script refuses
61
+ non-Linux hosts. Do not commit Darwin baselines.
62
+
63
+ When Docker is unavailable, use the **Operator snapshots** workflow:
64
+
65
+ ```sh
66
+ git push --force-with-lease origin feat/p4-ui-tests
67
+ gh workflow run operator-snapshots.yml --ref feat/p4-ui-tests
68
+ # Read the completed run ID from the Actions page or gh run list.
69
+ gh run download RUN_ID --name operator-linux-snapshots \
70
+ --dir test/browser/operator-visual.spec.ts-snapshots
71
+ ```
72
+
73
+ The workflow uploads all generated baselines and never commits them. Review the
74
+ images and changed files, commit the intentional changes, and push again. The
75
+ normal CI browser job must compare and pass against that commit. Opening the
76
+ initial PR also runs the update workflow, so the first baselines can be generated
77
+ before the workflow reaches main. Later updates use `workflow_dispatch`.
78
+
79
+ On a matching Linux runner, `npm ci`, install Chromium with the command above,
80
+ then run `npm run test:browser:snapshots`. The normal command is
81
+ `npm run test:browser`. Missing baselines fail CI; retries cannot bless them.
82
+ Set `OPERATOR_VISUAL_INSPECT=1` to retain local screenshots under ignored
83
+ `test-results/` for inspection, without updating committed baselines.
84
+
85
+ ## Real-server flows
86
+
87
+ `test/browser/operator-flows.spec.ts` uses `listen()` from `src/node.ts` with
88
+ loopback TCP servers. It intercepts only Clerk provider traffic with a test
89
+ publishable key; server identity uses the existing `fakeClerkAuth` seam. The
90
+ OAuth provider validates the code exchange and PKCE. Credential Test calls a
91
+ loopback downstream endpoint. Operator APIs, cookie/bearer admission, CSRF,
92
+ assets, handoffs, callbacks, and encrypted storage use production code.
93
+
94
+ The flows cover Clerk sign-in/reload/sign-out; OAuth connect/consent/callback/
95
+ connected reread/reload; and credential save/test/replace/remove. They collect
96
+ CSP violations across every document and popup, and fail on unexpected network
97
+ traffic. No credentials enter visual fixtures or screenshot baselines.
@@ -0,0 +1,132 @@
1
+ # Operator UI
2
+
3
+ Use this guide to enable or maintain the optional operator interface. For
4
+ client tool calls use [Operating an endpoint](./operating.md); for identities,
5
+ credential ownership, and grants use [Auth](./auth.md).
6
+ [All agent routes](./README.md) are in the index.
7
+
8
+ ## Task routes
9
+
10
+ | Task | Read |
11
+ | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
12
+ | Enable UI, vault, or history in a deployment | [Setup](#setup), then the platform template |
13
+ | Consume config, provenance, status, or activity | [Operator data contract](#operator-data-contract) |
14
+ | Change a UI page or data route | [Source and tests](#source-and-tests), [browser verification](./operator-tests.md) |
15
+ | Diagnose permission refusals | [Management permissions](./auth.md#management-permissions), [activity disclosure below](#operator-data-contract) |
16
+
17
+ ## Setup
18
+
19
+ Set `ui: operatorUi()` using `@zackbart/connecta/ui`. Branding belongs in
20
+ `operatorUi({ branding })`; the [Node template](../templates/node/README.md#select-optional-modules)
21
+ and [Worker example](../examples/worker/README.md#select-optional-modules)
22
+ own the runnable configuration, variables, and branding shape. The UI is an
23
+ explicit optional import and stays outside the root package import graph.
24
+
25
+ Overview, Connectors, Tools, Access, Activity, and Config show only what the
26
+ caller may inspect. Connector detail tabs cover configuration, schemas,
27
+ authentication, activity, and diagnostics. Config labels values as default or
28
+ configured. Deployment code owns connectors, grants, pools, and classification;
29
+ the UI changes only authorized authentication material.
30
+
31
+ Install the vault for declared credential slots and activity history for
32
+ persisted call records. Neither module grants permission to manage or read
33
+ it. Credential administration, personal connection, access-token management,
34
+ and activity access are separate identity decisions, denied by default where
35
+ specified in [auth](./auth.md#management-permissions). Machine tokens never
36
+ grant interactive credential or token management authority.
37
+
38
+ ## Operator data contract
39
+
40
+ `GET /ui/api/config`, owned by `operatorUi()`, returns `OperatorUiContract`
41
+ from `connecta/ui`. `src/operator-ui/contract.ts` is also the browser's type
42
+ source. The response has `schemaVersion: 1`, `config`, `configSources`, `live`, and `you`.
43
+ `config` is the construction-time `describeConfig()` snapshot, filtered to
44
+ visible connectors, granted tools, classification overrides, and admitted
45
+ pools. Pool tools are the intersection with the caller's identity grants.
46
+ `configSources` labels each serialized leaf as `default` or `config`, based on
47
+ option presence rather than equality with the default. Factory descriptions carry
48
+ relative `optionSources` paths so resolved module and transport defaults retain
49
+ their provenance. The snapshot copies only resolved values; the UI consumes
50
+ these presence facts separately. Its paths use connector
51
+ ids and pool names and are filtered after disclosure; hidden values leave no
52
+ provenance keys. It contains no source code or credential material.
53
+ Every response is private, `no-store` JSON. Only GET is allowed, with the
54
+ same auth gate and identity partition as `/ui/data` and `/ui/connectors/:id`.
55
+
56
+ `live.connectors` carries status and problem codes, complete registry tools
57
+ with their final read/write classification, catalog age in milliseconds, and
58
+ last-call time/outcome. Catalog descriptions and schemas are allowed for an
59
+ authenticated reader; grammar-failing names and addresses become `<withheld>`.
60
+ `auth.registrationPath` reports the selected downstream OAuth client mechanism when known.
61
+ Status prose, error text, credential values or suffixes, arguments, results,
62
+ and code are excluded. Static and unobserved catalogs have a null age;
63
+ persisted catalogs retain their original fetch time. Probes run with bounded
64
+ concurrency and the configured probe deadline, and release their scopes.
65
+
66
+ Last-call lookup requires the existing activity permission and read gate. It
67
+ scans up to 1,000 recent rows, filters connector/tool grants, and restricts
68
+ personal connectors to the caller's activity identity. Each retained fact
69
+ copies a validated timestamp and outcome only. A null call means unknown or
70
+ absent in that window, not proof of no calls. `live.activity` distinguishes
71
+ available, unconfigured, forbidden, and unavailable history. `you` names no
72
+ identity or auth material; it reports grants, root and admitted-pool trust,
73
+ and effective activity, token, and per-connector auth permissions.
74
+
75
+ `connecta doctor --config` fetches this authenticated contract and prints only
76
+ `config` as indented JSON. It requires the UI module and the existing doctor
77
+ authentication environment variables; it runs no diagnostic program, follows
78
+ no redirects, and prints no raw HTTP failure body.
79
+
80
+ The operator shell uses React, TanStack Router/Query/Table, Radix, cmdk and
81
+ Tailwind v4. Inter, CSS, JavaScript and dependency notices are hashed assets
82
+ under `/ui/assets/*`, served identically with immutable cache headers on Node
83
+ and Workers. HTML contains only mount points and escaped inert configuration;
84
+ it remains uncached. `generated.ts` is ignored and generated before build and
85
+ test; `check:operator-ui` detects stale assets and shared page styles. The UI
86
+ stays behind `./ui`, outside the root import graph. The identity-fenced store
87
+ owns authenticated reads and existing mutations. Overview, Connectors, connector
88
+ detail, Tools, Access and Config consume the typed contract. Activity retains
89
+ its authenticated data routes. Connector detail tabs live
90
+ in the URL hash; Activity filters live in the query string and apply to loaded
91
+ history. Both `/ui/activity` and `/ui/api/activity` require Activity access and
92
+ pass the optional activity `readGate`. Interactive operators and machine callers
93
+ admitted by `identity.activityAccess` share the same history disclosure rules.
94
+ Connector/tool grants and grants for the recorded pool filter each event. Shared
95
+ connector history can include other principals' events, with recorded request
96
+ IDs, validated client name/version and package version, and actor kind, ID and
97
+ namespace. Interactive reads may also add directory actor labels; machine reads
98
+ never add them. Personal connector history is owner-only: the event must have a
99
+ checked `principal` actor basis and actor ID/namespace matching the reader's
100
+ admitted principal. Rows without a provable personal owner are withheld. Activity
101
+ carries no arguments, results, code or raw downstream errors. The last-call
102
+ overlay uses the same event filter but returns only timestamp and outcome.
103
+ Calls group only by recorded request ids, with missing ids shown as
104
+ separate calls. Classification and result size are shown only when recorded. The verdict is
105
+ captured after registry resolution, and result size counts UTF-8 bytes of the
106
+ downstream value before paging or truncation. Nullable SQL columns preserve old
107
+ rows. Catalog changes use the same paging envelope with `kind: "catalog_drift"`,
108
+ `source: "catalog_refresh"` and a checked `catalog_changed` fact containing only
109
+ added, removed and changed tool counts. The first complete catalog is a baseline;
110
+ one refresh-publication hook emits each later change. It includes the request's
111
+ id and typed actor when available, otherwise a fresh id and system actor. No
112
+ names, descriptions or schemas enter the event. Private catalog changes require
113
+ a matching principal owner even when the connector uses shared auth. Empty credential declarations
114
+ report `credential_required` before running a connector status or catalog probe.
115
+ The Access adapter reports inbound provider kinds, admitted pools, grants, trust
116
+ and endpoint setup; token controls retain their existing permission gate.
117
+ Configuration remains in deployment code. The UI mutates only credentials,
118
+ OAuth connections and client tokens through the existing routes.
119
+
120
+ ## Source and tests
121
+
122
+ The contract type is [contract.ts](https://github.com/zackbart/connecta/blob/main/src/operator-ui/contract.ts).
123
+ [UI routes](https://github.com/zackbart/connecta/blob/main/src/routes/ui.ts) and
124
+ [UI implementation](https://github.com/zackbart/connecta/blob/main/src/ui.ts)
125
+ serve the authenticated shell and data. The browser lives in
126
+ [src/operator-ui](https://github.com/zackbart/connecta/tree/main/src/operator-ui).
127
+ [UI tests](https://github.com/zackbart/connecta/blob/main/test/ui.test.ts),
128
+ [credential-route tests](https://github.com/zackbart/connecta/blob/main/test/ui-credentials.test.ts),
129
+ [config snapshot tests](https://github.com/zackbart/connecta/blob/main/test/describe-config.test.ts),
130
+ and [browser flows](https://github.com/zackbart/connecta/blob/main/test/browser/operator-ui.spec.ts)
131
+ defend filtering and behavior. Use [Operator UI tests](./operator-tests.md)
132
+ for the browser state matrix and Linux snapshot procedure.
@@ -0,0 +1,65 @@
1
+ # Notion, Vercel and Cloudflare migration for 0.29
2
+
3
+ Use this upgrade guide for an existing deployment.
4
+ [Deployment upgrades](./deploying.md#upgrade-an-existing-deployment) cover other
5
+ version changes; [integrating services](./integrating.md) covers new connectors.
6
+ [The agent index](./README.md) routes package maintenance separately.
7
+
8
+ This is the Phase 1 item 5d migration input for [Phase 5 release #709](https://github.com/zackbart/connecta/issues/709).
9
+ Deploy it with the consolidated 0.29 release, not while the rework is in progress.
10
+ BePresent and One&Many use Notion and Cloudflare; their actual grants and
11
+ connector ids must be checked in deployment configuration before that release.
12
+ The provider audit establishes available auth modes, not production OAuth grants.
13
+
14
+ All three providers now default to hosted MCP. `surface: "api"` explicitly
15
+ selects a REST complement and accepts only its API-specific options. The old
16
+ Vercel/Cloudflare API modes are no longer complete alternatives; Notion retains
17
+ all operations required by its distinct integration identity. Adding `surface: "api"` keeps
18
+ REST reads/gaps but does not restore removed duplicates. For both sets of
19
+ capabilities, configure both connectors under distinct ids and authorize each.
20
+
21
+ ```ts
22
+ connectors: [
23
+ notion("notion", { purpose: "Workspace content" }),
24
+ notion("notion_rest", { surface: "api", purpose: "Internal integration content and exact REST operations" }),
25
+ cloudflare("cloudflare", { purpose: "Estate mutations", auth: { type: "credential" } }),
26
+ cloudflare("cloudflare_rest", { surface: "api", purpose: "Estate reads and byte/header operations", accountId: "account-id", zoneId: "zone-id" }),
27
+ ]
28
+ ```
29
+
30
+ Notion preserves headless/internal-integration capabilities. Add explicit
31
+ `surface: "api"` to retain that identity and migrate old REST names to
32
+ `integration_*`, for example `search` to `integration_search`, `create_page`
33
+ to `integration_create_page`, and `query_data_source` to
34
+ `integration_query_data_source`. Its token/sharing boundary stays intact.
35
+ Hosted MCP acts as an OAuth user, has its own grant, and cannot adopt an internal
36
+ token. Use it for user-owned work and hosted-only capabilities; authorize it
37
+ explicitly if those are needed. Do not replace a bot with a user as an auth fix.
38
+ All REST pagination, exact JSON blocks/properties, trash/restore and bot-owned
39
+ content writes remain available.
40
+
41
+ For Cloudflare, migrate ordinary JSON writes to hosted `search` then `execute`.
42
+ A scoped API token can authorize hosted MCP without interactive OAuth; configure
43
+ that credential independently even if it has the same value as the REST token.
44
+ Keep REST reads in read-only programs. Global API Key/email and R2 jurisdiction/storage-class
45
+ JSON mutations, plus byte/header-compatible uploads, stay in the explicit REST
46
+ complement. Replace `update_r2_bucket` with `cloudflare_api_mutate` using
47
+ `PATCH /accounts/{accountId}/r2/buckets/{bucketName}` and the header
48
+ `cf-r2-storage-class` set to `Standard` or `InfrequentAccess`. Omit the body;
49
+ include `cf-r2-jurisdiction` only when the bucket needs it. This remains a write.
50
+ `execute` remains a write even when its program only calls GET.
51
+ Trusted pools may execute writes; read-only pools use direct host-approved writes.
52
+
53
+ For Vercel, authorize the owning teams in hosted OAuth, migrate discovery/logs,
54
+ domain listing/adding, deployment cancellation and file uploads to live MCP
55
+ schemas, and keep the independently authorized REST complement for value-safe
56
+ project environment variables (including `upsert: false` create-only writes), domain verification/removal and deployment
57
+ deletion. Promotion now uses hosted `request_promote` from the rolling-releases
58
+ category. Raw hatches refuse all published REST counterparts, including project
59
+ creation/update. Do not copy REST argument
60
+ shapes into vendor tools, even when a tool name is unchanged.
61
+
62
+ The per-provider tables map every removed name and explain retained API tools:
63
+ [Notion](https://github.com/zackbart/connecta/blob/main/src/providers/notion/reconciliation.md),
64
+ [Vercel](https://github.com/zackbart/connecta/blob/main/src/providers/vercel/reconciliation.md), and
65
+ [Cloudflare](https://github.com/zackbart/connecta/blob/main/src/providers/cloudflare/reconciliation.md).
@@ -2,12 +2,18 @@
2
2
 
3
3
  This repository is deployment configuration, not a copy of Connecta itself.
4
4
 
5
- - Edit `src/index.ts` for connectors, authentication, storage, and public URL.
6
- - Keep `cloudflareAccessAuth()` as the inbound auth provider. Cloudflare Access
7
- authenticates the request before the Worker runs; do not add JWT parsing or a
8
- second Worker-side identity gate.
5
+ - Edit `src/connecta.config.ts` for connectors, authentication, storage, public
6
+ URL, and optional modules. `src/index.ts` only starts it. Set plain vars
7
+ `CONNECTA_ACTIVITY="on"` for preserved activity.
8
+ - Keep `cloudflareAccessAuth()` for human identity and `accessTokens(storage)`
9
+ always installed over the same `CONNECTA_DB` for machines. Cloudflare Access
10
+ admits the request before the Worker runs; a service identity alone is
11
+ refused inside connecta. Do not add JWT parsing or another identity gate.
12
+ Grant `identity.accessTokenManagement` explicitly to interactive operators;
13
+ this example permits every signed-in human to manage connectors and tokens.
9
14
  - Attach Access to the Worker itself, not only its hostname. Enable Managed
10
- OAuth and Dynamic Client Registration on that Access application.
15
+ OAuth on that Access application. CIMD is the spec's preferred client
16
+ registration; enable DCR as the fallback Access currently requires.
11
17
  - Managed OAuth's **Allowed redirect URIs** must contain all three entries
12
18
  below. This is application configuration under
13
19
  `oauth_configuration.dynamic_client_registration.allowed_uris`, not an
@@ -25,24 +31,40 @@ This repository is deployment configuration, not a copy of Connecta itself.
25
31
  allowed. If a client presents a different callback, copy that exact URI from
26
32
  its registration attempt and add the narrowest matching entry rather than
27
33
  broadening the allowlist to an entire origin.
28
- - Keep `new DynamicWorkerExecutor({ loader: env.LOADER })` loader-only. Do not
34
+
35
+ - Keep `workerExecutor({ loader: env.LOADER })` loader-only. Do not
29
36
  add bindings, modules, or outbound access to generated code.
37
+ Import it from `@zackbart/connecta/worker`; direct upstream
38
+ `new DynamicWorkerExecutor()` construction throws at boot. Keep the
39
+ `@cloudflare/codemode` optional peer installed.
30
40
  - Keep credentials in Worker secrets. Never commit credential values, Access
31
41
  service-token secrets, or `CREDENTIAL_ENCRYPTION_KEY`.
42
+ - All state lives in the one D1 database bound as `CONNECTA_DB`, through
43
+ `d1Storage` (and `d1ActivityStore`) from `@zackbart/connecta/d1`. Do not add
44
+ a KV namespace, a second database, or a copied storage adapter; connecta
45
+ creates its own tables. The only KV binding is in `kv-to-d1.wrangler.jsonc`,
46
+ which is never deployed. It exists for the one-shot copy from a 0.28 Workers
47
+ KV deployment (README.md § "Upgrading from 0.28"). Back up, block traffic
48
+ and background writers, drain, wait for stable KV, copy and verify, deploy
49
+ while maintenance remains, then mark cutover before reopening traffic. Never
50
+ rerun stale KV after cutover. Retain backups before removing KV.
32
51
  - Add application logic only inside deliberate `api()` connector handlers.
33
52
  Do not copy or modify Connecta package internals here.
34
53
  - Prefer `api()` when the agent must see an exact reviewed capability set;
35
54
  `remoteMcp()` follows the downstream server's evolving tool catalog.
36
- - Use Access service credentials for `connecta doctor` and unattended clients.
37
- A configured Connecta bearer cannot cross the Access edge alone. Connecta-issued
38
- tokens are removed. UI, vault, and activity use explicit optional imports;
55
+ - Unattended clients and `connecta doctor` need Access service credentials
56
+ plus a stored `cta_` bearer. Set `CF_ACCESS_CLIENT_ID`,
57
+ `CF_ACCESS_CLIENT_SECRET`, and `CONNECTA_TOKEN` together for doctor.
58
+ Bootstrap tokens through the Access-authenticated operator page or trusted
59
+ `AccessTokenManager.create` tooling against this same D1 storage, as README
60
+ "Machine tokens" describes. Never configure a static bearer or open startup.
61
+ UI, vault, and activity use explicit optional imports;
39
62
  auth changes require code-derived shared or personal management permissions.
40
63
  - Brand the operator UI in `operatorUi({ branding })`: product and owner names,
41
64
  description, favicon, and `theme` (`accent`, `radius`, `fontFamily`,
42
65
  `monoFamily`, `colorScheme`). Ask the deployment's owner for their brand
43
- rather than leaving the default. The commented block above
44
- `ui: operatorUi()` in `src/index.ts` shows the shape; README "UI and
45
- encrypted credentials" covers the rest.
66
+ rather than leaving the default. README "UI and encrypted credentials" shows
67
+ the shape.
46
68
  - After configuration changes, typecheck: inside the connecta repository that
47
69
  is `npm run check:examples`; a copied deployment runs its own `tsc --noEmit`.
48
70
  After deployment, connect both Claude and ChatGPT to `<PUBLIC_URL>/mcp` and