@zackbart/connecta 0.33.0 → 0.34.1
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 +65 -0
- package/README.md +100 -128
- package/SECURITY.md +1 -1
- package/bin/version.mjs +1 -1
- package/dist/activity.d.ts +3 -0
- package/dist/branding.d.ts +7 -0
- package/dist/branding.js +76 -9
- package/dist/catalog-drift.d.ts +30 -26
- package/dist/catalog-drift.js +169 -84
- package/dist/catalog-service.js +16 -2
- package/dist/config-value-sources.js +6 -1
- package/dist/config.d.ts +13 -2
- package/dist/config.js +36 -2
- package/dist/connector-caller.js +2 -1
- package/dist/connectors/api-connector.d.ts +3 -0
- package/dist/connectors/api-connector.js +5 -1
- package/dist/connectors/option-shapes.js +1 -1
- package/dist/connectors/remote-mcp.d.ts +2 -0
- package/dist/connectors/remote-mcp.js +5 -1
- package/dist/describe-config.d.ts +5 -1
- package/dist/describe-config.js +2 -0
- package/dist/execute.js +1 -11
- package/dist/fix-prompt.js +2 -2
- package/dist/index.js +1 -0
- package/dist/invocation.js +3 -2
- package/dist/membership.d.ts +2 -0
- package/dist/meta-tools.js +3 -2
- package/dist/oauth-callback-outcome.js +2 -2
- package/dist/operator-ui/agents.d.ts +1 -1
- package/dist/operator-ui/agents.js +16 -16
- package/dist/operator-ui/config-summary.js +565 -0
- package/dist/operator-ui/connection-map.js +376 -0
- package/dist/operator-ui/endpoints.js +45 -16
- package/dist/operator-ui/fix-prompts.js +1 -1
- package/dist/operator-ui/generated.js +4 -4
- package/dist/operator-ui/health.js +52 -0
- package/dist/operator-ui/member-page.js +13 -28
- package/dist/operator-ui/overview.js +123 -0
- package/dist/operator-ui/view.d.ts +26 -22
- package/dist/operator-ui/view.js +130 -96
- package/dist/page-styles.js +5 -3
- package/dist/provider.d.ts +6 -1
- package/dist/provider.js +18 -1
- package/dist/providers/_shared/google/workspace.d.ts +9 -4
- package/dist/providers/_shared/google/workspace.js +7 -3
- package/dist/providers/basecamp/index.d.ts +2 -0
- package/dist/providers/breeze/index.d.ts +2 -0
- package/dist/providers/ccb/index.d.ts +2 -0
- package/dist/providers/ccb/index.js +2 -2
- package/dist/providers/cloudflare/index.d.ts +2 -0
- package/dist/providers/cloudflare/index.js +5 -1
- package/dist/providers/cloudflare/openapi.generated.js +3296 -3206
- package/dist/providers/cloudflare/rest.js +19 -0
- package/dist/providers/cloudflare/skill.generated.js +2 -2
- package/dist/providers/cloudflare/value-safety.js +51 -18
- package/dist/providers/docs/index.js +1 -1
- package/dist/providers/docs/skill.generated.js +2 -2
- package/dist/providers/drive/index.js +1 -1
- package/dist/providers/drive/skill.generated.js +2 -2
- package/dist/providers/forms/index.js +1 -1
- package/dist/providers/forms/skill.generated.js +2 -2
- package/dist/providers/gmail/index.js +1 -1
- package/dist/providers/gmail/skill.generated.js +2 -2
- package/dist/providers/intercom/index.d.ts +24 -0
- package/dist/providers/intercom/index.js +121 -0
- package/dist/providers/intercom/skill.generated.js +8 -0
- package/dist/providers/linear/index.js +204 -19
- package/dist/providers/linear/skill.generated.js +2 -2
- package/dist/providers/mixpanel/index.d.ts +2 -0
- package/dist/providers/mixpanel/index.js +21 -17
- package/dist/providers/mixpanel/skill.generated.js +3 -3
- package/dist/providers/notion/index.d.ts +2 -0
- package/dist/providers/notion/index.js +1 -1
- package/dist/providers/notion/skill.generated.js +1 -1
- package/dist/providers/overflow/index.d.ts +2 -0
- package/dist/providers/overflow/index.js +1 -1
- package/dist/providers/overflow/skill.generated.js +2 -2
- package/dist/providers/planning-center/index.d.ts +2 -0
- package/dist/providers/planning-center/index.js +1 -1
- package/dist/providers/planning-center/skill.generated.js +4 -4
- package/dist/providers/revenuecat/index.d.ts +5 -3
- package/dist/providers/revenuecat/index.js +147 -7
- package/dist/providers/revenuecat/skill.generated.js +3 -3
- package/dist/providers/sheets/index.js +1 -1
- package/dist/providers/sheets/skill.generated.js +2 -2
- package/dist/providers/slides/index.js +1 -1
- package/dist/providers/slides/skill.generated.js +2 -2
- package/dist/providers/stripe/index.d.ts +2 -0
- package/dist/providers/stripe/index.js +50 -30
- package/dist/providers/stripe/skill.generated.js +2 -1
- package/dist/providers/tithely/index.d.ts +2 -0
- package/dist/providers/tithely/index.js +1 -1
- package/dist/providers/vercel/index.d.ts +2 -0
- package/dist/providers/vercel/index.js +2 -2
- package/dist/providers/vercel/openapi.generated.js +391 -374
- package/dist/providers/vercel/skill.generated.js +2 -2
- package/dist/providers/vercel/value-safety.js +14 -4
- package/dist/registry.d.ts +10 -14
- package/dist/registry.js +77 -62
- package/dist/routes/mcp.js +20 -13
- package/dist/routes/oauth.js +2 -2
- package/dist/routes/ui-data.js +8 -2
- package/dist/skills.js +18 -2
- package/dist/storage/sql.js +5 -1
- package/dist/types.d.ts +36 -11
- package/dist/ui.js +9 -4
- package/dist/usage-guide.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/README.md +2 -2
- package/documentation/architecture.md +66 -18
- package/documentation/auth.md +183 -67
- package/documentation/code-mode.md +30 -10
- package/documentation/deploying.md +5 -1
- package/documentation/integrating.md +64 -7
- package/documentation/meta-tools.md +38 -24
- package/documentation/migration-0.33.md +21 -13
- package/documentation/migration-0.34.md +67 -0
- package/documentation/operating.md +1 -1
- package/documentation/operator-tests.md +52 -20
- package/documentation/operator-ui.md +341 -104
- package/documentation/provider-auth-migration.md +22 -0
- package/examples/worker/AGENTS.md +15 -9
- package/examples/worker/README.md +41 -14
- package/examples/worker/src/connecta.config.ts +5 -4
- package/examples/worker/wrangler.jsonc +1 -1
- package/package.json +23 -19
- package/templates/node/AGENTS.md +13 -7
- package/templates/node/README.md +14 -11
- package/templates/node/package.json +1 -1
- package/templates/node/src/connecta.config.ts +2 -2
package/dist/types.d.ts
CHANGED
|
@@ -252,12 +252,15 @@ export interface ReviewedTool {
|
|
|
252
252
|
/** Why the verdict holds when the name or downstream annotations do not say. */
|
|
253
253
|
readonly reason?: string;
|
|
254
254
|
/**
|
|
255
|
-
* `sha256:<hex>` digest of the input
|
|
255
|
+
* `sha256-sets-v1:<hex>` digest of the reviewed input/output schemas.
|
|
256
|
+
* Legacy `sha256:<hex>` pins retain literal array ordering.
|
|
256
257
|
* Omit until a review has actually read them; an invented digest reports
|
|
257
258
|
* drift that never happened. When the live schema no longer matches it, or
|
|
258
259
|
* it cannot be checked, the verdict lapses and the tool is served as a write.
|
|
259
260
|
*/
|
|
260
261
|
readonly schemaDigest?: string;
|
|
262
|
+
/** Absence is expected under plan, feature, or permission gating. */
|
|
263
|
+
readonly optional?: boolean;
|
|
261
264
|
}
|
|
262
265
|
/**
|
|
263
266
|
* A reviewed classification of a downstream MCP catalog, keyed by exact tool
|
|
@@ -287,7 +290,7 @@ export interface CatalogDriftCounts {
|
|
|
287
290
|
droppedTools?: number;
|
|
288
291
|
/** Live tools no release classified. Each one fails closed at call time. */
|
|
289
292
|
unclassifiedTools: number;
|
|
290
|
-
/**
|
|
293
|
+
/** Required reviewed names this catalog no longer serves. */
|
|
291
294
|
unservedTools: number;
|
|
292
295
|
/** Explicit downstream annotations that contradict a vetted verdict. */
|
|
293
296
|
annotationConflicts: number;
|
|
@@ -296,6 +299,15 @@ export interface CatalogDriftCounts {
|
|
|
296
299
|
}
|
|
297
300
|
/** One drift observation, taken while serving a catalog refresh. */
|
|
298
301
|
export interface CatalogDriftReport extends CatalogDriftCounts {
|
|
302
|
+
/** False when this listing has no reviewed classification to compare. */
|
|
303
|
+
reviewedBaseline?: boolean;
|
|
304
|
+
/** Whether all pinned schemas could be checked on this observation. */
|
|
305
|
+
verification?: "complete" | "unavailable";
|
|
306
|
+
/** Live reviewed tools with and without recorded schema digests. */
|
|
307
|
+
schemaCoverage?: {
|
|
308
|
+
pinned: number;
|
|
309
|
+
unpinned: number;
|
|
310
|
+
};
|
|
299
311
|
/** When the observation was taken; never when a probe was scheduled. */
|
|
300
312
|
observedAt: string;
|
|
301
313
|
}
|
|
@@ -364,6 +376,8 @@ export type ConnectorSkillResourceContents = {
|
|
|
364
376
|
});
|
|
365
377
|
/** The whole plugin contract — the one open seam. */
|
|
366
378
|
export interface Connector {
|
|
379
|
+
/** Serve only read-classified tools on every endpoint. Defaults to false. */
|
|
380
|
+
readOnly?: boolean;
|
|
367
381
|
id: string;
|
|
368
382
|
/**
|
|
369
383
|
* Who owns this connector's downstream authentication. `shared` keeps one
|
|
@@ -398,7 +412,7 @@ export interface Connector {
|
|
|
398
412
|
* cross-operation sequencing rule).
|
|
399
413
|
*
|
|
400
414
|
* Served as `skill://connecta/connectors/<slug>/SKILL.md`, with generated
|
|
401
|
-
* frontmatter
|
|
415
|
+
* frontmatter, a read-only policy notice when configured, and the guide body. `connector:<id>` is a
|
|
402
416
|
* one-release lookup alias. The guide remains deployment-owned configuration;
|
|
403
417
|
* no runtime registration or shared mutable copy exists.
|
|
404
418
|
*/
|
|
@@ -605,7 +619,7 @@ export interface ConnectorDescription {
|
|
|
605
619
|
tools?: ConnectorToolDescription[];
|
|
606
620
|
}
|
|
607
621
|
export interface ConnectorUsageGuide {
|
|
608
|
-
/** Markdown
|
|
622
|
+
/** Markdown served by `skills`, with a policy notice when the connector is read-only. */
|
|
609
623
|
content: string;
|
|
610
624
|
/**
|
|
611
625
|
* Discovery hint describing the conventions the guide covers. Whitespace is
|
|
@@ -822,7 +836,7 @@ export interface ConnectaBranding {
|
|
|
822
836
|
description?: string;
|
|
823
837
|
/**
|
|
824
838
|
* Browser tab title and page meta name. Defaults to
|
|
825
|
-
* `"<productName>
|
|
839
|
+
* `"<productName> · <ownerName>"`, or just `productName` when no owner is set.
|
|
826
840
|
*/
|
|
827
841
|
pageTitle?: string;
|
|
828
842
|
/**
|
|
@@ -832,14 +846,18 @@ export interface ConnectaBranding {
|
|
|
832
846
|
* elsewhere (it replaces the `/favicon.svg` link in the page head; the
|
|
833
847
|
* `/favicon.*` routes still serve whatever `svg`/`ico` provide). `href` must
|
|
834
848
|
* be an absolute `http(s)` URL or a root-relative path; anything else falls
|
|
835
|
-
* back to the default mark.
|
|
849
|
+
* back to the default mark. With `svg` set, the top bar shows it beside the
|
|
850
|
+
* name; the drawn mark shows only when no branding is set.
|
|
836
851
|
*/
|
|
837
852
|
favicon?: {
|
|
838
853
|
svg?: string;
|
|
839
854
|
ico?: Uint8Array;
|
|
840
855
|
href?: string;
|
|
841
856
|
};
|
|
842
|
-
/**
|
|
857
|
+
/**
|
|
858
|
+
* `theme-color` meta value. Unset, pages follow the page background:
|
|
859
|
+
* `#f6f4ef` in light and `#12110f` in dark.
|
|
860
|
+
*/
|
|
843
861
|
themeColor?: string;
|
|
844
862
|
/**
|
|
845
863
|
* Operator-page appearance. Every field is optional, and a rejected value
|
|
@@ -860,18 +878,25 @@ export interface ConnectaBranding {
|
|
|
860
878
|
export interface ConnectaTheme {
|
|
861
879
|
/**
|
|
862
880
|
* The brand color: links, focus rings, primary actions, the active nav item.
|
|
863
|
-
* Hex only (`#rgb`, `#rrggbb`, or `#rrggbbaa`). Defaults to `#
|
|
881
|
+
* Hex only (`#rgb`, `#rrggbb`, or `#rrggbbaa`). Defaults to `#4c44e0`
|
|
882
|
+
* (`#8c86ff` in dark). Text on it and accent text in dark derive from it.
|
|
864
883
|
*/
|
|
865
884
|
accent?: string;
|
|
866
885
|
/**
|
|
867
886
|
* Corner rounding for cards, inputs, and buttons. A CSS length (`10px`,
|
|
868
887
|
* `0.5rem`) or a bare number read as pixels. `0` restores square corners.
|
|
869
|
-
* Defaults to `
|
|
888
|
+
* Defaults to `14px`.
|
|
870
889
|
*/
|
|
871
890
|
radius?: string | number;
|
|
872
|
-
/**
|
|
891
|
+
/**
|
|
892
|
+
* Body font stack. A plain CSS font-family list. Defaults to Hanken
|
|
893
|
+
* Grotesk, served with the operator UI, then a system stack.
|
|
894
|
+
*/
|
|
873
895
|
fontFamily?: string;
|
|
874
|
-
/**
|
|
896
|
+
/**
|
|
897
|
+
* Monospace font stack for addresses, ids, and the endpoint URL. Defaults
|
|
898
|
+
* to JetBrains Mono, served with the operator UI, then a system stack.
|
|
899
|
+
*/
|
|
875
900
|
monoFamily?: string;
|
|
876
901
|
/**
|
|
877
902
|
* `"system"` (the default) follows the operator's OS setting; `"light"` and
|
package/dist/ui.js
CHANGED
|
@@ -6,9 +6,10 @@ import { uiData } from "./routes/ui-data.js";
|
|
|
6
6
|
import { runEdge } from "./runtime/run.js";
|
|
7
7
|
import { OPERATOR_UI_STYLE_PATH, OPERATOR_UI_SCHEME_PATH, OPERATOR_UI_SCRIPT_PATH, OPERATOR_UI_NOTICES_PATH, } from "./operator-ui/generated.js";
|
|
8
8
|
export { filterUiConnectors, } from "./operator-ui/model.js";
|
|
9
|
-
import { escapeHtml, isSafeHttpsUrl, renderPage, resolveBranding } from "./branding.js";
|
|
9
|
+
import { brandMark, escapeHtml, isSafeHttpsUrl, renderPage, resolveBranding } from "./branding.js";
|
|
10
10
|
export { CONNECTA_FAVICON_SVG, resolveBranding, isSafeHttpUrl, isSafeHttpsUrl, isSafeIconHref } from "./branding.js";
|
|
11
11
|
const OPERATOR_PAGE_LABELS = {
|
|
12
|
+
overview: "Overview",
|
|
12
13
|
endpoints: "Endpoints",
|
|
13
14
|
connections: "Connectors",
|
|
14
15
|
connector: "Connector",
|
|
@@ -18,6 +19,8 @@ const OPERATOR_PAGE_LABELS = {
|
|
|
18
19
|
};
|
|
19
20
|
export function operatorPageForPath(path) {
|
|
20
21
|
if (path === "/")
|
|
22
|
+
return "overview";
|
|
23
|
+
if (path === "/endpoints")
|
|
21
24
|
return "endpoints";
|
|
22
25
|
if (path === "/connectors")
|
|
23
26
|
return "connections";
|
|
@@ -36,7 +39,7 @@ export function operatorPageForPath(path) {
|
|
|
36
39
|
return undefined;
|
|
37
40
|
}
|
|
38
41
|
export function operatorPageTitle(page, configuredTitle) {
|
|
39
|
-
return `${OPERATOR_PAGE_LABELS[page]}
|
|
42
|
+
return `${OPERATOR_PAGE_LABELS[page]} · ${configuredTitle}`;
|
|
40
43
|
}
|
|
41
44
|
/** Report the verdict the registry stored, independent of whether an endpoint is read-only. */
|
|
42
45
|
export function uiToolSafety(definition) {
|
|
@@ -146,8 +149,8 @@ _nonce, page = "endpoints") {
|
|
|
146
149
|
<h1>${OPERATOR_PAGE_LABELS[page]}</h1>
|
|
147
150
|
<div class="lead-copy">
|
|
148
151
|
<p>${escapeHtml(brand.description)}</p>
|
|
149
|
-
<noscript><p class="msg">
|
|
150
|
-
|
|
152
|
+
<noscript><p class="msg">Operator pages need JavaScript. Agents connect at
|
|
153
|
+
<span class="mono">/mcp</span>.</p></noscript>
|
|
151
154
|
</div>
|
|
152
155
|
</div>
|
|
153
156
|
</main>
|
|
@@ -159,6 +162,7 @@ _nonce, page = "endpoints") {
|
|
|
159
162
|
schemePinned: brand.theme.colorScheme !== "system",
|
|
160
163
|
titleSuffix: brand.pageTitle,
|
|
161
164
|
productName: brand.productName,
|
|
165
|
+
brandMark: brandMark(branding, true),
|
|
162
166
|
productDescription: brand.description,
|
|
163
167
|
productOperatorLabel: brand.productName + " operator",
|
|
164
168
|
})}</script><script defer src="${OPERATOR_UI_SCRIPT_PATH}"></script>`,
|
|
@@ -182,6 +186,7 @@ export function operatorUi(options = {}) {
|
|
|
182
186
|
options = assertKnownOptions(options, "operatorUi()", OPERATOR_UI_OPTIONS);
|
|
183
187
|
const reservedPaths = [
|
|
184
188
|
"/",
|
|
189
|
+
"/endpoints",
|
|
185
190
|
"/connectors",
|
|
186
191
|
"/connectors/*",
|
|
187
192
|
"/tools",
|
package/dist/usage-guide.js
CHANGED
|
@@ -77,7 +77,7 @@ async () => {
|
|
|
77
77
|
|
|
78
78
|
Host-call budget exhaustion ends the run with budget_exceeded. Catch and
|
|
79
79
|
allSettled cannot recover it or return partial output. Bound batches before
|
|
80
|
-
starting them;
|
|
80
|
+
starting them; every guest call except emit spends host calls.
|
|
81
81
|
Split remaining reads. Never replay writes for their output.
|
|
82
82
|
|
|
83
83
|
## Per-connector guides
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CONNECTA_VERSION = "0.
|
|
1
|
+
export declare const CONNECTA_VERSION = "0.34.1";
|
package/dist/version.js
CHANGED
package/documentation/README.md
CHANGED
|
@@ -11,7 +11,7 @@ For a new deployment, start with [Deploying Connecta](./deploying.md).
|
|
|
11
11
|
| Task | Self-contained procedure |
|
|
12
12
|
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
13
13
|
| Add or remove a connector | [Change the connector roster](./integrating.md#add-or-remove-a-connector) |
|
|
14
|
-
| Organize an agent's pools
|
|
14
|
+
| Organize an agent's pools and tiers | [Organizing an agent's pools](./auth.md#organizing-an-agents-pools) |
|
|
15
15
|
| Add a person (maintainer or pool member) | [Add a person](./auth.md#add-a-person), [member page](./operator-ui.md#use-the-member-page) |
|
|
16
16
|
| Connect a shared credential | [Connect a shared credential](./auth.md#connect-a-shared-credential) |
|
|
17
17
|
| Issue, rotate, or revoke an agent token | [Manage an agent token](./auth.md#issue-rotate-or-revoke-an-agent-token) |
|
|
@@ -71,7 +71,7 @@ own scoped change procedures. Each [provider folder](https://github.com/zackbart
|
|
|
71
71
|
owns its maintained `SKILL.md`, options, tests, fixtures, and review data.
|
|
72
72
|
Use those details instead of copying provider catalogs into general guides.
|
|
73
73
|
The provider list in the human README is generated; preserve its marker pair
|
|
74
|
-
and run `
|
|
74
|
+
and run `pnpm run check:providers-generated` after edits.
|
|
75
75
|
|
|
76
76
|
When changing behavior, update its owning contract and task guide in the same
|
|
77
77
|
change. Check examples against current source and point to the tests that
|
|
@@ -148,6 +148,7 @@ An admitted non-preflight `/mcp` request then takes five steps in
|
|
|
148
148
|
(`src/membership.ts`, `admitsMaintainer`, `memberPool`, and `agentPool` in
|
|
149
149
|
`src/routes/shared.ts`). Nothing intersects or widens either view; every
|
|
150
150
|
refusal is one 404 naming no pool.
|
|
151
|
+
Connector `readOnly` is enforced by catalog discovery and invocation before dispatch: effective read-only is endpoint OR connector, including on plain `/mcp`. Maintained provider construction carries the policy through the shared factory.
|
|
151
152
|
The endpoint's `readOnly` is the pool's own value, else the deployment's;
|
|
152
153
|
plain `/mcp` uses the deployment's. It travels to the meta-tools and the
|
|
153
154
|
program as one boolean that drops writes from `CatalogService` search and
|
|
@@ -158,7 +159,7 @@ An admitted non-preflight `/mcp` request then takes five steps in
|
|
|
158
159
|
narrower slice, and the subject and principal keys. Personal connectors use
|
|
159
160
|
the principal partition and result paging the subject partition with principal,
|
|
160
161
|
endpoint/pool, origin, connector, and tool bindings. Paging re-admits the
|
|
161
|
-
caller at its endpoint and rechecks
|
|
162
|
+
caller at its endpoint and rechecks endpoint OR connector `readOnly`; no caller parameter selects a partition (`test/identity-scope.test.ts`).
|
|
162
163
|
5. **Serve.** Refuse `?toolkit=` with a 404 — the toolkits are gone
|
|
163
164
|
([#178](https://github.com/zackbart/connecta/issues/178)) but their URLs were
|
|
164
165
|
handed out, and retiring a scoping boundary into fail-open is worse than any
|
|
@@ -174,7 +175,7 @@ never select an identity, grant, connector view, or pool. Direct and program
|
|
|
174
175
|
activity records retain only the self-declared `clientName` and `clientVersion`,
|
|
175
176
|
validated by one ASCII grammar at the record builder, SQL write/read boundaries,
|
|
176
177
|
and authenticated activity read route. Names match
|
|
177
|
-
`[A-Za-z0-9][A-Za-z0-9 ._@/+-]{0,63}`; versions match
|
|
178
|
+
`[A-Za-z0-9@][A-Za-z0-9 ._@/+-]{0,63}`; versions match
|
|
178
179
|
`[A-Za-z0-9][A-Za-z0-9._+-]{0,31}`, each as a whole string. Names allow up to
|
|
179
180
|
64 characters, versions up to 32. `__proto__`, `constructor`, and `prototype`
|
|
180
181
|
are reserved. Invalid values are absent, never truncated or escaped. Capabilities and other client metadata never enter activity.
|
|
@@ -970,7 +971,7 @@ manual review evidence instead of claiming a machine-checkable JSON pin.
|
|
|
970
971
|
|
|
971
972
|
The generic REST connector (`src/providers/_shared/rest/`) serves
|
|
972
973
|
`<vendor>_api_search`, `_api_details`, `_api_read`, and `_api_write` over an
|
|
973
|
-
`OperationIndex` that `
|
|
974
|
+
`OperationIndex` that `pnpm run providers:spec` compiles offline from the
|
|
974
975
|
provider's pinned `openapi.source.json` into `openapi.generated.ts`.
|
|
975
976
|
Each call is matched to an operation and checked against its parameters before
|
|
976
977
|
transport; `_api_read` admits GET and the vendor's reviewed read-only POSTs in
|
|
@@ -1062,7 +1063,7 @@ every vendor ships one reviewed table through one mechanism
|
|
|
1062
1063
|
message/error and raw string/object source payloads in both events and
|
|
1063
1064
|
invocation maps. The shared review harness rejects embedded-URL operation
|
|
1064
1065
|
keys absent from each vendor's pinned index and invalid path syntax.
|
|
1065
|
-
Vercel
|
|
1066
|
+
The current Vercel pin was reviewed from its full response document; its unversioned URL does not retain older documents.
|
|
1066
1067
|
Generic parameters in descriptions, metadata, nicknames, billing footers,
|
|
1067
1068
|
notes, DNS TXT, KV values and operator HTML retain their original bytes,
|
|
1068
1069
|
including whole URL strings. Ordinary code/key URLs can be false positives
|
|
@@ -1165,7 +1166,7 @@ a table.
|
|
|
1165
1166
|
|
|
1166
1167
|
`remoteMcp({ classify })` is the public way to declare what a downstream's
|
|
1167
1168
|
tools do: `{ tools: { name: "read" | "write" | "destructive" | { verdict,
|
|
1168
|
-
reason?, schemaDigest? } }, unlisted?: "hide" }`, validated at construction. It fails closed
|
|
1169
|
+
reason?, schemaDigest?, optional? } }, unlisted?: "hide" }`, validated at construction. It fails closed
|
|
1169
1170
|
(INV-1): a reviewed read fills silence but yields to an explicit write
|
|
1170
1171
|
annotation, a reviewed write stays a write whatever the downstream claims, an
|
|
1171
1172
|
unlisted tool is a read only when it says so, and a reviewed tool whose
|
|
@@ -1191,8 +1192,50 @@ receives a separate deep copy of its definition, so mutations cannot change
|
|
|
1191
1192
|
classification, schemas, or write accounting later in the same program.
|
|
1192
1193
|
A restart applies the current review to cached SDK facts. Retired registry
|
|
1193
1194
|
manifest versions 2 and 3 are ignored and expire on their original TTL.
|
|
1194
|
-
During
|
|
1195
|
-
|
|
1195
|
+
During listings the registry counts drift against the same record. Optional
|
|
1196
|
+
reviewed tools do not count as unserved when gated out. Reports carry an explicit
|
|
1197
|
+
reviewed-baseline fact, counts of live reviewed tools with and without schema
|
|
1198
|
+
pins, and complete/unavailable schema verification. A digest failure replaces
|
|
1199
|
+
the previous observation rather than retaining a stale clean result (INV-1,
|
|
1200
|
+
INV-6). Observation and classification share the same verification result for each
|
|
1201
|
+
listing; classification still fails closed.
|
|
1202
|
+
|
|
1203
|
+
Reports are in-memory only, weakly keyed by connector and a registry-owned
|
|
1204
|
+
catalog partition token. The partition uses the same admitted principal,
|
|
1205
|
+
subject, caller identity, authenticated flag and pool as catalog caching, plus
|
|
1206
|
+
connector id and endpoint URLs. Personal registries do not share tokens with
|
|
1207
|
+
each other or the root. Each registry retains at most 1,024 tokens; eviction or
|
|
1208
|
+
restart yields no observation, never another subject's counts. No new storage
|
|
1209
|
+
key or durable catalog record is introduced.
|
|
1210
|
+
|
|
1211
|
+
New schema pins use `sha256-sets-v1:<hex>`. Canonicalization sorts object keys
|
|
1212
|
+
and schema `required`, `enum`, and `type` arrays, including schema-valued
|
|
1213
|
+
legacy dependencies. Tuple arrays and JSON data
|
|
1214
|
+
inside defaults, constants, enum members and examples retain order. Existing
|
|
1215
|
+
`sha256:<hex>` pins continue using the original key-sorted, literal-array
|
|
1216
|
+
algorithm; their reviewed digests are unchanged. Migrating a legacy pin requires
|
|
1217
|
+
reviewing the complete schemas and recording a new versioned digest. Legacy
|
|
1218
|
+
pins may still report conservative drift for array reordering until migrated.
|
|
1219
|
+
The iterative digest retains the whole-schema node ceiling in both formats.
|
|
1220
|
+
|
|
1221
|
+
Contributor evidence: `test/provider-schema-pins.test.ts` checks every provider
|
|
1222
|
+
construction case in the generated roster. Every pinned digest requires a
|
|
1223
|
+
complete captured schema that passes runtime verification; changed input or
|
|
1224
|
+
output schemas must fail it. The guard also exercises both digest prefixes.
|
|
1225
|
+
|
|
1226
|
+
The maintainer `scripts/drift-check.mjs` compares published inventories with
|
|
1227
|
+
provider evidence. Table inventories can require `inventory.accessColumn` and
|
|
1228
|
+
record `reviewedAccess` (`read` or `write`, with destructive verdicts recorded
|
|
1229
|
+
as write). These access snapshots must agree with the provider's runtime
|
|
1230
|
+
classification. A documented access change or disappearance of a reviewed explicit Access
|
|
1231
|
+
value is advisory drift, never an
|
|
1232
|
+
automatically accepted verdict. An explicit access value makes an
|
|
1233
|
+
`acknowledgedUnclassified` entry stale: report it and resume reporting that
|
|
1234
|
+
unreviewed tool as an addition. Missing tools and already reviewed names also
|
|
1235
|
+
invalidate such acknowledgements. Duplicate explicit access values must agree;
|
|
1236
|
+
a blank duplicate does not erase an explicit value elsewhere. Missing required
|
|
1237
|
+
columns in any tool table, unknown access values and conflicting rows are provider-local parser
|
|
1238
|
+
findings. The internal `withVettedCatalog()`
|
|
1196
1239
|
helper has been removed. Public provider `*_VETTED_CATALOG` exports remain
|
|
1197
1240
|
deprecated aliases derived from each definition
|
|
1198
1241
|
(`test/classified-decorators.test.ts`, `test/hosted-presets.test.ts`).
|
|
@@ -1236,10 +1279,13 @@ connecta shows a person — the operator shell, the OAuth callback, a browser's
|
|
|
1236
1279
|
404 — reads it. `src/operator-ui/tokens.css`
|
|
1237
1280
|
resolves every color, radius, and font through a custom property and mixes the
|
|
1238
1281
|
rest from those with `color-mix`; `page.css` holds the base typography and the
|
|
1239
|
-
|
|
1240
|
-
page). The UI's `browser.css` imports both,
|
|
1241
|
-
|
|
1282
|
+
pieces server-rendered pages share (top bar, buttons, badges, messages, the
|
|
1283
|
+
one-message status page). The UI's `browser.css` imports both, then one file
|
|
1284
|
+
per area under `src/operator-ui/styles/` (fonts, shared components, shell, and
|
|
1285
|
+
each page). The build writes the shared CSS, minified, into
|
|
1286
|
+
`src/page-styles.ts`, with the hashed font paths, a module that core imports
|
|
1242
1287
|
without the UI bundle, so an OAuth callback still renders with the UI omitted.
|
|
1288
|
+
Those pages link the fonts only when the UI module serves them.
|
|
1243
1289
|
`renderPage` in `src/branding.ts` is the one layout: head, favicon (the default
|
|
1244
1290
|
is linked only when the UI serves it), `data-scheme`, the tokens with the theme
|
|
1245
1291
|
after them, and the masthead. So `branding.theme` only has to append a `:root`
|
|
@@ -1253,14 +1299,16 @@ Maintained providers act as the caller downstream. `src/connector-caller.ts`
|
|
|
1253
1299
|
attaches the admitted identity beside the request-scoped context, readable only
|
|
1254
1300
|
by in-repo code and set from authorization, never arguments. Google Workspace
|
|
1255
1301
|
domain-wide delegation
|
|
1256
|
-
(`src/providers/google/`, first consumed by `./providers/gmail`) hands the
|
|
1302
|
+
(`src/providers/_shared/google/`, first consumed by `./providers/gmail`) hands the
|
|
1257
1303
|
admitted identity to a deployment-config `subject` function and mints a
|
|
1258
1304
|
service-account token as whatever Workspace address it returns. The caller
|
|
1259
1305
|
carries whether an inbound provider _authenticated_ it: an open deployment
|
|
1260
1306
|
admits everyone as the anonymous actor, and the function is never asked about
|
|
1261
1307
|
them. It also carries the admitted pool's `owner`, which core copies from
|
|
1262
|
-
config: an agent acts as it, before and instead of the function
|
|
1263
|
-
|
|
1308
|
+
config: an agent acts as it, before and instead of the function. In a pool
|
|
1309
|
+
without one, the scoped registry view omits a mapping-subject connector for an
|
|
1310
|
+
agent (`src/registry.ts`, keyed on the tag in `src/workspace-subject.ts`), as it
|
|
1311
|
+
omits a personal connector, and the provider still fails closed if reached. A fixed `subject` address is every
|
|
1264
1312
|
caller's. No caller, an unauthenticated one, or no address fails
|
|
1265
1313
|
`auth_required` before any request leaves. The provider never chooses the account and a
|
|
1266
1314
|
deployment's own connector still cannot read the caller (PRINCIPLES.md, INV-3; `test/google-workspace-delegation.test.ts`). Its tokens live in a
|
|
@@ -1321,7 +1369,7 @@ Effect callers skip the Promise and take the program: `admit` and
|
|
|
1321
1369
|
and `acquireCallScoped` for call admission, `closeScope` and `closeScopeOnExit`
|
|
1322
1370
|
for a connector scope, `withDeadlineEffect` where Promise code has
|
|
1323
1371
|
`withDeadline`. The build prunes every declaration no `exports` target reaches,
|
|
1324
|
-
and `
|
|
1372
|
+
and `pnpm run check:declarations` fails if what remains names an Effect type.
|
|
1325
1373
|
|
|
1326
1374
|
### One runner
|
|
1327
1375
|
|
|
@@ -1456,7 +1504,7 @@ resolve a single copy. Adopting an unstable subpath is its own pull request.
|
|
|
1456
1504
|
|
|
1457
1505
|
The stable `4.0.0` release was re-evaluated on 2026-10-01 with
|
|
1458
1506
|
[`scripts/probes/effect-v4-evaluation.mjs`](https://github.com/zackbart/connecta/blob/main/scripts/probes/effect-v4-evaluation.mjs).
|
|
1459
|
-
Run `
|
|
1507
|
+
Run `pnpm run build`, then `node scripts/probes/effect-v4-evaluation.mjs output.json`.
|
|
1460
1508
|
The [raw observations](https://github.com/zackbart/connecta/blob/main/scripts/probes/effect-v4-evaluation-2026-10-01.json)
|
|
1461
1509
|
are synthetic Node requests and neutral esbuild bundles, not live-client or
|
|
1462
1510
|
workerd lifetime verification. Bundle figures add representative prototypes
|
|
@@ -1494,7 +1542,7 @@ replacement's benefit or compatibility.
|
|
|
1494
1542
|
The core's cost is recorded rather than guessed. Against 0.24.4 the root entry
|
|
1495
1543
|
grew from 235,346 to 279,526 bytes gzip, the Worker example from 263,949 to
|
|
1496
1544
|
314,336, and each provider by about 36 KB, since each reaches Effect through
|
|
1497
|
-
`remoteMcp()`; `
|
|
1545
|
+
`remoteMcp()`; `pnpm run check:bundle` caps every entry against
|
|
1498
1546
|
`scripts/bundle-budget.json`. An install carries about 53 MB of `effect`, with
|
|
1499
1547
|
no dependencies of its own.
|
|
1500
1548
|
|
|
@@ -1510,7 +1558,7 @@ src/
|
|
|
1510
1558
|
catalog-drift.ts reviewed classifications and the drift counts a refresh produces
|
|
1511
1559
|
provider.ts defineProvider(): the one maintained-provider shape
|
|
1512
1560
|
activity.ts optional history factory and best-effort recorder
|
|
1513
|
-
auth/
|
|
1561
|
+
auth/ Cloudflare Access, clerk (optional peer), downstream OAuth (remote and static)
|
|
1514
1562
|
executors/ the QuickJS pool and child (Node only)
|
|
1515
1563
|
node.ts listen() (Node only)
|
|
1516
1564
|
d1.ts, sqlite.ts the two storage drivers; storage/ holds the SQL core and key families
|
|
@@ -1518,7 +1566,7 @@ src/
|
|
|
1518
1566
|
|
|
1519
1567
|
There are exactly two deployment shapes — `templates/node/`, which
|
|
1520
1568
|
`connecta init` copies with its container files, and `examples/worker/` — and
|
|
1521
|
-
`test/deployment-shapes.node.test.ts` with `
|
|
1569
|
+
`test/deployment-shapes.node.test.ts` with `pnpm run check:examples` keeps both
|
|
1522
1570
|
compiling and configuring the real thing.
|
|
1523
1571
|
|
|
1524
1572
|
## Sharp edges
|