@sema-ai/registry-core 0.10.3
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 +131 -0
- package/README.md +84 -0
- package/dist/api/auth-bridge.d.ts +332 -0
- package/dist/api/auth-bridge.d.ts.map +1 -0
- package/dist/api/auth-bridge.js +211 -0
- package/dist/api/auth-bridge.js.map +1 -0
- package/dist/api/auth.d.ts +258 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +204 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/scopes.d.ts +353 -0
- package/dist/api/scopes.d.ts.map +1 -0
- package/dist/api/scopes.js +229 -0
- package/dist/api/scopes.js.map +1 -0
- package/dist/bundle.d.ts +14 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +68 -0
- package/dist/bundle.js.map +1 -0
- package/dist/config-fns.d.ts +236 -0
- package/dist/config-fns.d.ts.map +1 -0
- package/dist/config-fns.js +272 -0
- package/dist/config-fns.js.map +1 -0
- package/dist/cross-domain.d.ts +35 -0
- package/dist/cross-domain.d.ts.map +1 -0
- package/dist/cross-domain.js +119 -0
- package/dist/cross-domain.js.map +1 -0
- package/dist/file-edit.d.ts +37 -0
- package/dist/file-edit.d.ts.map +1 -0
- package/dist/file-edit.js +126 -0
- package/dist/file-edit.js.map +1 -0
- package/dist/file-store.d.ts +39 -0
- package/dist/file-store.d.ts.map +1 -0
- package/dist/file-store.js +142 -0
- package/dist/file-store.js.map +1 -0
- package/dist/fleet.d.ts +479 -0
- package/dist/fleet.d.ts.map +1 -0
- package/dist/fleet.js +303 -0
- package/dist/fleet.js.map +1 -0
- package/dist/hash.d.ts +33 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +60 -0
- package/dist/hash.js.map +1 -0
- package/dist/hooks.d.ts +5478 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +628 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/local-load.d.ts +33 -0
- package/dist/local-load.d.ts.map +1 -0
- package/dist/local-load.js +164 -0
- package/dist/local-load.js.map +1 -0
- package/dist/migrate.d.ts +245 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +543 -0
- package/dist/migrate.js.map +1 -0
- package/dist/node.d.ts +12 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +12 -0
- package/dist/node.js.map +1 -0
- package/dist/reader.d.ts +19 -0
- package/dist/reader.d.ts.map +1 -0
- package/dist/reader.js +2 -0
- package/dist/reader.js.map +1 -0
- package/dist/remote-exec.d.ts +275 -0
- package/dist/remote-exec.d.ts.map +1 -0
- package/dist/remote-exec.js +183 -0
- package/dist/remote-exec.js.map +1 -0
- package/dist/resolve-roster.d.ts +29 -0
- package/dist/resolve-roster.d.ts.map +1 -0
- package/dist/resolve-roster.js +105 -0
- package/dist/resolve-roster.js.map +1 -0
- package/dist/safety-merge-spec.d.ts +328 -0
- package/dist/safety-merge-spec.d.ts.map +1 -0
- package/dist/safety-merge-spec.js +65 -0
- package/dist/safety-merge-spec.js.map +1 -0
- package/dist/scheduler-store-node.d.ts +15 -0
- package/dist/scheduler-store-node.d.ts.map +1 -0
- package/dist/scheduler-store-node.js +43 -0
- package/dist/scheduler-store-node.js.map +1 -0
- package/dist/scheduler-store.d.ts +65 -0
- package/dist/scheduler-store.d.ts.map +1 -0
- package/dist/scheduler-store.js +59 -0
- package/dist/scheduler-store.js.map +1 -0
- package/dist/secret-refs.d.ts +34 -0
- package/dist/secret-refs.d.ts.map +1 -0
- package/dist/secret-refs.js +49 -0
- package/dist/secret-refs.js.map +1 -0
- package/dist/sha256.d.ts +17 -0
- package/dist/sha256.d.ts.map +1 -0
- package/dist/sha256.js +115 -0
- package/dist/sha256.js.map +1 -0
- package/dist/skills-manifest.d.ts +13 -0
- package/dist/skills-manifest.d.ts.map +1 -0
- package/dist/skills-manifest.js +55 -0
- package/dist/skills-manifest.js.map +1 -0
- package/dist/types.d.ts +9911 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1727 -0
- package/dist/types.js.map +1 -0
- package/package.json +130 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { DOMAIN_SCHEMAS, GOVERNANCE_MIRROR_KEYS, HOSTS_ARRAY_MAX, HOST_NAME_MAX, containsSecretToken } from "./types.js";
|
|
2
|
+
/** Redact secret-shaped tokens from a validation MESSAGE — a zod error echoes the offending value (e.g.
|
|
3
|
+
* `received 'sk-live-…'`), so a secret pasted into the WRONG field would leak via the error string. Redacts
|
|
4
|
+
* space-spanning auth credentials (`Bearer <token>`) FIRST (the token pass can't see across the space), then
|
|
5
|
+
* any secret-shaped run (`%` kept in the run so a percent-encoded secret stays whole for the percent-aware
|
|
6
|
+
* containsSecretToken). invariant ①: a secret VALUE never rides an error. R13/R14 (codex). */
|
|
7
|
+
export function redactSecrets(text) {
|
|
8
|
+
return text
|
|
9
|
+
.replace(/\b(bearer|basic)(\s+)\S+/gi, "$1$2[redacted-secret]")
|
|
10
|
+
.replace(/[A-Za-z0-9_./:+=%-]{6,}/g, (tok) => (containsSecretToken(tok) ? "[redacted-secret]" : tok));
|
|
11
|
+
}
|
|
12
|
+
/** Sanitize a ZodError IN PLACE so no surfaced error (message / `received` / nested `unionErrors`) echoes a
|
|
13
|
+
* pasted secret. RECURSES into `unionErrors` (a `z.union` failure nests a ZodError per member — e.g. RoleTarget
|
|
14
|
+
* `{model}|{select}`) and redacts string path segments too. The ONE sanitizer every validation entry point
|
|
15
|
+
* uses (parseDomain / validateDomain / validateRemoteExec / write*). R14 (codex). */
|
|
16
|
+
export function sanitizeZodError(err) {
|
|
17
|
+
for (const iss of err.issues) {
|
|
18
|
+
const rec = iss;
|
|
19
|
+
for (const k of Object.keys(rec)) {
|
|
20
|
+
const v = rec[k];
|
|
21
|
+
if (typeof v === "string")
|
|
22
|
+
rec[k] = redactSecrets(v);
|
|
23
|
+
else if (Array.isArray(v)) {
|
|
24
|
+
rec[k] = v.map((el) => {
|
|
25
|
+
if (typeof el === "string")
|
|
26
|
+
return redactSecrets(el);
|
|
27
|
+
if (el && typeof el === "object" && Array.isArray(el.issues))
|
|
28
|
+
return sanitizeZodError(el); // nested unionErrors
|
|
29
|
+
return el;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return err;
|
|
35
|
+
}
|
|
36
|
+
export const ROLE_RANK = { viewer: 0, editor: 1, publisher: 2, admin: 3 };
|
|
37
|
+
export const USER_ROLES = ["viewer", "editor", "publisher", "admin"];
|
|
38
|
+
/** True if `role` is at least `min` in the hierarchy (e.g. publisher satisfies editor). */
|
|
39
|
+
export function roleAtLeast(role, min) {
|
|
40
|
+
return ROLE_RANK[role] >= ROLE_RANK[min];
|
|
41
|
+
}
|
|
42
|
+
export function isRole(v) {
|
|
43
|
+
return typeof v === "string" && USER_ROLES.includes(v);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Minimum role to WRITE a domain. Default = `editor`; `skills` and `mcp` are raised to `publisher`
|
|
47
|
+
* because their content goes straight into the agent's system prompt / tool surface — one edit retargets
|
|
48
|
+
* the prompt of every worker × scenario that loads it (docs/MCP-SKILLS.md §3.3, decision §6 Q3 从严).
|
|
49
|
+
* Looked up by the [domain] PUT route. Any domain absent here uses {@link DEFAULT_DOMAIN_WRITE_ROLE}.
|
|
50
|
+
*/
|
|
51
|
+
export const DEFAULT_DOMAIN_WRITE_ROLE = "editor";
|
|
52
|
+
export const DOMAIN_WRITE_ROLE = {
|
|
53
|
+
skills: "publisher",
|
|
54
|
+
mcp: "publisher",
|
|
55
|
+
// plugins are an EXECUTABLE surface (commands/hooks/MCP ride in via the materialized plugin) — the same
|
|
56
|
+
// raised gate as skills/mcp (C2, clay 拍: 可执行面同档).
|
|
57
|
+
plugins: "publisher",
|
|
58
|
+
// scenarios carry SYSTEM-PROMPT-level text + can SHADOW built-in scenario names (clay 拍 ①②) — a stronger
|
|
59
|
+
// injection surface than skills, so at least the same gate.
|
|
60
|
+
scenarios: "publisher",
|
|
61
|
+
// systems drive CREDENTIAL minting/delivery/rotation (S2/S3) — the credential lifecycle is ≥ the skills tier.
|
|
62
|
+
systems: "publisher",
|
|
63
|
+
// access: DELETED in 0.6.0 (域整删,EXPERT-REDESIGN §9)。
|
|
64
|
+
// governance (治理三件,0.6.0 从 runtime 拆出): editor(EXPERT-REDESIGN §5 domainWriteRole 同步——与
|
|
65
|
+
// runtime 残余同档,default 即 editor,故不列条目;此注释即该裁定的落点)。
|
|
66
|
+
// entitlement governs who-can-USE-what (models/skills/mcp/budget/runtime caps) per principal — a governance +
|
|
67
|
+
// security surface (budget ceilings, bypass kill-switch) on par with systems. Same raised gate.
|
|
68
|
+
entitlement: "publisher",
|
|
69
|
+
// execution (0.8.0): editor — same档 as governance (治理旋钮同类;真安全边界在 service gate [580],
|
|
70
|
+
// client-advisory 面不值 publisher 档)。default 即 editor,故不列条目;此注释即该裁定的落点。
|
|
71
|
+
// projects (0.10.0, 142-S3): editor — 登记簿是身份索引不是注入面(无 prompt/凭据/可执行内容);
|
|
72
|
+
// mint/claim 动作端点与编辑面同档(草案 §3 "该 scope editor+")。default 即 editor,故不列条目。
|
|
73
|
+
};
|
|
74
|
+
/** The minimum role required to write `domain` (the raised gate for skills/mcp, else editor). */
|
|
75
|
+
export function domainWriteRole(domain) {
|
|
76
|
+
return DOMAIN_WRITE_ROLE[domain] ?? DEFAULT_DOMAIN_WRITE_ROLE;
|
|
77
|
+
}
|
|
78
|
+
/** The empty/defaults effective config at version 0 — what publish mode serves before the first publish.
|
|
79
|
+
* Seeds the epoch (`new Date(0)`) so it's deterministic (the wall-clock default was the original store.ts
|
|
80
|
+
* non-determinism — see the file header). */
|
|
81
|
+
export function emptyEffective() {
|
|
82
|
+
return buildEffective(0, () => undefined, new Date(0).toISOString());
|
|
83
|
+
}
|
|
84
|
+
/** Validate + fill defaults for a domain payload (or the schema's empty default when absent/invalid). */
|
|
85
|
+
export function parseDomain(domain, raw) {
|
|
86
|
+
// ONLY true absence (undefined) defaults; an explicit `null` (e.g. a `config.d/<d>.json` containing JSON
|
|
87
|
+
// `null`) is corrupt input → let zod reject it ("expected object, received null"), not silently default. R4.
|
|
88
|
+
let r;
|
|
89
|
+
try {
|
|
90
|
+
r = DOMAIN_SCHEMAS[domain].safeParse(raw === undefined ? {} : raw);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// a hostile getter/Proxy trap threw during traversal — its message may carry a secret; never surface it. R13.
|
|
94
|
+
throw new Error(`invalid "${domain}" config (a value could not be read during validation)`);
|
|
95
|
+
}
|
|
96
|
+
if (r.success)
|
|
97
|
+
return r.data;
|
|
98
|
+
throw sanitizeZodError(r.error); // recursive redaction (message/received/unionErrors) — no secret echo. R13/R14.
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Shared GC predicate for worker-status rows (F10) — keeps memory/sqlite/tidb identical. Given the rows'
|
|
102
|
+
* `{name, updatedAt}` and the GC options, returns the names to prune (A: not in `keepNames`; B: older than
|
|
103
|
+
* `ttlMs`). Pass neither selector → prunes nothing (guards against a wipe-all). See `ConfigStore.gcWorkerStatuses`.
|
|
104
|
+
*/
|
|
105
|
+
export function statusRowsToPrune(rows, opts) {
|
|
106
|
+
if (opts.keepNames === undefined && opts.ttlMs === undefined)
|
|
107
|
+
return [];
|
|
108
|
+
const keep = opts.keepNames ? new Set(opts.keepNames) : undefined;
|
|
109
|
+
const cutoff = opts.ttlMs !== undefined ? (opts.now ?? new Date()).getTime() - opts.ttlMs : undefined;
|
|
110
|
+
return rows
|
|
111
|
+
.filter((r) => (keep !== undefined && !keep.has(r.name)) || (cutoff !== undefined && Date.parse(r.updatedAt) < cutoff))
|
|
112
|
+
.map((r) => r.name);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Merge every domain into the effective config a consumer pulls. Shared by all store impls.
|
|
116
|
+
* `updatedAt` is REQUIRED (the determinism refactor — the original store.ts defaulted it to the wall clock,
|
|
117
|
+
* which made `emptyEffective`/the memory store non-deterministic). Every caller now supplies it explicitly.
|
|
118
|
+
*/
|
|
119
|
+
/** Lift the governance trio out of a LEGACY runtime doc (pre-0.6 stored runtime carried autonomy/commandPolicy/
|
|
120
|
+
* approvalRequire). Used as the governance domain's read fallback when governance was NEVER set — so a 0.5
|
|
121
|
+
* store upgrades with zero data migration and zero gate loss. An explicitly-set governance domain WINS
|
|
122
|
+
* (its absence-of-a-key then means "center not managing", never "fall back to legacy runtime"). */
|
|
123
|
+
export function legacyGovernanceFromRuntime(rawRuntime) {
|
|
124
|
+
if (rawRuntime === null || typeof rawRuntime !== "object")
|
|
125
|
+
return undefined;
|
|
126
|
+
const r = rawRuntime;
|
|
127
|
+
const lifted = {};
|
|
128
|
+
for (const k of GOVERNANCE_MIRROR_KEYS)
|
|
129
|
+
if (r[k] !== undefined)
|
|
130
|
+
lifted[k] = r[k];
|
|
131
|
+
return Object.keys(lifted).length ? lifted : undefined;
|
|
132
|
+
}
|
|
133
|
+
/** Per-domain READ-corruption policy (0.8.1) — what buildEffective does when a stored domain no longer parses.
|
|
134
|
+
* `"default"` = degrade to the schema default + warn (safe: the default only REMOVES capability, fail-closed).
|
|
135
|
+
* `"throw"` = keep fail-loud (defaulting would LOOSEN gates or destructively apply — worse than an outage,
|
|
136
|
+
* consumers fail-static on last-good). A `satisfies Record<DomainName,…>` forces every FUTURE domain to make
|
|
137
|
+
* this call explicitly (compile error until it's classified). Per-domain rationale:
|
|
138
|
+
* - models/skills/mcp/plugins/scenarios/systems/collab: additive capability catalogs — empty = the
|
|
139
|
+
* capability disappears (fail-closed), no gate is lost.
|
|
140
|
+
* - hosts: empty registry = no auto-placement targets (availability-only); self-registration re-lands
|
|
141
|
+
* entries as approved:false = 待批 (fail-closed). Plus the precise grandfather clamp runs FIRST.
|
|
142
|
+
* - rosters: THROW — a lost roster makes resolveEffectiveForWorker fall back to the FULL models catalog
|
|
143
|
+
* ("global(fallback)"), silently WIDENING every restricted worker's model access. 放权,不许.
|
|
144
|
+
* - workers: THROW — an empty fleet spec would make the reconciler RETIRE every managed worker
|
|
145
|
+
* (destructive apply — far worse than a read outage).
|
|
146
|
+
* - runtime: THROW — defaulting drops centrally-published rate/cost ceilings = unbounded spend (fail-open
|
|
147
|
+
* on the budget axis).
|
|
148
|
+
* - governance: THROW — defaulting drops autonomy/commandPolicy/approvalRequire = the consumer falls back
|
|
149
|
+
* to env/defaults with the operator's guardrails silently gone. 放权,不许.
|
|
150
|
+
* - entitlement: THROW — defaulting drops the org kill-switch/budget ceilings/tier restrictions for every
|
|
151
|
+
* principal. 放权,不许.
|
|
152
|
+
* - execution: THROW — defaulting flips required:true (sandbox mandate) back to false. 放权,不许.
|
|
153
|
+
* (0.10.1: sessionMirror rides the SAME stance — defaulting would evaporate an org's required:true
|
|
154
|
+
* mirror mandate = 审计面静默放权; the shared rationale is exactly WHY it was收编 here, not a new domain.)
|
|
155
|
+
* - projects: THROW — defaulting evaporates the whole identity ledger: once the S4 worker gate ships,
|
|
156
|
+
* every `proj:*` derivation fails-fast (全租户记忆面停摆 — consumers fail-static on last-good is
|
|
157
|
+
* strictly better); WORSE, the claim write face is read-modify-write — reading a defaulted-empty
|
|
158
|
+
* ledger and writing it back would CLOBBER existing registrations down to one entry (data loss,
|
|
159
|
+
* one layer beyond the rosters "放权" rationale). */
|
|
160
|
+
export const DOMAIN_READ_FALLBACK = {
|
|
161
|
+
models: "default",
|
|
162
|
+
rosters: "throw",
|
|
163
|
+
skills: "default",
|
|
164
|
+
mcp: "default",
|
|
165
|
+
plugins: "default",
|
|
166
|
+
scenarios: "default",
|
|
167
|
+
systems: "default",
|
|
168
|
+
collab: "default",
|
|
169
|
+
workers: "throw",
|
|
170
|
+
hosts: "default",
|
|
171
|
+
runtime: "throw",
|
|
172
|
+
governance: "throw",
|
|
173
|
+
entitlement: "throw",
|
|
174
|
+
execution: "throw",
|
|
175
|
+
projects: "throw",
|
|
176
|
+
};
|
|
177
|
+
/** READ-path grandfather clamp for the 0.8.0 hosts tightening (0.8.1, S3 M-1). Clamps ONLY the two bounds
|
|
178
|
+
* 0.8.0 added (name > 63 → drop the entry; array > 1024 → slice) so 0.7-era legal stored data keeps reading;
|
|
179
|
+
* everything else (regex, types, duplicates) is left for parseDomain — this is a targeted grandfather, not a
|
|
180
|
+
* lenient parser. PURE + idempotent; returns the ORIGINAL reference when nothing exceeds the bounds. */
|
|
181
|
+
export function grandfatherHostsRead(raw) {
|
|
182
|
+
if (raw === null || typeof raw !== "object" || !Array.isArray(raw.hosts)) {
|
|
183
|
+
return { raw, droppedNames: [] }; // not the expected shape — let parseDomain rule on it
|
|
184
|
+
}
|
|
185
|
+
const original = raw.hosts;
|
|
186
|
+
const droppedNames = [];
|
|
187
|
+
let hosts = original.filter((h) => {
|
|
188
|
+
const name = h !== null && typeof h === "object" ? h.name : undefined;
|
|
189
|
+
if (typeof name === "string" && name.length > HOST_NAME_MAX) {
|
|
190
|
+
droppedNames.push(name.slice(0, HOST_NAME_MAX) + "…"); // audit label — clipped so the warning itself stays bounded
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
return true;
|
|
194
|
+
});
|
|
195
|
+
let truncatedFrom;
|
|
196
|
+
if (hosts.length > HOSTS_ARRAY_MAX) {
|
|
197
|
+
truncatedFrom = hosts.length;
|
|
198
|
+
hosts = hosts.slice(0, HOSTS_ARRAY_MAX);
|
|
199
|
+
}
|
|
200
|
+
if (droppedNames.length === 0 && truncatedFrom === undefined)
|
|
201
|
+
return { raw, droppedNames }; // identity — byte-stable
|
|
202
|
+
return { raw: { ...raw, hosts }, droppedNames, truncatedFrom };
|
|
203
|
+
}
|
|
204
|
+
export function buildEffective(version, getRaw, updatedAt, onWarning) {
|
|
205
|
+
// Generic READ guardrail (0.8.1): a domain that no longer parses degrades to its schema default + a warning
|
|
206
|
+
// — but ONLY where DOMAIN_READ_FALLBACK says the default is safe; gate-bearing domains keep throwing (决策
|
|
207
|
+
// 表与逐域理由见 DOMAIN_READ_FALLBACK). The success path is UNCHANGED (same parseDomain, same bytes).
|
|
208
|
+
const parseOr = (domain, raw) => {
|
|
209
|
+
try {
|
|
210
|
+
return parseDomain(domain, raw);
|
|
211
|
+
}
|
|
212
|
+
catch (e) {
|
|
213
|
+
if (DOMAIN_READ_FALLBACK[domain] === "throw")
|
|
214
|
+
throw e;
|
|
215
|
+
onWarning?.({ domain, kind: "domain-defaulted", error: e });
|
|
216
|
+
return parseDomain(domain, undefined); // schema default — always valid
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
// governance TRUTH: the domain itself; if it was never set, lift the trio from a legacy runtime doc
|
|
220
|
+
// (0.5→0.6 upgrade path — a2/local stores keep their gates without a data migration).
|
|
221
|
+
const governanceRaw = getRaw("governance");
|
|
222
|
+
const governance = parseDomain("governance", governanceRaw === undefined ? legacyGovernanceFromRuntime(getRaw("runtime")) : governanceRaw);
|
|
223
|
+
// runtime slot = limit residue ONLY. 0.7.1(BREAKING,黑板 [549] 回执收账):E1 的 governance→runtime
|
|
224
|
+
// 六闸双写镜像已撤——service 1.150.0 已切优先读 eff.governance 并回帖确认(撤双写以其确认为门槛,
|
|
225
|
+
// ask⑤ 顺序契约兑现)。READ 方向的 legacy lift(governance 域从未设时从旧 runtime 文档抬升三闸,
|
|
226
|
+
// 见 legacyGovernanceFromRuntime)保留——那是 0.5→0.6 升级路径,与写出镜像无关。
|
|
227
|
+
const runtime = parseDomain("runtime", getRaw("runtime"));
|
|
228
|
+
// hosts: the PRECISE grandfather for the 0.8.0 tightening runs BEFORE parse (0.7-era legal data over the
|
|
229
|
+
// new bounds reads on, clamped + warned); any residual corruption falls to the generic guardrail above.
|
|
230
|
+
const hostsGf = grandfatherHostsRead(getRaw("hosts"));
|
|
231
|
+
if (hostsGf.droppedNames.length > 0 || hostsGf.truncatedFrom !== undefined) {
|
|
232
|
+
onWarning?.({ domain: "hosts", kind: "hosts-grandfathered", droppedNames: hostsGf.droppedNames, truncatedFrom: hostsGf.truncatedFrom });
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
version,
|
|
236
|
+
updatedAt,
|
|
237
|
+
models: parseOr("models", getRaw("models")),
|
|
238
|
+
rosters: parseDomain("rosters", getRaw("rosters")),
|
|
239
|
+
skills: parseOr("skills", getRaw("skills")),
|
|
240
|
+
mcp: parseOr("mcp", getRaw("mcp")),
|
|
241
|
+
plugins: parseOr("plugins", getRaw("plugins")),
|
|
242
|
+
scenarios: parseOr("scenarios", getRaw("scenarios")),
|
|
243
|
+
systems: parseOr("systems", getRaw("systems")),
|
|
244
|
+
collab: parseOr("collab", getRaw("collab")),
|
|
245
|
+
workers: parseDomain("workers", getRaw("workers")),
|
|
246
|
+
hosts: parseOr("hosts", hostsGf.raw),
|
|
247
|
+
runtime,
|
|
248
|
+
governance,
|
|
249
|
+
entitlement: parseDomain("entitlement", getRaw("entitlement")),
|
|
250
|
+
// execution (0.8.0, S3): plain scope-level parse — MIRRORS governance (no overlay/merge invented here).
|
|
251
|
+
execution: parseDomain("execution", getRaw("execution")),
|
|
252
|
+
// projects (0.10.0, 142-S3): THROW policy → parseDomain, never parseOr (defaulting would evaporate the
|
|
253
|
+
// identity ledger AND expose the claim read-modify-write face to clobbering stored registrations).
|
|
254
|
+
projects: parseDomain("projects", getRaw("projects")),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/** [599]③ 档位组→引擎单表的唯一解析点(0.9.0)。返回 ACTIVE 档位组的绑定表(剔除未绑档),即 core
|
|
258
|
+
* `RunnerDeps.tiers` 要吃的那张单表——组切换=center 换这张表下发,零新引擎机制。无 active 组/未命中/
|
|
259
|
+
* 组内一档未绑 → `undefined`(引擎档位层恒惰性,与「未配 tiers」逐字同义)。消费方(center /effective
|
|
260
|
+
* 投影、service applyEffective 接线)都走这一个函数,不要各自解析。 */
|
|
261
|
+
export function resolveActiveTiers(models) {
|
|
262
|
+
if (!models.activeTierGroup)
|
|
263
|
+
return undefined;
|
|
264
|
+
const group = (models.tierGroups ?? []).find((g) => g.name === models.activeTierGroup);
|
|
265
|
+
if (!group)
|
|
266
|
+
return undefined; // schema 已 fail-loud 悬空 active;这里兜底旧数据,静默=INERT 与缺表同义
|
|
267
|
+
const bound = Object.entries(group.tiers).filter((e) => typeof e[1] === "string" && e[1].length > 0);
|
|
268
|
+
if (bound.length === 0)
|
|
269
|
+
return undefined;
|
|
270
|
+
return Object.fromEntries(bound);
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=config-fns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-fns.js","sourceRoot":"","sources":["../src/config-fns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-domain referential integrity — the PURE half, shared by the single-domain PUT and the batch write so
|
|
3
|
+
* BOTH enforce the same rules (docs/MULTI-ROSTER.md §6). The FLEET-coupled `applyAutoPlacement` (which imports
|
|
4
|
+
* `../fleet/placement`) STAYS in sema-registry — it's not pure and not portable. This package carries only
|
|
5
|
+
* `refIntegrityIssues` + `siblingResolver` + the ref-issue types.
|
|
6
|
+
*
|
|
7
|
+
* BATCH-AWARE: a sibling domain (the models a roster references, the rosters a worker references) may be
|
|
8
|
+
* changing in the SAME batch. So checks resolve siblings through a {@link SiblingResolver} that prefers a
|
|
9
|
+
* value being written NOW over the stored one — otherwise "add a model AND a roster that uses it" in one
|
|
10
|
+
* batch would wrongly fail. The single-domain PUT passes no pending writes, so its resolver is just the
|
|
11
|
+
* reader (behaviour unchanged).
|
|
12
|
+
*/
|
|
13
|
+
import type { ConfigReader } from "./reader.js";
|
|
14
|
+
import type { DomainConfig } from "./types.js";
|
|
15
|
+
export interface RefIssue {
|
|
16
|
+
path: (string | number)[];
|
|
17
|
+
message: string;
|
|
18
|
+
code: string;
|
|
19
|
+
}
|
|
20
|
+
/** Resolve a sibling domain's effective value for integrity checks. */
|
|
21
|
+
export type SiblingResolver = <K extends keyof DomainConfig>(domain: K) => Promise<DomainConfig[K] | undefined>;
|
|
22
|
+
/** A resolver over the reader, optionally shadowed by pending (same-operation) writes keyed by domain.
|
|
23
|
+
* Widened from the fat ConfigStore to the narrow {@link ConfigReader} (it only calls `getDomain`) so a TOC
|
|
24
|
+
* file source can use it without the full store. */
|
|
25
|
+
export declare function siblingResolver(store: ConfigReader, pending?: Partial<{
|
|
26
|
+
[K in keyof DomainConfig]: DomainConfig[K];
|
|
27
|
+
}>): SiblingResolver;
|
|
28
|
+
/** The domains whose writes carry cross-domain model/roster references we validate at save time. */
|
|
29
|
+
export type RefCheckedDomain = "rosters" | "workers" | "models" | "collab" | "systems" | "entitlement";
|
|
30
|
+
/** Cross-domain ref integrity for a rosters/workers/models/collab/systems value. Paths start with the domain
|
|
31
|
+
* key (e.g. `["rosters", i, "models", j]`) so a caller can prefix a batch index. Empty = ok. Runtime
|
|
32
|
+
* resolution stays tolerant (falls back); this is purely a save-time guard — a precise 400 at save time is
|
|
33
|
+
* friendlier than a silently-wrong roster. */
|
|
34
|
+
export declare function refIntegrityIssues(domain: RefCheckedDomain, value: unknown, resolve: SiblingResolver): Promise<RefIssue[]>;
|
|
35
|
+
//# sourceMappingURL=cross-domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-domain.d.ts","sourceRoot":"","sources":["../src/cross-domain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,uEAAuE;AACvE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;AAEhH;;qDAEqD;AACrD,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC;KAAG,CAAC,IAAI,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC;CAAE,CAAC,GAAG,eAAe,CAKvI;AAED,oGAAoG;AACpG,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC;AAEvG;;;+CAG+C;AAC/C,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAkFhI"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/** A resolver over the reader, optionally shadowed by pending (same-operation) writes keyed by domain.
|
|
2
|
+
* Widened from the fat ConfigStore to the narrow {@link ConfigReader} (it only calls `getDomain`) so a TOC
|
|
3
|
+
* file source can use it without the full store. */
|
|
4
|
+
export function siblingResolver(store, pending) {
|
|
5
|
+
return async (domain) => {
|
|
6
|
+
if (pending && Object.prototype.hasOwnProperty.call(pending, domain))
|
|
7
|
+
return pending[domain];
|
|
8
|
+
return store.getDomain(domain);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Cross-domain ref integrity for a rosters/workers/models/collab/systems value. Paths start with the domain
|
|
12
|
+
* key (e.g. `["rosters", i, "models", j]`) so a caller can prefix a batch index. Empty = ok. Runtime
|
|
13
|
+
* resolution stays tolerant (falls back); this is purely a save-time guard — a precise 400 at save time is
|
|
14
|
+
* friendlier than a silently-wrong roster. */
|
|
15
|
+
export async function refIntegrityIssues(domain, value, resolve) {
|
|
16
|
+
const issues = [];
|
|
17
|
+
if (domain === "rosters") {
|
|
18
|
+
const catalog = new Set(((await resolve("models"))?.models ?? []).map((m) => m.name));
|
|
19
|
+
value.rosters.forEach((r, i) => {
|
|
20
|
+
r.models.forEach((name, j) => {
|
|
21
|
+
if (!catalog.has(name))
|
|
22
|
+
issues.push({ path: ["rosters", i, "models", j], message: `roster "${r.name}" references unknown model "${name}" (not in the models catalog)`, code: "custom" });
|
|
23
|
+
});
|
|
24
|
+
for (const [role, target] of Object.entries(r.roles ?? {})) {
|
|
25
|
+
if (target && "model" in target && !catalog.has(target.model))
|
|
26
|
+
issues.push({ path: ["rosters", i, "roles", role], message: `roster "${r.name}" role.${role} → unknown model "${target.model}"`, code: "custom" });
|
|
27
|
+
}
|
|
28
|
+
// 0.6.3 markers (primaryModel/cheapModel) reference the catalog like a {model}-form role does — same
|
|
29
|
+
// save-time guard (a dangling marker would silently derive nothing at resolution).
|
|
30
|
+
if (r.primaryModel && !catalog.has(r.primaryModel))
|
|
31
|
+
issues.push({ path: ["rosters", i, "primaryModel"], message: `roster "${r.name}" primaryModel → unknown model "${r.primaryModel}" (not in the models catalog)`, code: "custom" });
|
|
32
|
+
if (r.cheapModel && !catalog.has(r.cheapModel))
|
|
33
|
+
issues.push({ path: ["rosters", i, "cheapModel"], message: `roster "${r.name}" cheapModel → unknown model "${r.cheapModel}" (not in the models catalog)`, code: "custom" });
|
|
34
|
+
(r.atModelAllowlist ?? []).forEach((name, j) => {
|
|
35
|
+
if (!catalog.has(name))
|
|
36
|
+
issues.push({ path: ["rosters", i, "atModelAllowlist", j], message: `roster "${r.name}" atModelAllowlist "${name}" not in the models catalog`, code: "custom" });
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
else if (domain === "workers") {
|
|
41
|
+
const rosterNames = new Set(((await resolve("rosters"))?.rosters ?? []).map((r) => r.name));
|
|
42
|
+
value.workers.forEach((w, i) => {
|
|
43
|
+
if (w.roster && !rosterNames.has(w.roster))
|
|
44
|
+
issues.push({ path: ["workers", i, "roster"], message: `worker "${w.name}" references unknown roster "${w.roster}"`, code: "custom" });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else if (domain === "models") {
|
|
48
|
+
// The roles map + @-allowlist reference models in THIS payload's OWN catalog (they ship together in the
|
|
49
|
+
// models domain), so validate against `value`, not the stored/sibling models.
|
|
50
|
+
const m = value;
|
|
51
|
+
const catalog = new Set(m.models.map((x) => x.name));
|
|
52
|
+
for (const [role, target] of Object.entries(m.roles ?? {})) {
|
|
53
|
+
if (target && "model" in target && !catalog.has(target.model))
|
|
54
|
+
issues.push({ path: ["models", "roles", role], message: `models.roles.${role} → unknown model "${target.model}" (not in the catalog)`, code: "custom" });
|
|
55
|
+
}
|
|
56
|
+
(m.atModelAllowlist ?? []).forEach((name, j) => {
|
|
57
|
+
if (!catalog.has(name))
|
|
58
|
+
issues.push({ path: ["models", "atModelAllowlist", j], message: `atModelAllowlist "${name}" not in the models catalog`, code: "custom" });
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else if (domain === "collab") {
|
|
62
|
+
// collab (0.7.0, replaces teams): a slot member's `modelRef` is a models-CATALOG name (T1 — never a
|
|
63
|
+
// roster, never a gateway id) and must resolve against the catalog (sibling — batch-aware). ABSENT
|
|
64
|
+
// modelRef is the legal "跟随用户当前模型" state, not a dangle. This is the SAVE-time guard; a model
|
|
65
|
+
// deleted/renamed LATER still dangles → the web renders the 悬空 destructive badge (§11-6), same as
|
|
66
|
+
// groupBindings.
|
|
67
|
+
const catalog = new Set(((await resolve("models"))?.models ?? []).map((x) => x.name));
|
|
68
|
+
value.templates.forEach((t, i) => {
|
|
69
|
+
t.slots.forEach((s, j) => {
|
|
70
|
+
s.members.forEach((mem, k) => {
|
|
71
|
+
if (mem.modelRef && !catalog.has(mem.modelRef))
|
|
72
|
+
issues.push({ path: ["templates", i, "slots", j, "members", k, "modelRef"], message: `collab template "${t.id}" slot "${s.id}" → unknown model "${mem.modelRef}" (not in the catalog)`, code: "custom" });
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (domain === "systems") {
|
|
78
|
+
// systems.callsWorkers → workers domain (a dangling name would mint a credential routed at nobody;
|
|
79
|
+
// resolution stays tolerant — this is the save-time guard, same as the other ref-checked domains).
|
|
80
|
+
const workers = new Set((await resolve("workers"))?.workers.map((w) => w.name) ?? []);
|
|
81
|
+
value.systems.forEach((sys, i) => {
|
|
82
|
+
sys.callsWorkers.forEach((name, j) => {
|
|
83
|
+
if (!workers.has(name))
|
|
84
|
+
issues.push({ path: ["systems", i, "callsWorkers", j], message: `system "${sys.name}" references unknown worker "${name}"`, code: "custom" });
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
else if (domain === "entitlement") {
|
|
89
|
+
// A tier references FIVE sibling domains by name (roster→rosters, models[]→models catalog, visibleSkills→
|
|
90
|
+
// skills, visibleMcp→mcp, visiblePlugins→plugins). A dangling ref otherwise resolves silently (e.g. a typo'd roster → resolve-
|
|
91
|
+
// entitlement yields an empty set → the principal is silently denied) — a precise 400 at save time is
|
|
92
|
+
// friendlier, matching the rosters/workers guards.
|
|
93
|
+
const rosterNames = new Set(((await resolve("rosters"))?.rosters ?? []).map((r) => r.name));
|
|
94
|
+
const modelCatalog = new Set(((await resolve("models"))?.models ?? []).map((m) => m.name));
|
|
95
|
+
const skillNames = new Set((await resolve("skills"))?.skills.map((s) => s.name) ?? []);
|
|
96
|
+
const mcpNames = new Set((await resolve("mcp"))?.servers.map((s) => s.name) ?? []);
|
|
97
|
+
const pluginNames = new Set((await resolve("plugins"))?.plugins.map((p) => p.name) ?? []);
|
|
98
|
+
value.tiers.forEach((t, i) => {
|
|
99
|
+
if (t.roster && !rosterNames.has(t.roster))
|
|
100
|
+
issues.push({ path: ["tiers", i, "roster"], message: `tier "${t.id}" references unknown roster "${t.roster}"`, code: "custom" });
|
|
101
|
+
(t.models ?? []).forEach((name, j) => { if (!modelCatalog.has(name))
|
|
102
|
+
issues.push({ path: ["tiers", i, "models", j], message: `tier "${t.id}" model "${name}" not in the models catalog`, code: "custom" }); });
|
|
103
|
+
(t.visibleSkills ?? []).forEach((name, j) => { if (!skillNames.has(name))
|
|
104
|
+
issues.push({ path: ["tiers", i, "visibleSkills", j], message: `tier "${t.id}" visibleSkill "${name}" not in skills`, code: "custom" }); });
|
|
105
|
+
(t.visibleMcp ?? []).forEach((name, j) => { if (!mcpNames.has(name))
|
|
106
|
+
issues.push({ path: ["tiers", i, "visibleMcp", j], message: `tier "${t.id}" visibleMcp "${name}" not in mcp`, code: "custom" }); });
|
|
107
|
+
(t.visiblePlugins ?? []).forEach((name, j) => { if (!pluginNames.has(name))
|
|
108
|
+
issues.push({ path: ["tiers", i, "visiblePlugins", j], message: `tier "${t.id}" visiblePlugin "${name}" not in plugins`, code: "custom" }); });
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// Exhaustiveness guard: a new RefCheckedDomain MUST add its own branch above, not silently inherit another
|
|
113
|
+
// domain's validation. `never` makes that a compile error; the throw is the runtime backstop.
|
|
114
|
+
const unhandled = domain;
|
|
115
|
+
throw new Error(`refIntegrityIssues: unhandled domain "${String(unhandled)}"`);
|
|
116
|
+
}
|
|
117
|
+
return issues;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=cross-domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-domain.js","sourceRoot":"","sources":["../src/cross-domain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import { RemoteExecSpec } from "./remote-exec.js";
|
|
3
|
+
import { type DomainConfig, type DomainName, type EffectiveConfig } from "./types.js";
|
|
4
|
+
export type ValidateResult<T> = {
|
|
5
|
+
ok: true;
|
|
6
|
+
value: T;
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
issues: z.ZodIssue[];
|
|
10
|
+
};
|
|
11
|
+
/** VALIDATE a domain payload against its zod schema WITHOUT writing — the editor's "is this form valid?" check.
|
|
12
|
+
* Returns the parsed+defaulted value or the zod issues. Identical rules to the server's parseDomain. Throws
|
|
13
|
+
* (clear message) if `domain` is not a real domain name (a misuse, not invalid user data). */
|
|
14
|
+
export declare function validateDomain<K extends DomainName>(domain: K, raw: unknown): ValidateResult<DomainConfig[K]>;
|
|
15
|
+
/** Same, for the remote-exec contract (a standalone contract, not a DOMAIN_SCHEMAS member). */
|
|
16
|
+
export declare function validateRemoteExec(raw: unknown): ValidateResult<RemoteExecSpec>;
|
|
17
|
+
/** Absolute path to a domain's JSON file under a config root (mirrors FileConfigStore.domainPath). Guards the
|
|
18
|
+
* name (no `../../secret` traversal even if a caller bypasses the DomainName type). */
|
|
19
|
+
export declare function domainFilePath(root: string, domain: DomainName): string;
|
|
20
|
+
/** WRITE a domain file ATOMICALLY (write a tmp in the same dir → rename) so a crash never leaves a half-written
|
|
21
|
+
* config.d/<domain>.json. VALIDATES first (throws on invalid — never persists garbage); persists the parsed +
|
|
22
|
+
* defaulted value so the file is canonical. */
|
|
23
|
+
export declare function writeDomainFile<K extends DomainName>(root: string, domain: K, value: unknown): Promise<DomainConfig[K]>;
|
|
24
|
+
export interface RequiredEnvName {
|
|
25
|
+
envName: string;
|
|
26
|
+
refs: {
|
|
27
|
+
domain: string;
|
|
28
|
+
detail: string;
|
|
29
|
+
}[];
|
|
30
|
+
/** true if this env-NAME resolves in the supplied environment (.env merged over process.env). */
|
|
31
|
+
present: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** LIST every env-NAME the current local config requires (across models/workers/mcp + the
|
|
34
|
+
* remote-exec backend), marking which are MISSING from the resolved env — the TOC "you still need to set
|
|
35
|
+
* these secrets" panel. Reuses collectEnvRefs for the domain side, then appends the remoteExec secret refs. */
|
|
36
|
+
export declare function listRequiredEnvNames(eff: EffectiveConfig, remoteExec: RemoteExecSpec | undefined, resolvedEnv: Record<string, string | undefined>): RequiredEnvName[];
|
|
37
|
+
//# sourceMappingURL=file-edit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-edit.d.ts","sourceRoot":"","sources":["../src/file-edit.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAgC,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;CAAE,CAAC;AAiB7F;;+FAE+F;AAC/F,wBAAgB,cAAc,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAW7G;AAED,+FAA+F;AAC/F,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,CAQ/E;AAED;wFACwF;AACxF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAGvE;AAED;;gDAEgD;AAChD,wBAAsB,eAAe,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAe7H;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,iGAAiG;IACjG,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;gHAEgH;AAChH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,eAAe,EACpB,UAAU,EAAE,cAAc,GAAG,SAAS,EACtC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC9C,eAAe,EAAE,CAqCnB"}
|