@agenticprimitives/fabric 0.0.0-alpha.11 → 0.0.0-alpha.13
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/CLAUDE.md +5 -0
- package/dist/adoption.d.ts +79 -0
- package/dist/adoption.d.ts.map +1 -0
- package/dist/adoption.js +95 -0
- package/dist/adoption.js.map +1 -0
- package/dist/cloudflare/sql-vault.d.ts.map +1 -1
- package/dist/cloudflare/sql-vault.js +56 -0
- package/dist/cloudflare/sql-vault.js.map +1 -1
- package/dist/email/index.d.ts +75 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +77 -0
- package/dist/email/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/interactions/grant-scopes.d.ts +21 -0
- package/dist/interactions/grant-scopes.d.ts.map +1 -0
- package/dist/interactions/grant-scopes.js +39 -0
- package/dist/interactions/grant-scopes.js.map +1 -0
- package/dist/interactions/index.d.ts +1 -0
- package/dist/interactions/index.d.ts.map +1 -1
- package/dist/interactions/index.js +3 -0
- package/dist/interactions/index.js.map +1 -1
- package/dist/messaging/consult-routing.d.ts +21 -14
- package/dist/messaging/consult-routing.d.ts.map +1 -1
- package/dist/messaging/consult-routing.js +34 -25
- package/dist/messaging/consult-routing.js.map +1 -1
- package/dist/messaging/consult.d.ts +4 -0
- package/dist/messaging/consult.d.ts.map +1 -1
- package/dist/messaging/consult.js +3 -1
- package/dist/messaging/consult.js.map +1 -1
- package/dist/messaging/conversation.d.ts +69 -1
- package/dist/messaging/conversation.d.ts.map +1 -1
- package/dist/messaging/conversation.js +131 -0
- package/dist/messaging/conversation.js.map +1 -1
- package/dist/messaging/index.d.ts +1 -1
- package/dist/messaging/index.d.ts.map +1 -1
- package/dist/messaging/index.js +3 -1
- package/dist/messaging/index.js.map +1 -1
- package/package.json +13 -9
package/CLAUDE.md
CHANGED
|
@@ -39,6 +39,11 @@ interaction-aware ingress; on-chain `atl:gatewayRoot`; `A2aTaskDO`/`SessionStore
|
|
|
39
39
|
- **Transport-agnostic core.** No Cloudflare/MCP/A2A-SDK imports in `src/` — `./cloudflare` is the
|
|
40
40
|
only adapter and the only `@cloudflare/workers-types` consumer.
|
|
41
41
|
|
|
42
|
+
- **The adoption ladder's mechanics are here** (`src/adoption.ts`, promoted in spec 399 §4): `AdoptionLedger`
|
|
43
|
+
types, `adoptionStage(ledger, op, env)` (the deployment's `GATEWAY_SHADOW` gates a shadow; `""` is unset),
|
|
44
|
+
`compareServed` / `classifyDivergence` (a race is not a divergence), `shouldShadow` sampling, the bounded
|
|
45
|
+
in-memory `recordDivergence`. The ledger VALUES — which op is on which rung, and why — stay with the product.
|
|
46
|
+
|
|
42
47
|
## Boundary
|
|
43
48
|
`types`, `fulfillment`, `vault`, `audit`, `delegation`, `chain-state`, `tool-policy`, `agent-naming`
|
|
44
49
|
(injected resolver) ← `fabric`; `fabric/cloudflare → orchestration` (adapter-only); `fabric →
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** Which of the five candidate causes an op's move actually exercises. Naming it per op is the point of
|
|
2
|
+
* moving one at a time: if an op diverges, its concerns say where to look, and where not to. */
|
|
3
|
+
export type AdoptionConcern = 'auth' | 'projection' | 'ordering' | 'data-shape' | 'assistant';
|
|
4
|
+
export type AdoptionStage = 'off' | 'shadow' | 'serving';
|
|
5
|
+
export interface AdoptionEntry {
|
|
6
|
+
stage: AdoptionStage;
|
|
7
|
+
/** What moving this op puts at risk — read this first when its shadow diverges. */
|
|
8
|
+
concerns: readonly AdoptionConcern[];
|
|
9
|
+
/** Why this op is at this rung. Prose, because "it's next" and "it's blocked" look identical in a stage
|
|
10
|
+
* field, and the difference is the whole state of the migration. */
|
|
11
|
+
note: string;
|
|
12
|
+
/**
|
|
13
|
+
* Fields that legitimately differ between the two planes because each computes them at its own instant.
|
|
14
|
+
* Declared PER OP and BEFORE evidence arrives — classifying noise after seeing a report is how a real
|
|
15
|
+
* divergence gets explained away as expected. An EMPTY list is a claim, not an omission: it asserts this
|
|
16
|
+
* op has no per-read computation, so any difference is either a race or a defect. Say why in `note`.
|
|
17
|
+
*/
|
|
18
|
+
volatileFields: readonly string[];
|
|
19
|
+
}
|
|
20
|
+
/** The ledger: one place that says which plane serves what, so adoption is data rather than conditionals
|
|
21
|
+
* spread across a serving object. An op absent from it is `off`: adoption is opt-in, because the failure
|
|
22
|
+
* mode of opt-out is an op that moved because nobody remembered to stop it. */
|
|
23
|
+
export type AdoptionLedger = Readonly<Record<string, AdoptionEntry>>;
|
|
24
|
+
/**
|
|
25
|
+
* The stage an op runs at IN THIS DEPLOYMENT. The ledger says how far an op has climbed in the code; the
|
|
26
|
+
* deployment's `GATEWAY_SHADOW` says whether it is running the comparison at all. Both are required, and the
|
|
27
|
+
* env one defaults to OFF — constructing the gateway creates its tables, and an ungated shadow on a hot op
|
|
28
|
+
* would make that storage decision for every principal at once. Empty string is unset, not enabled
|
|
29
|
+
* (`wrangler`'s `VAR = ""` binds an empty string that `??` sails straight past).
|
|
30
|
+
*/
|
|
31
|
+
export declare function adoptionStage(ledger: AdoptionLedger, op: string, env?: {
|
|
32
|
+
GATEWAY_SHADOW?: string;
|
|
33
|
+
}): AdoptionStage;
|
|
34
|
+
export interface Divergence {
|
|
35
|
+
op: string;
|
|
36
|
+
at: string;
|
|
37
|
+
/** `equal` is recorded too. A shadow that only reports differences cannot distinguish "the planes agree"
|
|
38
|
+
* from "the shadow never ran", and those justify opposite decisions about promoting. */
|
|
39
|
+
kind: 'equal' | 'value' | 'raced' | 'gateway-error' | 'shadow-skipped';
|
|
40
|
+
detail?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compare the two planes' answers. Canonical JSON with sorted keys: key ORDER is not a difference worth
|
|
44
|
+
* blocking a promotion on. Everything else counts, including `undefined` vs absent — a field that vanished
|
|
45
|
+
* is exactly the data-shape drift being watched for.
|
|
46
|
+
*/
|
|
47
|
+
export declare function compareServed(op: string, served: unknown, shadow: unknown, at: string): Divergence;
|
|
48
|
+
/**
|
|
49
|
+
* Was an apparent divergence just the document moving between the two reads? After the shadow read, take
|
|
50
|
+
* the serving read AGAIN: `servedAgain` matches the shadow ⇒ the document moved — RACED, benign, evidence of
|
|
51
|
+
* nothing; `servedAgain` still matches the original and differs from the shadow ⇒ the planes really
|
|
52
|
+
* disagree. DELIBERATELY CONSERVATIVE: anything not provably a race stays `value`.
|
|
53
|
+
*/
|
|
54
|
+
export declare function classifyDivergence(input: {
|
|
55
|
+
op: string;
|
|
56
|
+
served: unknown;
|
|
57
|
+
shadow: unknown;
|
|
58
|
+
servedAgain: unknown;
|
|
59
|
+
at: string;
|
|
60
|
+
}): Divergence;
|
|
61
|
+
/**
|
|
62
|
+
* Should this call run its shadow? Shadowing doubles the delegated reads on the path being shadowed, so it
|
|
63
|
+
* is SAMPLED: at most one shadow per principal per `intervalMs`. Time-based rather than 1-in-N because it
|
|
64
|
+
* bounds the ADDED LOAD directly; a ratio bounds a proportion of a rate that varies with how many clients a
|
|
65
|
+
* principal has open. The first call always samples — a low-traffic principal must still contribute.
|
|
66
|
+
*/
|
|
67
|
+
export declare function shouldShadow(input: {
|
|
68
|
+
lastShadowAt: number | undefined;
|
|
69
|
+
now: number;
|
|
70
|
+
intervalMs: number;
|
|
71
|
+
}): boolean;
|
|
72
|
+
/** One shadow per principal per minute: enough to catch a systematic difference within a session, far below
|
|
73
|
+
* a per-principal read limiter's budget even with several clients open. */
|
|
74
|
+
export declare const SHADOW_INTERVAL_MS = 60000;
|
|
75
|
+
/** How many divergences to keep — in MEMORY, not durable storage: diagnostics with a shelf life of one
|
|
76
|
+
* investigation. Losing them on isolate recycle is the correct trade. */
|
|
77
|
+
export declare const DIVERGENCE_BUFFER = 20;
|
|
78
|
+
export declare function recordDivergence(buf: Divergence[], d: Divergence): Divergence[];
|
|
79
|
+
//# sourceMappingURL=adoption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adoption.d.ts","sourceRoot":"","sources":["../src/adoption.ts"],"names":[],"mappings":"AAiBA;iGACiG;AACjG,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,CAAC;AAE9F,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,aAAa,CAAC;IACrB,mFAAmF;IACnF,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC;yEACqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;gFAEgF;AAChF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAIlH;AAID,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX;6FACyF;IACzF,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,eAAe,GAAG,gBAAgB,CAAC;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAKlG;AAoBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAQxI;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAGlH;AAED;4EAC4E;AAC5E,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC;0EAC0E;AAC1E,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,EAAE,CAG/E"}
|
package/dist/adoption.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// INCREMENTAL SERVING-PLANE ADOPTION — the LADDER (ADR-0060; ADR-0055 amendment). Promoted from the runtime
|
|
2
|
+
// app in spec 399 W0 (§4): the ledger TYPES, the rung rule and the divergence/sampling mechanics are the
|
|
3
|
+
// contract every product adopting `PrincipalGatewayDO` needs; the ledger VALUES (which op sits on which rung,
|
|
4
|
+
// and why) stay with the product that owns those ops.
|
|
5
|
+
//
|
|
6
|
+
// THE LADDER. Every op climbs the same three rungs, and never skips one:
|
|
7
|
+
// `off` — the incumbent plane serves. The gateway is not consulted.
|
|
8
|
+
// `shadow` — the incumbent serves AND ITS ANSWER IS THE RESPONSE. The gateway runs alongside and the
|
|
9
|
+
// two are compared. Divergence is recorded; it never reaches the caller and never fails the
|
|
10
|
+
// request. This is the rung that converts "we think it matches" into evidence.
|
|
11
|
+
// `serving` — the gateway serves. Promotion is earned by a shadow run with no unexplained divergence,
|
|
12
|
+
// not by the code being finished.
|
|
13
|
+
//
|
|
14
|
+
// WHAT A RUNG DOES NOT DO. Shadowing proves the two planes AGREE; it does not prove either is right. An op
|
|
15
|
+
// whose incumbent implementation is wrong will shadow perfectly clean while the gateway faithfully
|
|
16
|
+
// reproduces the bug. Promotion is evidence of equivalence, not of correctness.
|
|
17
|
+
/**
|
|
18
|
+
* The stage an op runs at IN THIS DEPLOYMENT. The ledger says how far an op has climbed in the code; the
|
|
19
|
+
* deployment's `GATEWAY_SHADOW` says whether it is running the comparison at all. Both are required, and the
|
|
20
|
+
* env one defaults to OFF — constructing the gateway creates its tables, and an ungated shadow on a hot op
|
|
21
|
+
* would make that storage decision for every principal at once. Empty string is unset, not enabled
|
|
22
|
+
* (`wrangler`'s `VAR = ""` binds an empty string that `??` sails straight past).
|
|
23
|
+
*/
|
|
24
|
+
export function adoptionStage(ledger, op, env) {
|
|
25
|
+
const stage = ledger[op]?.stage ?? 'off';
|
|
26
|
+
if (stage === 'shadow' && (env?.GATEWAY_SHADOW ?? '').trim().toLowerCase() !== 'on')
|
|
27
|
+
return 'off';
|
|
28
|
+
return stage;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Compare the two planes' answers. Canonical JSON with sorted keys: key ORDER is not a difference worth
|
|
32
|
+
* blocking a promotion on. Everything else counts, including `undefined` vs absent — a field that vanished
|
|
33
|
+
* is exactly the data-shape drift being watched for.
|
|
34
|
+
*/
|
|
35
|
+
export function compareServed(op, served, shadow, at) {
|
|
36
|
+
const a = canonical(served);
|
|
37
|
+
const b = canonical(shadow);
|
|
38
|
+
if (a === b)
|
|
39
|
+
return { op, at, kind: 'equal' };
|
|
40
|
+
return { op, at, kind: 'value', detail: firstDifference(a, b) };
|
|
41
|
+
}
|
|
42
|
+
function canonical(v) {
|
|
43
|
+
return JSON.stringify(v, (_k, val) => val && typeof val === 'object' && !Array.isArray(val)
|
|
44
|
+
? Object.fromEntries(Object.entries(val).sort(([x], [y]) => x.localeCompare(y)))
|
|
45
|
+
: val) ?? 'undefined';
|
|
46
|
+
}
|
|
47
|
+
/** A bounded excerpt around the first difference. Bounded because a divergence report that embeds two whole
|
|
48
|
+
* documents is a copy of the person's records in a diagnostic buffer — the thing the vault doctrine exists
|
|
49
|
+
* to prevent, arrived at through the back door. */
|
|
50
|
+
function firstDifference(a, b) {
|
|
51
|
+
let i = 0;
|
|
52
|
+
while (i < a.length && i < b.length && a[i] === b[i])
|
|
53
|
+
i++;
|
|
54
|
+
const w = 40;
|
|
55
|
+
return `@${i}: served=${JSON.stringify(a.slice(Math.max(0, i - 8), i + w))} shadow=${JSON.stringify(b.slice(Math.max(0, i - 8), i + w))}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Was an apparent divergence just the document moving between the two reads? After the shadow read, take
|
|
59
|
+
* the serving read AGAIN: `servedAgain` matches the shadow ⇒ the document moved — RACED, benign, evidence of
|
|
60
|
+
* nothing; `servedAgain` still matches the original and differs from the shadow ⇒ the planes really
|
|
61
|
+
* disagree. DELIBERATELY CONSERVATIVE: anything not provably a race stays `value`.
|
|
62
|
+
*/
|
|
63
|
+
export function classifyDivergence(input) {
|
|
64
|
+
const first = compareServed(input.op, input.served, input.shadow, input.at);
|
|
65
|
+
if (first.kind === 'equal')
|
|
66
|
+
return first;
|
|
67
|
+
const settled = compareServed(input.op, input.servedAgain, input.shadow, input.at);
|
|
68
|
+
if (settled.kind === 'equal') {
|
|
69
|
+
return { op: input.op, at: input.at, kind: 'raced', detail: 'document changed between the serving read and the shadow read' };
|
|
70
|
+
}
|
|
71
|
+
return first;
|
|
72
|
+
}
|
|
73
|
+
// ── Sampling ──────────────────────────────────────────────────────────────────────────────────────────
|
|
74
|
+
/**
|
|
75
|
+
* Should this call run its shadow? Shadowing doubles the delegated reads on the path being shadowed, so it
|
|
76
|
+
* is SAMPLED: at most one shadow per principal per `intervalMs`. Time-based rather than 1-in-N because it
|
|
77
|
+
* bounds the ADDED LOAD directly; a ratio bounds a proportion of a rate that varies with how many clients a
|
|
78
|
+
* principal has open. The first call always samples — a low-traffic principal must still contribute.
|
|
79
|
+
*/
|
|
80
|
+
export function shouldShadow(input) {
|
|
81
|
+
if (input.lastShadowAt === undefined)
|
|
82
|
+
return true;
|
|
83
|
+
return input.now - input.lastShadowAt >= input.intervalMs;
|
|
84
|
+
}
|
|
85
|
+
/** One shadow per principal per minute: enough to catch a systematic difference within a session, far below
|
|
86
|
+
* a per-principal read limiter's budget even with several clients open. */
|
|
87
|
+
export const SHADOW_INTERVAL_MS = 60_000;
|
|
88
|
+
/** How many divergences to keep — in MEMORY, not durable storage: diagnostics with a shelf life of one
|
|
89
|
+
* investigation. Losing them on isolate recycle is the correct trade. */
|
|
90
|
+
export const DIVERGENCE_BUFFER = 20;
|
|
91
|
+
export function recordDivergence(buf, d) {
|
|
92
|
+
buf.push(d);
|
|
93
|
+
return buf.length > DIVERGENCE_BUFFER ? buf.slice(-DIVERGENCE_BUFFER) : buf;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=adoption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adoption.js","sourceRoot":"","sources":["../src/adoption.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-vault.d.ts","sourceRoot":"","sources":["../../src/cloudflare/sql-vault.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,KAAK,
|
|
1
|
+
{"version":3,"file":"sql-vault.d.ts","sourceRoot":"","sources":["../../src/cloudflare/sql-vault.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,KAAK,EAOL,UAAU,EACX,MAAM,0BAA0B,CAAC;AA4ClC;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,KAAK,CA4IvF"}
|
|
@@ -93,6 +93,62 @@ export function createDurableObjectSqlVault(sql, wrapper) {
|
|
|
93
93
|
updatedAt: r.updated_at,
|
|
94
94
|
}));
|
|
95
95
|
},
|
|
96
|
+
/**
|
|
97
|
+
* Spec 356 §2.3 — the selector runs in the store, so only matching rows are opened.
|
|
98
|
+
*
|
|
99
|
+
* `resource IN (…)` for singletons, `resource LIKE 'prefix%'` for keyed families, `LIMIT` always. The
|
|
100
|
+
* alternative — list every resource and read each — moves an owner's whole record set through the
|
|
101
|
+
* caller to answer a question about a few of them.
|
|
102
|
+
*
|
|
103
|
+
* An EMPTY selector matches nothing and touches no rows: a query that quietly meant "everything" when
|
|
104
|
+
* its selector failed to compile is the bug this shape exists to make impossible. `LIKE` wildcards in a
|
|
105
|
+
* prefix are escaped — a resource prefix is caller-influenced, and a stray `%` would widen the match.
|
|
106
|
+
*/
|
|
107
|
+
async query(req) {
|
|
108
|
+
const owner = req.owner.toLowerCase();
|
|
109
|
+
const clauses = [];
|
|
110
|
+
const binds = [owner];
|
|
111
|
+
const exact = (req.select.exact ?? []).filter((e) => e.length > 0);
|
|
112
|
+
if (exact.length) {
|
|
113
|
+
clauses.push(`resource IN (${exact.map(() => '?').join(', ')})`);
|
|
114
|
+
binds.push(...exact);
|
|
115
|
+
}
|
|
116
|
+
for (const prefix of (req.select.prefixes ?? []).filter((p) => p.length > 0)) {
|
|
117
|
+
clauses.push("resource LIKE ? ESCAPE '\\'");
|
|
118
|
+
binds.push(`${prefix.replace(/[\\%_]/g, (c) => `\\${c}`)}%`);
|
|
119
|
+
}
|
|
120
|
+
if (!clauses.length)
|
|
121
|
+
return [];
|
|
122
|
+
binds.push(Math.max(1, Math.min(req.limit ?? 200, 500)));
|
|
123
|
+
const rows = sql
|
|
124
|
+
.exec(`SELECT * FROM vault_objects
|
|
125
|
+
WHERE owner_address = ? AND deleted_at IS NULL AND (${clauses.join(' OR ')})
|
|
126
|
+
ORDER BY resource
|
|
127
|
+
LIMIT ?`, ...binds)
|
|
128
|
+
.toArray();
|
|
129
|
+
const out = [];
|
|
130
|
+
for (const row of rows) {
|
|
131
|
+
const data = await openEnvelope({
|
|
132
|
+
envelope: {
|
|
133
|
+
owner: row.owner_address,
|
|
134
|
+
resource: row.resource,
|
|
135
|
+
classification: row.classification,
|
|
136
|
+
crypto: JSON.parse(row.crypto_meta),
|
|
137
|
+
},
|
|
138
|
+
ciphertext: b64decode(row.ciphertext_b64),
|
|
139
|
+
wrappedDek: b64decode(row.wrapped_dek_b64),
|
|
140
|
+
wrapper,
|
|
141
|
+
});
|
|
142
|
+
out.push({
|
|
143
|
+
owner: row.owner_address,
|
|
144
|
+
resource: row.resource,
|
|
145
|
+
classification: row.classification,
|
|
146
|
+
data: projectFields(data, req.fields),
|
|
147
|
+
updatedAt: row.updated_at,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return out;
|
|
151
|
+
},
|
|
96
152
|
};
|
|
97
153
|
}
|
|
98
154
|
//# sourceMappingURL=sql-vault.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-vault.js","sourceRoot":"","sources":["../../src/cloudflare/sql-vault.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sql-vault.js","sourceRoot":"","sources":["../../src/cloudflare/sql-vault.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAErF,yEAAyE;AACzE,MAAM,YAAY,GAAG;;;;;;;;;;;EAWnB,CAAC;AACH,MAAM,YAAY,GAAG,8GAA8G,CAAC;AAcpI,SAAS,SAAS,CAAC,KAAiB;IAClC,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;QAAE,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AACD,SAAS,SAAS,CAAC,CAAS;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACnE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,sBAAsB,GAAwB,UAAU,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,GAAe,EAAE,OAAmB;IAC9E,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvB,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEvB,OAAO;QACL,KAAK,CAAC,IAAI,CAAc,GAAqB;YAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,GAAG;iBACb,IAAI,CACH,6FAA6F,EAC7F,KAAK,EACL,GAAG,CAAC,QAAQ,CACb;iBACA,OAAO,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YACtB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAI;gBACjC,QAAQ,EAAE;oBACR,KAAK,EAAE,GAAG,CAAC,aAAa;oBACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,cAAc,EAAE,GAAG,CAAC,cAAqC;oBACzD,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;iBACpC;gBACD,UAAU,EAAE,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC;gBACzC,UAAU,EAAE,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;gBAC1C,OAAO;aACR,CAAC,CAAC;YACH,OAAO;gBACL,KAAK,EAAE,GAAG,CAAC,aAAa;gBACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,cAAc,EAAE,GAAG,CAAC,cAAqC;gBACzD,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAM;gBAC1C,SAAS,EAAE,GAAG,CAAC,UAAU;aAC1B,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,KAAK,CAAc,GAAyB;YAChD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACtC,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACtB,GAAG,CAAC,IAAI,CACN,kIAAkI,EAClI,KAAK,EACL,GAAG,CAAC,QAAQ,CACb,CAAC;gBACF,OAAO;YACT,CAAC;YACD,MAAM,cAAc,GAAG,GAAG,CAAC,cAAc,IAAI,sBAAsB,CAAC;YACpE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9G,GAAG,CAAC,IAAI,CACN;;;;;;;;6BAQqB,EACrB,KAAK,EACL,GAAG,CAAC,QAAQ,EACZ,cAAc,EACd,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,EAC5B,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,EAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CACvC,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,KAAa;YACtB,MAAM,IAAI,GAAG,GAAG;iBACb,IAAI,CACH,iIAAiI,EACjI,KAAK,CAAC,WAAW,EAAE,CACpB;iBACA,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,cAAc,EAAE,CAAC,CAAC,cAAqC;gBACvD,SAAS,EAAE,CAAC,CAAC,UAAU;aACxB,CAAC,CAAC,CAAC;QACN,CAAC;QAED;;;;;;;;;;WAUG;QACH,KAAK,CAAC,KAAK,CAAc,GAAsB;YAC7C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACtC,MAAM,OAAO,GAAa,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAwB,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;YACvB,CAAC;YACD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC7E,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;gBAC5C,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;YAC/D,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO,EAAE,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YACzD,MAAM,IAAI,GAAG,GAAG;iBACb,IAAI,CACH;kEACwD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;;oBAElE,EACV,GAAG,KAAK,CACT;iBACA,OAAO,EAAE,CAAC;YACb,MAAM,GAAG,GAAqB,EAAE,CAAC;YACjC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAI;oBACjC,QAAQ,EAAE;wBACR,KAAK,EAAE,GAAG,CAAC,aAAa;wBACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;wBACtB,cAAc,EAAE,GAAG,CAAC,cAAqC;wBACzD,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;qBACpC;oBACD,UAAU,EAAE,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC;oBACzC,UAAU,EAAE,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;oBAC1C,OAAO;iBACR,CAAC,CAAC;gBACH,GAAG,CAAC,IAAI,CAAC;oBACP,KAAK,EAAE,GAAG,CAAC,aAAa;oBACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,cAAc,EAAE,GAAG,CAAC,cAAqC;oBACzD,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAM;oBAC1C,SAAS,EAAE,GAAG,CAAC,UAAU;iBAC1B,CAAC,CAAC;YACL,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** What a provider needs to send one message. Deliberately small — no attachments, no templates. */
|
|
2
|
+
export interface OutboundEmailV1 {
|
|
3
|
+
to: string;
|
|
4
|
+
subject: string;
|
|
5
|
+
text: string;
|
|
6
|
+
/** Optional HTML alternative. Providers that cannot send it fall back to `text`. */
|
|
7
|
+
html?: string;
|
|
8
|
+
/** Set when this mail continues a conversation, so replies thread in the recipient's mail client. */
|
|
9
|
+
inReplyTo?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface EmailSendResultV1 {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
/** The provider's own id for the message, when it gives one — kept so a thread can cite it. */
|
|
14
|
+
messageId?: string;
|
|
15
|
+
error?: string;
|
|
16
|
+
/** Which provider actually sent it. Recorded, because "the email went" is a different fact per rail. */
|
|
17
|
+
via?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* THE PORT. One method, and the implementations are leaves.
|
|
21
|
+
*
|
|
22
|
+
* `available` is separate from `send` on purpose: a surface must be able to say "email is not set up
|
|
23
|
+
* here" BEFORE offering somebody an email invitation, rather than accepting the address and failing.
|
|
24
|
+
*/
|
|
25
|
+
export interface EmailSenderPort {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
available(): boolean;
|
|
28
|
+
send(msg: OutboundEmailV1): Promise<EmailSendResultV1>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* TWO INTEGRATIONS, ONE PORT — the first that is available sends.
|
|
32
|
+
*
|
|
33
|
+
* Not a fallback chain (ADR-0013): the order is a DEPLOYMENT PREFERENCE stated once, and a provider that
|
|
34
|
+
* is configured but fails returns an error rather than handing the message to the next one. Sending the
|
|
35
|
+
* same mail twice because the first attempt's response was slow is worse than not sending it.
|
|
36
|
+
*/
|
|
37
|
+
export declare function firstAvailableSender(senders: readonly EmailSenderPort[]): EmailSenderPort | null;
|
|
38
|
+
/** An inbound message, already parsed. The adapter does the MIME; this is what the inbox needs. */
|
|
39
|
+
export interface InboundEmailV1 {
|
|
40
|
+
/** What the mail was sent TO — the only routable fact in it. */
|
|
41
|
+
to: string;
|
|
42
|
+
/** What it CLAIMS to be from. Unverified by construction; shown as a claim, never resolved as identity. */
|
|
43
|
+
from: string;
|
|
44
|
+
subject: string;
|
|
45
|
+
text: string;
|
|
46
|
+
/** Provider message id, for de-duplication and for citing the mail this message came from. */
|
|
47
|
+
messageId?: string;
|
|
48
|
+
/** Names only. An attachment is announced, never admitted (rule 4). */
|
|
49
|
+
attachments?: Array<{
|
|
50
|
+
name: string;
|
|
51
|
+
size?: number;
|
|
52
|
+
contentType?: string;
|
|
53
|
+
}>;
|
|
54
|
+
}
|
|
55
|
+
/** The handle an address routes to: `alice@faithnet.me` → `alice`. Empty when the zone is not ours. */
|
|
56
|
+
export declare function handleFromAddress(address: string, zones: readonly string[]): string;
|
|
57
|
+
/** Is this a well-formed address at all? Shape only — nothing here says a mailbox exists. */
|
|
58
|
+
export declare function isEmailAddress(v: string): boolean;
|
|
59
|
+
export declare const EMAIL_BODY_LIMIT = 16000;
|
|
60
|
+
/**
|
|
61
|
+
* An inbound email as the message a thread will hold.
|
|
62
|
+
*
|
|
63
|
+
* WHAT IT KEEPS: the words, who it says it is from, what it was about, and what came with it BY NAME.
|
|
64
|
+
* WHAT IT REFUSES: anything past the cap (truncated, and it says so — a body silently cut in half is a
|
|
65
|
+
* message that misleads), and every attachment's content.
|
|
66
|
+
*
|
|
67
|
+
* The result is deliberately plain text: a thread that renders remote HTML from an unverified sender is
|
|
68
|
+
* a phishing surface with a nice font.
|
|
69
|
+
*/
|
|
70
|
+
export declare function inboundEmailToMessage(mail: InboundEmailV1): {
|
|
71
|
+
bodyText: string;
|
|
72
|
+
subject: string;
|
|
73
|
+
claimedFrom: string;
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/email/index.ts"],"names":[],"mappings":"AAwBA,oGAAoG;AACpG,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qGAAqG;IACrG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wGAAwG;IACxG,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,SAAS,IAAI,OAAO,CAAC;IACrB,IAAI,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI,CAEhG;AAED,mGAAmG;AACnG,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,2GAA2G;IAC3G,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5E;AAED,uGAAuG;AACvG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQnF;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAetH"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// EMAIL AS A CHANNEL INTO THE INBOX — spec 365.
|
|
2
|
+
//
|
|
3
|
+
// A person's agent should be reachable by the address they already have, and an email they send or
|
|
4
|
+
// receive should land in the SAME thread as everything else they say to that person. Two mailboxes for
|
|
5
|
+
// one relationship is how half a conversation goes missing.
|
|
6
|
+
//
|
|
7
|
+
// FOUR RULES, and the whole design is these:
|
|
8
|
+
//
|
|
9
|
+
// 1. AN EMAIL IS NOT AUTHORITY (spec 309 §4.2). Inbound mail creates a MESSAGE and can never trigger
|
|
10
|
+
// an act. Nobody sends an email that moves money; the acts a person can take from a thread are the
|
|
11
|
+
// ones their own surface offers them, under their own mandate.
|
|
12
|
+
// 2. THE SENDER IS AN UNVERIFIED CLAIM. `From:` is a header anyone can write, so routing is done by
|
|
13
|
+
// the address the mail was SENT TO (`<handle>@<zone>` → the naming service → an agent), never by
|
|
14
|
+
// who it says it is from. The claim travels with the message, labelled as a claim.
|
|
15
|
+
// 3. PARSE IN MEMORY, STORE IN THE VAULT (spec 362 §6.2). The raw message is read into a message body
|
|
16
|
+
// the owner's vault holds and is never written to a serving-plane store — a mailbox is exactly the
|
|
17
|
+
// kind of durable private record ADR-0055 keeps out of DO storage.
|
|
18
|
+
// 4. BOUNDED, ALWAYS. A body has a size cap and attachments are named, not admitted: an inbox that
|
|
19
|
+
// accepts whatever arrives is a way to fill somebody's vault from the outside.
|
|
20
|
+
//
|
|
21
|
+
// The SENDER PORT is here and the providers are not: a transport is a leaf binding that depends inward
|
|
22
|
+
// (ADR-0057), and this package must not know whether the deployment sends through an HTTP API or a
|
|
23
|
+
// platform binding.
|
|
24
|
+
/**
|
|
25
|
+
* TWO INTEGRATIONS, ONE PORT — the first that is available sends.
|
|
26
|
+
*
|
|
27
|
+
* Not a fallback chain (ADR-0013): the order is a DEPLOYMENT PREFERENCE stated once, and a provider that
|
|
28
|
+
* is configured but fails returns an error rather than handing the message to the next one. Sending the
|
|
29
|
+
* same mail twice because the first attempt's response was slow is worse than not sending it.
|
|
30
|
+
*/
|
|
31
|
+
export function firstAvailableSender(senders) {
|
|
32
|
+
return senders.find((s) => s.available()) ?? null;
|
|
33
|
+
}
|
|
34
|
+
/** The handle an address routes to: `alice@faithnet.me` → `alice`. Empty when the zone is not ours. */
|
|
35
|
+
export function handleFromAddress(address, zones) {
|
|
36
|
+
const at = address.trim().toLowerCase();
|
|
37
|
+
const m = /^([^@\s]+)@([^@\s]+)$/.exec(at);
|
|
38
|
+
if (!m)
|
|
39
|
+
return '';
|
|
40
|
+
const [, local = '', domain = ''] = m;
|
|
41
|
+
if (!zones.some((z) => domain === z.toLowerCase() || domain.endsWith(`.${z.toLowerCase()}`)))
|
|
42
|
+
return '';
|
|
43
|
+
// Plus-addressing is the person's own tag, not part of who they are: `alice+bills@` is alice.
|
|
44
|
+
return (local.split('+')[0] ?? '').trim();
|
|
45
|
+
}
|
|
46
|
+
/** Is this a well-formed address at all? Shape only — nothing here says a mailbox exists. */
|
|
47
|
+
export function isEmailAddress(v) {
|
|
48
|
+
return /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v.trim());
|
|
49
|
+
}
|
|
50
|
+
export const EMAIL_BODY_LIMIT = 16_000;
|
|
51
|
+
/**
|
|
52
|
+
* An inbound email as the message a thread will hold.
|
|
53
|
+
*
|
|
54
|
+
* WHAT IT KEEPS: the words, who it says it is from, what it was about, and what came with it BY NAME.
|
|
55
|
+
* WHAT IT REFUSES: anything past the cap (truncated, and it says so — a body silently cut in half is a
|
|
56
|
+
* message that misleads), and every attachment's content.
|
|
57
|
+
*
|
|
58
|
+
* The result is deliberately plain text: a thread that renders remote HTML from an unverified sender is
|
|
59
|
+
* a phishing surface with a nice font.
|
|
60
|
+
*/
|
|
61
|
+
export function inboundEmailToMessage(mail) {
|
|
62
|
+
const body = (mail.text ?? '').trim();
|
|
63
|
+
const truncated = body.length > EMAIL_BODY_LIMIT;
|
|
64
|
+
const kept = truncated ? `${body.slice(0, EMAIL_BODY_LIMIT)}\n\n[…] this email was longer than ${EMAIL_BODY_LIMIT} characters and the rest was not kept.` : body;
|
|
65
|
+
const files = (mail.attachments ?? []).filter((a) => a.name);
|
|
66
|
+
const noted = files.length
|
|
67
|
+
? `\n\n${files.length === 1 ? 'It came with a file' : `It came with ${files.length} files`}, which were not saved: ${files.map((f) => f.name).join(', ')}.`
|
|
68
|
+
: '';
|
|
69
|
+
return {
|
|
70
|
+
subject: (mail.subject ?? '').trim() || '(no subject)',
|
|
71
|
+
claimedFrom: (mail.from ?? '').trim(),
|
|
72
|
+
// WHO IT SAYS IT IS FROM, said as a claim. A person reading this must not be able to mistake an
|
|
73
|
+
// email address for a verified identity — that mistake is the whole of email fraud.
|
|
74
|
+
bodyText: `${kept}${noted}\n\n— sent by email from ${mail.from} (an email address, not a verified agent)`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/email/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -37,4 +37,6 @@ export { buildDeliveryEnvelope, admitDeliveryEnvelope, deliveryToExchangeRecord,
|
|
|
37
37
|
export type { DeliveryEnvelopeV1, DeliveryAdmission } from './delivery-envelope.js';
|
|
38
38
|
export { emptyInboxData, parseInboxData, hydrateInboxStores, mergeContextRefs, upsertConversation, type InboxDataV1, } from './inbox-doc.js';
|
|
39
39
|
export { RECORD_CATALOG, catalogEntryFor, type RecordCatalogEntry } from './record-catalog.js';
|
|
40
|
+
export { adoptionStage, compareServed, classifyDivergence, shouldShadow, recordDivergence, SHADOW_INTERVAL_MS, DIVERGENCE_BUFFER } from './adoption.js';
|
|
41
|
+
export type { AdoptionConcern, AdoptionStage, AdoptionEntry, AdoptionLedger, Divergence } from './adoption.js';
|
|
40
42
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -62,4 +62,7 @@ export { emptyInboxData, parseInboxData, hydrateInboxStores, mergeContextRefs, u
|
|
|
62
62
|
// The registered record catalog (spec 322 §1) — resource pattern → type tag + ontology binding +
|
|
63
63
|
// classification floor. The catalog, never the resource string, carries the semantics.
|
|
64
64
|
export { RECORD_CATALOG, catalogEntryFor } from './record-catalog.js';
|
|
65
|
+
// ── ADR-0060 / spec 399 §4 — the serving-plane adoption LADDER: ledger types, the rung rule, divergence and sampling.
|
|
66
|
+
// The ledger's VALUES stay with the product whose ops they name.
|
|
67
|
+
export { adoptionStage, compareServed, classifyDivergence, shouldShadow, recordDivergence, SHADOW_INTERVAL_MS, DIVERGENCE_BUFFER } from './adoption.js';
|
|
65
68
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Ops the record-scope gate distinguishes: a tombstone (`delete`) is a DISTINCT op from `write`. */
|
|
2
|
+
export type RecordScopeOp = 'read' | 'write' | 'delete';
|
|
3
|
+
/** A group of resources granted the same ops, before a server is named. */
|
|
4
|
+
export interface RecordScopeSpec {
|
|
5
|
+
resources: ReadonlyArray<string>;
|
|
6
|
+
ops: ReadonlyArray<RecordScopeOp>;
|
|
7
|
+
}
|
|
8
|
+
/** One group bound to an MCP server — structurally the delegation package's `VaultRecordScopeGrant`, so it
|
|
9
|
+
* feeds `buildVaultRecordScopeCaveat` directly; fabric does not depend on delegation (ADR-0047 boundary). */
|
|
10
|
+
export interface RecordScopeGroup {
|
|
11
|
+
server: string;
|
|
12
|
+
resources: string[];
|
|
13
|
+
ops: RecordScopeOp[];
|
|
14
|
+
}
|
|
15
|
+
export declare const INTERACTIONS_GRANT_CORE_SCOPES: ReadonlyArray<RecordScopeSpec>;
|
|
16
|
+
/**
|
|
17
|
+
* The grant's scope groups for one MCP server: the core, then the product's extensions (its own app
|
|
18
|
+
* namespaces — read-only for the agent's grounding, read+write for steward seeding), in that order.
|
|
19
|
+
*/
|
|
20
|
+
export declare function interactionsGrantScopes(server: string, extensions?: ReadonlyArray<RecordScopeSpec>): RecordScopeGroup[];
|
|
21
|
+
//# sourceMappingURL=grant-scopes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant-scopes.d.ts","sourceRoot":"","sources":["../../src/interactions/grant-scopes.ts"],"names":[],"mappings":"AAgBA,qGAAqG;AACrG,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAExD,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAAG,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAAC,GAAG,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;CAAE;AAExG;8GAC8G;AAC9G,MAAM,WAAW,gBAAgB;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,aAAa,EAAE,CAAA;CAAE;AAE/F,eAAO,MAAM,8BAA8B,EAAE,aAAa,CAAC,eAAe,CA8BzE,CAAC;AAEF;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,GAAE,aAAa,CAAC,eAAe,CAAM,GAAG,gBAAgB,EAAE,CAE3H"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const INTERACTIONS_GRANT_CORE_SCOPES = [
|
|
2
|
+
{ resources: [
|
|
3
|
+
'vault:conversation.index', 'vault:conversation.topic:*', 'vault:message.body:topic:*',
|
|
4
|
+
'vault:inbox.data', 'vault:directory.data', 'vault:relationships.data', 'vault:member.profile:*',
|
|
5
|
+
'vault:org.membership:*', 'vault:org.applications', 'vault:impact-profile', 'vault:capabilities.data',
|
|
6
|
+
'vault:skills.data', 'vault:home.manifest', 'vault:control-events.data', 'vault:coordination.requests',
|
|
7
|
+
'vault:coordination.index', 'vault:coordination.endeavor:*', 'vault:content.*',
|
|
8
|
+
'vault:resolution.requests', 'vault:resolution.grants', 'vault:archetype.assignment', 'vault:payment.receipt:*',
|
|
9
|
+
'vault:household.data',
|
|
10
|
+
// Spec 370 P7 — the person's own recent asks, so "him" can mean whom they just meant.
|
|
11
|
+
'vault:conversation.recent',
|
|
12
|
+
// Spec 381 — a run's provenance, kept where the authority was spent (the DO copy is the rebuild).
|
|
13
|
+
'vault:run.provenance:*',
|
|
14
|
+
// Spec 391 — a step's raw result, too large for the run's record, kept where the run ran.
|
|
15
|
+
'vault:run.artifact:*',
|
|
16
|
+
// Spec 385 — the person's scoped confirmation memory (which "David", per word + capability + argument).
|
|
17
|
+
'vault:confirmation.preferences',
|
|
18
|
+
// Spec 394 — the person's standing instructions (a declared default per room + capability + argument).
|
|
19
|
+
'vault:standing.instructions',
|
|
20
|
+
], ops: ['read', 'write'] },
|
|
21
|
+
// Spec 354 K3 — the PLAYBOOK may also be REMOVED, which is a real custodial act: an agent goes back to the
|
|
22
|
+
// bare harness. A tombstone is a DISTINCT op at the record-scope gate (spec 317 §3.2 / audit F1 — a
|
|
23
|
+
// write-only delegate must not be able to censor records), so the broad bucket above cannot express it.
|
|
24
|
+
{ resources: ['vault:archetype.assignment'], ops: ['read', 'write', 'delete'] },
|
|
25
|
+
// Spec 322 W3f — dm bodies are READ-only here: the DO serves the owner's mail reads, while only the
|
|
26
|
+
// (write-only) delivery plane may create them. Planes stay disjoint on writes.
|
|
27
|
+
{ resources: ['vault:message.body:dm:*'], ops: ['read'] },
|
|
28
|
+
// The org's own invitations, read-only — what makes membership-read's invited-member path live. Writes
|
|
29
|
+
// stay on the delivery plane.
|
|
30
|
+
{ resources: ['vault:org.invite:*'], ops: ['read'] },
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* The grant's scope groups for one MCP server: the core, then the product's extensions (its own app
|
|
34
|
+
* namespaces — read-only for the agent's grounding, read+write for steward seeding), in that order.
|
|
35
|
+
*/
|
|
36
|
+
export function interactionsGrantScopes(server, extensions = []) {
|
|
37
|
+
return [...INTERACTIONS_GRANT_CORE_SCOPES, ...extensions].map((g) => ({ server, resources: [...g.resources], ops: [...g.ops] }));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=grant-scopes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant-scopes.js","sourceRoot":"","sources":["../../src/interactions/grant-scopes.ts"],"names":[],"mappings":"AA0BA,MAAM,CAAC,MAAM,8BAA8B,GAAmC;IAC5E,EAAE,SAAS,EAAE;YACX,0BAA0B,EAAE,4BAA4B,EAAE,4BAA4B;YACtF,kBAAkB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,wBAAwB;YAChG,wBAAwB,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,yBAAyB;YACrG,mBAAmB,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,6BAA6B;YACtG,0BAA0B,EAAE,+BAA+B,EAAE,iBAAiB;YAC9E,2BAA2B,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,yBAAyB;YAC/G,sBAAsB;YACtB,sFAAsF;YACtF,2BAA2B;YAC3B,kGAAkG;YAClG,wBAAwB;YACxB,0FAA0F;YAC1F,sBAAsB;YACtB,wGAAwG;YACxG,gCAAgC;YAChC,uGAAuG;YACvG,6BAA6B;SAC9B,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAC3B,2GAA2G;IAC3G,oGAAoG;IACpG,wGAAwG;IACxG,EAAE,SAAS,EAAE,CAAC,4BAA4B,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE;IAC/E,oGAAoG;IACpG,+EAA+E;IAC/E,EAAE,SAAS,EAAE,CAAC,yBAAyB,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE;IACzD,uGAAuG;IACvG,8BAA8B;IAC9B,EAAE,SAAS,EAAE,CAAC,oBAAoB,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE;CACrD,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,aAA6C,EAAE;IACrG,OAAO,CAAC,GAAG,8BAA8B,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AACnI,CAAC"}
|
|
@@ -12,4 +12,5 @@ export { type PresentationDefinitionRef, type CredentialFormat, type PermissionT
|
|
|
12
12
|
export { type DataSensitivity, type ActionRiskMetadataV1, type RiskDisposition, type RiskEvaluationOpts, type RiskEvaluation, evaluateActionRisk, } from './risk.js';
|
|
13
13
|
export { type ActionCardKind, type ActionDescriptorV1, type ActionCardV1, type CardValidationError, validateActionCard, } from './cards.js';
|
|
14
14
|
export { type InteractionExchangeRecordV1, buildExchangeRecord, type RelationshipExchangePort, } from './relationship.js';
|
|
15
|
+
export { INTERACTIONS_GRANT_CORE_SCOPES, interactionsGrantScopes, type RecordScopeOp, type RecordScopeSpec, type RecordScopeGroup, } from './grant-scopes.js';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interactions/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,2CAA2C,CAAC;AACrE,eAAO,MAAM,cAAc,EAAG,qBAA8B,CAAC;AAC7D,eAAO,MAAM,QAAQ,4CAA4C,CAAC;AAElE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,eAAe,EACf,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,QAAQ,EACR,cAAc,EACd,WAAW,EACX,WAAW,EACX,OAAO,GACR,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,KAAK,gBAAgB,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAC;AAEnF,OAAO,EAAE,KAAK,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAE3F,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,wBAAwB,GACzB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,sBAAsB,EACtB,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,iCAAiC,GAClC,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,KAAK,2BAA2B,EAChC,mBAAmB,EACnB,KAAK,wBAAwB,GAC9B,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interactions/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,2CAA2C,CAAC;AACrE,eAAO,MAAM,cAAc,EAAG,qBAA8B,CAAC;AAC7D,eAAO,MAAM,QAAQ,4CAA4C,CAAC;AAElE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,eAAe,EACf,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,QAAQ,EACR,cAAc,EACd,WAAW,EACX,WAAW,EACX,OAAO,GACR,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,KAAK,gBAAgB,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAC;AAEnF,OAAO,EAAE,KAAK,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAE3F,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,wBAAwB,GACzB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,sBAAsB,EACtB,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,iCAAiC,GAClC,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,KAAK,2BAA2B,EAChC,mBAAmB,EACnB,KAAK,wBAAwB,GAC9B,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,EACvB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC"}
|
|
@@ -20,4 +20,7 @@ export { createPermissionTicket, isTicketExpired, checkPresentationAnswersChalle
|
|
|
20
20
|
export { evaluateActionRisk, } from './risk.js';
|
|
21
21
|
export { validateActionCard, } from './cards.js';
|
|
22
22
|
export { buildExchangeRecord, } from './relationship.js';
|
|
23
|
+
// The interactions grant's record scopes — one list the Home (issuing the grant) and the agent runtime
|
|
24
|
+
// (a chartered child's genesis planes) both compose from; the product appends its own namespaces.
|
|
25
|
+
export { INTERACTIONS_GRANT_CORE_SCOPES, interactionsGrantScopes, } from './grant-scopes.js';
|
|
23
26
|
//# sourceMappingURL=index.js.map
|