@zackbart/connecta 0.37.1 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/README.md +5 -4
- package/bin/connecta.mjs +1 -39
- package/bin/version.mjs +1 -1
- package/dist/access-tokens.js +2 -4
- package/dist/agent-identity.js +1 -1
- package/dist/agent-routes.js +231 -0
- package/dist/auth/clerk-sdk/generated.js +2 -1
- package/dist/auth/downstream-oauth/consent.js +519 -0
- package/dist/auth/downstream-oauth/grant-store.js +439 -0
- package/dist/auth/downstream-oauth/refresh-coordinator.js +562 -0
- package/dist/auth/downstream-oauth/refresh-records.js +447 -0
- package/dist/auth/downstream-oauth/sdk-hooks.js +242 -0
- package/dist/auth/downstream-oauth.js +66 -2516
- package/dist/auth/downstream-revocation.js +1 -1
- package/dist/auth/native.js +27 -0
- package/dist/auth/oauth-grant.js +24 -0
- package/dist/auth/oauth-token-response.js +1 -1
- package/dist/auth/static-oauth.js +153 -131
- package/dist/auth/vercel-agent.js +2 -1
- package/dist/auth-elicitation.js +9 -3
- package/dist/authorization-handoff.js +11 -5
- package/dist/branding.d.ts +1 -15
- package/dist/branding.js +2 -2
- package/dist/bytes.js +42 -0
- package/dist/call-admission-context.js +2 -5
- package/dist/call-recovery.js +0 -3
- package/dist/catalog-cache.js +130 -43
- package/dist/catalog-fingerprint.js +2 -18
- package/dist/catalog-policy.js +18 -0
- package/dist/catalog-service.js +285 -48
- package/dist/catalog.js +18 -2
- package/dist/config-defaults.d.ts +1 -0
- package/dist/config-defaults.js +1 -0
- package/dist/config-schema.d.ts +1 -1
- package/dist/config-schema.js +6 -2
- package/dist/config.d.ts +57 -25
- package/dist/config.js +30 -77
- package/dist/connector-caller.d.ts +1 -1
- package/dist/connector-health.js +59 -0
- package/dist/connector-status.js +117 -0
- package/dist/connectors/api-connector.d.ts +7 -2
- package/dist/connectors/api-connector.js +11 -7
- package/dist/connectors/guarded-fetch.d.ts +0 -6
- package/dist/connectors/guarded-fetch.js +1 -11
- package/dist/connectors/negotiation-cache.js +22 -4
- package/dist/connectors/remote-mcp/call.js +164 -0
- package/dist/connectors/remote-mcp/catalog.js +278 -0
- package/dist/connectors/remote-mcp/config.js +263 -0
- package/dist/connectors/remote-mcp/connection.js +671 -0
- package/dist/connectors/remote-mcp/errors.js +488 -0
- package/dist/connectors/remote-mcp/oauth.js +469 -0
- package/dist/connectors/remote-mcp/resources.js +473 -0
- package/dist/connectors/remote-mcp/runtime.js +1 -0
- package/dist/connectors/remote-mcp/transport.js +544 -0
- package/dist/connectors/remote-mcp.js +61 -2898
- package/dist/connectors/resource-uri.js +0 -4
- package/dist/credential-contract.d.ts +23 -0
- package/dist/credential-reads.js +17 -0
- package/dist/credential-verification.js +53 -0
- package/dist/credentials.d.ts +7 -0
- package/dist/credentials.js +60 -25
- package/dist/d1.d.ts +0 -89
- package/dist/d1.js +0 -34
- package/dist/describe-config.d.ts +12 -2
- package/dist/describe-config.js +2 -0
- package/dist/discovery-health.js +199 -0
- package/dist/downstream-input.js +4 -2
- package/dist/errors.d.ts +55 -17
- package/dist/errors.js +95 -41
- package/dist/execute.js +172 -125
- package/dist/executor-result.js +5 -2
- package/dist/executors/quickjs-runtime.js +2 -25
- package/dist/executors/quickjs.js +1 -1
- package/dist/guest-functions.js +83 -0
- package/dist/guest-runtime.js +63 -20
- package/dist/guest-types.d.ts +24 -10
- package/dist/http/argument-problems.js +35 -0
- package/dist/http/client.js +1 -1
- package/dist/http/errors.js +7 -6
- package/dist/http/fields.js +192 -13
- package/dist/http/hatch-response.js +73 -0
- package/dist/http/hatch.js +88 -23
- package/dist/http/json-schema.js +1 -1
- package/dist/http/node-transport.js +0 -1
- package/dist/http/oauth.js +4 -3
- package/dist/http/paging.js +6 -9
- package/dist/http/provider.js +33 -5
- package/dist/http/safety.js +9 -1
- package/dist/http/services.js +1 -8
- package/dist/http/tools.js +45 -30
- package/dist/http/vendor.js +7 -7
- package/dist/identity.js +2 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -2
- package/dist/invocation-auth.js +2 -1
- package/dist/invocation.js +21 -6
- package/dist/membership.d.ts +13 -5
- package/dist/membership.js +34 -2
- package/dist/meta-tools.js +50 -35
- package/dist/native-recovery.js +4 -16
- package/dist/native-tools.js +6 -2
- package/dist/oauth-handoff.js +2 -2
- package/dist/oauth-sealing.js +10 -0
- package/dist/operation-vocabulary.js +136 -14
- package/dist/operator-record.d.ts +2 -2
- package/dist/operator-record.js +2 -49
- package/dist/operator-ui/contract.d.ts +12 -2
- package/dist/operator-ui/generated.js +3 -3
- package/dist/operator-ui/model.d.ts +22 -1
- package/dist/program-writes.js +3 -8
- package/dist/provider-call.js +0 -7
- package/dist/provider.d.ts +1 -1
- package/dist/providers/_shared/google/kit.js +1 -6
- package/dist/providers/_shared/google/service-account.js +1 -3
- package/dist/providers/_shared/google/workspace.d.ts +1 -1
- package/dist/providers/_shared/guide.js +3 -0
- package/dist/providers/_shared/json.js +12 -0
- package/dist/providers/_shared/rest/compact-index.js +1 -1
- package/dist/providers/_shared/rest/kit.js +1 -3
- package/dist/providers/_shared/rest/operation-index.js +49 -53
- package/dist/providers/_shared/rest/value-safety.js +106 -28
- package/dist/providers/breeze/api.js +9 -8
- package/dist/providers/breeze/index.js +4 -2
- package/dist/providers/breeze/skill.generated.js +1 -1
- package/dist/providers/breeze/tools.js +7 -7
- package/dist/providers/ccb/api.js +3 -7
- package/dist/providers/ccb/index.js +7 -1
- package/dist/providers/ccb/skill.generated.js +1 -1
- package/dist/providers/ccb/tools.js +1 -6
- package/dist/providers/cloudflare/api.js +10 -3
- package/dist/providers/cloudflare/index.js +2 -1
- package/dist/providers/cloudflare/safety.js +3 -3
- package/dist/providers/cloudflare/skill.generated.js +1 -1
- package/dist/providers/docs/lib/schemas.js +24 -22
- package/dist/providers/docs/safety.js +2 -0
- package/dist/providers/docs/skill.generated.js +1 -1
- package/dist/providers/docs/tools.js +4 -14
- package/dist/providers/drive/api.js +1 -0
- package/dist/providers/drive/lib/contracts.js +8 -5
- package/dist/providers/drive/skill.generated.js +1 -1
- package/dist/providers/drive/tools.js +23 -41
- package/dist/providers/forms/api.js +1 -0
- package/dist/providers/forms/skill.generated.js +1 -1
- package/dist/providers/forms/tools.js +11 -16
- package/dist/providers/github/api.js +1 -0
- package/dist/providers/github/lib/discovery.js +1 -1
- package/dist/providers/github/skill.generated.js +1 -1
- package/dist/providers/github/tools.js +61 -17
- package/dist/providers/gmail/lib/schemas.js +60 -50
- package/dist/providers/gmail/skill.generated.js +1 -1
- package/dist/providers/gmail/tools.js +12 -26
- package/dist/providers/granola/index.js +2 -0
- package/dist/providers/granola/skill.generated.js +1 -1
- package/dist/providers/overflow/api.js +8 -4
- package/dist/providers/overflow/index.js +2 -1
- package/dist/providers/overflow/skill.generated.js +1 -1
- package/dist/providers/overflow/tools.js +3 -7
- package/dist/providers/planning-center/api.js +5 -2
- package/dist/providers/planning-center/lib/constants.d.ts +1 -1
- package/dist/providers/planning-center/lib/json-api.js +1 -9
- package/dist/providers/planning-center/skill.generated.js +1 -1
- package/dist/providers/planning-center/tools.js +2 -1
- package/dist/providers/quickbooks/safety.js +80 -39
- package/dist/providers/quickbooks/skill.generated.js +1 -1
- package/dist/providers/sheets/api.js +1 -0
- package/dist/providers/sheets/skill.generated.js +1 -1
- package/dist/providers/sheets/tools.js +14 -23
- package/dist/providers/slides/skill.generated.js +1 -1
- package/dist/providers/slides/tools.js +19 -26
- package/dist/providers/stripe/index.js +2 -1
- package/dist/providers/stripe/safety.js +2 -2
- package/dist/providers/stripe/skill.generated.js +1 -1
- package/dist/providers/tithely/api.js +5 -8
- package/dist/providers/tithely/index.js +3 -2
- package/dist/providers/tithely/skill.generated.js +1 -1
- package/dist/providers/tithely/tools.js +7 -5
- package/dist/providers/vercel/api.js +2 -7
- package/dist/providers/vercel/lib/pin.js +1 -1
- package/dist/providers/vercel/safety.js +1 -1
- package/dist/providers/vercel/skill.generated.js +1 -1
- package/dist/providers/vercel/tools.js +6 -4
- package/dist/redaction-marker.js +2 -2
- package/dist/registry.d.ts +11 -5
- package/dist/registry.js +46 -20
- package/dist/request-principal.js +1 -1
- package/dist/request-state.js +2 -2
- package/dist/routes/access-tokens.js +1 -1
- package/dist/routes/activity-disclosure.js +1 -1
- package/dist/routes/connect.js +2 -2
- package/dist/routes/credentials.js +130 -61
- package/dist/routes/dispatch.js +5 -1
- package/dist/routes/mcp.js +34 -17
- package/dist/routes/oauth-management.js +1 -1
- package/dist/routes/operator.js +6 -5
- package/dist/routes/shared.d.ts +13 -8
- package/dist/routes/shared.js +15 -9
- package/dist/routes/ui-config.js +3 -3
- package/dist/routes/ui-data.js +126 -20
- package/dist/routes/ui.js +17 -1
- package/dist/runtime/call-admission.js +1 -1
- package/dist/runtime/call.js +8 -3
- package/dist/runtime/native-storage.js +9 -0
- package/dist/runtime/request-reads.js +182 -0
- package/dist/runtime/request-scope.js +16 -0
- package/dist/runtime/settlement.js +1 -1
- package/dist/runtime/shared-read.js +2 -15
- package/dist/runtime/storage.js +12 -0
- package/dist/sent-secrets.d.ts +1 -2
- package/dist/sent-secrets.js +3 -8
- package/dist/server.js +4 -4
- package/dist/skills.js +44 -54
- package/dist/sqlite.d.ts +0 -19
- package/dist/sqlite.js +2 -83
- package/dist/storage/keys.js +69 -128
- package/dist/storage/memory.js +8 -2
- package/dist/storage/sql-native.js +27 -101
- package/dist/storage/sql.d.ts +1 -24
- package/dist/storage/sql.js +13 -14
- package/dist/storage-digest.js +32 -0
- package/dist/timeout.js +8 -0
- package/dist/tool-error.js +4 -0
- package/dist/types.d.ts +33 -0
- package/dist/url-safety.js +0 -4
- package/dist/usage-guide.js +18 -37
- package/dist/validate.d.ts +3 -0
- package/dist/validate.js +220 -158
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker.js +1 -1
- package/dist/write-outcome.js +0 -3
- package/documentation/README.md +19 -55
- package/documentation/architecture.md +436 -515
- package/documentation/auth.md +229 -88
- package/documentation/code-mode.md +201 -94
- package/documentation/deploying.md +25 -43
- package/documentation/integrating.md +18 -19
- package/documentation/meta-tools.md +225 -51
- package/documentation/migration-0.33.md +10 -6
- package/documentation/migration-0.34.md +5 -5
- package/documentation/migration-retired-layouts.md +74 -0
- package/documentation/operator-tests.md +20 -120
- package/documentation/operator-ui.md +108 -16
- package/documentation/pool-membership-upgrade.md +44 -0
- package/documentation/provider-auth-migration.md +4 -10
- package/documentation/provider-migration-0.29.md +4 -15
- package/documentation/providers.md +105 -0
- package/examples/worker/AGENTS.md +14 -16
- package/examples/worker/README.md +24 -118
- package/examples/worker/src/connecta.config.ts +1 -0
- package/guides/connecting-agents.md +9 -31
- package/guides/how-it-works.md +6 -4
- package/guides/safety-and-trust.md +4 -1
- package/package.json +19 -19
- package/templates/node/AGENTS.md +13 -12
- package/templates/node/README.md +9 -26
- package/templates/node/package.json +1 -1
- package/templates/node/src/connecta.config.ts +1 -0
- package/dist/auth/oauth-v2-migration.js +0 -135
- package/dist/provider-call-facts.d.ts +0 -115
- package/dist/provider-call.d.ts +0 -112
- package/dist/storage/d1-copy.js +0 -255
- package/dist/storage/sql-schema.d.ts +0 -6
- package/examples/worker/kv-to-d1.wrangler.jsonc +0 -26
- package/examples/worker/scripts/copy-kv-to-d1.mjs +0 -162
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Migration to 0.33
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
general procedure; [the agent index](./README.md) routes other work.
|
|
3
|
+
Apply the [general upgrade procedure](./deploying.md#upgrade-an-existing-deployment)
|
|
4
|
+
when moving from 0.32 to 0.33.
|
|
6
5
|
|
|
7
6
|
0.33 makes pools the access model.
|
|
8
7
|
Every deployment with inbound auth changes its configuration. Each removed
|
|
@@ -41,6 +40,10 @@ the sections in order, then [verify](#verify).
|
|
|
41
40
|
| `DELETE /ui/credentials/<id>` on an empty slot answering 204 | 409 `{ "problem": "credential_required" }` |
|
|
42
41
|
| The `agent_not_maintainer` denial reason | Removed; agents are refused at human endpoints before admission |
|
|
43
42
|
|
|
43
|
+
This guide records the 0.33 migration. Current versions require every pool to
|
|
44
|
+
list only people or only agents. If a 0.33 deployment combined them, follow
|
|
45
|
+
[Split mixed pools](./pool-membership-upgrade.md) as well.
|
|
46
|
+
|
|
44
47
|
## Maintainers and pool members
|
|
45
48
|
|
|
46
49
|
0.32 combined an identity resolver, a top-level `grant`, and pool `grant`
|
|
@@ -338,8 +341,9 @@ pools: {
|
|
|
338
341
|
|
|
339
342
|
## Verify
|
|
340
343
|
|
|
341
|
-
1. Start the deployment; construction errors name each removed option's
|
|
342
|
-
replacement.
|
|
344
|
+
1. Start the deployment; 0.33 construction errors name each removed option's
|
|
345
|
+
replacement. Releases after 0.37.1 use generic unknown-option errors;
|
|
346
|
+
use this guide for replacements.
|
|
343
347
|
2. Sign in as a maintainer and confirm plain `/mcp` and the operator UI work.
|
|
344
348
|
3. Run `connecta doctor --pool <pool>` with each agent's token, and confirm
|
|
345
349
|
the same token at `/mcp` is refused.
|
|
@@ -349,4 +353,4 @@ pools: {
|
|
|
349
353
|
absent: search finds none of their tools and a call fails
|
|
350
354
|
`unknown_address`. The same holds in any pool without an owner, even one
|
|
351
355
|
that lists a Workspace connector with a subject mapping.
|
|
352
|
-
6. Confirm each `<agent>-<user>` pool lists
|
|
356
|
+
6. Confirm each `<agent>-<user>` pool lists only the agent in `members` (the current construction rule).
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# Migration to 0.34
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
general procedure; [the agent index](./README.md) routes other work. Upgrades
|
|
6
|
-
from earlier versions must also apply the intervening migrations.
|
|
3
|
+
Apply the [general upgrade procedure](./deploying.md#upgrade-an-existing-deployment)
|
|
4
|
+
when moving from 0.33 to 0.34, including intervening migrations for older versions.
|
|
7
5
|
|
|
8
6
|
No storage migration, token rotation or required configuration field is added.
|
|
9
7
|
Review the following changes before updating the package pin.
|
|
@@ -41,7 +39,9 @@ If an agent needs to act as Alice, put that access in her personal pool and set
|
|
|
41
39
|
to use. Confirm the pool's tools and members before adding an owner. Follow
|
|
42
40
|
[the agent pool layout](./auth.md#organizing-an-agents-pools) for the full
|
|
43
41
|
configuration. People in the same pool, agents in owned pools and connectors
|
|
44
|
-
with a fixed `subject` address keep their behavior.
|
|
42
|
+
with a fixed `subject` address keep their behavior. Current versions also
|
|
43
|
+
require each pool to list only people or only agents; see
|
|
44
|
+
[Split mixed pools](./pool-membership-upgrade.md).
|
|
45
45
|
|
|
46
46
|
## Optional settings and development tooling
|
|
47
47
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Migrate before past-layout support is removed
|
|
2
|
+
|
|
3
|
+
Use this guide before upgrading to the release that removes the pre-0.29
|
|
4
|
+
storage and OAuth layout migrations. [Deployment upgrades](./deploying.md#upgrade-an-existing-deployment)
|
|
5
|
+
cover the general procedure; [the agent index](./README.md) routes other work.
|
|
6
|
+
Apply intervening configuration and provider migrations too.
|
|
7
|
+
|
|
8
|
+
**0.37.1 is the last bridge release containing these migrations.** A deployment
|
|
9
|
+
with Workers KV, a JSON state file, or OAuth layout-2 grants must first upgrade
|
|
10
|
+
to exactly `@zackbart/connecta@0.37.1` and finish the relevant migrations there.
|
|
11
|
+
Installing the bridge release alone does not migrate unused grants or storage.
|
|
12
|
+
Deployments already using D1 or SQLite with layout-3 grants need no conversion.
|
|
13
|
+
Keep the existing database, connector ids, owner partitions, and vault key.
|
|
14
|
+
|
|
15
|
+
## Before updating the package pin
|
|
16
|
+
|
|
17
|
+
1. Back up the source state and destination database securely, including expiry
|
|
18
|
+
metadata, and preserve the credential encryption key. Stop traffic and all
|
|
19
|
+
background writers; drain OAuth callbacks and refreshes. Keep a recoverable
|
|
20
|
+
0.37.1 deployment and its installed package until verification completes.
|
|
21
|
+
2. For Workers KV, use 0.37.1's installed
|
|
22
|
+
`examples/worker/scripts/copy-kv-to-d1.mjs` and `kv-to-d1.wrangler.jsonc`.
|
|
23
|
+
Follow that version's `examples/worker/README.md#upgrading-from-028`:
|
|
24
|
+
wait for stable KV, run `--maintenance`, resolve invalid entries and
|
|
25
|
+
conflicts, run `--maintenance --verify`, switch to D1 under maintenance,
|
|
26
|
+
verify, then run `--maintenance --mark-live` before reopening traffic.
|
|
27
|
+
The underlying API is `copyKvToD1(kv, db, { source })` from
|
|
28
|
+
`@zackbart/connecta/d1`; finish every returned cursor, verify hashes and
|
|
29
|
+
expiries, and call `markKvToD1Live(db, source)` before cutover. Never copy
|
|
30
|
+
stale KV over a database that has accepted new writes.
|
|
31
|
+
3. For Node's pre-SQLite JSON state, stop the server and run the bridge CLI:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
npx --yes --package=@zackbart/connecta@0.37.1 connecta migrate-state .connecta-state.json .connecta.sqlite
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
It copies live entries with their expiry, keeps existing destination keys,
|
|
38
|
+
and leaves the JSON file unchanged. The old activity JSONL is not imported.
|
|
39
|
+
Use the destination SQLite file for subsequent starts.
|
|
40
|
+
|
|
41
|
+
4. While still running 0.37.1 over the SQL destination, open **every OAuth
|
|
42
|
+
grant once, for every connector and owner partition** through its normal
|
|
43
|
+
authorized connection. This includes dormant personal grants. The first
|
|
44
|
+
grant read converts layout 2 to the single layout-3 `oauth:grant` record
|
|
45
|
+
and deletes historical keys. Merely listing configuration is insufficient.
|
|
46
|
+
Grants too old to have issuer binding, invalid ciphertext, and pending
|
|
47
|
+
consents require fresh authorization on the bridge release.
|
|
48
|
+
5. Verify each existing OAuth connection, vault credential and agent token,
|
|
49
|
+
including every personal owner. Confirm layout-3 grant records and no
|
|
50
|
+
pending layout-2 cleanup using trusted storage tooling without printing
|
|
51
|
+
credential bodies. Only then upgrade the package pin to the removing release.
|
|
52
|
+
|
|
53
|
+
## Removed interfaces and stale state
|
|
54
|
+
|
|
55
|
+
| Removed path | Behavior after upgrading | Recovery |
|
|
56
|
+
| ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
57
|
+
| OAuth layout-2 reader and cleanup | An owner with only old keys has no usable grant. Reads return absent, credentials are never opened or copied, and a warning says to authorize again or migrate on 0.37.1. Calls require consent. Old keys remain untouched. Existing layout-3 grants, including those with an obsolete cleanup marker, remain readable. | Connect again. To preserve an old grant instead, restore a consistent pre-upgrade backup and run the bridge procedure. |
|
|
58
|
+
| `copyKvToD1`, `markKvToD1Live`, their types/error, and copy script/config | Named imports fail; no KV copy runs. A KV adapter without atomic compare-and-set is refused at construction. A fresh D1 database contains none of the old credentials or tokens. The `/d1` subpath still exports `d1Storage` and `d1ActivityStore`. | Stop writers and restore a consistent backup with 0.37.1, then copy and verify before cutover. |
|
|
59
|
+
| `importStateFile`, `StateFileImport`, and `connecta migrate-state` | Named imports fail; the CLI command exits nonzero with usage. The SQLite adapter never reads the JSON file, so a fresh database has no old credentials or tokens. | Import on 0.37.1 while stopped, then point the deployment at that SQLite file. |
|
|
60
|
+
| Retired `execute.resumableWrites`, `execute.pausedRunTtlSeconds`, `identity`, `grant`, and deployment/pool `trust` migration hints | Construction still rejects these as ordinary unknown configuration options. It no longer expands identity keys or prints replacement instructions. Pool `grant` is also rejected. | Remove obsolete options. Follow [migration to 0.33](./migration-0.33.md) for `maintainers`, pool `members`, `agents`, and explicit `readOnly`. |
|
|
61
|
+
|
|
62
|
+
A rollback after accepting new SQL writes can resurrect revoked credentials or
|
|
63
|
+
spent refresh tokens. Recover from a consistent backup under maintenance rather
|
|
64
|
+
than merging old KV/JSON state into a live database. If preserving old auth is
|
|
65
|
+
unnecessary, reconnect credentials and issue fresh agent tokens in the current
|
|
66
|
+
SQL deployment; revoke superseded credentials at their providers.
|
|
67
|
+
|
|
68
|
+
## Verify
|
|
69
|
+
|
|
70
|
+
Run `connecta doctor --pool <pool>` with each agent's token. Open each shared
|
|
71
|
+
and personal OAuth connection and make a controlled read. Confirm authorization
|
|
72
|
+
works without an unsupported-layout warning, the intended SQL database is used,
|
|
73
|
+
and the operator UI shows expected credentials and activity. Remove one-shot
|
|
74
|
+
migration routes and bindings after successful cutover.
|
|
@@ -24,24 +24,17 @@ committed through the deployment's own store, so the contract's `agents` and
|
|
|
24
24
|
last seen are fixed. The restricted state is the member fixture from
|
|
25
25
|
`test/fixtures/operator-contract-v2.ts`, and the endpoint and matrix variants
|
|
26
26
|
use its maintainer fixture, which covers every runs-as kind and agent pools,
|
|
27
|
-
with `test/fixtures/operator-console.ts` crowding the team pool so its avatar
|
|
27
|
+
with `test/fixtures/operator-console.ts` crowding the people-only team pool so its avatar
|
|
28
28
|
stack collapses to "+3".
|
|
29
|
-
Collections use their corresponding browser types.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
exclusion on Node and Workers, and runs `expectMemberViewWithholds` on the
|
|
33
|
-
member body. A fixture's config cannot silently become a stale copy of the
|
|
34
|
-
server serializer.
|
|
29
|
+
Collections use their corresponding browser types. Real contract serialization,
|
|
30
|
+
member projection and secret withholding are exercised through
|
|
31
|
+
`test/operator-contract.test.ts` and `test/operator-contract-server.test.ts`.
|
|
35
32
|
|
|
36
33
|
`test/browser/operator-visual.spec.ts` intercepts API reads and serves the real
|
|
37
|
-
hashed assets and HTML with the production CSP.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
for `.map-svg.tracing` before capturing. Screenshots use a fixed
|
|
42
|
-
clock, UTC, en-US, locally hosted fonts, disabled animations, hidden carets,
|
|
43
|
-
and a 1280 × 900 viewport. Narrow fixtures use 390 × 844. Every test waits for
|
|
44
|
-
its state and fonts before capturing.
|
|
34
|
+
hashed assets and HTML with the production CSP. It captures populated Overview
|
|
35
|
+
and connector Connection pages in light and dark themes: four screenshots.
|
|
36
|
+
Each capture waits for the heading, page content and fonts, with a fixed clock,
|
|
37
|
+
and resets scrolling before the full-page image.
|
|
45
38
|
|
|
46
39
|
## Loading and recovery probes
|
|
47
40
|
|
|
@@ -52,115 +45,22 @@ The suite also checks default v2 compatibility, the unchanged member projection,
|
|
|
52
45
|
blocked custom connectors and bounded essential token-slot failure.
|
|
53
46
|
`test/ui.test.ts` checks complete detail schemas and independent sibling scope cleanup.
|
|
54
47
|
|
|
55
|
-
`test/
|
|
56
|
-
|
|
57
|
-
connector paths and custom connectors. Storage spies require zero auth mutations,
|
|
58
|
-
including migration and resealing. `test/operator-store.test.ts` counts scoped
|
|
59
|
-
refresh/focus/mutation/poll requests, coalescing and bounded retries, and verifies
|
|
60
|
-
stale admission blocks privileged reads, connection writes and token actions while
|
|
48
|
+
`test/operator-store.test.ts` counts scoped refresh/focus/mutation/poll requests,
|
|
49
|
+
coalescing and bounded retries, and verifies stale admission blocks privileged reads, connection writes and token actions while
|
|
61
50
|
retaining the snapshot. Late reads, role/identity changes and concurrent polls
|
|
62
51
|
exercise publication fences. Browser recovery and flow suites use real routes to
|
|
63
52
|
check a usable shell with a stalled connector, OAuth return and scoped Refresh.
|
|
64
53
|
|
|
65
|
-
##
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
| Connectors | No connectors | Config | Member page, no connector request |
|
|
76
|
-
| Connector Tools | Empty catalog | Config | Member page, no connector request |
|
|
77
|
-
| Connector Connection | Deployment-managed auth | Config | Member page, no connector request |
|
|
78
|
-
| Connector Activity | No calls | Activity | Member page, no activity request |
|
|
79
|
-
| Tokens | No declared agents | Token list | Member page, no token request |
|
|
80
|
-
| Activity | No calls | Activity | Member page, no activity request |
|
|
81
|
-
| Settings | Snapshot without connectors or pools | Config | Member page, no configuration facts |
|
|
82
|
-
|
|
83
|
-
Populated Overview has a failing connector, auth and credential problems
|
|
84
|
-
and a tokenless agent in its attention list. Populated Endpoints shows who can use each endpoint; populated Tokens has one
|
|
85
|
-
agent per slot state, with pools and last seen.
|
|
86
|
-
|
|
87
|
-
Another 60 screenshots cover the Overview map on the frozen v2 maintainer, one
|
|
88
|
-
person's trace, and the narrow map list; configured, mismatched, unreadable and multifield
|
|
89
|
-
credentials; all three OAuth client mechanisms; clean and unobserved drift;
|
|
90
|
-
historical Activity; client setup; schema dialog; read/write filters; narrow
|
|
91
|
-
Settings; narrow sign-in and Connection; deployment branding; `/mcp`
|
|
92
|
-
and an agent pool expanded with every runs-as kind; command search; narrow
|
|
93
|
-
endpoints; the connector × endpoint matrix, one cell's open popover, and the
|
|
94
|
-
narrow matrix; a new token's one-time secret dialog; and the member page, wide
|
|
95
|
-
and narrow. `endpoints-expanded` and `narrow-endpoints` include the team row
|
|
96
|
-
collapsed to "+3". The base
|
|
97
|
-
populated Activity fixture includes grouped calls, an ungrouped legacy row,
|
|
98
|
-
classification/result size/client facts, and a catalog-change event.
|
|
99
|
-
|
|
100
|
-
`test/browser/operator-matrix.spec.ts` serves the frozen v2 fixtures to the
|
|
101
|
-
real shell. It covers the matrix's table semantics, cell names, status dots,
|
|
102
|
-
runs-as labels in each kind's popover, popover keyboard behavior, placement at a short viewport, the in-flow
|
|
103
|
-
fallback without CSS anchors, and the absence of `style` attributes, agent URLs on Endpoints, the member page (its
|
|
104
|
-
received body checked with `expectMemberViewWithholds`, `/ui/data` answering 404
|
|
105
|
-
and never requested, no maintainer fact rendered, no maintainer request sent),
|
|
106
|
-
the 401 sign-in and 404 no-access gates on `/ui/api/config` with no maintainer
|
|
107
|
-
navigation, the shared recovery banner on Tokens and Activity through a failed
|
|
108
|
-
refresh that stalls past its deadline (one focusable Retry, no maintainer
|
|
109
|
-
request until Retry succeeds), an open client setup drawer closed by a failed
|
|
110
|
-
refresh with focus on Retry, Tokens under recovery (an open rotate question
|
|
111
|
-
closes with focus on Retry and nothing sent; an unseen secret dialog stays open
|
|
112
|
-
over the banner until dismissed), payload sentinels, CSP, and the refusal of a v1 body. Matrix coverage excludes retired grants from
|
|
113
|
-
its live counts and pie, keeps their names inspectable in the popover, and
|
|
114
|
-
renders an unavailable catalog as a dashed empty ring with "?" and an unknown
|
|
115
|
-
accessible name. Cell names distinguish equal grants against different live
|
|
116
|
-
catalog sizes. `test/operator-endpoints.test.ts` covers those view-model cases,
|
|
117
|
-
including a known empty catalog versus an unavailable one.
|
|
118
|
-
`test/operator-connection-map.test.ts` also checks that a failed or unobserved
|
|
119
|
-
catalog counts no tools, which the map draws as a muted dash, while a known
|
|
120
|
-
empty catalog counts zero.
|
|
121
|
-
`test/browser/operator-overview.spec.ts` covers the Overview on the frozen v2
|
|
122
|
-
fixtures: the status pill, stat labels and numbers, map columns, dashed read-only grants and dotted
|
|
123
|
-
tokenless access; attention rows with their fix links, a copied fix prompt equal
|
|
124
|
-
to the catalogue's text, config order through a staggered full refresh, prototype-named
|
|
125
|
-
connector IDs during loading and failure, and stable single-card height when
|
|
126
|
-
its catalog empties. A single long-id, long-title card at 320, 390, 1024 and
|
|
127
|
-
1440px covers all eight status labels, both auth scopes, with and without the
|
|
128
|
-
Read-only badge, tools and an action. Text rows stay single-line, full text
|
|
129
|
-
remains accessible, links stay focusable, and the detail header and Overview
|
|
130
|
-
attention rows retain their height; the hover
|
|
131
|
-
sentence replacing the legend, and dimming; keyboard focus in column order with each node's sentence
|
|
132
|
-
as its accessible name, Enter opening an endpoint's row and a connector; the
|
|
133
|
-
narrow list, whose caller chips link where their map nodes do; an empty deployment; and a member at `/` getting the member page
|
|
134
|
-
with no maintainer read, plus CSP and no `style` attributes.
|
|
135
|
-
`test/browser/operator-console.spec.ts` covers UI-3: who-can-use chips by
|
|
136
|
-
label, raw id and agent mark and "+N" from the keyboard; Tokens rows,
|
|
137
|
-
issue with the once-only secret dialog, in-row rotate and revoke questions,
|
|
138
|
-
503, 499 and 409 failures that send exactly one request, slots missing from
|
|
139
|
-
the list or left unresolved shown with disabled controls until Refresh; and the
|
|
140
|
-
member page (its received body checked with `expectMemberViewWithholds`, no
|
|
141
|
-
tabs, Search or maintainer fact, OAuth Connect, Reconnect and Disconnect sent as
|
|
142
|
-
`?mode=continue`, `?mode=restart` and `DELETE`, the credential `actions`
|
|
143
|
-
shapes, a refresh that drops an action closing its confirmation, a failed or
|
|
144
|
-
stalled refresh keeping member chrome with Retry, a consent that outlasts the
|
|
145
|
-
OAuth poll window), plus keyboard, sentinels, CSP and no `style` attributes.
|
|
146
|
-
`test/operator-console.test.ts` covers the chip, slot-row and member-page view
|
|
147
|
-
models. `test/browser/operator-scheme.spec.ts` holds the main bundle and checks the
|
|
148
|
-
first painted background: saved dark on a light system paints dark, a pinned
|
|
149
|
-
light deployment paints light over saved dark, and throwing storage keeps the
|
|
150
|
-
system scheme while the released bundle settles on the normal bearer gate, and a
|
|
151
|
-
sign-in there raises no error. The real-route token test in `test/browser/operator-ui.spec.ts` serves
|
|
152
|
-
the contract, `/ui/data` and the slot routes from one real v2 deployment and
|
|
153
|
-
checks that each mutation sent a distinct 22-character `expect`.
|
|
154
|
-
`test/operator-store.test.ts` serves `/ui/api/config` from its own mock, so
|
|
155
|
-
each test's data and detail answers stay separate, and covers role changes: a
|
|
156
|
-
maintainer demoted after a failed refresh keeps no maintainer state and sends
|
|
157
|
-
no maintainer request, and a promoted member loads maintainer data fresh. It
|
|
158
|
-
also drives UI-3's slot fence with a session-token read held open: reloads and
|
|
159
|
-
contract refreshes that move or drop a slot before dispatch, late results that
|
|
160
|
-
cannot overwrite newer evidence, unknown and unreadable outcomes that only a
|
|
161
|
-
later list read settles, revisions sent as `expect` and compared with the
|
|
162
|
-
contract, an identity change that leaves the next identity's fence alone, and
|
|
163
|
-
member actions whose `manage` a refresh changes.
|
|
54
|
+
## Browser behavior evidence
|
|
55
|
+
|
|
56
|
+
| Suite | Assertions |
|
|
57
|
+
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
58
|
+
| `test/browser/operator-matrix.spec.ts` | Members see their own page on every path, get scoped setup links, and never request maintainer data. |
|
|
59
|
+
| `test/browser/operator-overview.spec.ts` | Overview health, counts and map edges; per-caller status and principal-refusal copy without secret fix prompts. |
|
|
60
|
+
| `test/browser/operator-console.spec.ts` | Token issue/rotate/revoke confirmations and once-only secret display; member credential fields and OAuth connect/reconnect/disconnect controls. |
|
|
61
|
+
| `test/browser/operator-pages.spec.ts` | Resolved read/write filters, inert schema text, Activity history/grouping, and legacy URL redirects. |
|
|
62
|
+
| `test/browser/operator-shell.spec.ts` | Clerk loader and child-script behavior under CSP, with inline and foreign scripts blocked. |
|
|
63
|
+
| `test/browser/operator-ui.spec.ts` | Identity changes cancel reads and close popups, OAuth polling stays scoped, token mutations use real routes and distinct revisions, and declared agents show scoped credentials and usage. |
|
|
164
64
|
|
|
165
65
|
Screenshots cover presentation. Keep unit and server tests for INV-6 sentinels,
|
|
166
66
|
secret disclosure, auth and grant boundaries, CSRF, identity fences, cancellation,
|
|
@@ -113,6 +113,12 @@ Pool endpoint rows show the effective surface (`meta` or `native`) and whether
|
|
|
113
113
|
code is on. These are read-only facts from deployment configuration; change
|
|
114
114
|
`surface` and `executeCode` in deployment code.
|
|
115
115
|
|
|
116
|
+
Plain `/mcp` is routed by sign-in: the `/mcp` row and matrix column show the
|
|
117
|
+
whole catalog maintainers receive, and a pool row shows what its people
|
|
118
|
+
receive at both `/mcp/<pool>` and, when they belong to no other pool, plain
|
|
119
|
+
`/mcp`. A note above the rows says so. People in several pools appear in
|
|
120
|
+
`config.peopleInSeveralPools`; plain `/mcp` refuses them.
|
|
121
|
+
|
|
116
122
|
One row each for `/mcp` and every pool: the path, a read-only pill on a
|
|
117
123
|
read-only endpoint, a copyable URL, who can use it, its connectors as colored
|
|
118
124
|
monograms (four, then "+N"), its tool count over a read and write bar, and a
|
|
@@ -121,7 +127,9 @@ Setup button.
|
|
|
121
127
|
- Who can use it is `root.maintainers` on `/mcp` and the pool's `members`
|
|
122
128
|
elsewhere, as an avatar stack named on hover and to screen readers (label,
|
|
123
129
|
raw id when the label is null, or agent name). Four show, then a "+N"
|
|
124
|
-
button. A pool
|
|
130
|
+
button. A pool lists only people or only agents. An agent pool's row
|
|
131
|
+
still shows two URLs labeled People and Agents; the People URL
|
|
132
|
+
(`/mcp/<pool>`) admits no one, because the pool has no people.
|
|
125
133
|
- Expanding a row lists everyone by name, then each connector with what it
|
|
126
134
|
runs as and its tools, write tools amber with a pencil. Runs-as comes from
|
|
127
135
|
the endpoint's matrix cell: "Shared · saved <date>", "Shared · connected
|
|
@@ -194,8 +202,9 @@ tabs:
|
|
|
194
202
|
annotation badges (Destructive, Open world), filtered by search and All,
|
|
195
203
|
Read and Write. A tool opens its schema in a side drawer.
|
|
196
204
|
- **Connection.** An Authentication card (mode, OAuth client mechanism, who
|
|
197
|
-
manages it, OAuth actions, and the credential card
|
|
198
|
-
field states, and Replace, Test and Remove); a
|
|
205
|
+
manages it, the last verification, OAuth actions, and the credential card
|
|
206
|
+
with masked last four, field states, and Replace, Test and Remove); a
|
|
207
|
+
Diagnostics card of tiles
|
|
199
208
|
(catalog age and last call) with a fix prompt beside each
|
|
200
209
|
problem; and a Configuration card. Its badges name the kind (Remote MCP,
|
|
201
210
|
HTTP API or Custom), provider, auth scope, endpoint host and usage guide.
|
|
@@ -340,10 +349,12 @@ connections**, has no tabs; its heading shows the signed-in email when the
|
|
|
340
349
|
sign-in exposes one (Clerk's primary email), and its top bar shows branding and
|
|
341
350
|
an **Account** button with Sign out or Change token. It lists:
|
|
342
351
|
|
|
343
|
-
- **Your endpoints**: one card per
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
352
|
+
- **Your endpoints**: one card per address with a copy button and **Client
|
|
353
|
+
setup**. A member of exactly one pool sees one card for plain `/mcp`, named
|
|
354
|
+
after the pool it serves; a member of several pools sees one
|
|
355
|
+
`/mcp/<pool>` card per pool. For example, Bob, only in pool `team`, copies
|
|
356
|
+
`https://connecta.example.com/mcp` into an MCP client and authenticates as
|
|
357
|
+
Bob.
|
|
347
358
|
- **Your accounts**: the personal connectors in their pools, each with a
|
|
348
359
|
monogram, tool count, one status badge in an aligned column, and only the
|
|
349
360
|
controls its `manage.actions` lists. A saved credential that no longer fits
|
|
@@ -415,7 +426,8 @@ without this capability contribute an unconfirmed count of zero. For example,
|
|
|
415
426
|
The maintainer view carries:
|
|
416
427
|
|
|
417
428
|
- `config`, the construction-time `describeConfig()` snapshot, including
|
|
418
|
-
`maintainers
|
|
429
|
+
`maintainers`, each pool's `members`, `peopleInSeveralPools` (non-maintainer
|
|
430
|
+
people plain `/mcp` refuses because they are in several pools), and `configSources`, which labels
|
|
419
431
|
each serialized leaf as `default` or `config` from option presence rather
|
|
420
432
|
than equality with the default. Factory descriptions carry relative
|
|
421
433
|
`optionSources` paths so resolved module and transport defaults retain their
|
|
@@ -488,7 +500,9 @@ The maintainer view carries:
|
|
|
488
500
|
The member view is exactly that member's projection: `config`,
|
|
489
501
|
`configSources` and `root` are `null`, `live.connectors`, `agents` and
|
|
490
502
|
`matrix` are empty, and `live.activity` is `"forbidden"`. `pools` lists only
|
|
491
|
-
their pools, each with `owner: null` and `members: []`.
|
|
503
|
+
their pools, each with `owner: null` and `members: []`. With exactly one pool,
|
|
504
|
+
its `humanPath` is `/mcp`, the address that serves them that pool, and the
|
|
505
|
+
member's catalog reads carry that pool as plain `/mcp` would. `connectors` lists
|
|
492
506
|
each connector in those pools with its title, the member's pools that serve
|
|
493
507
|
it, its auth scope, the tools those pools grant with their classification,
|
|
494
508
|
`connection` (their own partition's state and problem code for a personal
|
|
@@ -556,6 +570,58 @@ the config snapshot, and never treats a `per_caller` overlay as an error.
|
|
|
556
570
|
complete classified tools with input/output schemas, registration path, catalog
|
|
557
571
|
age, and activity-derived last-call facts under the reader's disclosure policy.
|
|
558
572
|
A failed or timed-out connector releases its own scope; siblings finish independently.
|
|
573
|
+
The status and catalog observation has its own deadline: 8 seconds, or
|
|
574
|
+
`discovery.probeTimeoutMs` when that is shorter, in which case the whole row
|
|
575
|
+
uses that one deadline. The 8-second value is fixed, not configured; agent
|
|
576
|
+
discovery keeps the full `discovery.probeTimeoutMs`. When the deadline ends
|
|
577
|
+
first, the downstream read is aborted and the row returns `status: "error"`
|
|
578
|
+
with `problem: "connector_timeout"` in the row and its overlay. The row still
|
|
579
|
+
carries its credential card and auth permissions, so a slow connector's slot
|
|
580
|
+
stays manageable. Any other failure keeps `connector_unavailable`. The
|
|
581
|
+
connector renders as **Not responding**, with fixed copy, a fix prompt and
|
|
582
|
+
Refresh.
|
|
583
|
+
**Stored status.** Each live `GET /ui/connectors/:id` records one status
|
|
584
|
+
observation for that connector and viewer partition before it answers: its
|
|
585
|
+
state, problem code, tool count and observation time. Authored static catalogs
|
|
586
|
+
such as `api()` connectors are recorded too, since their status still checks
|
|
587
|
+
auth. The record lives in the `connector-health:v1:` family under the same
|
|
588
|
+
owner partition as the catalog cache (principal, subject, caller identity and
|
|
589
|
+
pool, endpoint, described configuration and package version), so a personal
|
|
590
|
+
connector's observation is one person's. It also carries the catalog
|
|
591
|
+
generation read before the probe, through the request's read memo that the
|
|
592
|
+
catalog listing reuses. It holds no tools, schemas, status prose or
|
|
593
|
+
credential facts. It expires 120 seconds after it was observed, and lapses at
|
|
594
|
+
once when a credential change, OAuth connect or disconnect, or invalidation
|
|
595
|
+
rotates the generation. A read that ends at the row's own deadline, including
|
|
596
|
+
a configured `discovery.probeTimeoutMs` shorter than 8 seconds, records
|
|
597
|
+
`connector_timeout` before it answers. An observation is written only while
|
|
598
|
+
the caller is still waiting: a request its caller has already left starts no
|
|
599
|
+
write. A write that has started is never raced against a deadline or
|
|
600
|
+
detached, because a storage write cannot be withdrawn once sent. The request,
|
|
601
|
+
whether it times out or its caller leaves meanwhile, settles only after that
|
|
602
|
+
write does, bounded by the storage layer like every other awaited write, so
|
|
603
|
+
nothing commits after the request ends.
|
|
604
|
+
|
|
605
|
+
`GET /ui/connectors/:id?observation=stored` answers from a current observation
|
|
606
|
+
without probing the downstream. The row and overlay carry `observedAgeMs`, the
|
|
607
|
+
stored `status`, `problem` and `toolCount`, and `tools: []`; the tools stay in
|
|
608
|
+
the catalog cache. The credential card, drift, permissions and any
|
|
609
|
+
authorization link are computed fresh on every request. Without a current
|
|
610
|
+
observation the route does the live read and records it, with no
|
|
611
|
+
`observedAgeMs`. Nothing is refreshed after the response: no deferred work and
|
|
612
|
+
no `ctx.waitUntil`.
|
|
613
|
+
|
|
614
|
+
The browser asks each connector for its stored observation on the page load
|
|
615
|
+
that follows admission, and fixes the observation time once as each stored
|
|
616
|
+
row lands. The list card and the connector page mark a stored row the same
|
|
617
|
+
way, "Stored status, checked … ago", with an age that keeps counting, and
|
|
618
|
+
show its tools as awaiting the live read rather than as none. The browser then
|
|
619
|
+
sends one plain live read per stored row, through the same queue of eight
|
|
620
|
+
detail reads. A stored `connector_timeout` row is not read again on its own;
|
|
621
|
+
its mark says to Refresh, and it waits for Refresh like a live timeout.
|
|
622
|
+
Refresh, a single connector's read, recovery retries and OAuth polls always
|
|
623
|
+
read live.
|
|
624
|
+
|
|
559
625
|
The summary and each detail carry `viewerKey` for the principal admitted to that
|
|
560
626
|
request. The browser publishes the detail and overlay atomically only when that
|
|
561
627
|
key matches admission. A changed viewer key, including an Access switch between
|
|
@@ -568,7 +634,7 @@ screen. The first answer for the new viewer triggers readmission, which clears
|
|
|
568
634
|
everything retained.
|
|
569
635
|
Config observations never
|
|
570
636
|
overwrite a completed detail row. Each connector opens at most one live observation
|
|
571
|
-
per page load; the summary `/ui/data` performs no downstream probes.
|
|
637
|
+
per page load, after its stored read; the summary `/ui/data` performs no downstream probes.
|
|
572
638
|
|
|
573
639
|
`GET /ui/api/config?connector=<id>` narrows the same contract to one connector
|
|
574
640
|
before status and catalog probes. For a maintainer, config, provenance, live
|
|
@@ -628,8 +694,23 @@ bounded at 2, 2, 4 and 8 seconds; a later focus return can try again after backo
|
|
|
628
694
|
|
|
629
695
|
Connector Refresh, focus recovery and mutation follow-ups read only affected
|
|
630
696
|
connectors. Focus probes unhealthy rows, never healthy siblings. All detail reads
|
|
631
|
-
share
|
|
697
|
+
in one tab share an eight-request limit and coalesce per connector, so a page of
|
|
698
|
+
up to eight connectors loads in one round. The limit is fixed, not configured.
|
|
699
|
+
It bounds how many connectors one tab waits on at once; a tab still reads each
|
|
700
|
+
connector once per load, so the limit adds no requests to any one connector.
|
|
701
|
+
Detail reads do not consume `admission.requests` permits, which govern `/mcp`
|
|
702
|
+
only. They still share isolate CPU and memory, D1, and downstream account quotas
|
|
703
|
+
with agent traffic; each tab adds up to eight concurrent downstream reads, and
|
|
704
|
+
several connectors on one vendor account share that vendor's rate limit. Over HTTP/1.1 the browser itself allows about six
|
|
705
|
+
connections per origin.
|
|
706
|
+
Failures retry only their
|
|
632
707
|
connector with the same bounded backoff; recovery never replays a mutation.
|
|
708
|
+
A `connector_timeout` row is parked instead. It spends its automatic retry
|
|
709
|
+
budget, and focus and visibility returns skip it. Only Refresh, a full refresh
|
|
710
|
+
or a mutation follow-up reads it again, so an outage holds a detail slot once
|
|
711
|
+
per explicit request, never repeatedly. An OAuth start's consent-return poll is
|
|
712
|
+
the exception: a timeout during its 30-second window keeps polling, and success
|
|
713
|
+
still stops it.
|
|
633
714
|
Mutations cancel affected reads and advance their publication fence both at
|
|
634
715
|
dispatch and on settlement, including failure. Follow-ups require an observation
|
|
635
716
|
started after settlement, so a Refresh or retry started during the write cannot
|
|
@@ -638,9 +719,21 @@ while identity and full refresh revisions fence the complete view. An explicit
|
|
|
638
719
|
OAuth start polls only that connector every two seconds for up to 30 seconds.
|
|
639
720
|
Concurrent authorizations retain independent cancellation and publication. Success,
|
|
640
721
|
failed reads, disconnect, navigation, unmount and identity reset stop the matching
|
|
641
|
-
poll. Recovery never starts authorization. A scoped result cannot confirm identity,
|
|
722
|
+
poll; a `connector_timeout` result does not. Recovery never starts authorization. A scoped result cannot confirm identity,
|
|
642
723
|
role, token slots or any other deployment-wide admission fact.
|
|
643
724
|
|
|
725
|
+
A credential connector's `/ui/data` and `/ui/connectors/<id>` row carries
|
|
726
|
+
`verification: { outcome, observedAt }` when a record of the stored save
|
|
727
|
+
exists (see [last verification](./auth.md#test-then-save-and-last-verification)).
|
|
728
|
+
The auth facts show it as **Last verified**: Verified, Saved without a test,
|
|
729
|
+
Rejected, Missing permission, Service unreachable, Test timed out or Test
|
|
730
|
+
failed, with its time. A maintainer's credential form on a testable connector
|
|
731
|
+
saves through **Test and save** (`verify: "test"`). A failed test leaves the
|
|
732
|
+
form open with fixed copy for its failure class, and adds **Save without
|
|
733
|
+
testing**, a save without `verify`. Test shows the same per-class copy and reloads
|
|
734
|
+
the connector so its last verification updates. The member page's
|
|
735
|
+
credential form saves without a test and offers Test once a value is stored.
|
|
736
|
+
|
|
644
737
|
Unreadable credential metadata uses `configured: null`, including named fields,
|
|
645
738
|
and renders as unavailable with a retry prompt. It does not claim that the slot
|
|
646
739
|
is empty. Overview, Endpoints, Connectors, connector
|
|
@@ -699,10 +792,9 @@ the page's styles.
|
|
|
699
792
|
|
|
700
793
|
`src/operator-ui/config-summary.ts` maps the snapshot and its provenance to
|
|
701
794
|
those tiles: one table of limit labels, the formatters, and the walk that turns
|
|
702
|
-
an unmapped key into an Other tile. `app/config-tiles.tsx` draws them
|
|
703
|
-
`test/operator-
|
|
704
|
-
|
|
705
|
-
unmapped.
|
|
795
|
+
an unmapped key into an Other tile. `app/config-tiles.tsx` draws them.
|
|
796
|
+
`test/browser/operator-flows.spec.ts` checks Settings provenance through the
|
|
797
|
+
production UI and real routes.
|
|
706
798
|
|
|
707
799
|
The contract type is [contract.ts](https://github.com/zackbart/connecta/blob/main/src/operator-ui/contract.ts).
|
|
708
800
|
[UI routes](https://github.com/zackbart/connecta/blob/main/src/routes/ui.ts) and
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Split mixed pools
|
|
2
|
+
|
|
3
|
+
Every pool must list only people or only `agent:` references. A mixed pool
|
|
4
|
+
throws `ConfigError` at construction naming the pool, for example
|
|
5
|
+
`ConnectaConfig.pools.team.members mixes people and agents; list only one kind.`
|
|
6
|
+
This also applies to personal pools with or without `owner`. Pool names and
|
|
7
|
+
connector ids do not decide membership type. People-only pools may retain an
|
|
8
|
+
`owner`; it never changes the account a person uses.
|
|
9
|
+
|
|
10
|
+
Before upgrading, inspect every pool's `members`, including generated lists.
|
|
11
|
+
For each mixed team pool, define its tool list once and create two pools:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const teamTools = ["crm", "tickets"];
|
|
15
|
+
const pools = {
|
|
16
|
+
team: { tools: teamTools, members: ["user_alice", "user_bob"] },
|
|
17
|
+
"assistant-team": { tools: teamTools, members: ["agent:assistant"] },
|
|
18
|
+
};
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Keep the original human pool name when possible so people's existing
|
|
22
|
+
`/mcp/team` address stays valid. Point the agent harness at
|
|
23
|
+
`/agent/assistant-team` and update its tier list to that name. Copy the
|
|
24
|
+
original `readOnly`, `surface`, `executeCode` and `description` settings
|
|
25
|
+
to both new pools as appropriate so each preserves its intended behavior.
|
|
26
|
+
If the mixed pool set `owner`, keep `owner` on the agent pool: it is the
|
|
27
|
+
Workspace address the agent acts as, and without it Workspace connectors with
|
|
28
|
+
a mapping `subject` disappear for the agent. People never use `owner`; they
|
|
29
|
+
always act as themselves, so the people pool does not need it. Agent pools
|
|
30
|
+
never count toward a person's plain `/mcp` routing, so a person who was in
|
|
31
|
+
one mixed pool and no other still reaches the people pool at plain `/mcp`.
|
|
32
|
+
|
|
33
|
+
For personal `assistant-alice` pools, keep only `"agent:assistant"` in
|
|
34
|
+
`members` and retain the owner's Workspace address and tools. Give people
|
|
35
|
+
their own people-only pools. Workspace mapping connectors act as each person;
|
|
36
|
+
shared-auth connectors act as their saved account for every member, so review
|
|
37
|
+
those grants before copying personal tool lists.
|
|
38
|
+
|
|
39
|
+
An agent can still belong to many pools with one token. Tokens, credentials,
|
|
40
|
+
`poolFor` tier selection logic and the Eve helper need no changes beyond pool
|
|
41
|
+
names in client configuration. Rebuild and restart the deployment, then verify
|
|
42
|
+
people and agents can each open their intended endpoints. See
|
|
43
|
+
[Organizing an agent's pools](./auth.md#organizing-an-agents-pools) for the
|
|
44
|
+
complete layout.
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
# Provider auth migration
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
For
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Use this upgrade guide when moving a Stripe, Vercel, or Cloudflare
|
|
9
|
-
deployment from 0.30 to 0.31, where `auth` selects each provider's
|
|
10
|
-
implementation.
|
|
11
|
-
[Deployment upgrades](./deploying.md#upgrade-an-existing-deployment) cover other
|
|
12
|
-
version changes; [integrating services](./integrating.md) covers new connectors.
|
|
3
|
+
This guide covers the 0.30-to-0.31 change to auth-selected implementations.
|
|
4
|
+
For current versions, follow [deployment upgrades](./deploying.md#upgrade-an-existing-deployment)
|
|
5
|
+
and [hosted MCP migration](./hosted-mcp-migration.md); hosted selectors below
|
|
6
|
+
are historical.
|
|
13
7
|
|
|
14
8
|
A dual provider requires `auth`. `{ type: "oauth" }` connects the vendor's
|
|
15
9
|
hosted MCP server, OAuth only. A key type connects Connecta's REST connector
|
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
# Notion, Vercel and Cloudflare migration for 0.29
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
For
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Use this upgrade guide for an existing deployment.
|
|
9
|
-
[Deployment upgrades](./deploying.md#upgrade-an-existing-deployment) cover other
|
|
10
|
-
version changes; [integrating services](./integrating.md) covers new connectors.
|
|
11
|
-
[The agent index](./README.md) routes package maintenance separately.
|
|
12
|
-
|
|
13
|
-
This was the Phase 1 item 5d migration input for [Phase 5 release #709](https://github.com/zackbart/connecta/issues/709),
|
|
14
|
-
which shipped as 0.29.0.
|
|
15
|
-
Deployments that use Notion or Cloudflare must check their actual grants and
|
|
16
|
-
connector ids in deployment configuration before that release.
|
|
17
|
-
The provider audit establishes available auth modes, not production OAuth grants.
|
|
3
|
+
This guide records the 0.29 Notion, Vercel and Cloudflare option changes.
|
|
4
|
+
For upgrades to current versions, use [deployment upgrades](./deploying.md#upgrade-an-existing-deployment)
|
|
5
|
+
and [hosted MCP migration](./hosted-mcp-migration.md); the hosted selectors below
|
|
6
|
+
are historical and cannot be used in current configuration.
|
|
18
7
|
|
|
19
8
|
Cloudflare's part of this guide is superseded: `cloudflare()` now selects its
|
|
20
9
|
implementation by `auth` and its key connector is complete on its own. Follow
|