@zackbart/connecta 0.37.1 → 0.38.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 +31 -0
- package/README.md +2 -2
- 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/auth/clerk-sdk/generated.js +2 -1
- package/dist/auth/downstream-oauth.js +19 -153
- package/dist/auth/downstream-revocation.js +1 -1
- package/dist/auth/oauth-grant.js +11 -0
- package/dist/auth/oauth-token-response.js +1 -1
- package/dist/auth/vercel-agent.js +2 -1
- package/dist/auth-elicitation.js +2 -2
- 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-fingerprint.js +2 -18
- package/dist/catalog-service.js +1 -1
- 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 +41 -14
- package/dist/config.js +21 -71
- package/dist/connectors/api-connector.js +4 -3
- package/dist/connectors/guarded-fetch.d.ts +0 -6
- package/dist/connectors/guarded-fetch.js +1 -11
- package/dist/connectors/remote-mcp.js +10 -43
- package/dist/connectors/resource-uri.js +0 -4
- package/dist/d1.d.ts +0 -89
- package/dist/d1.js +0 -34
- package/dist/downstream-input.js +2 -2
- package/dist/execute.js +22 -13
- package/dist/executor-result.js +2 -1
- package/dist/executors/quickjs-runtime.js +2 -25
- package/dist/executors/quickjs.js +1 -1
- package/dist/guest-runtime.js +5 -3
- package/dist/guest-types.d.ts +5 -5
- package/dist/http/client.js +1 -1
- package/dist/http/errors.js +2 -2
- package/dist/http/json-schema.js +1 -1
- package/dist/http/node-transport.js +0 -1
- package/dist/http/oauth.js +1 -1
- package/dist/http/paging.js +6 -9
- package/dist/http/provider.js +1 -1
- package/dist/http/safety.js +1 -1
- package/dist/http/services.js +1 -8
- package/dist/http/tools.js +1 -7
- package/dist/http/vendor.js +7 -7
- package/dist/identity.js +2 -6
- package/dist/invocation-auth.js +2 -1
- package/dist/meta-tools.js +27 -27
- package/dist/native-tools.js +2 -1
- package/dist/oauth-handoff.js +2 -2
- package/dist/operation-vocabulary.js +1 -1
- package/dist/operator-record.js +1 -49
- package/dist/operator-ui/contract.d.ts +2 -2
- package/dist/operator-ui/generated.js +3 -3
- 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 +1 -3
- package/dist/providers/_shared/rest/value-safety.js +26 -28
- package/dist/providers/breeze/api.js +2 -7
- package/dist/providers/breeze/index.js +4 -2
- package/dist/providers/breeze/tools.js +3 -4
- package/dist/providers/ccb/api.js +1 -6
- package/dist/providers/ccb/index.js +2 -1
- package/dist/providers/ccb/tools.js +1 -6
- package/dist/providers/cloudflare/api.js +2 -2
- package/dist/providers/cloudflare/index.js +2 -1
- package/dist/providers/cloudflare/safety.js +3 -3
- package/dist/providers/docs/tools.js +2 -10
- package/dist/providers/drive/tools.js +12 -25
- package/dist/providers/forms/tools.js +1 -9
- package/dist/providers/gmail/tools.js +5 -21
- package/dist/providers/overflow/api.js +1 -3
- package/dist/providers/overflow/index.js +2 -1
- package/dist/providers/overflow/tools.js +3 -7
- package/dist/providers/planning-center/api.js +2 -1
- 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/tools.js +2 -1
- package/dist/providers/sheets/tools.js +1 -9
- package/dist/providers/slides/tools.js +4 -13
- package/dist/providers/stripe/index.js +2 -1
- package/dist/providers/stripe/safety.js +2 -2
- package/dist/providers/tithely/api.js +2 -7
- package/dist/providers/tithely/index.js +3 -2
- package/dist/providers/tithely/tools.js +7 -5
- package/dist/providers/vercel/api.js +1 -6
- package/dist/providers/vercel/lib/pin.js +1 -1
- package/dist/providers/vercel/safety.js +1 -1
- package/dist/providers/vercel/tools.js +2 -1
- package/dist/redaction-marker.js +2 -2
- package/dist/registry.d.ts +1 -1
- package/dist/registry.js +5 -7
- 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 +1 -1
- package/dist/routes/mcp.js +4 -3
- package/dist/routes/oauth-management.js +1 -1
- package/dist/routes/operator.js +4 -3
- package/dist/routes/shared.d.ts +8 -8
- package/dist/routes/shared.js +9 -9
- package/dist/routes/ui-config.js +1 -1
- package/dist/routes/ui.js +1 -1
- package/dist/runtime/call-admission.js +1 -1
- package/dist/runtime/call.js +1 -1
- package/dist/runtime/settlement.js +1 -1
- package/dist/runtime/shared-read.js +2 -15
- 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 +8 -35
- package/dist/sqlite.d.ts +0 -19
- package/dist/sqlite.js +2 -83
- package/dist/storage/keys.js +16 -125
- package/dist/storage/sql-native.js +0 -101
- package/dist/storage/sql.d.ts +1 -24
- package/dist/storage/sql.js +1 -12
- package/dist/tool-error.js +4 -0
- package/dist/url-safety.js +0 -4
- package/dist/usage-guide.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker.js +1 -1
- package/documentation/README.md +6 -42
- package/documentation/architecture.md +86 -496
- package/documentation/auth.md +12 -25
- package/documentation/code-mode.md +90 -66
- package/documentation/deploying.md +19 -40
- package/documentation/integrating.md +4 -19
- package/documentation/meta-tools.md +6 -6
- package/documentation/migration-0.33.md +5 -5
- package/documentation/migration-0.34.md +2 -4
- package/documentation/migration-retired-layouts.md +74 -0
- package/documentation/operator-tests.md +19 -119
- package/documentation/operator-ui.md +3 -4
- package/documentation/provider-auth-migration.md +4 -10
- package/documentation/provider-migration-0.29.md +4 -15
- package/examples/worker/AGENTS.md +4 -6
- package/examples/worker/README.md +20 -115
- package/guides/connecting-agents.md +7 -30
- package/guides/how-it-works.md +2 -2
- package/guides/safety-and-trust.md +4 -1
- package/package.json +19 -19
- package/templates/node/README.md +9 -26
- package/templates/node/package.json +1 -1
- 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
package/dist/storage/keys.js
CHANGED
|
@@ -141,7 +141,7 @@ export const catalogKeys = {
|
|
|
141
141
|
name: "catalog",
|
|
142
142
|
scope: "root",
|
|
143
143
|
prefixes: ["catalog:"],
|
|
144
|
-
// Retired v2/v3 listings
|
|
144
|
+
// Retired v2/v3 listings expire on their original TTL; no runtime reads them.
|
|
145
145
|
version: { number: 3, in: "value" },
|
|
146
146
|
codec: textCodec,
|
|
147
147
|
ttl: {
|
|
@@ -242,38 +242,6 @@ export const credentialKeys = {
|
|
|
242
242
|
},
|
|
243
243
|
credential: (connectorId, owner) => `${owner ? scopes.principal(owner) : ""}${scopes.connector(connectorId)}credential:v1`,
|
|
244
244
|
};
|
|
245
|
-
/** Seconds a Workers KV → D1 copy's resume point stays usable. */
|
|
246
|
-
export const KV_COPY_CURSOR_TTL_SECONDS = 7 * 24 * 60 * 60;
|
|
247
|
-
/**
|
|
248
|
-
* Where a one-shot Workers KV → D1 copy (`copyKvToD1` in `src/d1.ts`) resumes,
|
|
249
|
-
* held in D1 under a random token. Workers KV's own list cursor can spell the
|
|
250
|
-
* last key it listed, so the caller holds the token and never the cursor.
|
|
251
|
-
*/
|
|
252
|
-
export const kvCopyKeys = {
|
|
253
|
-
family: {
|
|
254
|
-
name: "kv-copy",
|
|
255
|
-
scope: "root",
|
|
256
|
-
prefixes: ["kv-copy:v1:"],
|
|
257
|
-
version: { number: 1, in: "key" },
|
|
258
|
-
codec: textCodec,
|
|
259
|
-
ttl: { kind: "fixed", seconds: KV_COPY_CURSOR_TTL_SECONDS },
|
|
260
|
-
durable: false,
|
|
261
|
-
},
|
|
262
|
-
cursor: (token) => validateStorageKey(`kv-copy:v1:cursor:${token}`),
|
|
263
|
-
};
|
|
264
|
-
/** Once traffic uses D1, copying stale KV state is refused. */
|
|
265
|
-
export const kvCutoverKeys = {
|
|
266
|
-
family: {
|
|
267
|
-
name: "kv-cutover",
|
|
268
|
-
scope: "root",
|
|
269
|
-
prefixes: ["kv-cutover:v1:"],
|
|
270
|
-
version: { number: 1, in: "key" },
|
|
271
|
-
codec: textCodec,
|
|
272
|
-
ttl: { kind: "durable" },
|
|
273
|
-
durable: true,
|
|
274
|
-
},
|
|
275
|
-
source: (source) => validateStorageKey(`kv-cutover:v1:${encodeURIComponent(source)}`),
|
|
276
|
-
};
|
|
277
245
|
// --- connector families ---------------------------------------------------
|
|
278
246
|
/** Seconds a consent's flow record stays claimable, the same as its link. */
|
|
279
247
|
export const OAUTH_FLOW_TTL_SECONDS = 15 * 60;
|
|
@@ -356,38 +324,6 @@ export const oauthRefreshActiveKeys = {
|
|
|
356
324
|
prefix: "oauth:refresh-active:",
|
|
357
325
|
holder: (epoch, holder) => validateStorageKey(`oauth:refresh-active:${epoch}:${holder}`),
|
|
358
326
|
};
|
|
359
|
-
/** The values layout 2 stored, each under its historical key. */
|
|
360
|
-
const oauthV2Field = {
|
|
361
|
-
client: "oauth:client",
|
|
362
|
-
tokens: "oauth:tokens",
|
|
363
|
-
pending: "oauth:pending",
|
|
364
|
-
verifier: "oauth:verifier",
|
|
365
|
-
state: "oauth:state",
|
|
366
|
-
discovery: "oauth:discovery",
|
|
367
|
-
};
|
|
368
|
-
/**
|
|
369
|
-
* Layout 2, read once to migrate it into a grant record and then deleted:
|
|
370
|
-
* each value at its field key, suffixed `:epoch:<generation>` once a modern
|
|
371
|
-
* generation owned it; the active generation at `oauth:generation`; a reset's
|
|
372
|
-
* cleanup lineage at `oauth:cleanup:` and `oauth:cleanup-at:`.
|
|
373
|
-
*/
|
|
374
|
-
export const oauthV2Keys = {
|
|
375
|
-
family: {
|
|
376
|
-
name: "oauth-v2",
|
|
377
|
-
scope: "connector",
|
|
378
|
-
prefixes: [...Object.values(oauthV2Field), "oauth:generation", "oauth:cleanup:", "oauth:cleanup-at:"],
|
|
379
|
-
version: { number: 2, in: "value" },
|
|
380
|
-
codec: textCodec,
|
|
381
|
-
ttl: { kind: "durable" },
|
|
382
|
-
durable: true,
|
|
383
|
-
},
|
|
384
|
-
field: oauthV2Field,
|
|
385
|
-
/** One listing covers every layout 2 key; the reader keeps those above. */
|
|
386
|
-
scan: "oauth:",
|
|
387
|
-
/** A value's physical key; `epoch` null is the historical unsuffixed name. */
|
|
388
|
-
value: (key, epoch) => validateStorageKey(epoch === null ? key : `${key}:epoch:${epoch}`),
|
|
389
|
-
generation: "oauth:generation",
|
|
390
|
-
};
|
|
391
327
|
/** Single-use browser links (`used`/`started`/`failed`/`closed`) and MRTR rounds. */
|
|
392
328
|
export const oauthConnectKeys = {
|
|
393
329
|
family: {
|
|
@@ -430,63 +366,18 @@ export const inputRetryKeys = {
|
|
|
430
366
|
},
|
|
431
367
|
used: (nonce) => validateStorageKey(`input-retry:v1:${nonce}`),
|
|
432
368
|
};
|
|
433
|
-
/**
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
accessTokenKeys.family,
|
|
449
|
-
agentObservationKeys.family,
|
|
450
|
-
credentialKeys.family,
|
|
451
|
-
oauthGrantKeys.family,
|
|
452
|
-
oauthFlowKeys.family,
|
|
453
|
-
oauthRefreshKeys.family,
|
|
454
|
-
oauthRefreshSpentKeys.family,
|
|
455
|
-
oauthRefreshActiveKeys.family,
|
|
456
|
-
oauthV2Keys.family,
|
|
457
|
-
oauthConnectKeys.family,
|
|
458
|
-
negotiationKeys.family,
|
|
459
|
-
inputRetryKeys.family,
|
|
460
|
-
kvCopyKeys.family,
|
|
461
|
-
kvCutoverKeys.family,
|
|
462
|
-
];
|
|
463
|
-
// Principal, connector, and subject segments are hex digests and connector
|
|
464
|
-
// ids, so none holds a colon.
|
|
465
|
-
const PRINCIPAL_SCOPE = /^principal:[^:]*:/;
|
|
466
|
-
const CONNECTOR_SCOPE = /^conn:[^:]*:/;
|
|
467
|
-
const PARTITION_SCOPE = /^(?:results:|subject:[^:]*:)/;
|
|
468
|
-
/**
|
|
469
|
-
* The family a physical key belongs to, for reports that count keys without
|
|
470
|
-
* naming them: one-shot migrations report per family, never per key. A key
|
|
471
|
-
* no family claims is `connector-owned` when a custom connector wrote it
|
|
472
|
-
* through its own `ctx.storage`, and `unclassified` otherwise (a key an older release wrote).
|
|
473
|
-
*/
|
|
474
|
-
export function familyOfKey(key) {
|
|
475
|
-
let rest = key.replace(PRINCIPAL_SCOPE, "");
|
|
476
|
-
let scope = "root";
|
|
477
|
-
for (const [pattern, nested] of [
|
|
478
|
-
[CONNECTOR_SCOPE, "connector"],
|
|
479
|
-
[PARTITION_SCOPE, "partition"],
|
|
480
|
-
]) {
|
|
481
|
-
const match = pattern.exec(rest);
|
|
482
|
-
if (match) {
|
|
483
|
-
rest = rest.slice(match[0].length);
|
|
484
|
-
scope = nested;
|
|
485
|
-
break;
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
const family = KEY_FAMILIES.find((candidate) => candidate.scope === scope && candidate.prefixes.some((prefix) => rest.startsWith(prefix)));
|
|
489
|
-
if (family)
|
|
490
|
-
return family.name;
|
|
491
|
-
return scope === "connector" ? "connector-owned" : "unclassified";
|
|
492
|
-
}
|
|
369
|
+
/** Retired OAuth names are inspected only to report that fresh consent is required. */
|
|
370
|
+
export const retiredOAuthKeys = {
|
|
371
|
+
scan: "oauth:",
|
|
372
|
+
prefixes: [
|
|
373
|
+
"oauth:client",
|
|
374
|
+
"oauth:tokens",
|
|
375
|
+
"oauth:pending",
|
|
376
|
+
"oauth:verifier",
|
|
377
|
+
"oauth:state",
|
|
378
|
+
"oauth:discovery",
|
|
379
|
+
"oauth:generation",
|
|
380
|
+
"oauth:cleanup:",
|
|
381
|
+
"oauth:cleanup-at:",
|
|
382
|
+
],
|
|
383
|
+
};
|
|
@@ -177,107 +177,6 @@ export function nativeSqlStorage(driver) {
|
|
|
177
177
|
},
|
|
178
178
|
};
|
|
179
179
|
}
|
|
180
|
-
/** Keys one read compares: D1 binds at most 100 parameters, one is `now`. */
|
|
181
|
-
const COPY_READ_KEYS = 99;
|
|
182
|
-
/** Writes one transaction carries, by count and by UTF-8 bytes. */
|
|
183
|
-
const COPY_BATCH_STATEMENTS = 50;
|
|
184
|
-
const COPY_BATCH_BYTES = 4 * 1024 * 1024;
|
|
185
|
-
/**
|
|
186
|
-
* Copy entries into the key-value table, verbatim: same key, same value,
|
|
187
|
-
* same absolute expiry. A live row holding a different value is kept unless
|
|
188
|
-
* `overwrite` is set, so a second copy of the same entries writes nothing.
|
|
189
|
-
* Writes go out in bounded transactions; the outcomes follow `entries`.
|
|
190
|
-
*/
|
|
191
|
-
export function copyIntoSqlEffect(driver, entries, options) {
|
|
192
|
-
return Effect.gen(function* () {
|
|
193
|
-
const { overwrite, now } = options;
|
|
194
|
-
for (const entry of entries)
|
|
195
|
-
validateStorageKey(entry.key);
|
|
196
|
-
yield* driver.batch(KV_SCHEMA.map((statement) => sql(statement)));
|
|
197
|
-
const live = "(expires_at_ms IS NULL OR expires_at_ms > ?)";
|
|
198
|
-
const currentValues = (keys) => Effect.gen(function* () {
|
|
199
|
-
const values = new Map();
|
|
200
|
-
for (let start = 0; start < keys.length; start += COPY_READ_KEYS) {
|
|
201
|
-
const chunk = keys.slice(start, start + COPY_READ_KEYS);
|
|
202
|
-
const rows = yield* driver.all(sql(`SELECT key, ${textColumn("value")}, expires_at_ms FROM connecta_kv
|
|
203
|
-
WHERE key IN (${chunk.map(() => "?").join(", ")}) AND ${live}`, ...chunk, now));
|
|
204
|
-
// The message names no key: a copy's errors reach operator output.
|
|
205
|
-
for (const row of rows) {
|
|
206
|
-
values.set(row.key, {
|
|
207
|
-
value: textOf(row.value, row.value_bytes, "a stored value") ?? "",
|
|
208
|
-
expiresAtMs: row.expires_at_ms,
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return values;
|
|
213
|
-
});
|
|
214
|
-
const outcomes = Array.from({ length: entries.length });
|
|
215
|
-
const writes = [];
|
|
216
|
-
const existing = yield* currentValues(entries.map((entry) => entry.key));
|
|
217
|
-
for (const [index, entry] of entries.entries()) {
|
|
218
|
-
const current = existing.get(entry.key);
|
|
219
|
-
if (current?.value === entry.value && current.expiresAtMs === entry.expiresAtMs) {
|
|
220
|
-
outcomes[index] = "unchanged";
|
|
221
|
-
}
|
|
222
|
-
else if (current !== undefined && !overwrite) {
|
|
223
|
-
outcomes[index] = "conflict";
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
outcomes[index] = current === undefined ? "copied" : "overwritten";
|
|
227
|
-
writes.push({
|
|
228
|
-
index,
|
|
229
|
-
bytes: new TextEncoder().encode(entry.key).byteLength + new TextEncoder().encode(entry.value).byteLength + 32,
|
|
230
|
-
statement: overwrite
|
|
231
|
-
? sql(`INSERT INTO connecta_kv (key, value, expires_at_ms)
|
|
232
|
-
VALUES (?, ?, ?)
|
|
233
|
-
ON CONFLICT (key) DO UPDATE SET
|
|
234
|
-
value = excluded.value, expires_at_ms = excluded.expires_at_ms`, entry.key, entry.value, entry.expiresAtMs)
|
|
235
|
-
: // Absent when read; a live row written since is kept, not replaced.
|
|
236
|
-
sql(`INSERT INTO connecta_kv (key, value, expires_at_ms)
|
|
237
|
-
VALUES (?, ?, ?)
|
|
238
|
-
ON CONFLICT (key) DO UPDATE SET
|
|
239
|
-
value = excluded.value, expires_at_ms = excluded.expires_at_ms
|
|
240
|
-
WHERE connecta_kv.expires_at_ms IS NOT NULL
|
|
241
|
-
AND connecta_kv.expires_at_ms <= ?`, entry.key, entry.value, entry.expiresAtMs, now),
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
const raced = [];
|
|
246
|
-
let batch = [];
|
|
247
|
-
let batchBytes = 0;
|
|
248
|
-
const flush = () => Effect.gen(function* () {
|
|
249
|
-
if (batch.length === 0)
|
|
250
|
-
return;
|
|
251
|
-
const changes = yield* driver.batch(batch.map((write) => write.statement));
|
|
252
|
-
for (const [position, write] of batch.entries()) {
|
|
253
|
-
if (!(changes[position] > 0))
|
|
254
|
-
raced.push(write.index);
|
|
255
|
-
}
|
|
256
|
-
batch = [];
|
|
257
|
-
batchBytes = 0;
|
|
258
|
-
});
|
|
259
|
-
for (const write of writes) {
|
|
260
|
-
if (batch.length > 0 && (batch.length >= COPY_BATCH_STATEMENTS || batchBytes + write.bytes > COPY_BATCH_BYTES)) {
|
|
261
|
-
yield* flush();
|
|
262
|
-
}
|
|
263
|
-
batch.push(write);
|
|
264
|
-
batchBytes += write.bytes;
|
|
265
|
-
}
|
|
266
|
-
yield* flush();
|
|
267
|
-
// A row another writer added between the read and the write: report what
|
|
268
|
-
// it holds, and leave it.
|
|
269
|
-
if (raced.length > 0) {
|
|
270
|
-
const after = yield* currentValues(raced.map((index) => entries[index].key));
|
|
271
|
-
for (const index of raced) {
|
|
272
|
-
const entry = entries[index];
|
|
273
|
-
const current = after.get(entry.key);
|
|
274
|
-
outcomes[index] =
|
|
275
|
-
current?.value === entry.value && current.expiresAtMs === entry.expiresAtMs ? "unchanged" : "conflict";
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return outcomes;
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
180
|
// --- activity -----------------------------------------------------------
|
|
282
181
|
/**
|
|
283
182
|
* The activity table, with keyset paging on `(occurred_at_ms, id)`. Its shape
|
package/dist/storage/sql.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { ActivityStore } from "../activity.js";
|
|
2
2
|
import type { KVStorage } from "../types.js";
|
|
3
|
-
/** The 0.28-compatible key-value table and expiry index. */
|
|
4
|
-
export { KV_SCHEMA } from "./sql-schema.js";
|
|
5
3
|
type SqlValue = string | number | null;
|
|
6
4
|
export interface SqlStatement {
|
|
7
5
|
readonly sql: string;
|
|
@@ -21,18 +19,6 @@ export interface SqlDriver {
|
|
|
21
19
|
}
|
|
22
20
|
/** The two drivers, as `describe()` names them. */
|
|
23
21
|
export type SqlKind = "d1" | "sqlite";
|
|
24
|
-
export interface SqlCopyEntry {
|
|
25
|
-
readonly key: string;
|
|
26
|
-
readonly value: string;
|
|
27
|
-
/** Epoch milliseconds; null never expires. */
|
|
28
|
-
readonly expiresAtMs: number | null;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* What a copy did with one entry: written where no live row was, left alone
|
|
32
|
-
* because the live row already held the value, refused because it held
|
|
33
|
-
* another (`conflict`), or replaced under `overwrite` (`overwritten`).
|
|
34
|
-
*/
|
|
35
|
-
export type SqlCopyOutcome = "copied" | "unchanged" | "conflict" | "overwritten";
|
|
36
22
|
export interface SqlActivityOptions {
|
|
37
23
|
/**
|
|
38
24
|
* Days of history kept. Each write removes a bounded batch of older rows,
|
|
@@ -48,13 +34,4 @@ export declare function sqlStorage(driver: SqlDriver, kind: SqlKind): KVStorage;
|
|
|
48
34
|
* payload to leak.
|
|
49
35
|
*/
|
|
50
36
|
export declare function sqlActivityStore(driver: SqlDriver, kind: SqlKind, options?: SqlActivityOptions): ActivityStore;
|
|
51
|
-
|
|
52
|
-
* Copy entries into the key-value table, verbatim: same key, same value,
|
|
53
|
-
* same absolute expiry. A live row holding a different value is kept unless
|
|
54
|
-
* `overwrite` is set, so a second copy of the same entries writes nothing.
|
|
55
|
-
* Writes go out in bounded transactions; the outcomes follow `entries`.
|
|
56
|
-
*/
|
|
57
|
-
export declare function copyIntoSql(driver: SqlDriver, entries: readonly SqlCopyEntry[], options: {
|
|
58
|
-
overwrite: boolean;
|
|
59
|
-
now: number;
|
|
60
|
-
}): Promise<SqlCopyOutcome[]>;
|
|
37
|
+
export {};
|
package/dist/storage/sql.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { runEdge } from "../runtime/run.js";
|
|
2
2
|
import { registerNativeStorage, registerNativeActivity } from "../runtime/native-storage.js";
|
|
3
3
|
import { nativeSqlDriver } from "./sql-driver.js";
|
|
4
|
-
import { nativeSqlStorage, nativeSqlActivityStore
|
|
5
|
-
/** The 0.28-compatible key-value table and expiry index. */
|
|
6
|
-
export { KV_SCHEMA } from "./sql-schema.js";
|
|
4
|
+
import { nativeSqlStorage, nativeSqlActivityStore } from "./sql-native.js";
|
|
7
5
|
/** `KVStorage` over one `connecta_kv` table. */
|
|
8
6
|
export function sqlStorage(driver, kind) {
|
|
9
7
|
const native = nativeSqlStorage(nativeSqlDriver(driver));
|
|
@@ -30,12 +28,3 @@ export function sqlActivityStore(driver, kind, options = {}) {
|
|
|
30
28
|
list: (options) => runEdge(native.list(options)),
|
|
31
29
|
}, native);
|
|
32
30
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Copy entries into the key-value table, verbatim: same key, same value,
|
|
35
|
-
* same absolute expiry. A live row holding a different value is kept unless
|
|
36
|
-
* `overwrite` is set, so a second copy of the same entries writes nothing.
|
|
37
|
-
* Writes go out in bounded transactions; the outcomes follow `entries`.
|
|
38
|
-
*/
|
|
39
|
-
export function copyIntoSql(driver, entries, options) {
|
|
40
|
-
return runEdge(copyIntoSqlEffect(nativeSqlDriver(driver), entries, options));
|
|
41
|
-
}
|
package/dist/url-safety.js
CHANGED
|
@@ -117,10 +117,6 @@ export function classifyHost(hostname) {
|
|
|
117
117
|
return "loopback";
|
|
118
118
|
return "public";
|
|
119
119
|
}
|
|
120
|
-
/** True for loopback and private hosts alike. */
|
|
121
|
-
export function isPrivateHost(hostname) {
|
|
122
|
-
return classifyHost(hostname) !== "public";
|
|
123
|
-
}
|
|
124
120
|
/**
|
|
125
121
|
* Why connecta must not fetch `target`, a URL the downstream advertised, for a
|
|
126
122
|
* connector configured at `configured` — or undefined when it may.
|
package/dist/usage-guide.js
CHANGED
|
@@ -84,8 +84,8 @@ Split remaining reads. Never replay writes for their output.
|
|
|
84
84
|
|
|
85
85
|
## Per-connector guides
|
|
86
86
|
|
|
87
|
-
Fetch a listed guide
|
|
88
|
-
inside a program; it returns \`{ name, text, format: "text" }\`.
|
|
87
|
+
Fetch a listed guide by its exact name with the skills tool, or
|
|
88
|
+
\`connecta.skill(name)\` inside a program; it returns \`{ name, text, format: "text" }\`.
|
|
89
89
|
\`guideRequired: true\` is a hard stop. connector_required and approval_required
|
|
90
90
|
remain after schema expansion; schema_truncated clears after exact describe.
|
|
91
91
|
Otherwise fetch for units, pagination, aliases, or sequences.
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CONNECTA_VERSION = "0.
|
|
1
|
+
export declare const CONNECTA_VERSION = "0.38.0";
|
package/dist/version.js
CHANGED
package/dist/worker.js
CHANGED
|
@@ -47,7 +47,7 @@ function routeGuestImports(source) {
|
|
|
47
47
|
export function workerExecutor(options) {
|
|
48
48
|
// One pool per executor, so per isolate. A queued run may wait out one
|
|
49
49
|
// default guest deadline: programs spend it awaiting host calls, and a
|
|
50
|
-
// five-second wait refused nearly every run queued behind one
|
|
50
|
+
// five-second wait refused nearly every run queued behind one.
|
|
51
51
|
const admission = new AdmissionController(options.admission ?? {
|
|
52
52
|
concurrency: 2,
|
|
53
53
|
maxQueueSize: 8,
|
package/documentation/README.md
CHANGED
|
@@ -36,20 +36,8 @@ The separate `@zackbart/connecta-eve` helper is available from 0.35.0. Its
|
|
|
36
36
|
[package guide](https://github.com/zackbart/connecta/blob/main/packages/connecta-eve/README.md)
|
|
37
37
|
owns installation, supported Node/Eve versions, and token-source setup.
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
`documentation/`, `templates/`, and `examples/worker/` are written first for an
|
|
42
|
-
agent operating a deployment from the installed package. The root `README.md`
|
|
43
|
-
and `guides/` explain the product for people and also ship in the package;
|
|
44
|
-
they own no operator contracts. Operator conventions must be self-contained rules plus a
|
|
45
|
-
neutral example. Decision records and issues explain why; no operator task
|
|
46
|
-
requires them, `spec/`, `.claude/`, or the Connecta source checkout. Those
|
|
47
|
-
three directories do not ship. Contributor source maps, INV citations, and
|
|
48
|
-
implementation/test evidence belong under clearly labeled contributor
|
|
49
|
-
headings and are optional for operators. Use `assistant`, `alice`, `bob`,
|
|
50
|
-
`crm`, `tickets`, `notes_alice`, and `alice@example.com` in examples; never
|
|
51
|
-
real deployment, client, person, or organization names. Maintained provider
|
|
52
|
-
product names stay.
|
|
39
|
+
For pre-0.29 storage or OAuth grants, complete the [retired layout migrations](./migration-retired-layouts.md)
|
|
40
|
+
on 0.37.1 before upgrading past that bridge release.
|
|
53
41
|
|
|
54
42
|
## Contract reference
|
|
55
43
|
|
|
@@ -61,6 +49,7 @@ product names stay.
|
|
|
61
49
|
| [Architecture (contributor reference)](./architecture.md) | Request lifetimes, routes, storage, configuration, import boundaries, and Effect implementation |
|
|
62
50
|
| [Operator UI](./operator-ui.md) | Optional UI setup, scoped configuration and live-data contract, activity disclosure, and UI implementation |
|
|
63
51
|
| [Operator UI tests (contributor reference)](./operator-tests.md) | Browser state matrix, real-server flows, and snapshot maintenance |
|
|
52
|
+
| [Retired layout migrations](./migration-retired-layouts.md) | Required 0.37.1 bridge for KV, JSON state, and OAuth layout-2 grants |
|
|
64
53
|
| [Migration to 0.33](./migration-0.33.md) | Upgrade actions from 0.32 options to maintainers, members, agents, agent endpoints, and pool owners |
|
|
65
54
|
| [Provider migration for 0.29](./provider-migration-0.29.md) | Upgrade actions for Notion, Vercel, and Cloudflare; provider reconciliation tables supply exact name mappings |
|
|
66
55
|
| [Provider migration for 0.35](./provider-migration-0.35.md) | Provider upgrade actions for 0.35.0 |
|
|
@@ -72,34 +61,9 @@ implementation evidence.
|
|
|
72
61
|
|
|
73
62
|
## Contributor reference
|
|
74
63
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
Connecta offers and the setup handoff. The human guides explain
|
|
79
|
-
[how it works](../guides/how-it-works.md), [connecting agents](../guides/connecting-agents.md),
|
|
80
|
-
and [safety and trust](../guides/safety-and-trust.md). Keep their examples small
|
|
81
|
-
and consistent with these contracts. Configuration references, complete setup
|
|
82
|
-
procedures, migrations, and internal module maps belong here in agent documentation.
|
|
83
|
-
|
|
84
|
-
[AGENTS.md](https://github.com/zackbart/connecta/blob/main/AGENTS.md) is the
|
|
85
|
-
canonical repository policy, with `CLAUDE.md` as its symlink. Do not copy its
|
|
86
|
-
verification, review, or release rules into another policy document.
|
|
87
|
-
|
|
88
|
-
Deployment-local READMEs and agent instructions own runnable platform setup:
|
|
89
|
-
[Node and Docker](../templates/node/README.md), [Workers](../examples/worker/README.md).
|
|
90
|
-
Keep those aligned with their configuration and with this task router.
|
|
91
|
-
Repository [skills](https://github.com/zackbart/connecta/tree/main/.claude/skills)
|
|
92
|
-
own scoped change procedures. Each [provider folder](https://github.com/zackbart/connecta/tree/main/src/providers)
|
|
93
|
-
owns its maintained `SKILL.md`, options, tests, fixtures, and review data.
|
|
94
|
-
Use those details instead of copying provider catalogs into general guides.
|
|
95
|
-
The provider list in the human README is generated; preserve its marker pair
|
|
96
|
-
and run `pnpm run check:providers-generated` after edits.
|
|
97
|
-
|
|
98
|
-
When changing behavior, update its owning contract and task guide in the same
|
|
99
|
-
change. Check examples against current source and point to the tests that
|
|
100
|
-
defend the contract. Published Markdown links to repo-only files must use
|
|
101
|
-
canonical `https://github.com/zackbart/connecta/blob/main/…` or `tree/main/…`
|
|
102
|
-
links. Keep `documentation/` flat, with Markdown files only.
|
|
64
|
+
For source changes, follow [AGENTS.md](https://github.com/zackbart/connecta/blob/main/AGENTS.md).
|
|
65
|
+
Contributor references describe implementation and test evidence; deployment
|
|
66
|
+
operators can use the task procedures above without a source checkout.
|
|
103
67
|
|
|
104
68
|
The [changelog](../CHANGELOG.md) records shipped releases.
|
|
105
69
|
[Decisions](https://github.com/zackbart/connecta/tree/main/decisions) explain
|