@zackbart/connecta 0.16.1 → 0.18.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.
- package/CHANGELOG.md +180 -0
- package/README.md +4 -0
- package/dist/catalog-service.d.ts +10 -0
- package/dist/catalog-service.js +77 -5
- package/dist/catalog.js +114 -12
- package/dist/errors.d.ts +4 -6
- package/dist/execute.d.ts +7 -0
- package/dist/execute.js +262 -168
- package/dist/invocation.js +3 -1
- package/dist/meta-tools.d.ts +4 -0
- package/dist/meta-tools.js +55 -23
- package/dist/operator-ui/generated.d.ts +1 -1
- package/dist/operator-ui/generated.js +1 -1
- package/dist/operator-ui/model.d.ts +3 -1
- package/dist/providers/mixpanel.d.ts +3 -5
- package/dist/providers/mixpanel.js +73 -5
- package/dist/providers/stripe.d.ts +25 -24
- package/dist/providers/stripe.js +64 -35
- package/dist/registry.d.ts +32 -9
- package/dist/registry.js +217 -33
- package/dist/routes/mcp.js +6 -0
- package/dist/routes/ui.js +1 -1
- package/dist/skills.d.ts +5 -1
- package/dist/skills.js +206 -30
- package/dist/types.d.ts +14 -2
- package/dist/ui.js +4 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/architecture.md +8 -5
- package/documentation/code-mode.md +68 -68
- package/documentation/connector-guides.md +29 -27
- package/documentation/connectors.md +13 -1
- package/documentation/meta-tools.md +53 -19
- package/documentation/mixpanel.md +20 -0
- package/documentation/notion.md +17 -0
- package/documentation/operations.md +24 -21
- package/documentation/operator-ui.md +12 -2
- package/documentation/provider-audit.md +15 -7
- package/documentation/provider-conventions.md +26 -13
- package/documentation/stripe.md +66 -59
- package/documentation/upgrading.md +46 -4
- package/ethos.md +7 -7
- package/examples/worker/README.md +4 -3
- package/package.json +2 -2
- package/templates/node/README.md +7 -0
- package/templates/node/package.json +5 -2
|
@@ -8,15 +8,18 @@ needs most.
|
|
|
8
8
|
|
|
9
9
|
`createConnecta(config)` returns `{ fetch, registry, close }`. `fetch` takes
|
|
10
10
|
the Workers `(request, env, ctx)` signature; passing `ctx` through is what lets
|
|
11
|
-
connecta hand deferred work
|
|
12
|
-
|
|
11
|
+
connecta hand deferred work to `ctx.waitUntil` instead of losing it when the
|
|
12
|
+
response returns. That work is best-effort activity writes and the bounded
|
|
13
|
+
refresh an agent catalog read already demanded while it served a complete stale
|
|
14
|
+
entry. Node's adapter tracks the same promises and drains them on shutdown.
|
|
13
15
|
|
|
14
16
|
An `executor` is required. A deployment without one throws at construction
|
|
15
17
|
rather than serving a smaller surface
|
|
16
18
|
([#273](https://github.com/zackbart/connecta/issues/273)): Node uses
|
|
17
19
|
`quickJsExecutor()` from `@zackbart/connecta/quickjs`, Workers use
|
|
18
20
|
`new DynamicWorkerExecutor({ loader: env.LOADER })` from
|
|
19
|
-
`@cloudflare/codemode`.
|
|
21
|
+
`@cloudflare/codemode`. The Worker executor must stay loader-only: `bindings`,
|
|
22
|
+
`modules`, and `globalOutbound` grant ambient guest authority.
|
|
20
23
|
|
|
21
24
|
Both executor packages are optional peers: they never install with connecta,
|
|
22
25
|
and a deployment installs the one its runtime needs. The manifest publishes the
|
|
@@ -84,7 +87,7 @@ optional.
|
|
|
84
87
|
| `discovery.concurrency?` | 4 | connector catalogs/status probes in flight at once |
|
|
85
88
|
| `discovery.catalogTtlSeconds?` | 300 | fresh TTL for cached tool lists |
|
|
86
89
|
| `discovery.persistCatalog?` | true | persist serializable catalogs as a manifest plus revision-addressed chunks |
|
|
87
|
-
| `discovery.staleCatalogSeconds?` | 3600 | how long
|
|
90
|
+
| `discovery.staleCatalogSeconds?` | 3600 | how long a complete expired catalog stays usable for agent SWR and as a refresh-failure fallback |
|
|
88
91
|
| `discovery.probeTimeoutMs?` | 30_000 | per-connector deadline for catalog fan-out; a timed-out connector degrades alone. Not a tool-call deadline |
|
|
89
92
|
| `calls.defaultTimeoutMs?` | **unset (opt-in)** | deadline for calls that pass no `timeoutMs`. Bounds one attempt, so retries can still extend total duration |
|
|
90
93
|
| `calls.maxResultBytes?` | 50_000 | inline result cap before truncation and `get_result` paging; a connector may override it. Invalid values warn and fall back |
|
|
@@ -180,7 +183,7 @@ Two more runners are deliberately outside `check`:
|
|
|
180
183
|
|
|
181
184
|
- `npm run test:browser` — Playwright against a real headless Chromium
|
|
182
185
|
(`npm run test:browser:install` once). It covers the embedded bundle without
|
|
183
|
-
adding a browser download to
|
|
186
|
+
adding a browser download to the CI release check.
|
|
184
187
|
- `npm run drift:check` — the maintainer-run provider drift check, with local
|
|
185
188
|
provider credentials exported. No credential goes near CI and nothing files
|
|
186
189
|
itself; findings are read by a human and become issues
|
|
@@ -221,36 +224,36 @@ in.
|
|
|
221
224
|
| `catalog.test.ts` | lexical ranking and the compact schema renderer — `const`, `allOf` beside siblings, `$ref`, the depth limit, per-schema caching, and 2020-12 keyword compatibility |
|
|
222
225
|
| `clerk.test.ts` | protected-resource metadata, the browser sign-in config, OAuth and session tokens, cached best-effort activity labels with their caps, the hand-applied `azp` rejection, and the `allowedDomains` allowlist including every lookalike that must not be repaired into a match |
|
|
223
226
|
| `cloudflare-provider.test.ts` | `cloudflare()` construction, tool surface, request building, projections, typed failures, and credential test |
|
|
224
|
-
| `cloudflare-registry.test.ts` | the same provider inside a real deployment: discovery, addressing, and admission through the registry |
|
|
225
|
-
| `code-first-surface.test.ts` | the seven-tool surface itself — an executor required
|
|
227
|
+
| `cloudflare-registry.test.ts` | the same provider inside a real deployment: discovery including compact page bounds, addressing, and admission through the registry |
|
|
228
|
+
| `code-first-surface.test.ts` | the seven-tool surface itself — an executor required, every removed option and top-level tool refused, compact always-loaded routing pinned below 1,000 characters, complete on-demand usage served, and `connecta.ui` findable before connector search |
|
|
226
229
|
| `codemode-compat.test.ts` | the `Executor` seam staying structurally compatible with `@cloudflare/codemode`'s `DynamicWorkerExecutor`, enforced by `tsc` |
|
|
227
230
|
| `config.test.ts` | the grouped `ConnectaConfig` boundary — each group forwarding to its internals, malformed admission bounds failing construction, and one complete migration error for legacy own-properties |
|
|
228
231
|
| `credentials.test.ts` | the pure stored-shape classifier (containment, not equality) and the AES-GCM vault: round-trip, ciphertext bound to its connector id, named field sets, masked metadata, wrong-key rejection, deletion, coexistence with OAuth keys |
|
|
229
232
|
| `d1-activity-example.test.ts` | the Worker example's deployment-owned D1 activity store: actor namespace round-trip, payload-free friction reconstructed from the persisted code, and agreement with the package's friction table |
|
|
230
233
|
| `downstream-oauth.test.ts` | `KvOAuthProvider` round-trips and races, `auth_required` versus `error`, `startAuth`/`finishAuth`, callback refusal equality, bounded diagnostics, and HTML escaping |
|
|
231
234
|
| `errors.test.ts` | `ConnectorCallError` codes, retryable defaults and overrides, `retryAfterMs` round-trip, typed-over-heuristic classification, `AbortError` as a retryable timeout, and framing errors |
|
|
232
|
-
| `execute.test.ts` | the code-mode host bridge: identifier sanitization, MCP-result unwrapping, sandbox provider construction, fail-closed filtering of destructive and unannotated tools,
|
|
235
|
+
| `execute.test.ts` | the code-mode host bridge: identifier sanitization, MCP-result unwrapping, sandbox provider construction, authenticated thrown-failure framing, fail-closed filtering of destructive and unannotated tools, MCP/code-mode invocation parity, and payload-free describe diagnostics |
|
|
233
236
|
| `execute-emit.test.ts` | `connecta.emit` (M1–M10) — block validation, budgets, the provider, delivery after the result envelope on success only, and the defaults |
|
|
234
237
|
| `execute-ui.test.ts` | `connecta.ui` (U1–U9) — validation, multiplicity and budget, the provider, `_meta` delivery, and the Apps shell |
|
|
235
238
|
| `executor-admission.test.ts` | the portable bounded FIFO both pools use: active and queue ceilings, stable retryable overload, queue timeout, cancellation removal, idempotent release, shutdown |
|
|
236
239
|
| `guarded-fetch.test.ts` | the guarded transport — construction, request building, destination confinement, and response handling |
|
|
237
|
-
| `guest-api-contract.test.ts` | the
|
|
240
|
+
| `guest-api-contract.test.ts` | the shared guest contract on the Dynamic Worker, including caught call, typed inline describe recovery, discovery, utility, batch, and budget failure codes; plus the real authority boundary — local `data:` fetch, denied egress, unresolved DNS, empty environment paths, unavailable filesystem/HTTP builtins, and present runtime globals |
|
|
238
241
|
| `linear-provider.test.ts` / `linear-registry.test.ts` | the Linear proxy's construction, classification, and guide; then the same connector inside a real deployment |
|
|
239
|
-
| `meta-tools.test.ts` | the registry-backed meta-tools: bounded discovery with page and address maxima,
|
|
240
|
-
| `mixpanel-provider.test.ts` / `mixpanel-registry.test.ts` | the Mixpanel proxy, then the same connector inside a real deployment |
|
|
241
|
-
| `notion-provider.test.ts` / `notion-registry.test.ts` | Notion's tool surface, request construction, lean projections, both pagination conventions, error mapping, and writes; then the connector in a real deployment |
|
|
242
|
+
| `meta-tools.test.ts` | the registry-backed meta-tools: bounded discovery with page and address maxima, compact descriptions and the complete on-demand usage skill, compact and JSON schemas with constraints, typed describe recovery and suggestions, structured errors, connector-guide selection and summary bounds, stored-credential drift, catalog health, field projection, truncation and `get_result`, per-connector result bounds, probe timeouts, and unavailable or unknown browse recovery |
|
|
243
|
+
| `mixpanel-provider.test.ts` / `mixpanel-registry.test.ts` | the Mixpanel proxy, its conditional-input guide and complete reviewed schema-digest manifest, then the same connector inside a real deployment |
|
|
244
|
+
| `notion-provider.test.ts` / `notion-registry.test.ts` | Notion's deliberate tool surface, including declined expanded page inputs, request construction, lean projections, both pagination conventions, error mapping, and writes; then the connector in a real deployment |
|
|
242
245
|
| `operator-boundary.test.ts` | the operator row of the decisions table, after every mutation route: authentication material managed without moving a declared structure, and the one honest exception — a credential write making a remote catalog appear, which is discovery arriving, not an operator editing the deployment |
|
|
243
246
|
| `operator-store.test.ts` | `src/operator-ui/app/store.ts` against a fake browser: the Clerk listener, `gate()`, the generation fence, and the request path |
|
|
244
|
-
| `provider-conventions.test.ts` | the conventions a test can hold: hand-written providers refusing schemas they cannot enforce (H5), Cloudflare stating its second pagination convention in the schema (H10), and Notion saying it has no escape hatch (H14) |
|
|
245
|
-
| `registry.test.ts` | construction and id validation, startup
|
|
247
|
+
| `provider-conventions.test.ts` | the conventions a test can hold: hand-written providers refusing schemas they cannot enforce (H5), their compact discovery schemas staying complete (H7), Cloudflare stating its second pagination convention in the schema (H10), and Notion saying it has no escape hatch (H14) |
|
|
248
|
+
| `registry.test.ts` | construction and id validation, startup warnings, address resolution, catalog TTL/persistence/completeness, agent-only stale-while-revalidate with cross-request single-flight shared with blocking reads in both start orders, owned teardown, invalidation/fingerprint guards, blocking diagnostics, and broken-connector isolation |
|
|
246
249
|
| `remote-mcp.test.ts` | `remoteMcp()` against an in-process server through the `_transportFactory` seam: passthrough, downstream `isError`, Workers-safe output-schema validation, request-scoped client reuse and at-most-once scope close; plus the real transport's manual redirect policy, destination guard, credential containment, and downstream session termination |
|
|
247
250
|
| `remote-mcp-pagination.test.ts` | the `tools/list` cursor chain in both directions — exact cursor handoff, first-wins dedup, a failed later page rejecting rather than returning its prefix, the runaway backstops, the tool-metadata re-prime across pages, and paginated catalogs reaching the discovery path |
|
|
248
251
|
| `request-admission.test.ts` | `/mcp` bounded before auth, the stable 503 and `Retry-After`, health and operator responsiveness under saturation, payload-free counters, queued cancellation, shutdown rejection while active work drains, and the separate fallback code pool |
|
|
249
|
-
| `server.test.ts` | end-to-end `/mcp` (401 → initialize instructions → seven
|
|
252
|
+
| `server.test.ts` | end-to-end `/mcp` (401 → compact initialize instructions → seven compact definitions with bounded connector inventory → complete usage skill → `call_tool`), conditional guide pointers, open routes, Clerk `.well-known` metadata without network, code mode, and deferred catalog reads through both discovery surfaces |
|
|
250
253
|
| `server-route-contracts.test.ts` | the route contracts `server.ts` must keep byte-identical: every built-in answered ahead of connector routes inside the security wrapper, open data-free shells with framing denied, per-route auth and same-origin requirements with exact 401/403/405 bodies, and OAuth `verifyState`-before-`finishAuth` ordering |
|
|
251
254
|
| `startup-warnings.test.ts` | every construction-time `logger.warn` and, as importantly, the conditions that must *not* trigger one: open mode with a credential or OAuth connector, `publicUrl` unset beside OAuth, dropped branding and `uiAuth` URLs, a missing `verifyState`, a credential test-hook mismatch, and an unusable `calls.maxResultBytes` |
|
|
252
|
-
| `stripe-provider.test.ts` / `stripe-registry.test.ts` | the Stripe proxy's
|
|
253
|
-
| `ui.test.ts` | the server shell and `/ui/*` routes and the app's pure state rules from `view.ts` — filtering, page routing and capability states, credential management, gated `/ui/data` with broken-connector isolation, and the URL safety gates |
|
|
255
|
+
| `stripe-provider.test.ts` / `stripe-registry.test.ts` | the Stripe proxy's mixed-mode OAuth and fixed-mode header contracts, admission, exact account selectors, and no-guess rule; then fixed credentials in a real deployment |
|
|
256
|
+
| `ui.test.ts` | the server shell and `/ui/*` routes and the app's pure state rules from `view.ts` — filtering, page routing and capability states, credential management, gated `/ui/data` with broken-connector isolation and registry-owned catalog-observation containment, and the URL safety gates |
|
|
254
257
|
| `validate.test.ts` | `validateToolInput()` — a returned (not thrown) `invalid_args` naming the path, `additionalProperties: false` enforcement, per-schema validator caching, and an unusable schema passed through with one warning |
|
|
255
258
|
|
|
256
259
|
### Node-bound (`NODE_ONLY_SUITES`)
|
|
@@ -260,12 +263,12 @@ justification for *not* re-running it in workerd, so "it was easier" is not one.
|
|
|
260
263
|
|
|
261
264
|
| Suite | Covers | Why Node |
|
|
262
265
|
| --- | --- | --- |
|
|
263
|
-
| `deployment-shapes.test.ts` | the Worker as the only example, one Node template that is also its own container, the same source running locally and in the container, the full operator surface in both, a template that cannot start on its own `.env.example`, a Worker README naming every optional peer its entrypoint imports, and the initializer's `.gitignore` staying in step | walks the template and example trees with Node filesystem APIs |
|
|
266
|
+
| `deployment-shapes.test.ts` | the Worker as the only example with a loader-only sandbox, one Node template that is also its own container, the same source running locally and in the container, the Node template's pinned esbuild install-script approval, the full operator surface in both, a template that cannot start on its own `.env.example`, a Worker README naming every optional peer its entrypoint imports, and the initializer's `.gitignore` staying in step | walks the template and example trees with Node filesystem APIs |
|
|
264
267
|
| `doc-links.test.ts` | the documentation checker itself — local file and fragment resolution, repository URLs resolved back to the checkout, duplicate heading slugs, fenced-code exclusion, and useful failures | spawns the Node checker against filesystem fixtures |
|
|
265
268
|
| `doctor-cli.test.ts` | `connecta doctor`'s executor line end to end — the sandbox the deployment reports is the one named, an unidentifiable executor gets an executor-neutral line, and a hostile name is bounded and stripped before it reaches a terminal | spawns the CLI against a Node HTTP deployment over real sockets |
|
|
266
|
-
| `drift-check.test.ts` | the maintainer drift checker — recorded touched endpoints, a quiet revision bump, clear failures for an unavailable spec/manifest/credential, `$ref` traversal, and one well-formed row per endpoint | spawns the Node checker against filesystem fixtures |
|
|
269
|
+
| `drift-check.test.ts` | the maintainer drift checker — hosted-provider credential framing, recorded touched endpoints, a quiet revision bump, clear failures for an unavailable spec/manifest/credential, `$ref` traversal, and one well-formed row per endpoint | spawns the Node checker against filesystem fixtures |
|
|
267
270
|
| `file-storage.test.ts` | `fileStorage()` across instances, logical TTL plus physical pruning without clobbering a newer value, and corrupt-file quarantine | exercises the Node filesystem storage adapter |
|
|
268
|
-
| `guest-api-contract-quickjs.test.ts` | the shared guest-contract cases on the real QuickJS executor | runs the contract cases on the Node QuickJS executor |
|
|
271
|
+
| `guest-api-contract-quickjs.test.ts` | the shared guest-contract cases on the real QuickJS executor, including identical caught failure codes and inline describe recovery, its exact absent globals, and blocked runtime imports | runs the contract cases on the Node QuickJS executor |
|
|
269
272
|
| `node.test.ts` | the `listen()` adapter propagating an HTTP client disconnect through the Web `Request` and the MCP handler into a program's connector call, releasing both admission permits | exercises the Node HTTP adapter over real TCP sockets |
|
|
270
273
|
| `packed-links.test.ts` | the packed-link gate itself — shipped targets and repository URLs accepted, relative links into unshipped paths and directories rejected with the citation to write instead, reference definitions seen, fenced examples ignored, the changelog exempt | spawns the Node packed-link gate against filesystem fixtures |
|
|
271
274
|
| `package-surface.test.ts` | the published boundary — built output shipped, the `exports` map carrying exactly the documented subpaths plus `./package.json`, only generic factories, platform storage kept in examples, Clerk and QuickJS behind optional subpaths, every provider independently importable, and the Cloudflare provider free of bare specifiers | walks the package tree with Node filesystem APIs |
|
|
@@ -283,7 +286,7 @@ justification for *not* re-running it in workerd, so "it was easier" is not one.
|
|
|
283
286
|
|
|
284
287
|
| Suite | Covers |
|
|
285
288
|
| --- | --- |
|
|
286
|
-
| `browser/operator-ui.spec.ts` | the operator wiring in a real browser: the shell staying open until authentication, credential and access-token and OAuth flows end to end, drift shown without naming a tool, and every failure and empty state |
|
|
289
|
+
| `browser/operator-ui.spec.ts` | the operator wiring in a real browser: Clerk loader order across its version redirect and a real load failure, the shell staying open until authentication, credential and access-token and OAuth flows end to end, drift shown without naming a tool, and every failure and empty state |
|
|
287
290
|
| `browser/program-ui.spec.ts` | the Apps shell in a real browser: a bound view merging fixed and declared arguments and correlating concurrent reads, and the one-string payload receiving no read bridge ([program UI read calls](./program-ui-read-calls.md)) |
|
|
288
291
|
|
|
289
292
|
**The `_transportFactory` seam.** `RemoteMcpOptions._transportFactory` is
|
|
@@ -44,6 +44,14 @@ every operator-configured URL stay in `src/ui.ts`, where they are gated before
|
|
|
44
44
|
they can become an attribute; the bundle renders everything that has a state.
|
|
45
45
|
Two roots share one store: `#operatorNav` and `#operatorContent`.
|
|
46
46
|
|
|
47
|
+
The Clerk loader is intentionally blocking. The inline operator bundle calls
|
|
48
|
+
`boot()` as soon as the parser reaches the end of the body, so a deferred Clerk
|
|
49
|
+
script would make an expected parse-time gap look like a permanent network
|
|
50
|
+
failure. Blocking also preserves the existing failure path: after a real
|
|
51
|
+
loader error, the parser continues and `boot()` renders the Clerk load message.
|
|
52
|
+
Clerk's redirect from the major-version loader URL to its pinned asset keeps
|
|
53
|
+
the same ordering.
|
|
54
|
+
|
|
47
55
|
## Rules that are not obvious
|
|
48
56
|
|
|
49
57
|
- **No operator data in the shell.** Every page serves the same markup. Connector,
|
|
@@ -93,9 +101,11 @@ well as Node and there is no DOM in either:
|
|
|
93
101
|
something calls them when the identity actually changes. It typechecks in the
|
|
94
102
|
DOM-lib program (`tsconfig.operator-ui.json`) because it imports the store.
|
|
95
103
|
- `test/browser/operator-ui.spec.ts` — the wiring, in a real browser:
|
|
104
|
+
Clerk loader order across its version redirect and a real load failure, plus
|
|
96
105
|
credential, token, and OAuth flows end to end, including their failure and
|
|
97
|
-
empty states. Run it with `npm run test:browser`
|
|
98
|
-
once, for Chromium). It is not part of
|
|
106
|
+
empty states. Run it with `npm run test:browser`
|
|
107
|
+
(`npm run test:browser:install` once, for Chromium). It is not part of
|
|
108
|
+
`npm run check`.
|
|
99
109
|
|
|
100
110
|
## Why the bundle is committed
|
|
101
111
|
|
|
@@ -81,6 +81,14 @@ deliberate surface.
|
|
|
81
81
|
| H13 guide | meets | structured, declared summary, `required: true` with a stated reason — the database→data-source lookup is a sequence no complete schema can express |
|
|
82
82
|
| H14 hatch | **missed → fixed** | Notion has no guarded raw-REST tool, which H14 explicitly permits for a finite surface — provided it says so. It did not. The guide now names the absence, so an agent does not spend a search proving there is no `notion_api_get` |
|
|
83
83
|
|
|
84
|
+
The 0.17.0 drift review also considered Notion's expanded create and update
|
|
85
|
+
contracts. Workspace-private creation, templates, placement, richer media,
|
|
86
|
+
locking, and irreversible content erasure stay outside the maintained surface.
|
|
87
|
+
They are separate ownership, ordering, asynchronous, coordination, file, or
|
|
88
|
+
deletion workflows rather than missing fields on the five existing writes
|
|
89
|
+
([#408](https://github.com/zackbart/connecta/issues/408),
|
|
90
|
+
[#409](https://github.com/zackbart/connecta/issues/409)).
|
|
91
|
+
|
|
84
92
|
## Linear — hosted-MCP proxy
|
|
85
93
|
|
|
86
94
|
| Convention | Verdict | Notes |
|
|
@@ -104,17 +112,17 @@ deliberate surface.
|
|
|
104
112
|
| Convention | Verdict | Notes |
|
|
105
113
|
| --- | --- | --- |
|
|
106
114
|
| P1 add, never rewrite | meets | annotations only |
|
|
107
|
-
| P2 identity | meets | required `purpose`, `instructions` appended, classification untouchable from there |
|
|
108
|
-
| P3 routing fact | meets |
|
|
109
|
-
| P4 endpoint default | meets |
|
|
115
|
+
| P2 identity | meets | required `purpose`, `instructions` appended, classification untouchable from there; purpose states deployment routing intent and the guide says it is not proof of authenticated account identity |
|
|
116
|
+
| P3 routing fact | meets | OAuth metadata states mixed account scope and the guide resolves mode from `livemode`; fixed header credentials retain their mode in every routing surface |
|
|
117
|
+
| P4 endpoint default | meets | OAuth has no connector-wide mode to default; static headers require one, and construction throws when a recognizable key prefix contradicts it |
|
|
110
118
|
| P5 classification | meets | including the two verdicts that needed an argument — `stripe_api_read` is a read because the tool is the boundary, `create_refund` is destructive despite its name |
|
|
111
119
|
| P6 catalog varies | **missed → fixed** | the doc already knew this (`get_balance_summary` is Treasury and gated; a `create_customer` example survives in Stripe's prose but not its tool table), but the *guide* did not say it, and the guide is what reaches the agent. Added |
|
|
112
|
-
| P7 reduction advice | **missed → fixed** |
|
|
113
|
-
| P8 identity resolution | **missed → fixed** |
|
|
114
|
-
| P9 authentication | meets | OAuth default, `requireHttps`, restricted key documented as a secret and paired with the narrowest scope. The `auth_required` → `authorize_connector` route was added
|
|
120
|
+
| P7 reduction advice | **missed → fixed** | OAuth has a mixed-scope summary; fixed credentials keep mode-shaped summaries. `required` stays unset because the four generic tools remain the routing decision |
|
|
121
|
+
| P8 identity resolution | **missed → fixed** | The guide names typed object ids and their read sources. For OAuth it requires `list_available_accounts_or_orgs`, then carries the returned `stripe_context` and `livemode` unchanged; ambiguity stops ([#404](https://github.com/zackbart/connecta/issues/404), [#414](https://github.com/zackbart/connecta/issues/414)) |
|
|
122
|
+
| P9 authentication | meets | OAuth default, `requireHttps`, restricted key documented as a secret and paired with the narrowest scope. The guide distinguishes organization accounts within an OAuth session from Connect connected accounts, whose calls reject OAuth and use a deployment-configured restricted key plus `Stripe-Account`. The `auth_required` → `authorize_connector` route was added alongside P8, since a proxy's only recovery instruction lives there |
|
|
115
123
|
| P10 no credential test | meets | no credential slot; the mode/key contradiction throws at construction instead, which is where P10 says the H12 guarantee gets paid |
|
|
116
124
|
| P11 transport vs tool error | meets | inherited from `remoteMcp()`; the guide now also says that a rejected argument or plan restriction arrives in Stripe's own words and is not an authorization problem |
|
|
117
|
-
| P12 admission budget | meets |
|
|
125
|
+
| P12 admission budget | meets | fixed credentials use their documented mode rate; mixed OAuth uses the stricter 25/s sandbox rate and concurrency bound |
|
|
118
126
|
| P13 drift visible | meets | both lists are module-level constants in one file, and are the manifest the refresh-time drift check compares against ([#343](https://github.com/zackbart/connecta/issues/343)) |
|
|
119
127
|
|
|
120
128
|
## Mixpanel — hosted-MCP proxy
|
|
@@ -50,19 +50,24 @@ floor. From `src/catalog.ts` and `src/catalog-service.ts`:
|
|
|
50
50
|
`fullDescriptions: true`. Prose past those points reaches an agent only when
|
|
51
51
|
it pays for the expansion.
|
|
52
52
|
- **A compact schema renders into at most 1,024 UTF-8 bytes**, and any single
|
|
53
|
-
enum
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
enum or constraint annotation into at most 256. Numeric bounds, string
|
|
54
|
+
length bounds, patterns, and formats ride beside their TypeScript-like type.
|
|
55
|
+
Past a cap the renderer keeps what fits and degrades the rest — a prefix of
|
|
56
|
+
the enum plus `unknown`, a shape without the constraints that did not fit, a
|
|
57
|
+
required-first object with `unknown` types, or
|
|
58
|
+
`unknown /* truncated */` — and flags the match, which costs a describe
|
|
59
|
+
round trip to recover.
|
|
57
60
|
- **`inputKeys`, `requiredInputKeys`, and `outputKeys` come only from bounded
|
|
58
61
|
plain-object schemas.** A top-level `anyOf` has no keys to list, so a caller
|
|
59
62
|
learns nothing about the arguments without expanding the schema.
|
|
60
|
-
- **A guide summary is
|
|
61
|
-
|
|
63
|
+
- **A guide summary is bounded at 120 characters.** A configured value past
|
|
64
|
+
the bound refuses construction. An omitted one defaults to the guide's first
|
|
65
|
+
meaningful body paragraph, joined across physical line wraps and shortened
|
|
66
|
+
at a readable boundary.
|
|
62
67
|
- **Search returns a connector's `id`, `title`, `guide`, and `guideSummary` —
|
|
63
68
|
never its `description`.** The description reaches an agent only as the
|
|
64
|
-
fallback summary for a guide with no usable body
|
|
65
|
-
in the title and the guide's
|
|
69
|
+
fallback summary for a guide with no usable body paragraph. Routing facts belong
|
|
70
|
+
in the title and the guide's opening paragraph; a routing fact that lives only in
|
|
66
71
|
the connector description has been written into a field the model does not
|
|
67
72
|
read. Neither the `id` nor the `title` is a lexical document, so a term drawn
|
|
68
73
|
from one of them is not a search hit — it is a no-match whose guidance names
|
|
@@ -141,7 +146,8 @@ wrong-tool selection.
|
|
|
141
146
|
Every tool carries a hand-written `inputSchema`: a plain object at the top
|
|
142
147
|
level, `additionalProperties: false`, an accurate `required` list, an `enum` on
|
|
143
148
|
every constrained field, explicit numeric bounds on every page size and count,
|
|
144
|
-
|
|
149
|
+
explicit string bounds where length or shape is constrained, and a description
|
|
150
|
+
on every property — nested objects and array items included,
|
|
145
151
|
because a caller composing an array element is reading that element's fields,
|
|
146
152
|
not the parent's prose. `api()` enforces the enforceability half for free since
|
|
147
153
|
[#340](https://github.com/zackbart/connecta/issues/340): a schema the validator
|
|
@@ -165,10 +171,12 @@ argument retries.
|
|
|
165
171
|
### H7 — Schemas fit the compact renderer, or selection does not depend on the part that is cut
|
|
166
172
|
|
|
167
173
|
Keep the common path's compact input and output shapes inside 1,024 bytes and
|
|
168
|
-
each enum
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
each enum or constraint annotation inside 256. Numeric and string constraints
|
|
175
|
+
render when they fit. Search drops complete constraints that do not fit and
|
|
176
|
+
sets the existing truncation flag; compact describe keeps them. Where a
|
|
177
|
+
legitimate enum genuinely cannot fit — 21 DNS record types — the truncation is
|
|
178
|
+
acceptable only if the tool's name and description already carry enough for
|
|
179
|
+
selection, so the caller expands the schema to *call*, not to *choose*.
|
|
172
180
|
|
|
173
181
|
*Why:* a truncated compact shape costs a describe round trip. *Cost:* discovery
|
|
174
182
|
tokens.
|
|
@@ -561,6 +569,11 @@ One credential per provider comes from the environment —
|
|
|
561
569
|
`CONNECTA_DRIFT_LINEAR_KEY`, `CONNECTA_DRIFT_STRIPE_KEY`,
|
|
562
570
|
`CONNECTA_DRIFT_MIXPANEL_KEY` — and a missing or dead one stops the run with a
|
|
563
571
|
message naming it rather than reporting an empty catalog as mass removal.
|
|
572
|
+
Linear and bare Stripe values use their documented bearer or Basic framing.
|
|
573
|
+
Mixpanel's beta service-account form is provider-specific:
|
|
574
|
+
`user:secret` becomes `Bearer Basic <base64(user:secret)>`, exactly as its MCP
|
|
575
|
+
documentation requires. A value that already includes whitespace is treated
|
|
576
|
+
as a complete Authorization value and passes through unchanged.
|
|
564
577
|
|
|
565
578
|
**Touched endpoints.** A hand-written provider is written against a published
|
|
566
579
|
OpenAPI document and calls a few dozen of its operations, so
|
package/documentation/stripe.md
CHANGED
|
@@ -1,71 +1,63 @@
|
|
|
1
1
|
# Stripe prebuilt connection
|
|
2
2
|
|
|
3
3
|
Import `stripe()` independently from `@zackbart/connecta/providers/stripe`. It
|
|
4
|
-
wraps [Stripe's hosted MCP server](https://docs.stripe.com/mcp) with
|
|
5
|
-
|
|
4
|
+
wraps [Stripe's hosted MCP server](https://docs.stripe.com/mcp) with OAuth by
|
|
5
|
+
default, account-scoped mode guidance, a conservative admission policy, a
|
|
6
6
|
task-oriented usage guide, and a vetted safety classification. It adds no
|
|
7
7
|
provider dependency and is not reachable from Connecta's root entry.
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
import { stripe } from "@zackbart/connecta/providers/stripe";
|
|
11
11
|
|
|
12
|
-
const billing = stripe("
|
|
13
|
-
|
|
14
|
-
title: "Stripe (production)",
|
|
15
|
-
purpose: "Revenue, disputes, and refunds for the real business",
|
|
12
|
+
const billing = stripe("stripe", {
|
|
13
|
+
purpose: "Revenue, disputes, and refunds across our Stripe organization",
|
|
16
14
|
instructions: "Never refund above $500 without a human in the loop.",
|
|
17
15
|
});
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
The `id` owns the ordinary connector namespaces
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
The `id` owns the ordinary connector namespaces. Choose a connector boundary
|
|
19
|
+
for its credential or OAuth session and business purpose — not automatically
|
|
20
|
+
for each Stripe account. One OAuth session may cover live and sandbox accounts
|
|
21
|
+
in the same Stripe organization. Use separate connectors when the credential
|
|
22
|
+
or business purpose differs.
|
|
23
|
+
|
|
24
|
+
`purpose` is required because it tells an agent where the deployment intends
|
|
25
|
+
to route a question. The connector id, title, and purpose are configuration,
|
|
26
|
+
not proof of which account the authenticated Stripe session will use. Account
|
|
23
27
|
`instructions` are appended to the maintained guide and cannot change the
|
|
24
28
|
connector's safety classification.
|
|
25
29
|
|
|
26
|
-
##
|
|
30
|
+
## OAuth mode belongs to the selected account
|
|
27
31
|
|
|
28
|
-
`mode`
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
Do not pass `mode` for OAuth. Stripe's `list_available_accounts_or_orgs` returns
|
|
33
|
+
each available account with its `stripe_context` and `livemode`. The same OAuth
|
|
34
|
+
session can return both `livemode: true` and `livemode: false` results.
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
The served guide tells agents to call that tool before each account-scoped
|
|
37
|
+
operation. They select the intended result and carry its exact `stripe_context`
|
|
38
|
+
and `livemode` unchanged. Connector id, title, purpose, and OAuth identity are
|
|
39
|
+
routing hints. They never prove the account or mode. Ambiguity stops the call.
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
OAuth metadata therefore stays neutral:
|
|
38
42
|
|
|
39
|
-
- the default
|
|
40
|
-
- the
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
answer a question about live revenue, payouts, or a named customer from this
|
|
46
|
-
connector";
|
|
47
|
-
- the admission policy, below.
|
|
43
|
+
- the default title is `Stripe`;
|
|
44
|
+
- the description says `live and sandbox accounts`;
|
|
45
|
+
- the guide warns that live writes move real money and sandbox writes change
|
|
46
|
+
test data;
|
|
47
|
+
- admission uses the stricter sandbox ceiling, because Connecta cannot select
|
|
48
|
+
a different connector policy after the account-scoped call begins.
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
credential shape this release does not recognize, is left alone rather than
|
|
54
|
-
guessed at — and the error names only the two modes, never the key.
|
|
50
|
+
`mode` remains required for `headers` auth. A restricted key has one fixed live
|
|
51
|
+
or sandbox scope. Its title, description, guide, and admission policy keep the
|
|
52
|
+
fixed-mode behavior. Construction still throws when a recognizable key prefix
|
|
53
|
+
contradicts its declared mode.
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
hand-written connectors with different ids: separate addresses, catalogs,
|
|
58
|
-
credentials, storage, admission counters, and health.
|
|
55
|
+
For OAuth, deploy one connector for the session:
|
|
59
56
|
|
|
60
57
|
```ts
|
|
61
58
|
connectors: [
|
|
62
|
-
stripe("
|
|
63
|
-
|
|
64
|
-
purpose: "Revenue, disputes, and refunds for the real business",
|
|
65
|
-
}),
|
|
66
|
-
stripe("stripe_sandbox", {
|
|
67
|
-
mode: "sandbox",
|
|
68
|
-
purpose: "Rehearsing billing changes before they touch production",
|
|
59
|
+
stripe("stripe", {
|
|
60
|
+
purpose: "Live and sandbox billing for our Stripe organization",
|
|
69
61
|
}),
|
|
70
62
|
]
|
|
71
63
|
```
|
|
@@ -74,7 +66,17 @@ connectors: [
|
|
|
74
66
|
|
|
75
67
|
OAuth is the default and the option Stripe recommends: it supports dynamic
|
|
76
68
|
client registration and PKCE, and each connector instance keeps its own flow
|
|
77
|
-
and tokens in connector-scoped storage. Stripe
|
|
69
|
+
and tokens in connector-scoped storage. Stripe's current
|
|
70
|
+
[session-management documentation](https://docs.stripe.com/mcp#manage-mcp-client-sessions)
|
|
71
|
+
says one OAuth session can be tied to more than one account in the same Stripe
|
|
72
|
+
organization. It does not say every session has multiple accounts.
|
|
73
|
+
|
|
74
|
+
That scope changes what an agent must prove before an account-scoped call. It
|
|
75
|
+
calls `list_available_accounts_or_orgs`, resolves the intended result, and
|
|
76
|
+
carries its exact `stripe_context` and `livemode`. If more than one account
|
|
77
|
+
fits, the agent stops and asks.
|
|
78
|
+
|
|
79
|
+
Stripe also accepts a
|
|
78
80
|
[restricted API key](https://docs.stripe.com/keys#create-restricted-api-key) as
|
|
79
81
|
a bearer token for headless agents:
|
|
80
82
|
|
|
@@ -93,9 +95,12 @@ Use a restricted key, not a secret key, and scope it to the operations the
|
|
|
93
95
|
agent actually needs; Stripe's own guidance is to "limit your agent's access to
|
|
94
96
|
exactly the functionality it requires". Keep it in the runtime's secret store.
|
|
95
97
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
Organization accounts in one OAuth session are not Stripe Connect connected
|
|
99
|
+
accounts. Connect platforms can act as a connected account with
|
|
100
|
+
`connectedAccount`, which adds Stripe's documented `Stripe-Account` header at
|
|
101
|
+
connector construction. Stripe does not support OAuth for connected-account
|
|
102
|
+
calls, so this requires a restricted key through `headers` auth and throws
|
|
103
|
+
otherwise:
|
|
99
104
|
|
|
100
105
|
```ts
|
|
101
106
|
stripe("merchant_42", {
|
|
@@ -109,8 +114,7 @@ stripe("merchant_42", {
|
|
|
109
114
|
});
|
|
110
115
|
```
|
|
111
116
|
|
|
112
|
-
Administrators must enable MCP access in the Stripe Dashboard
|
|
113
|
-
manages that setting **separately for sandbox and live mode**. A connector that
|
|
117
|
+
Administrators must enable MCP access in the Stripe Dashboard. A connector that
|
|
114
118
|
boots but cannot list tools is usually a dashboard toggle, not a bad key.
|
|
115
119
|
|
|
116
120
|
## The eleven tools, and what they are classified as
|
|
@@ -158,7 +162,7 @@ serves, an unclassified and unannotated `create_customer` lands on the approval
|
|
|
158
162
|
path. Expect the undocumented Treasury tools Stripe alludes to to arrive
|
|
159
163
|
unclassified as well — annotated ones will be taken at their word.
|
|
160
164
|
|
|
161
|
-
The upshot is that this
|
|
165
|
+
The upshot is that this connection's tool list is not a fixed set, and the usage
|
|
162
166
|
guide tells the agent so: search this connector for what it actually exposes
|
|
163
167
|
rather than assuming a documented tool is present. The guide also names the id
|
|
164
168
|
discipline the downstream schemas cannot enforce — Stripe ids are typed
|
|
@@ -166,6 +170,13 @@ prefixes (`cus_`, `sub_`, `ch_`, `pi_`, `in_`, `acct_`), a plausible-looking one
|
|
|
166
170
|
belongs to a different object or to nobody, and the id a write takes comes from
|
|
167
171
|
`stripe_api_search` or a list read rather than from a guess.
|
|
168
172
|
|
|
173
|
+
Account selection comes before that object-id rule. The served guide names
|
|
174
|
+
`list_available_accounts_or_orgs`, `stripe_context`, and `livemode`, and tells
|
|
175
|
+
the agent to stop when the account, mode, or selector is ambiguous. It keeps
|
|
176
|
+
organization-account selection separate from the restricted-key-only Connect
|
|
177
|
+
path, so an agent cannot repair uncertainty by fabricating `Stripe-Account` as
|
|
178
|
+
a tool argument.
|
|
179
|
+
|
|
169
180
|
Stripe publishes no stability or deprecation policy for this tool set and
|
|
170
181
|
invites tool requests by email, so treat the list as unversioned. `get_balance_summary`
|
|
171
182
|
is Treasury, which Stripe labels public preview and gates behind an access
|
|
@@ -179,9 +190,10 @@ Stripe documents no rate limit specific to the MCP server. The connection
|
|
|
179
190
|
therefore transcribes the account limit that MCP traffic spends
|
|
180
191
|
([rate limits](https://docs.stripe.com/rate-limits)): **100 requests per second
|
|
181
192
|
in live mode, 25 in a sandbox**, and any single endpoint is capped at 25 per
|
|
182
|
-
second regardless of mode
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
second regardless of mode. OAuth uses 25 calls per second and concurrency 4,
|
|
194
|
+
the safe bound for a session that can reach either mode. Fixed live credentials
|
|
195
|
+
use 100 calls per second and concurrency 8. Fixed sandbox credentials use 25
|
|
196
|
+
and concurrency 4. Stripe
|
|
185
197
|
documents that per-account and per-endpoint concurrency limits exist, and
|
|
186
198
|
surface as `429` with a `Stripe-Rate-Limited-Reason` of `global-concurrency` or
|
|
187
199
|
`endpoint-concurrency`, but publishes no number.
|
|
@@ -195,14 +207,9 @@ admission and still needs restrained use.
|
|
|
195
207
|
|
|
196
208
|
## What is not verified
|
|
197
209
|
|
|
198
|
-
Stripe's MCP documentation is silent on
|
|
210
|
+
Stripe's MCP documentation is silent on one thing this connection had to reason
|
|
199
211
|
about rather than read:
|
|
200
212
|
|
|
201
|
-
- **How an OAuth session resolves to live versus sandbox at call time.** Stripe
|
|
202
|
-
says sessions are "scoped to … the current environment (live mode or a
|
|
203
|
-
sandbox)" and that dashboard access is managed separately per environment, but
|
|
204
|
-
never states the mechanism. The key-prefix check covers `headers` auth only;
|
|
205
|
-
for OAuth, `mode` is a declaration Connecta surfaces and cannot verify.
|
|
206
213
|
- **Whether pagination cursors and `Idempotency-Key` are passable through
|
|
207
214
|
`stripe_api_read` / `stripe_api_write`.** The conventions in the usage guide
|
|
208
215
|
are Stripe's documented API conventions; how they thread through the generic
|
|
@@ -57,7 +57,7 @@ exist so far:
|
|
|
57
57
|
| --- | --- | --- |
|
|
58
58
|
| **pre-template** | before 0.10.2 | no `connecta init` existed; hand-written, or copied from the retired `examples/node` |
|
|
59
59
|
| **A** | 0.10.2 – 0.15.1 | `.env.example`, `.gitignore`, `AGENTS.md`, `CLAUDE.md`, `README.md`, `package.json`, `src/index.ts`, `tsconfig.json` |
|
|
60
|
-
| **B** | 0.16.0 – 0.
|
|
60
|
+
| **B** | 0.16.0 – 0.18.0 | adds `.dockerignore`, `Dockerfile`, `docker-compose.yml`, and `src/file-activity.ts`; `src/index.ts` grows the four commented operator blocks; `.env.example` ships `CONNECTA_TOKEN=` empty |
|
|
61
61
|
|
|
62
62
|
Generation A is a decade in template years and identifying it precisely does
|
|
63
63
|
not matter, because you are about to reconstruct it exactly rather than guess
|
|
@@ -106,7 +106,7 @@ know what to preserve, once to know what to re-verify at the end.
|
|
|
106
106
|
### Bump the pin and install
|
|
107
107
|
|
|
108
108
|
```sh
|
|
109
|
-
npm pkg set dependencies.@zackbart/connecta=0.
|
|
109
|
+
npm pkg set dependencies.@zackbart/connecta=0.18.0
|
|
110
110
|
npm install
|
|
111
111
|
```
|
|
112
112
|
|
|
@@ -130,7 +130,7 @@ Generate the *current* template beside the base you already made, into the same
|
|
|
130
130
|
`$SCRATCH`:
|
|
131
131
|
|
|
132
132
|
```sh
|
|
133
|
-
(cd "$SCRATCH" && npx @zackbart/connecta@0.
|
|
133
|
+
(cd "$SCRATCH" && npx @zackbart/connecta@0.18.0 init current)
|
|
134
134
|
```
|
|
135
135
|
|
|
136
136
|
You now have a three-way merge with a real base: `$SCRATCH/base` is what this
|
|
@@ -186,7 +186,7 @@ A deployment older than 0.10.2 has no base to diff against. Do not try to
|
|
|
186
186
|
manufacture one. Instead:
|
|
187
187
|
|
|
188
188
|
1. `SCRATCH=$(mktemp -d)`, then
|
|
189
|
-
`(cd "$SCRATCH" && npx @zackbart/connecta@0.
|
|
189
|
+
`(cd "$SCRATCH" && npx @zackbart/connecta@0.18.0 init current)` — there is no
|
|
190
190
|
`base` leg here, only the current template to read from.
|
|
191
191
|
2. Copy `$SCRATCH/current` into the deployment file by file, **skipping
|
|
192
192
|
`src/index.ts`**.
|
|
@@ -207,6 +207,48 @@ first, so cross them bottom-up: start at the oldest one still above this
|
|
|
207
207
|
deployment's pin and work back up the page, because each boundary assumes the
|
|
208
208
|
older ones are already done.
|
|
209
209
|
|
|
210
|
+
### 0.17.0 → 0.18.0
|
|
211
|
+
|
|
212
|
+
One floor moves and one always-loaded surface shrinks; neither changes a
|
|
213
|
+
deployment's configuration.
|
|
214
|
+
|
|
215
|
+
**Node 22 is the minimum supported release.** The published engine range and
|
|
216
|
+
the Node template both declare `>=22.0.0`, matching the template's
|
|
217
|
+
`node:22-slim` image. A Docker deployment already runs Node 22; a bare-metal
|
|
218
|
+
deployment on Node 20 must upgrade its runtime before taking this version.
|
|
219
|
+
Worker deployments are unaffected (#422).
|
|
220
|
+
|
|
221
|
+
**Model-facing guidance is split by load cost.** MCP instructions and tool
|
|
222
|
+
definitions now carry route selection, the fail-closed boundary, and minimum
|
|
223
|
+
guest syntax. Detailed selection, repair, runtime, and example guidance moved
|
|
224
|
+
to the existing `skills({ name: "usage" })` response. Clients that never fetch
|
|
225
|
+
the skill keep the same routes and need no deployment change; clients that
|
|
226
|
+
cache tool definitions should refresh them after upgrading (#418).
|
|
227
|
+
|
|
228
|
+
### 0.16.1 → 0.17.0
|
|
229
|
+
|
|
230
|
+
Two construction rules need a deployment check.
|
|
231
|
+
|
|
232
|
+
**A Dynamic Worker executor is loader-only.** The supported construction is
|
|
233
|
+
exactly:
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
new DynamicWorkerExecutor({ loader: env.LOADER })
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Remove `bindings`, `modules`, or `globalOutbound` from that options object.
|
|
240
|
+
Those fields grant guest code ambient configuration, code, or egress. This is
|
|
241
|
+
the supported sandbox boundary rather than a new Connecta-side inspection of
|
|
242
|
+
the third-party executor object. The shipped Worker example was already
|
|
243
|
+
loader-only, and Node deployments use `quickJsExecutor()`, so neither needs a
|
|
244
|
+
change (#390).
|
|
245
|
+
|
|
246
|
+
**An explicit guide summary must fit discovery.** Connecta normalizes
|
|
247
|
+
whitespace in `usageGuide.summary` and refuses registry construction when the
|
|
248
|
+
result is longer than 120 characters. Shorten it to 120 characters or fewer,
|
|
249
|
+
or omit it and let Connecta derive a bounded summary from the guide's opening
|
|
250
|
+
prose. A blank explicit summary still takes the derived-summary path (#392).
|
|
251
|
+
|
|
210
252
|
### 0.16.0 → 0.16.1
|
|
211
253
|
|
|
212
254
|
Nothing throws, and a Node deployment crosses this on the version bump alone.
|