@dzhechkov/harness-core 0.7.4 → 0.7.6
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/.dz-manifest.json +141 -61
- package/README.md +38 -1
- package/dist/agentdb-index.d.ts.map +1 -1
- package/dist/agentdb-index.js +26 -2
- package/dist/agentdb-index.js.map +1 -1
- package/dist/amendment-trace.d.ts.map +1 -1
- package/dist/amendment-trace.js +6 -1
- package/dist/amendment-trace.js.map +1 -1
- package/dist/cadence.d.ts +66 -0
- package/dist/cadence.d.ts.map +1 -0
- package/dist/cadence.js +222 -0
- package/dist/cadence.js.map +1 -0
- package/dist/feature-adr-routing.d.ts.map +1 -1
- package/dist/feature-adr-routing.js +7 -2
- package/dist/feature-adr-routing.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/loop-blobs.generated.js +2 -2
- package/dist/loop-blobs.generated.js.map +1 -1
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +53 -18
- package/dist/operations.js.map +1 -1
- package/dist/provenance.d.ts +6 -0
- package/dist/provenance.d.ts.map +1 -1
- package/dist/provenance.js +22 -1
- package/dist/provenance.js.map +1 -1
- package/dist/publish.d.ts +31 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +78 -0
- package/dist/publish.js.map +1 -1
- package/dist/recall-hook-policy.d.ts +3 -1
- package/dist/recall-hook-policy.d.ts.map +1 -1
- package/dist/recall-hook-policy.js +15 -2
- package/dist/recall-hook-policy.js.map +1 -1
- package/dist/recall-usage.d.ts +15 -0
- package/dist/recall-usage.d.ts.map +1 -1
- package/dist/recall-usage.js +51 -1
- package/dist/recall-usage.js.map +1 -1
- package/dist/score.d.ts.map +1 -1
- package/dist/score.js +38 -4
- package/dist/score.js.map +1 -1
- package/dist/skill-drift.d.ts +8 -2
- package/dist/skill-drift.d.ts.map +1 -1
- package/dist/skill-drift.js +60 -11
- package/dist/skill-drift.js.map +1 -1
- package/dist/skill-install-roots.d.ts +100 -0
- package/dist/skill-install-roots.d.ts.map +1 -0
- package/dist/skill-install-roots.js +116 -0
- package/dist/skill-install-roots.js.map +1 -0
- package/dist/tg-post.d.ts +76 -0
- package/dist/tg-post.d.ts.map +1 -0
- package/dist/tg-post.js +158 -0
- package/dist/tg-post.js.map +1 -0
- package/dist/usage.d.ts +31 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +108 -21
- package/dist/usage.js.map +1 -1
- package/dist/writer-quiescence.d.ts +42 -0
- package/dist/writer-quiescence.d.ts.map +1 -0
- package/dist/writer-quiescence.js +82 -0
- package/dist/writer-quiescence.js.map +1 -0
- package/package.json +13 -13
- package/sbom.json +260 -60
- package/src/agentdb-index.ts +26 -2
- package/src/amendment-trace.ts +6 -1
- package/src/cadence.ts +227 -0
- package/src/feature-adr-routing.ts +7 -2
- package/src/index.ts +8 -1
- package/src/loop-blobs.generated.ts +2 -2
- package/src/operations.ts +52 -19
- package/src/provenance.ts +23 -1
- package/src/publish.ts +98 -0
- package/src/recall-hook-policy.ts +15 -2
- package/src/recall-usage.ts +44 -1
- package/src/score.ts +30 -4
- package/src/skill-drift.ts +70 -13
- package/src/skill-install-roots.ts +119 -0
- package/src/tg-post.ts +192 -0
- package/src/usage.ts +132 -17
- package/src/writer-quiescence.ts +95 -0
package/dist/skill-drift.d.ts
CHANGED
|
@@ -42,9 +42,15 @@ export interface SweepOptions {
|
|
|
42
42
|
* `.claude/skills/<skill>` dev copies are excluded — the repo's own `dz sync` test treats them as
|
|
43
43
|
* "legitimately lagging" the published version, so counting them makes the gate red-on-arrival.
|
|
44
44
|
* The dangerous drift (goap, brutal-honesty) was always between PUBLISHED packages.
|
|
45
|
-
* - `'
|
|
45
|
+
* - `'installs'` (what the `no-skill-drift` HARD rule uses): packages + every per-target install
|
|
46
|
+
* root EXCEPT {@link DEV_SKILL_ROOT}. Machine-generated installs have no licence to lag, so
|
|
47
|
+
* holding them to byte-identity is a gate that can actually be satisfied — unlike `'all'`,
|
|
48
|
+
* which includes the hand-edited dev tree and is therefore red-on-arrival as a gate.
|
|
49
|
+
* - `'all'`: packages + EVERY per-target skills install root ({@link SKILL_INSTALL_ROOTS}) — the
|
|
50
|
+
* raw sweep the audit script does. A root that is absent, or present without a `SKILL.md`,
|
|
51
|
+
* contributes nothing, so this is inert for a repo that installs only one target.
|
|
46
52
|
*/
|
|
47
|
-
readonly scope?: 'packages' | 'all';
|
|
53
|
+
readonly scope?: 'packages' | 'installs' | 'all';
|
|
48
54
|
/** Skill basenames whose drift is ACCEPTED (documented intentional forks) — reported separately, never counted as gate drift. */
|
|
49
55
|
readonly allowlist?: readonly string[];
|
|
50
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-drift.d.ts","sourceRoot":"","sources":["../src/skill-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"skill-drift.d.ts","sourceRoot":"","sources":["../src/skill-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAQH,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,gGAAgG;IAChG,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,KAAK,CAAC;IACjD,iIAAiI;IACjI,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,4GAA4G;IAC5G,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,wGAAwG;IACxG,QAAQ,CAAC,WAAW,EAAE,SAAS,YAAY,EAAE,CAAC;CAC/C;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvE,8CAA8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,kDAAkD;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,+FAA+F;AAC/F,MAAM,WAAW,UAAU;IACzB,sFAAsF;IACtF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wFAAwF;IACxF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IACvC,oGAAoG;IACpG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8FAA8F;IAC9F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2GAA2G;IAC3G,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gGAAgG;IAChG,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AA6KD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,WAAW,CA2ClF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,UAAU,CA8D3G"}
|
package/dist/skill-drift.js
CHANGED
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
* @packageDocumentation
|
|
21
21
|
*/
|
|
22
22
|
import { readdirSync, statSync, readFileSync, writeFileSync, mkdirSync, rmSync, existsSync } from 'node:fs';
|
|
23
|
-
import { join, relative, resolve, dirname, basename } from 'node:path';
|
|
23
|
+
import { join, relative, resolve, dirname, basename, sep } from 'node:path';
|
|
24
24
|
import { createHash } from 'node:crypto';
|
|
25
|
+
import { DEV_SKILL_ROOT, SKILL_INSTALL_ROOTS, TARGET_ENRICHMENT_ASSETS } from './skill-install-roots.js';
|
|
25
26
|
const SKILL_MANIFEST = 'SKILL.md';
|
|
26
27
|
const IGNORED_ENTRIES = new Set(['node_modules', '__pycache__', '.DS_Store', 'run-history.json']);
|
|
27
28
|
/** md5 of a file's bytes (identical to both prototype scripts ⇒ identical drift verdicts). */
|
|
@@ -59,11 +60,43 @@ function walk(dir) {
|
|
|
59
60
|
* so BOTH the CI sweep AND the canonical-free `sync-canonical --check` share one implementation and
|
|
60
61
|
* yield the same verdict. Behavior-preserving refactor — no numbers change.
|
|
61
62
|
*/
|
|
63
|
+
/**
|
|
64
|
+
* Is this skill-dir-relative path a TARGET ENRICHMENT asset ({@link TARGET_ENRICHMENT_ASSETS})?
|
|
65
|
+
*
|
|
66
|
+
* Such a file exists in ONE copy by design — `dz init --enrich` writes it into the install tree and
|
|
67
|
+
* the canonical never has it. Counting it as drift makes the gate unsatisfiable; removing it during
|
|
68
|
+
* a heal destroys valid output. Compared with POSIX separators so a Windows `relative()` still matches.
|
|
69
|
+
*/
|
|
70
|
+
function isEnrichmentAsset(rel, copyDir) {
|
|
71
|
+
const owner = TARGET_ENRICHMENT_ASSETS[rel.split(sep).join('/')];
|
|
72
|
+
if (owner === undefined)
|
|
73
|
+
return false;
|
|
74
|
+
// The exemption is only valid inside the root that OWNS the asset. Elsewhere the same filename is
|
|
75
|
+
// a misplaced extra file, and waving it through would make the sweep report clean while the healer
|
|
76
|
+
// preserved it. ANCHORED at the skill dir, not searched across the whole absolute path: a repo that
|
|
77
|
+
// itself lives under a directory containing `/.agents/skills/` would otherwise have every copy in
|
|
78
|
+
// it — packages included — classified as codex-owned (cross-family review, 2026-08-25).
|
|
79
|
+
const posix = copyDir.split(sep).join('/');
|
|
80
|
+
return posix.endsWith('/' + owner + '/' + posix.split('/').slice(-1)[0]);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The canonical's own file list, with every enrichment-asset NAME removed regardless of where the
|
|
84
|
+
* canonical came from. A canonical picked by `--auto` (or handed in with `--from`) can itself be an
|
|
85
|
+
* enriched install copy; propagating its target-specific metadata into the package and other target
|
|
86
|
+
* copies is never correct, and the exemption above would then stop it ever being cleaned up.
|
|
87
|
+
*/
|
|
88
|
+
function withoutEnrichmentNames(rels) {
|
|
89
|
+
return rels.filter((r) => TARGET_ENRICHMENT_ASSETS[r.split(sep).join('/')] === undefined);
|
|
90
|
+
}
|
|
62
91
|
function comparePeers(copies) {
|
|
63
92
|
const relFiles = new Set();
|
|
64
93
|
for (const c of copies)
|
|
65
|
-
for (const f of walk(c))
|
|
66
|
-
|
|
94
|
+
for (const f of walk(c)) {
|
|
95
|
+
const rel = relative(c, f);
|
|
96
|
+
if (isEnrichmentAsset(rel, c))
|
|
97
|
+
continue;
|
|
98
|
+
relFiles.add(rel);
|
|
99
|
+
}
|
|
67
100
|
let driftFiles = 0;
|
|
68
101
|
let missingFiles = 0;
|
|
69
102
|
for (const rel of relFiles) {
|
|
@@ -89,7 +122,10 @@ function comparePeers(copies) {
|
|
|
89
122
|
* hence it is only ever reached behind an explicit `--auto` opt-in plus a loud warning.
|
|
90
123
|
*/
|
|
91
124
|
function pickMostComplete(copies) {
|
|
92
|
-
|
|
125
|
+
// Enrichment assets do not make a copy more COMPLETE — they make it a target install. Counting
|
|
126
|
+
// them would let an enriched copy win the heuristic on files no other copy is supposed to have.
|
|
127
|
+
const size = (d) => withoutEnrichmentNames(walk(d).map((p) => relative(d, p))).length;
|
|
128
|
+
return [...copies].sort().reduce((best, c) => (size(c) > size(best) ? c : best));
|
|
93
129
|
}
|
|
94
130
|
/**
|
|
95
131
|
* Resolve WHICH dir is canonical for a sync/check run, and HOW it resolved. Precedence is identical
|
|
@@ -111,12 +147,24 @@ function resolveCanonical(root, skill, copies, opts) {
|
|
|
111
147
|
return { canonical: null, resolvedFrom: 'none' };
|
|
112
148
|
}
|
|
113
149
|
/**
|
|
114
|
-
* Every skill dir (a dir containing `SKILL.md`) under `packages/` +
|
|
115
|
-
* `node_modules` / `__pycache__`.
|
|
150
|
+
* Every skill dir (a dir containing `SKILL.md`) under `packages/` + every per-target install root
|
|
151
|
+
* in {@link SKILL_INSTALL_ROOTS}, excluding `node_modules` / `__pycache__`. Originally ported from
|
|
152
|
+
* `scripts/drift-sweep-skills.mjs`, which searched `.claude/skills` alone — see ADR-001
|
|
153
|
+
* (skill-copy-discovery) for why one hardcoded root let the Codex install drift unseen.
|
|
116
154
|
*/
|
|
117
155
|
function findSkillDirs(root, scope = 'all') {
|
|
118
156
|
const dirs = [];
|
|
119
|
-
|
|
157
|
+
// Roots are ANCHORED at the repo root — never a recursive search for `*/skills`. A stale agent
|
|
158
|
+
// worktree under `.claude/worktrees/<id>/` holds a full second copy of `packages/`,
|
|
159
|
+
// `.claude/skills` AND `.agents/skills`; a recursive sweep would report every skill in the repo
|
|
160
|
+
// as drifting against a checkout nobody maintains, and the healer would be entitled to WRITE
|
|
161
|
+
// into it (ADR-001, Option C rejected on exactly this measurement).
|
|
162
|
+
const installRoots = scope === 'installs'
|
|
163
|
+
? SKILL_INSTALL_ROOTS.filter((r) => r !== DEV_SKILL_ROOT)
|
|
164
|
+
: SKILL_INSTALL_ROOTS;
|
|
165
|
+
const roots = scope === 'packages'
|
|
166
|
+
? [join(root, 'packages')]
|
|
167
|
+
: [join(root, 'packages'), ...installRoots.map((r) => join(root, ...r.split('/')))];
|
|
120
168
|
const stack = roots.filter((p) => existsSync(p));
|
|
121
169
|
while (stack.length) {
|
|
122
170
|
const d = stack.pop();
|
|
@@ -231,16 +279,17 @@ export function syncCanonicalSkill(root, skill, opts = {}) {
|
|
|
231
279
|
// Bare WRITE with no resolvable canonical → REFUSE. Mutates nothing (`wrote:[]` proves it).
|
|
232
280
|
return { canonical: '', canonicalExists: false, resolvedFrom, copies: allCopies.length, synced: 0, drifted: 0, wrote: [] };
|
|
233
281
|
}
|
|
234
|
-
const canonFiles = walk(canonical)
|
|
235
|
-
.map((p) => relative(canonical, p))
|
|
236
|
-
.sort();
|
|
282
|
+
const canonFiles = withoutEnrichmentNames(walk(canonical).map((p) => relative(canonical, p))).sort();
|
|
237
283
|
// Every <skill>/ dir except the canonical itself.
|
|
238
284
|
const copies = allCopies.filter((d) => relative(canonical, d) !== '');
|
|
239
285
|
let drifted = 0;
|
|
240
286
|
let synced = 0;
|
|
241
287
|
const wrote = [];
|
|
242
288
|
for (const copy of copies) {
|
|
243
|
-
|
|
289
|
+
// Target ENRICHMENT assets are excluded from the copy's file set entirely: they exist in the
|
|
290
|
+
// install tree by design, the canonical never has them, and both the drift verdict and the
|
|
291
|
+
// removal pass below must leave them alone.
|
|
292
|
+
const copyFiles = new Set(walk(copy).map((p) => relative(copy, p)).filter((f) => !isEnrichmentAsset(f, copy)));
|
|
244
293
|
let differs = false;
|
|
245
294
|
// Extra files in the copy not present in canonical ⇒ drift.
|
|
246
295
|
for (const f of copyFiles)
|
package/dist/skill-drift.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-drift.js","sourceRoot":"","sources":["../src/skill-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC5G,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"skill-drift.js","sourceRoot":"","sources":["../src/skill-drift.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where installed skill dirs live — the single source of truth for skill-copy DISCOVERY.
|
|
3
|
+
*
|
|
4
|
+
* The harness installs skills into a per-TARGET tree (`dz install --target <name>`). Five of the
|
|
5
|
+
* ten targets in {@link TARGET_NAMES} emit an agentskills.io-shaped directory containing a
|
|
6
|
+
* `SKILL.md`; the other five (copilot, cursor, windsurf, gemini, agents-md) emit rules/instructions
|
|
7
|
+
* FILES and therefore hold no skill dirs to keep in sync.
|
|
8
|
+
*
|
|
9
|
+
* | Target | Root | Adapter constant |
|
|
10
|
+
* |---|---|---|
|
|
11
|
+
* | `claude-code` | `.claude/skills` | — (the adapter exports no root constant) |
|
|
12
|
+
* | `codex` | `.agents/skills` | `CODEX_SKILLS_ROOT` |
|
|
13
|
+
* | `opencode` | `.opencode/skills` | `OPENCODE_SKILLS_ROOT` |
|
|
14
|
+
* | `hermes` | `.hermes/skills` | `HERMES_SKILLS_ROOT` |
|
|
15
|
+
* | `openclaude` | `.openclaude/skills` | `OPENCLAUDE_SKILLS_ROOT` |
|
|
16
|
+
*
|
|
17
|
+
* **Why this list is data with no imports.** `skill-drift.ts` — the drift detector behind the
|
|
18
|
+
* `no-skill-drift` HARD guard rule — is deliberately dependency-free (`node:fs`/`node:path`/
|
|
19
|
+
* `node:crypto`). `targets.ts`, which owns the adapter registry, imports all ten adapter packages;
|
|
20
|
+
* importing it from the drift sweep would drag ten packages into the guard's load path for a list
|
|
21
|
+
* of five strings. So the list lives here as data, and the link back to the adapters is asserted in
|
|
22
|
+
* `test/skill-install-roots.test.ts`, where importing them costs nothing.
|
|
23
|
+
*
|
|
24
|
+
* **Why this matters (the defect that produced it, MEASURED 2026-08-25).** `findSkillDirs` searched
|
|
25
|
+
* `packages/` + `.claude/skills` only. `.agents/skills/feature-adr` — the Codex install — drifted
|
|
26
|
+
* from the canonical for a day while `dz sync-canonical feature-adr --check` reported "all 3 copies
|
|
27
|
+
* match canonical" and the HARD guard passed. Two feature-adr gates were degraded in that copy: the
|
|
28
|
+
* K1 name-availability section was missing from `SKILL.md`, and the C6 amendment-integrity check
|
|
29
|
+
* was missing from the K2 script. A gate that cannot see a copy cannot gate it.
|
|
30
|
+
*
|
|
31
|
+
* **Honest limit.** A target whose adapter exports no root constant (today: `claude-code`) must be
|
|
32
|
+
* listed here by hand — the completeness test proves every EXPORTED constant is covered, and cannot
|
|
33
|
+
* prove a constant that does not exist is covered.
|
|
34
|
+
*
|
|
35
|
+
* @packageDocumentation
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Files a TARGET legitimately adds INSIDE an installed skill dir — enrichment, not drift.
|
|
39
|
+
*
|
|
40
|
+
* `dz init --enrich` / `dz setup --enrich` write per-target metadata into the skill dir itself
|
|
41
|
+
* (`operations.ts`): codex gets `<skillDir>/agents/openai.yaml` (UI metadata + risk scoring),
|
|
42
|
+
* hermes gets `<skillDir>/hermes-config.yaml`. OpenCode's enrichment lands in
|
|
43
|
+
* `.opencode/agents/<id>.md`, OUTSIDE any skill dir, so it needs no entry here.
|
|
44
|
+
*
|
|
45
|
+
* These paths must be invisible to the drift comparison and untouchable by the healer. Without the
|
|
46
|
+
* exemption, widening discovery to install roots would (a) report permanent, unfixable drift on any
|
|
47
|
+
* enriched install — making the HARD gate unsatisfiable — and (b) worse, let `dz sync-canonical`
|
|
48
|
+
* DELETE the enrichment, because the heal removes every file the canonical does not have. Found by
|
|
49
|
+
* cross-family review (Codex `gpt-5.6-sol`, 2026-08-25) on a latent defect: this repo's own
|
|
50
|
+
* `.agents/` install was never enriched, so no test and no live run would have shown it.
|
|
51
|
+
*
|
|
52
|
+
* Each asset is mapped to the install root that OWNS it, because the exemption must depend on WHERE
|
|
53
|
+
* the file sits, not only on its name: `agents/openai.yaml` under a package copy, or
|
|
54
|
+
* `hermes-config.yaml` outside the hermes root, is a misplaced file — waving it through would let
|
|
55
|
+
* the sweep report clean and the healer preserve it (second cross-family round, 2026-08-25).
|
|
56
|
+
*
|
|
57
|
+
* Keys are relative to the skill dir root and POSIX-separated; values are repo-root-relative install
|
|
58
|
+
* roots from {@link SKILL_INSTALL_ROOT_BY_TARGET}.
|
|
59
|
+
*/
|
|
60
|
+
export declare const TARGET_ENRICHMENT_ASSETS: Readonly<Record<string, string>>;
|
|
61
|
+
/**
|
|
62
|
+
* The one install root that is ALSO the repo's hand-edited development tree.
|
|
63
|
+
*
|
|
64
|
+
* `.claude/skills` is where this repo's own skills are authored before they are synced into
|
|
65
|
+
* `packages/`, so it legitimately LAGS the published copies — MEASURED 2026-08-25, `dz drift-check
|
|
66
|
+
* --all` reports three skills drifting for exactly that reason (`decision-mockups` 12/22 files,
|
|
67
|
+
* `idea2prd-manual` 3/11, `observability` 1/5). A byte-identity GATE that included it would be
|
|
68
|
+
* red-on-arrival, which is why `scope: 'packages'` exists at all.
|
|
69
|
+
*
|
|
70
|
+
* Every OTHER root in {@link SKILL_INSTALL_ROOTS} is machine-generated by `dz install --target …`
|
|
71
|
+
* and has no licence to lag: a stale generated copy is the defect this module was written for.
|
|
72
|
+
* That asymmetry is what `scope: 'installs'` encodes.
|
|
73
|
+
*/
|
|
74
|
+
export declare const DEV_SKILL_ROOT = ".claude/skills";
|
|
75
|
+
/**
|
|
76
|
+
* Every `--target` name → the repo-root-relative dir into which it installs `SKILL.md`-bearing
|
|
77
|
+
* skill dirs, or `null` for a target that emits rules/instructions FILES and therefore holds no
|
|
78
|
+
* skill dirs to keep in sync.
|
|
79
|
+
*
|
|
80
|
+
* **This map, not the derived list, is the thing a new target must touch.** Its keys are asserted
|
|
81
|
+
* against `TARGET_NAMES` in `test/skill-install-roots.test.ts`, so adding target #11 turns that
|
|
82
|
+
* test RED until someone states whether it installs skill dirs — which is exactly the question
|
|
83
|
+
* nobody was asked when `codex` was added and its install tree went ungated. A test that
|
|
84
|
+
* hand-enumerated the adapter constants would have stayed green through that (raised by
|
|
85
|
+
* cross-family review, Codex `gpt-5.6-sol`, 2026-08-25).
|
|
86
|
+
*
|
|
87
|
+
* Kept as a literal with NO imports: `skill-drift.ts` consumes it and is documented dependency-free,
|
|
88
|
+
* while `targets.ts` — which owns the adapter registry — pulls in all ten adapter packages.
|
|
89
|
+
*/
|
|
90
|
+
export declare const SKILL_INSTALL_ROOT_BY_TARGET: Readonly<Record<string, string | null>>;
|
|
91
|
+
/**
|
|
92
|
+
* Repo-root-relative directories that hold installed `SKILL.md`-bearing skill dirs — DERIVED from
|
|
93
|
+
* {@link SKILL_INSTALL_ROOT_BY_TARGET} so the two can never disagree. POSIX separators; consumers
|
|
94
|
+
* `join()` them onto the repo root themselves.
|
|
95
|
+
*
|
|
96
|
+
* Consumed by `findSkillDirs` (`skill-drift.ts`). A root that does not exist, or exists without any
|
|
97
|
+
* `SKILL.md`, contributes nothing — so listing a root the current repo does not use is inert.
|
|
98
|
+
*/
|
|
99
|
+
export declare const SKILL_INSTALL_ROOTS: readonly string[];
|
|
100
|
+
//# sourceMappingURL=skill-install-roots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-install-roots.d.ts","sourceRoot":"","sources":["../src/skill-install-roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGrE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAYhF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EACR,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where installed skill dirs live — the single source of truth for skill-copy DISCOVERY.
|
|
3
|
+
*
|
|
4
|
+
* The harness installs skills into a per-TARGET tree (`dz install --target <name>`). Five of the
|
|
5
|
+
* ten targets in {@link TARGET_NAMES} emit an agentskills.io-shaped directory containing a
|
|
6
|
+
* `SKILL.md`; the other five (copilot, cursor, windsurf, gemini, agents-md) emit rules/instructions
|
|
7
|
+
* FILES and therefore hold no skill dirs to keep in sync.
|
|
8
|
+
*
|
|
9
|
+
* | Target | Root | Adapter constant |
|
|
10
|
+
* |---|---|---|
|
|
11
|
+
* | `claude-code` | `.claude/skills` | — (the adapter exports no root constant) |
|
|
12
|
+
* | `codex` | `.agents/skills` | `CODEX_SKILLS_ROOT` |
|
|
13
|
+
* | `opencode` | `.opencode/skills` | `OPENCODE_SKILLS_ROOT` |
|
|
14
|
+
* | `hermes` | `.hermes/skills` | `HERMES_SKILLS_ROOT` |
|
|
15
|
+
* | `openclaude` | `.openclaude/skills` | `OPENCLAUDE_SKILLS_ROOT` |
|
|
16
|
+
*
|
|
17
|
+
* **Why this list is data with no imports.** `skill-drift.ts` — the drift detector behind the
|
|
18
|
+
* `no-skill-drift` HARD guard rule — is deliberately dependency-free (`node:fs`/`node:path`/
|
|
19
|
+
* `node:crypto`). `targets.ts`, which owns the adapter registry, imports all ten adapter packages;
|
|
20
|
+
* importing it from the drift sweep would drag ten packages into the guard's load path for a list
|
|
21
|
+
* of five strings. So the list lives here as data, and the link back to the adapters is asserted in
|
|
22
|
+
* `test/skill-install-roots.test.ts`, where importing them costs nothing.
|
|
23
|
+
*
|
|
24
|
+
* **Why this matters (the defect that produced it, MEASURED 2026-08-25).** `findSkillDirs` searched
|
|
25
|
+
* `packages/` + `.claude/skills` only. `.agents/skills/feature-adr` — the Codex install — drifted
|
|
26
|
+
* from the canonical for a day while `dz sync-canonical feature-adr --check` reported "all 3 copies
|
|
27
|
+
* match canonical" and the HARD guard passed. Two feature-adr gates were degraded in that copy: the
|
|
28
|
+
* K1 name-availability section was missing from `SKILL.md`, and the C6 amendment-integrity check
|
|
29
|
+
* was missing from the K2 script. A gate that cannot see a copy cannot gate it.
|
|
30
|
+
*
|
|
31
|
+
* **Honest limit.** A target whose adapter exports no root constant (today: `claude-code`) must be
|
|
32
|
+
* listed here by hand — the completeness test proves every EXPORTED constant is covered, and cannot
|
|
33
|
+
* prove a constant that does not exist is covered.
|
|
34
|
+
*
|
|
35
|
+
* @packageDocumentation
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Files a TARGET legitimately adds INSIDE an installed skill dir — enrichment, not drift.
|
|
39
|
+
*
|
|
40
|
+
* `dz init --enrich` / `dz setup --enrich` write per-target metadata into the skill dir itself
|
|
41
|
+
* (`operations.ts`): codex gets `<skillDir>/agents/openai.yaml` (UI metadata + risk scoring),
|
|
42
|
+
* hermes gets `<skillDir>/hermes-config.yaml`. OpenCode's enrichment lands in
|
|
43
|
+
* `.opencode/agents/<id>.md`, OUTSIDE any skill dir, so it needs no entry here.
|
|
44
|
+
*
|
|
45
|
+
* These paths must be invisible to the drift comparison and untouchable by the healer. Without the
|
|
46
|
+
* exemption, widening discovery to install roots would (a) report permanent, unfixable drift on any
|
|
47
|
+
* enriched install — making the HARD gate unsatisfiable — and (b) worse, let `dz sync-canonical`
|
|
48
|
+
* DELETE the enrichment, because the heal removes every file the canonical does not have. Found by
|
|
49
|
+
* cross-family review (Codex `gpt-5.6-sol`, 2026-08-25) on a latent defect: this repo's own
|
|
50
|
+
* `.agents/` install was never enriched, so no test and no live run would have shown it.
|
|
51
|
+
*
|
|
52
|
+
* Each asset is mapped to the install root that OWNS it, because the exemption must depend on WHERE
|
|
53
|
+
* the file sits, not only on its name: `agents/openai.yaml` under a package copy, or
|
|
54
|
+
* `hermes-config.yaml` outside the hermes root, is a misplaced file — waving it through would let
|
|
55
|
+
* the sweep report clean and the healer preserve it (second cross-family round, 2026-08-25).
|
|
56
|
+
*
|
|
57
|
+
* Keys are relative to the skill dir root and POSIX-separated; values are repo-root-relative install
|
|
58
|
+
* roots from {@link SKILL_INSTALL_ROOT_BY_TARGET}.
|
|
59
|
+
*/
|
|
60
|
+
export const TARGET_ENRICHMENT_ASSETS = {
|
|
61
|
+
'agents/openai.yaml': '.agents/skills',
|
|
62
|
+
'hermes-config.yaml': '.hermes/skills',
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* The one install root that is ALSO the repo's hand-edited development tree.
|
|
66
|
+
*
|
|
67
|
+
* `.claude/skills` is where this repo's own skills are authored before they are synced into
|
|
68
|
+
* `packages/`, so it legitimately LAGS the published copies — MEASURED 2026-08-25, `dz drift-check
|
|
69
|
+
* --all` reports three skills drifting for exactly that reason (`decision-mockups` 12/22 files,
|
|
70
|
+
* `idea2prd-manual` 3/11, `observability` 1/5). A byte-identity GATE that included it would be
|
|
71
|
+
* red-on-arrival, which is why `scope: 'packages'` exists at all.
|
|
72
|
+
*
|
|
73
|
+
* Every OTHER root in {@link SKILL_INSTALL_ROOTS} is machine-generated by `dz install --target …`
|
|
74
|
+
* and has no licence to lag: a stale generated copy is the defect this module was written for.
|
|
75
|
+
* That asymmetry is what `scope: 'installs'` encodes.
|
|
76
|
+
*/
|
|
77
|
+
export const DEV_SKILL_ROOT = '.claude/skills';
|
|
78
|
+
/**
|
|
79
|
+
* Every `--target` name → the repo-root-relative dir into which it installs `SKILL.md`-bearing
|
|
80
|
+
* skill dirs, or `null` for a target that emits rules/instructions FILES and therefore holds no
|
|
81
|
+
* skill dirs to keep in sync.
|
|
82
|
+
*
|
|
83
|
+
* **This map, not the derived list, is the thing a new target must touch.** Its keys are asserted
|
|
84
|
+
* against `TARGET_NAMES` in `test/skill-install-roots.test.ts`, so adding target #11 turns that
|
|
85
|
+
* test RED until someone states whether it installs skill dirs — which is exactly the question
|
|
86
|
+
* nobody was asked when `codex` was added and its install tree went ungated. A test that
|
|
87
|
+
* hand-enumerated the adapter constants would have stayed green through that (raised by
|
|
88
|
+
* cross-family review, Codex `gpt-5.6-sol`, 2026-08-25).
|
|
89
|
+
*
|
|
90
|
+
* Kept as a literal with NO imports: `skill-drift.ts` consumes it and is documented dependency-free,
|
|
91
|
+
* while `targets.ts` — which owns the adapter registry — pulls in all ten adapter packages.
|
|
92
|
+
*/
|
|
93
|
+
export const SKILL_INSTALL_ROOT_BY_TARGET = {
|
|
94
|
+
'claude-code': '.claude/skills',
|
|
95
|
+
codex: '.agents/skills',
|
|
96
|
+
opencode: '.opencode/skills',
|
|
97
|
+
hermes: '.hermes/skills',
|
|
98
|
+
openclaude: '.openclaude/skills',
|
|
99
|
+
// Rules/instructions FILE targets — no skill dirs, nothing to compare.
|
|
100
|
+
copilot: null,
|
|
101
|
+
'agents-md': null,
|
|
102
|
+
cursor: null,
|
|
103
|
+
gemini: null,
|
|
104
|
+
windsurf: null,
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Repo-root-relative directories that hold installed `SKILL.md`-bearing skill dirs — DERIVED from
|
|
108
|
+
* {@link SKILL_INSTALL_ROOT_BY_TARGET} so the two can never disagree. POSIX separators; consumers
|
|
109
|
+
* `join()` them onto the repo root themselves.
|
|
110
|
+
*
|
|
111
|
+
* Consumed by `findSkillDirs` (`skill-drift.ts`). A root that does not exist, or exists without any
|
|
112
|
+
* `SKILL.md`, contributes nothing — so listing a root the current repo does not use is inert.
|
|
113
|
+
*/
|
|
114
|
+
export const SKILL_INSTALL_ROOTS = Object.values(SKILL_INSTALL_ROOT_BY_TARGET)
|
|
115
|
+
.filter((r) => r !== null);
|
|
116
|
+
//# sourceMappingURL=skill-install-roots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-install-roots.js","sourceRoot":"","sources":["../src/skill-install-roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAqC;IACxE,oBAAoB,EAAE,gBAAgB;IACtC,oBAAoB,EAAE,gBAAgB;CACvC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAA4C;IACnF,aAAa,EAAE,gBAAgB;IAC/B,KAAK,EAAE,gBAAgB;IACvB,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,gBAAgB;IACxB,UAAU,EAAE,oBAAoB;IAChC,uEAAuE;IACvE,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAsB,MAAM,CAAC,MAAM,CAAC,4BAA4B,CAAC;KAC9F,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dz tg-post` — the pure half: validate an approved draft against what Telegram will accept and
|
|
3
|
+
* what the channel's own accepted design demands.
|
|
4
|
+
*
|
|
5
|
+
* The design is NOT this module's to invent. features/genai-tweets-channel/ carries four ACCEPTED
|
|
6
|
+
* ADRs (2026-08-04): HTML mode, never MarkdownV2 (18 escapes against 3, one miss is a 400); the
|
|
7
|
+
* cadence rule "no posts 00:00-06:00 MSK"; link previews off by default because x.com previews in
|
|
8
|
+
* Telegram have been broken since 2022; and ADR-004's standing order — publishing stays MANUAL, and
|
|
9
|
+
* autonomous publishing means REVISING the ADR, not flipping a quiet flag. This module only makes
|
|
10
|
+
* those decisions checkable.
|
|
11
|
+
*
|
|
12
|
+
* PURE: no filesystem, no network, no clock — the timestamp arrives as a parameter, or the MSK
|
|
13
|
+
* night-window rule could not be tested at all.
|
|
14
|
+
*/
|
|
15
|
+
/** Tags Bot API accepts in HTML mode (verified against the live docs, Bot API 10.2). */
|
|
16
|
+
export declare const TG_ALLOWED_TAGS: readonly string[];
|
|
17
|
+
/** Hard ceiling for `sendMessage.text`, characters after entity parsing. */
|
|
18
|
+
export declare const TG_TEXT_LIMIT = 4096;
|
|
19
|
+
export interface TgHtmlIssue {
|
|
20
|
+
readonly kind: 'unknown-tag' | 'unclosed-tag' | 'stray-close' | 'bare-ampersand' | 'bare-angle' | 'over-limit' | 'empty';
|
|
21
|
+
readonly detail: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The character count Telegram limits: text WITHOUT the markup. An approximation is stated as one —
|
|
25
|
+
* entities like tg-emoji count differently — but a draft within this bound by a margin is safe, and
|
|
26
|
+
* the render prints the number so the author sees the headroom, not a verdict.
|
|
27
|
+
*/
|
|
28
|
+
export declare function tgVisibleLength(html: string): number;
|
|
29
|
+
/**
|
|
30
|
+
* Everything wrong with a draft, or an empty list. One pass, every finding named — a validator that
|
|
31
|
+
* stops at the first fault sends the author around the loop once per mistake.
|
|
32
|
+
*/
|
|
33
|
+
export declare function tgPostHtmlIssues(html: string): TgHtmlIssue[];
|
|
34
|
+
export interface TgSendDecision {
|
|
35
|
+
readonly action: 'send' | 'refuse';
|
|
36
|
+
readonly reason: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* May this draft go out NOW?
|
|
40
|
+
*
|
|
41
|
+
* The night window is ADR-003's cadence rule, encoded as a refusal with an explicit override rather
|
|
42
|
+
* than as advice: 00:00-06:00 MSK is when the channel's audience is asleep and its author is too —
|
|
43
|
+
* a send landing then is far more often a timezone mistake than an intention. `--night` states the
|
|
44
|
+
* intention; without it the refusal names the local MSK time it computed, so the operator can check
|
|
45
|
+
* the arithmetic instead of trusting it.
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* The dedup key for a post: sha256 of its VISIBLE text (markup stripped). Two drafts that render
|
|
49
|
+
* identically in Telegram are the same post even if their HTML differs by a whitespace — the key
|
|
50
|
+
* must be about what the reader sees, not the bytes (G5, ADR-005).
|
|
51
|
+
*/
|
|
52
|
+
export declare function tgVisibleSha256(html: string): string;
|
|
53
|
+
/** One recorded send. sha256 is the visible-text key; ts is ISO. */
|
|
54
|
+
/** One journal line. status: 'pending' written BEFORE the send (crash-window guard), 'sent' after
|
|
55
|
+
* Telegram accepts. A legacy line with no status is treated as 'sent'. */
|
|
56
|
+
export interface TgSentRecord {
|
|
57
|
+
readonly sha256: string;
|
|
58
|
+
readonly ts: string;
|
|
59
|
+
readonly status?: 'pending' | 'sent';
|
|
60
|
+
}
|
|
61
|
+
export declare function decideTgSend(input: {
|
|
62
|
+
readonly issues: readonly TgHtmlIssue[];
|
|
63
|
+
readonly provenanceOutcome: 'allowed' | 'blocked' | 'not-established' | 'skipped';
|
|
64
|
+
readonly confirmed: boolean;
|
|
65
|
+
readonly nowUtcIso: string;
|
|
66
|
+
readonly nightOverride: boolean;
|
|
67
|
+
/** G6 stop-cord: a `.dz/tg-post/HALT` file exists. Checked FIRST, before anything else. */
|
|
68
|
+
readonly halted?: boolean;
|
|
69
|
+
/** sha256 of THIS post's visible text (tgVisibleSha256) — the G5 dedup key. */
|
|
70
|
+
readonly sha256?: string;
|
|
71
|
+
/** The send journal as FACTS (the pure half never reads a file). Undefined ⇒ log unreadable. */
|
|
72
|
+
readonly sentLog?: readonly TgSentRecord[] | undefined;
|
|
73
|
+
/** G4 ceiling; default 10 (ADR-003). Sends in the trailing 24h are counted against it. */
|
|
74
|
+
readonly maxPostsPerDay?: number;
|
|
75
|
+
}): TgSendDecision;
|
|
76
|
+
//# sourceMappingURL=tg-post.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tg-post.d.ts","sourceRoot":"","sources":["../src/tg-post.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AAEH,wFAAwF;AACxF,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAG5C,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,GAAG,aAAa,GAAG,gBAAgB,GAAG,YAAY,GAAG,YAAY,GAAG,OAAO,CAAC;IACzH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CA+C5D;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED,oEAAoE;AACpE;2EAC2E;AAC3E,MAAM,WAAW,YAAY;IAAG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;CAAE;AAEpH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAC;IAClF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,gGAAgG;IAChG,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;IACvD,0FAA0F;IAC1F,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC,GAAG,cAAc,CAwDjB"}
|