@doidor/agentrig 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -33
- package/dist/agent/copilot.js +46 -5
- package/dist/agent/copilot.js.map +1 -1
- package/dist/cli.js +44 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/compile.js +3 -0
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +115 -8
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/eval-dynamic.js +316 -0
- package/dist/commands/eval-dynamic.js.map +1 -0
- package/dist/commands/eval-scaffold.js +173 -0
- package/dist/commands/eval-scaffold.js.map +1 -0
- package/dist/commands/eval.js +184 -55
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/fix.js +52 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/update.js +182 -16
- package/dist/commands/update.js.map +1 -1
- package/dist/core/audit.js +269 -9
- package/dist/core/audit.js.map +1 -1
- package/dist/core/compile.js +5 -1
- package/dist/core/compile.js.map +1 -1
- package/dist/core/fix.js +108 -0
- package/dist/core/fix.js.map +1 -0
- package/dist/core/install.js +50 -4
- package/dist/core/install.js.map +1 -1
- package/dist/core/markers.js +85 -0
- package/dist/core/markers.js.map +1 -0
- package/dist/core/model-family.js +31 -0
- package/dist/core/model-family.js.map +1 -0
- package/dist/core/scenario-runner.js +298 -0
- package/dist/core/scenario-runner.js.map +1 -0
- package/dist/core/state.js +11 -0
- package/dist/core/state.js.map +1 -1
- package/dist/core/validate.js +129 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/prompts/index.js +121 -30
- package/dist/prompts/index.js.map +1 -1
- package/knowledge/PRINCIPLES.md +2 -2
- package/knowledge/manifest.json +16 -1
- package/knowledge/templates/AGENTS.md +8 -7
- package/knowledge/templates/agents/README.md +4 -4
- package/knowledge/templates/agents/developer.yml +1 -1
- package/knowledge/templates/agents/judge.yml +1 -1
- package/knowledge/templates/agents/reviewer.yml +1 -1
- package/knowledge/templates/agents/triager.yml +5 -4
- package/knowledge/templates/dashboard/dashboard.mjs +12 -5
- package/knowledge/templates/eval/RUBRIC.md +87 -64
- package/knowledge/templates/eval/axes.json +25 -25
- package/knowledge/templates/eval/calibration/README.md +54 -0
- package/knowledge/templates/eval/calibration/review/seed-correct.yml +43 -0
- package/knowledge/templates/eval/calibration/run/seed-correct.yml +35 -0
- package/knowledge/templates/eval/calibration/run/seed-no-verify.yml +34 -0
- package/knowledge/templates/eval/checks.json +92 -14
- package/knowledge/templates/eval/scenarios/add-small-feature/README.md +17 -0
- package/knowledge/templates/eval/scenarios/add-small-feature/fixture/SPEC.md +25 -0
- package/knowledge/templates/eval/scenarios/add-small-feature/fixture/package.json +9 -0
- package/knowledge/templates/eval/scenarios/add-small-feature/fixture/src/slugify.js +5 -0
- package/knowledge/templates/eval/scenarios/add-small-feature/fixture/tests/feature.test.js +31 -0
- package/knowledge/templates/eval/scenarios/add-small-feature/judge_brief.md +25 -0
- package/knowledge/templates/eval/scenarios/add-small-feature/oracle.yml +41 -0
- package/knowledge/templates/eval/scenarios/add-small-feature/prompt.md +17 -0
- package/knowledge/templates/eval/scenarios/add-small-feature/scenario.yml +22 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/README.md +18 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/fixture/package.json +9 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/fixture/src/math.js +13 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/fixture/tests/add.test.js +7 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/fixture/tests/divide.test.js +11 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/fixture/tests/multiply.test.js +7 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/judge_brief.md +20 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/oracle.yml +33 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/prompt.md +12 -0
- package/knowledge/templates/eval/scenarios/fix-failing-test/scenario.yml +23 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/README.md +17 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/fixture/baseline/package.json +6 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/fixture/baseline/src/format.js +4 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/fixture/baseline/src/pagination.js +7 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/fixture/change/src/format.js +6 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/fixture/change/src/pagination.js +7 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/judge_brief.md +38 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/oracle.yml +29 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/prompt.md +33 -0
- package/knowledge/templates/eval/scenarios/review-catches-bug/scenario.yml +23 -0
- package/knowledge/templates/eval/score.mjs +368 -42
- package/knowledge/templates/eval/static-audit.mjs +228 -17
- package/knowledge/templates/harness/state-machine.yml +18 -12
- package/knowledge/templates/skills/harness-eval/SKILL.md +59 -54
- package/knowledge/templates/skills/log-gotcha/SKILL.md +68 -0
- package/knowledge/templates/skills/self-verify/SKILL.md +32 -8
- package/package.json +4 -3
- package/knowledge/templates/eval/scenarios/README.md +0 -24
- package/knowledge/templates/eval/scenarios/add-small-feature.md +0 -28
- package/knowledge/templates/eval/scenarios/fix-failing-test.md +0 -27
- package/knowledge/templates/eval/scenarios/review-catches-bug.md +0 -30
package/dist/commands/update.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from "node:fs";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
-
import {
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
import { writeState, readState, lastReconciliationFor, } from "../core/state.js";
|
|
5
6
|
import { loadManifest, refreshPolicy } from "../core/knowledge.js";
|
|
6
7
|
import { install, baseVars, addOnlyCopy } from "../core/install.js";
|
|
7
8
|
import { linkSurfaces } from "../core/surfaces.js";
|
|
@@ -14,34 +15,115 @@ import { getProvider } from "../agent/index.js";
|
|
|
14
15
|
import { buildUpdatePrompt, SYSTEM_MESSAGE } from "../prompts/index.js";
|
|
15
16
|
import { renderAudit } from "./eval.js";
|
|
16
17
|
import { join } from "../core/fsutil.js";
|
|
18
|
+
import { populateAgentsMarkers } from "../core/markers.js";
|
|
19
|
+
import { runValidation } from "../core/validate.js";
|
|
20
|
+
import { autoFix } from "../core/fix.js";
|
|
17
21
|
import pkg from "../version.js";
|
|
18
22
|
function hashFile(path) {
|
|
19
23
|
if (!existsSync(path))
|
|
20
24
|
return null;
|
|
21
25
|
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
22
26
|
}
|
|
27
|
+
function classifyDrift(repoFile, canonicalFile, brokenPaths, relPath) {
|
|
28
|
+
if (brokenPaths.has(relPath)) {
|
|
29
|
+
return { path: relPath, severity: "broken", reason: "fails YAML/syntax validation" };
|
|
30
|
+
}
|
|
31
|
+
const local = readFileSync(repoFile, "utf8");
|
|
32
|
+
const canonical = readFileSync(canonicalFile, "utf8");
|
|
33
|
+
if (local.includes(canonical.trim())) {
|
|
34
|
+
return { path: relPath, severity: "enhancement", reason: "local is a strict superset of canonical" };
|
|
35
|
+
}
|
|
36
|
+
if (canonical.includes(local.trim())) {
|
|
37
|
+
return { path: relPath, severity: "stale", reason: "canonical is a strict superset of local" };
|
|
38
|
+
}
|
|
39
|
+
return { path: relPath, severity: "mixed", reason: "both diverged independently" };
|
|
40
|
+
}
|
|
41
|
+
function severityBadge(s) {
|
|
42
|
+
switch (s) {
|
|
43
|
+
case "broken": return color.red("🔴 broken");
|
|
44
|
+
case "stale": return color.yellow("🟡 stale");
|
|
45
|
+
case "enhancement": return color.green("🟢 enhancement");
|
|
46
|
+
case "mixed": return color.dim("⚪ mixed");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
23
49
|
/** Read-only: show how preserved (tailorable) files differ from the latest canonical version. */
|
|
24
50
|
function diffPreserved(repoRoot) {
|
|
25
51
|
const manifest = loadManifest();
|
|
52
|
+
const validation = runValidation(repoRoot);
|
|
53
|
+
const brokenPaths = new Set([...validation.yaml.map((y) => y.path)]);
|
|
26
54
|
const preserved = manifest.artifacts.filter((a) => a.kind !== "template" && refreshPolicy(a) === "preserve");
|
|
27
|
-
|
|
55
|
+
const classified = [];
|
|
56
|
+
const driftInfos = [];
|
|
28
57
|
for (const a of preserved) {
|
|
29
58
|
const { drifted } = addOnlyCopy(repoRoot, resolveSrc(a.src), join(repoRoot, a.dest), a.mode, false);
|
|
30
59
|
for (const relPath of drifted) {
|
|
31
|
-
any = true;
|
|
32
|
-
const repoFile = join(repoRoot, relPath);
|
|
33
|
-
// Map the drifted repo-relative path back to its canonical source file.
|
|
34
60
|
const sub = relPath.slice(a.dest.length).replace(/^\//, "");
|
|
35
61
|
const canonical = sub ? join(resolveSrc(a.src), sub) : resolveSrc(a.src);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
log.info(res.stdout ? res.stdout.trimEnd() : color.dim(" (binary or unreadable diff)"));
|
|
62
|
+
driftInfos.push({ rel: relPath, canonical });
|
|
63
|
+
classified.push(classifyDrift(join(repoRoot, relPath), canonical, brokenPaths, relPath));
|
|
39
64
|
}
|
|
40
65
|
}
|
|
41
|
-
if (
|
|
66
|
+
if (classified.length === 0) {
|
|
42
67
|
log.ok("no preserved files have drifted from canonical.");
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
// Summary first: counts per severity, then the unified diffs grouped by severity.
|
|
71
|
+
const counts = { broken: 0, stale: 0, enhancement: 0, mixed: 0 };
|
|
72
|
+
for (const c of classified)
|
|
73
|
+
counts[c.severity]++;
|
|
74
|
+
log.info(color.bold("Drift summary"));
|
|
75
|
+
log.info(` ${severityBadge("broken")}: ${counts.broken} ${severityBadge("stale")}: ${counts.stale} ${severityBadge("enhancement")}: ${counts.enhancement} ${severityBadge("mixed")}: ${counts.mixed}`);
|
|
76
|
+
log.info(color.dim(" 🔴 fails validation — run `agentrig fix` to restore from canonical."));
|
|
77
|
+
log.info(color.dim(" 🟡 canonical has new content your file lacks — review for merge."));
|
|
78
|
+
log.info(color.dim(" 🟢 your file is a superset of canonical — likely safe to keep."));
|
|
79
|
+
log.info(color.dim(" ⚪ both diverged independently — needs reconciliation."));
|
|
80
|
+
const order = ["broken", "stale", "mixed", "enhancement"];
|
|
81
|
+
for (const sev of order) {
|
|
82
|
+
const group = classified.filter((c) => c.severity === sev);
|
|
83
|
+
if (!group.length)
|
|
84
|
+
continue;
|
|
85
|
+
log.info("");
|
|
86
|
+
log.info(color.bold(`${severityBadge(sev)} (${group.length})`));
|
|
87
|
+
for (const c of group) {
|
|
88
|
+
const info = driftInfos.find((d) => d.rel === c.path);
|
|
89
|
+
const repoFile = join(repoRoot, c.path);
|
|
90
|
+
log.info(color.bold(`\n• ${c.path}`) + color.dim(` — ${c.reason}`));
|
|
91
|
+
const res = spawnSync("diff", ["-u", "--label", "canonical", info.canonical, "--label", c.path, repoFile], { encoding: "utf8" });
|
|
92
|
+
log.info(res.stdout ? res.stdout.trimEnd() : color.dim(" (binary or unreadable diff)"));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
43
95
|
return 0;
|
|
44
96
|
}
|
|
97
|
+
/** Group a list of repo-relative paths by parent directory for readable enumeration. */
|
|
98
|
+
function groupByDir(paths) {
|
|
99
|
+
const out = new Map();
|
|
100
|
+
for (const p of paths.sort()) {
|
|
101
|
+
const dir = dirname(p) || ".";
|
|
102
|
+
const list = out.get(dir) ?? [];
|
|
103
|
+
list.push(p);
|
|
104
|
+
out.set(dir, list);
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
/** Print `count file(s)` with parent-dir grouping when there are more than a handful. */
|
|
109
|
+
function logFileList(label, paths) {
|
|
110
|
+
if (paths.length === 0)
|
|
111
|
+
return;
|
|
112
|
+
if (paths.length <= 6) {
|
|
113
|
+
log.info(color.dim(` ${label}:`));
|
|
114
|
+
for (const p of paths)
|
|
115
|
+
log.info(color.dim(` · ${p}`));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
log.info(color.dim(` ${label} (grouped):`));
|
|
119
|
+
for (const [dir, list] of groupByDir(paths)) {
|
|
120
|
+
log.info(color.dim(` · ${dir}/ (${list.length})`));
|
|
121
|
+
for (const p of list.slice(0, 3))
|
|
122
|
+
log.info(color.dim(` ${p}`));
|
|
123
|
+
if (list.length > 3)
|
|
124
|
+
log.info(color.dim(` … and ${list.length - 3} more`));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
45
127
|
/**
|
|
46
128
|
* Re-sync the latest canonical best practices into a repo. Machinery files are overwritten;
|
|
47
129
|
* tailorable artifacts are refreshed add-only (new files added, existing ones preserved) with any
|
|
@@ -94,13 +176,11 @@ export async function updateCommand(repoRoot, options) {
|
|
|
94
176
|
}
|
|
95
177
|
if (added.length) {
|
|
96
178
|
log.step("dry run — would add new files:");
|
|
97
|
-
|
|
98
|
-
log.info(` ${f}`);
|
|
179
|
+
logFileList("new", added);
|
|
99
180
|
}
|
|
100
181
|
if (drifted.length) {
|
|
101
182
|
log.step("dry run — preserved (local edits kept); agent would reconcile canonical drift:");
|
|
102
|
-
|
|
103
|
-
log.info(color.dim(` ${f}`));
|
|
183
|
+
logFileList("preserved", drifted);
|
|
104
184
|
}
|
|
105
185
|
log.step("dry run — agent would reconcile templates:");
|
|
106
186
|
for (const t of templates)
|
|
@@ -112,15 +192,32 @@ export async function updateCommand(repoRoot, options) {
|
|
|
112
192
|
const onlyOverwrite = { ...manifest, artifacts: toOverwrite };
|
|
113
193
|
const { installed } = install(repoRoot, onlyOverwrite, { vars: baseVars(repoRoot), preserve: false });
|
|
114
194
|
log.ok(`overwrote ${installed.length} owned file(s); added ${added.length} new file(s); preserved ${drifted.length} edited file(s)`);
|
|
195
|
+
logFileList("added", added);
|
|
196
|
+
if (drifted.length)
|
|
197
|
+
logFileList("preserved (canonical drifted)", drifted);
|
|
115
198
|
// Ensure vendor-surface symlinks exist (added in later knowledge versions).
|
|
116
199
|
const surfaces = linkSurfaces(repoRoot);
|
|
117
200
|
if (surfaces.created.length)
|
|
118
201
|
log.ok(`linked surfaces: ${surfaces.created.join(", ")} → .agents`);
|
|
202
|
+
// Repopulate deterministic marker blocks in AGENTS.md BEFORE compile — `compile` does this too
|
|
203
|
+
// but reading from a fresh skills inventory here guarantees the downstream projections see it
|
|
204
|
+
// even when AGENTS.md was a preserved (drifted) file and compile's projection picks up the
|
|
205
|
+
// marker-refreshed body.
|
|
206
|
+
const markerReport = populateAgentsMarkers(repoRoot);
|
|
207
|
+
if (markerReport.updated.length) {
|
|
208
|
+
log.ok(`AGENTS.md: refreshed marker block${markerReport.updated.length === 1 ? "" : "s"} — ${markerReport.updated.join(", ")}`);
|
|
209
|
+
}
|
|
119
210
|
// Re-project the canonical source into every agent surface (local + remote).
|
|
120
211
|
const compiled = compileSurfaces(repoRoot);
|
|
121
212
|
log.ok(`compiled ${compiled.generated.length} agent-surface file(s)`);
|
|
122
|
-
// The agent reconciles templates plus any preserved files whose canonical version drifted
|
|
123
|
-
|
|
213
|
+
// The agent reconciles templates plus any preserved files whose canonical version drifted —
|
|
214
|
+
// but skip files the user has already consciously diverged on AGAINST the same canonical hash.
|
|
215
|
+
const reconcileNeeded = drifted.filter((rel) => !alreadyDivergedOn(repoRoot, state, rel, refreshable));
|
|
216
|
+
const skippedFromReconcile = drifted.filter((rel) => alreadyDivergedOn(repoRoot, state, rel, refreshable));
|
|
217
|
+
if (skippedFromReconcile.length) {
|
|
218
|
+
log.info(color.dim(` skipping ${skippedFromReconcile.length} file(s) you previously chose to keep local; canonical hasn't changed since then.`));
|
|
219
|
+
}
|
|
220
|
+
const reconcileList = [...reconcileNeeded, ...templates];
|
|
124
221
|
if (!options.skipAgent) {
|
|
125
222
|
const provider = getProvider();
|
|
126
223
|
const pre = await provider.preflight();
|
|
@@ -151,21 +248,60 @@ export async function updateCommand(repoRoot, options) {
|
|
|
151
248
|
}
|
|
152
249
|
}
|
|
153
250
|
else if (drifted.length) {
|
|
154
|
-
log.warn(`--skip-agent: ${drifted.length} edited file(s) were preserved; canonical updates to them were NOT applied
|
|
251
|
+
log.warn(`--skip-agent: ${drifted.length} edited file(s) were preserved; canonical updates to them were NOT applied:`);
|
|
252
|
+
logFileList("not reconciled", drifted);
|
|
155
253
|
log.warn("Run `agentrig update` (with the agent) to reconcile them, or diff against the templates manually.");
|
|
156
254
|
}
|
|
255
|
+
// Validate the refreshed install. Hard failures (broken YAML, unknown model id) are fatal
|
|
256
|
+
// unless --auto-fix was passed, in which case we self-heal here.
|
|
257
|
+
const validation = runValidation(repoRoot);
|
|
258
|
+
if (validation.hasBlockers) {
|
|
259
|
+
log.info("");
|
|
260
|
+
if (options.autoFix) {
|
|
261
|
+
log.step("validation found blockers; --auto-fix applying deterministic repairs…");
|
|
262
|
+
const fix = autoFix(repoRoot, { yamlFindings: validation.yaml, modelFindings: validation.models });
|
|
263
|
+
for (const a of fix.actions)
|
|
264
|
+
log.ok(`${a.path}: ${a.description}`);
|
|
265
|
+
for (const u of fix.unresolved)
|
|
266
|
+
log.warn(`unresolved: ${u.path} — ${u.reason}`);
|
|
267
|
+
if (fix.unresolved.length) {
|
|
268
|
+
log.error("auto-fix could not resolve every blocker; aborting.");
|
|
269
|
+
return 1;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
for (const y of validation.yaml)
|
|
274
|
+
log.error(`${y.path}: invalid YAML — ${y.error.split("\n")[0]}`);
|
|
275
|
+
for (const m of validation.models) {
|
|
276
|
+
const hint = m.suggestions.length ? `; did you mean ${m.suggestions.join(", ")}?` : "";
|
|
277
|
+
log.error(`${m.path}: unknown model "${m.value}"${hint}`);
|
|
278
|
+
}
|
|
279
|
+
log.error("Refusing to leave a broken install in place. Re-run with --auto-fix to repair from canonical, or `agentrig fix`.");
|
|
280
|
+
return 1;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
157
283
|
// Merge installed records: every refreshable artifact is present/current after update.
|
|
284
|
+
// Also append reconciliation records for every drifted file so a future update can know
|
|
285
|
+
// the user consciously chose to keep this version.
|
|
158
286
|
const now = new Date().toISOString();
|
|
159
287
|
const byId = new Map(state.installed.map((i) => [i.id, i]));
|
|
160
288
|
for (const a of refreshable) {
|
|
161
289
|
byId.set(a.id, { id: a.id, dest: a.dest, knowledgeVersion: manifest.knowledgeVersion, installedAt: now });
|
|
162
290
|
}
|
|
291
|
+
const newReconciliations = drifted.map((rel) => ({
|
|
292
|
+
dest: rel,
|
|
293
|
+
knowledgeVersion: manifest.knowledgeVersion,
|
|
294
|
+
decision: "kept-local",
|
|
295
|
+
canonicalHash: canonicalHashFor(rel, refreshable) ?? "",
|
|
296
|
+
decidedAt: now,
|
|
297
|
+
}));
|
|
163
298
|
const newState = {
|
|
164
299
|
...state,
|
|
165
300
|
agentrigVersion: pkg.version,
|
|
166
301
|
knowledgeVersion: manifest.knowledgeVersion,
|
|
167
302
|
updatedAt: now,
|
|
168
303
|
installed: [...byId.values()],
|
|
304
|
+
reconciled: [...(state.reconciled ?? []), ...newReconciliations],
|
|
169
305
|
};
|
|
170
306
|
writeState(repoRoot, newState);
|
|
171
307
|
log.ok("updated .agentrig/state.json");
|
|
@@ -173,4 +309,34 @@ export async function updateCommand(repoRoot, options) {
|
|
|
173
309
|
renderAudit(auditHarness(repoRoot));
|
|
174
310
|
return 0;
|
|
175
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Resolve the canonical source path for a repo-relative drifted file by scanning the manifest.
|
|
314
|
+
* Returns null when no canonical match exists (e.g. user-added file under a managed dir).
|
|
315
|
+
*/
|
|
316
|
+
function canonicalPathFor(rel, artifacts) {
|
|
317
|
+
for (const a of artifacts) {
|
|
318
|
+
if (a.dest === rel)
|
|
319
|
+
return resolveSrc(a.src);
|
|
320
|
+
if (a.kind === "dir" && rel.startsWith(`${a.dest}/`)) {
|
|
321
|
+
const sub = rel.slice(a.dest.length).replace(/^\//, "");
|
|
322
|
+
return join(resolveSrc(a.src), sub);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
function canonicalHashFor(rel, artifacts) {
|
|
328
|
+
const p = canonicalPathFor(rel, artifacts);
|
|
329
|
+
return p ? hashFile(p) : null;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* True when the user has previously chosen to keep their local copy of this file AND canonical
|
|
333
|
+
* hasn't changed since that decision. In that case we skip re-prompting on the next update.
|
|
334
|
+
*/
|
|
335
|
+
function alreadyDivergedOn(_repoRoot, state, rel, artifacts) {
|
|
336
|
+
const record = lastReconciliationFor(state, rel);
|
|
337
|
+
if (!record || record.decision !== "kept-local")
|
|
338
|
+
return false;
|
|
339
|
+
const currentCanonical = canonicalHashFor(rel, artifacts);
|
|
340
|
+
return Boolean(currentCanonical) && currentCanonical === record.canonicalHash;
|
|
341
|
+
}
|
|
176
342
|
//# sourceMappingURL=update.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAsB,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,GAAG,MAAM,eAAe,CAAC;AAUhC,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AAED,iGAAiG;AACjG,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC;IAC7G,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpG,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;YAC9B,GAAG,GAAG,IAAI,CAAC;YACX,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACzC,wEAAwE;YACxE,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACzE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC;YACvF,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YAC7H,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAG;QAAE,GAAG,CAAC,EAAE,CAAC,iDAAiD,CAAC,CAAC;IACpE,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,OAAsB;IAC1E,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAClE,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;QAC3E,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,WAAW,GAAG,KAAK,CAAC,gBAAgB,KAAK,QAAQ,CAAC,gBAAgB,CAAC;IACzE,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAC5E,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE7F,kGAAkG;IAClG,4EAA4E;IAC5E,MAAM,WAAW,GAAuB,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,EAAE,CAAC;QAC5E,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACrB,IAAI,WAAW;gBAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC5E,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,4FAA4F;IAC5F,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,EAAE,CAAC;QAC3E,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACpG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,KAAK,CAAC,gBAAgB,MAAM,QAAQ,CAAC,gBAAgB,KAAK,CAAC,CAAC,CAAC;IAE3H,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3F,GAAG,CAAC,EAAE,CAAC,0CAA0C,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvB,GAAG,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YACxD,KAAK,MAAM,CAAC,IAAI,WAAW;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAC3C,KAAK,MAAM,CAAC,IAAI,KAAK;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;YAC3F,KAAK,MAAM,CAAC,IAAI,OAAO;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QACvD,KAAK,MAAM,CAAC,IAAI,SAAS;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,oFAAoF;IACpF,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChC,MAAM,aAAa,GAAG,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;IAC9D,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACtG,GAAG,CAAC,EAAE,CAAC,aAAa,SAAS,CAAC,MAAM,yBAAyB,KAAK,CAAC,MAAM,2BAA2B,OAAO,CAAC,MAAM,iBAAiB,CAAC,CAAC;IAErI,4EAA4E;IAC5E,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM;QAAE,GAAG,CAAC,EAAE,CAAC,oBAAoB,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEjG,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC3C,GAAG,CAAC,EAAE,CAAC,YAAY,QAAQ,CAAC,SAAS,CAAC,MAAM,wBAAwB,CAAC,CAAC;IAEtE,2FAA2F;IAC3F,MAAM,aAAa,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,GAAG,CAAC,EAAE,CAAC,gBAAgB,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YACtC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC,KAAK,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,iBAAiB,CAAC;gBAC7C,GAAG,EAAE,QAAQ;gBACb,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,aAAa,EAAE,cAAc;gBAC7B,OAAO,EAAE,OAAO,CAAC,MAAM;aACxB,CAAC,CAAC;YACH,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC;gBACnE,OAAO,CAAC,IAAI,EAAE,CAAC;gBACf,GAAG,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC;gBAClC,IAAI,OAAO,CAAC,OAAO;oBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACpD,CAAC;oBAAS,CAAC;gBACT,OAAO,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,KAAK,CAAC,GAAG,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,sBAAsB,GAAG,CAAC,MAAM,4BAA4B,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,IAAI,CAAC,iBAAiB,OAAO,CAAC,MAAM,6EAA6E,CAAC,CAAC;QACvH,GAAG,CAAC,IAAI,CAAC,mGAAmG,CAAC,CAAC;IAChH,CAAC;IAED,uFAAuF;IACvF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5G,CAAC;IACD,MAAM,QAAQ,GAAkB;QAC9B,GAAG,KAAK;QACR,eAAe,EAAE,GAAG,CAAC,OAAO;QAC5B,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;QAC3C,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;KAC9B,CAAC;IACF,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,GAAG,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC;IAEvC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACb,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,SAAS,EACT,qBAAqB,GAGtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,GAAG,MAAM,eAAe,CAAC;AAWhC,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AAmBD,SAAS,aAAa,CAAC,QAAgB,EAAE,aAAqB,EAAE,WAAwB,EAAE,OAAe;IACvG,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;IACvF,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,yCAAyC,EAAE,CAAC;IACvG,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,yCAAyC,EAAE,CAAC;IACjG,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC;AACrF,CAAC;AAED,SAAS,aAAa,CAAC,CAAgB;IACrC,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC7C,KAAK,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC9C,KAAK,aAAa,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACzD,KAAK,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC;IAC7G,MAAM,UAAU,GAAsB,EAAE,CAAC;IACzC,MAAM,UAAU,GAAyC,EAAE,CAAC;IAC5D,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpG,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACzE,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;YAC7C,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,GAAG,CAAC,EAAE,CAAC,iDAAiD,CAAC,CAAC;QAC1D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,kFAAkF;IAClF,MAAM,MAAM,GAAkC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAChG,KAAK,MAAM,CAAC,IAAI,UAAU;QAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;IACjD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACtC,GAAG,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,MAAM,MAAM,aAAa,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,KAAK,MAAM,aAAa,CAAC,aAAa,CAAC,KAAK,MAAM,CAAC,WAAW,MAAM,aAAa,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9M,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC,CAAC;IAC7F,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC,CAAC;IAC1F,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC,CAAC;IACxF,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC,CAAC;IAE/E,MAAM,KAAK,GAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAC3E,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,SAAS;QAC5B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAChE,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAE,CAAC;YACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YACxC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACrE,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACjI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,wFAAwF;AACxF,SAAS,UAAU,CAAC,KAAe;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACb,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,yFAAyF;AACzF,SAAS,WAAW,CAAC,KAAa,EAAE,KAAe;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACtB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,KAAK;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,GAAG,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QACtE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACpF,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,OAAsB;IAC1E,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAClE,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;QAC3E,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,WAAW,GAAG,KAAK,CAAC,gBAAgB,KAAK,QAAQ,CAAC,gBAAgB,CAAC;IACzE,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAC5E,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE7F,kGAAkG;IAClG,4EAA4E;IAC5E,MAAM,WAAW,GAAuB,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,EAAE,CAAC;QAC5E,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACrB,IAAI,WAAW;gBAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC5E,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,4FAA4F;IAC5F,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,EAAE,CAAC;QAC3E,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACpG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,KAAK,CAAC,gBAAgB,MAAM,QAAQ,CAAC,gBAAgB,KAAK,CAAC,CAAC,CAAC;IAE3H,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3F,GAAG,CAAC,EAAE,CAAC,0CAA0C,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvB,GAAG,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YACxD,KAAK,MAAM,CAAC,IAAI,WAAW;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAC3C,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;YAC3F,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACpC,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QACvD,KAAK,MAAM,CAAC,IAAI,SAAS;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,oFAAoF;IACpF,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChC,MAAM,aAAa,GAAG,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;IAC9D,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACtG,GAAG,CAAC,EAAE,CAAC,aAAa,SAAS,CAAC,MAAM,yBAAyB,KAAK,CAAC,MAAM,2BAA2B,OAAO,CAAC,MAAM,iBAAiB,CAAC,CAAC;IACrI,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5B,IAAI,OAAO,CAAC,MAAM;QAAE,WAAW,CAAC,+BAA+B,EAAE,OAAO,CAAC,CAAC;IAE1E,4EAA4E;IAC5E,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM;QAAE,GAAG,CAAC,EAAE,CAAC,oBAAoB,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEjG,+FAA+F;IAC/F,8FAA8F;IAC9F,2FAA2F;IAC3F,yBAAyB;IACzB,MAAM,YAAY,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAChC,GAAG,CAAC,EAAE,CAAC,oCAAoC,YAAY,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClI,CAAC;IAED,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC3C,GAAG,CAAC,EAAE,CAAC,YAAY,QAAQ,CAAC,SAAS,CAAC,MAAM,wBAAwB,CAAC,CAAC;IAEtE,4FAA4F;IAC5F,+FAA+F;IAC/F,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IACvG,MAAM,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IAC3G,IAAI,oBAAoB,CAAC,MAAM,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,oBAAoB,CAAC,MAAM,mFAAmF,CAAC,CAAC,CAAC;IACpJ,CAAC;IACD,MAAM,aAAa,GAAG,CAAC,GAAG,eAAe,EAAE,GAAG,SAAS,CAAC,CAAC;IACzD,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,GAAG,CAAC,EAAE,CAAC,gBAAgB,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YACtC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC,KAAK,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,iBAAiB,CAAC;gBAC7C,GAAG,EAAE,QAAQ;gBACb,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,aAAa,EAAE,cAAc;gBAC7B,OAAO,EAAE,OAAO,CAAC,MAAM;aACxB,CAAC,CAAC;YACH,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC;gBACnE,OAAO,CAAC,IAAI,EAAE,CAAC;gBACf,GAAG,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC;gBAClC,IAAI,OAAO,CAAC,OAAO;oBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACpD,CAAC;oBAAS,CAAC;gBACT,OAAO,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,KAAK,CAAC,GAAG,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,sBAAsB,GAAG,CAAC,MAAM,4BAA4B,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,IAAI,CAAC,iBAAiB,OAAO,CAAC,MAAM,6EAA6E,CAAC,CAAC;QACvH,WAAW,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,mGAAmG,CAAC,CAAC;IAChH,CAAC;IAED,0FAA0F;IAC1F,iEAAiE;IACjE,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,GAAG,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;YAClF,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YACnG,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO;gBAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACnE,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,UAAU;gBAAE,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YAChF,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;gBAC1B,GAAG,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;gBACjE,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI;gBAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClG,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvF,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,GAAG,CAAC,KAAK,CAAC,kHAAkH,CAAC,CAAC;YAC9H,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,uFAAuF;IACvF,wFAAwF;IACxF,mDAAmD;IACnD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5G,CAAC;IACD,MAAM,kBAAkB,GAAuB,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnE,IAAI,EAAE,GAAG;QACT,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;QAC3C,QAAQ,EAAE,YAAY;QACtB,aAAa,EAAE,gBAAgB,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE;QACvD,SAAS,EAAE,GAAG;KACf,CAAC,CAAC,CAAC;IACJ,MAAM,QAAQ,GAAkB;QAC9B,GAAG,KAAK;QACR,eAAe,EAAE,GAAG,CAAC,OAAO;QAC5B,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;QAC3C,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,kBAAkB,CAAC;KACjE,CAAC;IACF,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,GAAG,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC;IAEvC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACb,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,GAAW,EAAE,SAAuD;IAC5F,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG;YAAE,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACxD,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,SAAuD;IAC5F,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC3C,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CACxB,SAAiB,EACjB,KAAoB,EACpB,GAAW,EACX,SAAuD;IAEvD,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,YAAY;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC1D,OAAO,OAAO,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,KAAK,MAAM,CAAC,aAAa,CAAC;AAChF,CAAC"}
|
package/dist/core/audit.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { existsSync, statSync, readdirSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
+
import YAML from "yaml";
|
|
3
4
|
import { readText } from "./fsutil.js";
|
|
4
5
|
import { loadCanonicalChecks } from "./knowledge.js";
|
|
6
|
+
import { sameFamily } from "./model-family.js";
|
|
5
7
|
function frontmatter(text) {
|
|
6
8
|
if (!text || !text.startsWith("---"))
|
|
7
9
|
return null;
|
|
@@ -53,7 +55,43 @@ function scoreCheck(repoRoot, c) {
|
|
|
53
55
|
? { score: 1, evidence: "" }
|
|
54
56
|
: { score: 0.5, evidence: `missing keys: ${missing.join(", ")}` };
|
|
55
57
|
}
|
|
58
|
+
case "frontmatter-keys-all": {
|
|
59
|
+
// Walk every <dir>/<entry>/<file> and assert each has the required frontmatter keys.
|
|
60
|
+
// Catches the gap where today only one skill (self-verify) is spot-checked.
|
|
61
|
+
const dir = String(c.path);
|
|
62
|
+
const fileName = String(c.file ?? "SKILL.md");
|
|
63
|
+
const abs = rel(dir);
|
|
64
|
+
if (!existsSync(abs) || !statSync(abs).isDirectory()) {
|
|
65
|
+
return { score: 0, evidence: `missing dir ${dir}` };
|
|
66
|
+
}
|
|
67
|
+
const keys = c.keys ?? [];
|
|
68
|
+
const offenders = [];
|
|
69
|
+
for (const entry of readdirSync(abs)) {
|
|
70
|
+
if (entry.startsWith(".") || entry.startsWith("_"))
|
|
71
|
+
continue;
|
|
72
|
+
const subAbs = join(abs, entry);
|
|
73
|
+
if (!statSync(subAbs).isDirectory())
|
|
74
|
+
continue;
|
|
75
|
+
const filePath = join(subAbs, fileName);
|
|
76
|
+
if (!existsSync(filePath)) {
|
|
77
|
+
offenders.push(`${entry}/${fileName} missing`);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const fm = frontmatter(readText(filePath));
|
|
81
|
+
if (fm == null) {
|
|
82
|
+
offenders.push(`${entry} no frontmatter`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const missing = keys.filter((k) => !new RegExp("^\\s*" + k + "\\s*:", "m").test(fm));
|
|
86
|
+
if (missing.length)
|
|
87
|
+
offenders.push(`${entry} missing ${missing.join("/")}`);
|
|
88
|
+
}
|
|
89
|
+
if (offenders.length === 0)
|
|
90
|
+
return { score: 1, evidence: "" };
|
|
91
|
+
return { score: 0.5, evidence: offenders.join("; ") };
|
|
92
|
+
}
|
|
56
93
|
case "roles-distinct-models": {
|
|
94
|
+
// Legacy: kept for back-compat. Prefer roles-distinct-families.
|
|
57
95
|
const key = String(c.key ?? "model");
|
|
58
96
|
const dev = extractValue(read(String(c.developer)), key);
|
|
59
97
|
const rev = extractValue(read(String(c.reviewer)), key);
|
|
@@ -63,10 +101,220 @@ function scoreCheck(repoRoot, c) {
|
|
|
63
101
|
? { score: 1, evidence: "" }
|
|
64
102
|
: { score: 0.5, evidence: `developer and reviewer share model "${dev}"` };
|
|
65
103
|
}
|
|
104
|
+
case "roles-distinct-families": {
|
|
105
|
+
// The single-model-bias mitigation principle is about model FAMILIES, not exact ids.
|
|
106
|
+
// claude-sonnet-4.5 vs claude-sonnet-4.6 must FAIL here.
|
|
107
|
+
const key = String(c.key ?? "model");
|
|
108
|
+
const dev = extractValue(read(String(c.developer)), key);
|
|
109
|
+
const rev = extractValue(read(String(c.reviewer)), key);
|
|
110
|
+
if (!dev || !rev)
|
|
111
|
+
return { score: 0, evidence: "developer/reviewer model not declared" };
|
|
112
|
+
if (!sameFamily(dev, rev))
|
|
113
|
+
return { score: 1, evidence: "" };
|
|
114
|
+
return { score: 0, evidence: `developer "${dev}" and reviewer "${rev}" share a model family` };
|
|
115
|
+
}
|
|
116
|
+
case "state-machine-dag": {
|
|
117
|
+
// Structural: parse the state machine YAML and assert it actually IS a DAG with
|
|
118
|
+
// the minimum lifecycle present, instead of just substring-matching "states:".
|
|
119
|
+
const p = String(c.path);
|
|
120
|
+
const text = read(p);
|
|
121
|
+
if (text == null)
|
|
122
|
+
return { score: 0, evidence: `missing ${p}` };
|
|
123
|
+
let parsed;
|
|
124
|
+
try {
|
|
125
|
+
parsed = YAML.parse(text);
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
return { score: 0, evidence: `${p} is not valid YAML: ${e.message}` };
|
|
129
|
+
}
|
|
130
|
+
const states = Array.isArray(parsed?.states) ? parsed.states : [];
|
|
131
|
+
const transitions = Array.isArray(parsed?.transitions) ? parsed.transitions : [];
|
|
132
|
+
const minStates = Number(c.minStates ?? 6);
|
|
133
|
+
const requirePath = String(c.requirePath ?? "queued->merged");
|
|
134
|
+
const problems = [];
|
|
135
|
+
if (states.length < minStates)
|
|
136
|
+
problems.push(`${states.length} states, need ≥${minStates}`);
|
|
137
|
+
const stateNames = new Set(states.map((s) => String(s?.name ?? "")).filter(Boolean));
|
|
138
|
+
const badTransitions = transitions.filter((t) => !t?.from || !t?.to || !t?.trigger);
|
|
139
|
+
if (badTransitions.length)
|
|
140
|
+
problems.push(`${badTransitions.length} transitions missing from/to/trigger`);
|
|
141
|
+
// BFS for the required path. The 'any' wildcard from-state acts as a universal source.
|
|
142
|
+
const [src, dst] = requirePath.split("->");
|
|
143
|
+
if (src && dst) {
|
|
144
|
+
const adj = new Map();
|
|
145
|
+
for (const t of transitions) {
|
|
146
|
+
const from = String(t?.from ?? "");
|
|
147
|
+
const to = String(t?.to ?? "");
|
|
148
|
+
if (!from || !to)
|
|
149
|
+
continue;
|
|
150
|
+
if (from === "any") {
|
|
151
|
+
for (const s of stateNames) {
|
|
152
|
+
if (!adj.has(s))
|
|
153
|
+
adj.set(s, new Set());
|
|
154
|
+
adj.get(s).add(to);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
if (!adj.has(from))
|
|
159
|
+
adj.set(from, new Set());
|
|
160
|
+
adj.get(from).add(to);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (!hasPath(adj, src, dst))
|
|
164
|
+
problems.push(`no path ${src}→${dst}`);
|
|
165
|
+
}
|
|
166
|
+
if (problems.length === 0)
|
|
167
|
+
return { score: 1, evidence: "" };
|
|
168
|
+
return { score: 0.5, evidence: problems.join("; ") };
|
|
169
|
+
}
|
|
170
|
+
case "quality-probe": {
|
|
171
|
+
// A handful of cheap content sanity checks (P1.4). Each probe has a `probe` kind.
|
|
172
|
+
const probe = String(c.probe ?? "");
|
|
173
|
+
const p = String(c.path ?? "");
|
|
174
|
+
switch (probe) {
|
|
175
|
+
case "no-unfilled-placeholders": {
|
|
176
|
+
const text = read(p);
|
|
177
|
+
if (text == null)
|
|
178
|
+
return { score: 0, evidence: `missing ${p}` };
|
|
179
|
+
// Strip ```code blocks``` and `inline code` before scanning, so the probe doesn't
|
|
180
|
+
// false-positive on docs that *describe* placeholder syntax (e.g. "{{VAR}} substitution").
|
|
181
|
+
const stripped = text
|
|
182
|
+
.replace(/```[\s\S]*?```/g, "")
|
|
183
|
+
.replace(/`[^`\n]*`/g, "");
|
|
184
|
+
const tokens = stripped.match(/\{\{[A-Z_]+\}\}/g) ?? [];
|
|
185
|
+
return tokens.length === 0
|
|
186
|
+
? { score: 1, evidence: "" }
|
|
187
|
+
: { score: 0, evidence: `unfilled tokens in ${p}: ${[...new Set(tokens)].join(", ")}` };
|
|
188
|
+
}
|
|
189
|
+
case "axes-json-coherent": {
|
|
190
|
+
const text = read(p);
|
|
191
|
+
if (text == null)
|
|
192
|
+
return { score: 0, evidence: `missing ${p}` };
|
|
193
|
+
let j;
|
|
194
|
+
try {
|
|
195
|
+
j = JSON.parse(text);
|
|
196
|
+
}
|
|
197
|
+
catch (e) {
|
|
198
|
+
return { score: 0, evidence: `${p} not valid JSON: ${e.message}` };
|
|
199
|
+
}
|
|
200
|
+
if (!j?.types)
|
|
201
|
+
return { score: 0, evidence: `${p} missing "types"` };
|
|
202
|
+
const issues = [];
|
|
203
|
+
for (const [tname, t] of Object.entries(j.types)) {
|
|
204
|
+
if (!t?.categories) {
|
|
205
|
+
issues.push(`${tname}: no categories`);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
for (const [cname, cat] of Object.entries(t.categories)) {
|
|
209
|
+
for (const [axis, spec] of Object.entries(cat)) {
|
|
210
|
+
// Both shapes: v1 = ["CODE",...]; v2 = { codes: [...], weight, veto }
|
|
211
|
+
const codes = Array.isArray(spec) ? spec : spec?.codes;
|
|
212
|
+
if (!Array.isArray(codes) || codes.length === 0) {
|
|
213
|
+
issues.push(`${tname}/${cname}/${axis}: no issue codes`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return issues.length === 0
|
|
219
|
+
? { score: 1, evidence: "" }
|
|
220
|
+
: { score: 0.5, evidence: issues.join("; ") };
|
|
221
|
+
}
|
|
222
|
+
case "checks-json-coherent": {
|
|
223
|
+
const text = read(p);
|
|
224
|
+
if (text == null)
|
|
225
|
+
return { score: 0, evidence: `missing ${p}` };
|
|
226
|
+
let j;
|
|
227
|
+
try {
|
|
228
|
+
j = JSON.parse(text);
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
return { score: 0, evidence: `${p} not valid JSON: ${e.message}` };
|
|
232
|
+
}
|
|
233
|
+
const checks = j?.checks ?? [];
|
|
234
|
+
const knownTypes = new Set([
|
|
235
|
+
"path-exists", "file-contains", "dir-min", "frontmatter-keys",
|
|
236
|
+
"frontmatter-keys-all", "roles-distinct-models", "roles-distinct-families",
|
|
237
|
+
"state-machine-dag", "quality-probe", "marker-populated",
|
|
238
|
+
]);
|
|
239
|
+
const ids = checks.map((x) => x?.id ?? "");
|
|
240
|
+
const dupIds = ids.filter((id, i) => id && ids.indexOf(id) !== i);
|
|
241
|
+
const badTypes = checks.filter((x) => !knownTypes.has(String(x?.type ?? "")));
|
|
242
|
+
const issues = [];
|
|
243
|
+
if (dupIds.length)
|
|
244
|
+
issues.push(`duplicate ids: ${[...new Set(dupIds)].join(", ")}`);
|
|
245
|
+
if (badTypes.length)
|
|
246
|
+
issues.push(`unknown check types: ${badTypes.map((x) => x?.type).join(", ")}`);
|
|
247
|
+
return issues.length === 0
|
|
248
|
+
? { score: 1, evidence: "" }
|
|
249
|
+
: { score: 0.5, evidence: issues.join("; ") };
|
|
250
|
+
}
|
|
251
|
+
case "context-md-present": {
|
|
252
|
+
return existsSync(rel(p))
|
|
253
|
+
? { score: 1, evidence: "" }
|
|
254
|
+
: { score: 0.5, evidence: `${p} missing — run \`agentrig init\` to investigate the repo` };
|
|
255
|
+
}
|
|
256
|
+
default:
|
|
257
|
+
return { score: 0, evidence: `unknown quality probe "${probe}"` };
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
case "marker-populated": {
|
|
261
|
+
// Assert that an AGENTRIG:<name>:start/end block in AGENTS.md is non-empty AND, when a
|
|
262
|
+
// `enumerateDir` is supplied, mentions every entry under that directory. Catches the
|
|
263
|
+
// failure mode where the marker pair exists but nothing populates the body.
|
|
264
|
+
const p = String(c.path);
|
|
265
|
+
const name = String(c.marker ?? "");
|
|
266
|
+
const text = read(p);
|
|
267
|
+
if (text == null)
|
|
268
|
+
return { score: 0, evidence: `missing ${p}` };
|
|
269
|
+
const pair = new RegExp(`<!--\\s*AGENTRIG:${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:start\\s*-->([\\s\\S]*?)<!--\\s*AGENTRIG:${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:end\\s*-->`);
|
|
270
|
+
const m = text.match(pair);
|
|
271
|
+
if (!m)
|
|
272
|
+
return { score: 0, evidence: `marker pair AGENTRIG:${name} missing from ${p}` };
|
|
273
|
+
const body = m[1].trim();
|
|
274
|
+
if (!body || /\{\{[A-Z_]+\}\}/.test(body)) {
|
|
275
|
+
return { score: 0, evidence: `AGENTRIG:${name} block is empty or has unfilled placeholders` };
|
|
276
|
+
}
|
|
277
|
+
const enumerateDir = c.enumerateDir ? String(c.enumerateDir) : null;
|
|
278
|
+
if (enumerateDir) {
|
|
279
|
+
const abs = rel(enumerateDir);
|
|
280
|
+
if (!existsSync(abs) || !statSync(abs).isDirectory()) {
|
|
281
|
+
// Nothing to enumerate — body just needs to be non-empty, which we already checked.
|
|
282
|
+
return { score: 1, evidence: "" };
|
|
283
|
+
}
|
|
284
|
+
const required = readdirSync(abs).filter((e) => !e.startsWith(".") && !e.startsWith("_"));
|
|
285
|
+
const missing = required.filter((entry) => !body.includes(entry));
|
|
286
|
+
if (missing.length === 0)
|
|
287
|
+
return { score: 1, evidence: "" };
|
|
288
|
+
return { score: 0.5, evidence: `block missing entries from ${enumerateDir}: ${missing.join(", ")}` };
|
|
289
|
+
}
|
|
290
|
+
return { score: 1, evidence: "" };
|
|
291
|
+
}
|
|
66
292
|
default:
|
|
67
293
|
return { score: 0, evidence: `unknown check type ${c.type}` };
|
|
68
294
|
}
|
|
69
295
|
}
|
|
296
|
+
/** BFS path existence. Used by the state-machine-dag check. */
|
|
297
|
+
function hasPath(adj, src, dst) {
|
|
298
|
+
if (src === dst)
|
|
299
|
+
return true;
|
|
300
|
+
const seen = new Set([src]);
|
|
301
|
+
const queue = [src];
|
|
302
|
+
while (queue.length) {
|
|
303
|
+
const cur = queue.shift();
|
|
304
|
+
const nexts = adj.get(cur);
|
|
305
|
+
if (!nexts)
|
|
306
|
+
continue;
|
|
307
|
+
for (const n of nexts) {
|
|
308
|
+
if (n === dst)
|
|
309
|
+
return true;
|
|
310
|
+
if (!seen.has(n)) {
|
|
311
|
+
seen.add(n);
|
|
312
|
+
queue.push(n);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
70
318
|
/** Resolve which checks to use: prefer the repo's installed checks.json, else AgentRig canonical. */
|
|
71
319
|
function resolveChecks(repoRoot) {
|
|
72
320
|
const repoChecks = readText(join(repoRoot, ".agentrig", "eval", "checks.json"));
|
|
@@ -84,24 +332,36 @@ export function auditHarness(repoRoot) {
|
|
|
84
332
|
const { checks, source } = resolveChecks(repoRoot);
|
|
85
333
|
const results = checks.map((c) => {
|
|
86
334
|
const { score, evidence } = scoreCheck(repoRoot, c);
|
|
87
|
-
|
|
335
|
+
// Default layer is "completeness" so unannotated check files still work.
|
|
336
|
+
const layer = c.layer === "quality" ? "quality" : "completeness";
|
|
337
|
+
return { id: c.id, principle: c.principle, title: c.title, score, evidence, layer };
|
|
88
338
|
});
|
|
89
|
-
let
|
|
90
|
-
let
|
|
339
|
+
let cwSum = 0, cwScore = 0; // completeness
|
|
340
|
+
let qwSum = 0, qwScore = 0; // quality
|
|
91
341
|
const principleAcc = new Map();
|
|
92
342
|
for (let i = 0; i < results.length; i++) {
|
|
343
|
+
const r = results[i];
|
|
93
344
|
const w = Number(checks[i].weight ?? 1);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
345
|
+
if (r.layer === "quality") {
|
|
346
|
+
qwSum += w;
|
|
347
|
+
qwScore += w * r.score;
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
cwSum += w;
|
|
351
|
+
cwScore += w * r.score;
|
|
352
|
+
}
|
|
353
|
+
const acc = principleAcc.get(r.principle) ?? { sum: 0, n: 0 };
|
|
354
|
+
acc.sum += r.score;
|
|
98
355
|
acc.n += 1;
|
|
99
|
-
principleAcc.set(
|
|
356
|
+
principleAcc.set(r.principle, acc);
|
|
100
357
|
}
|
|
101
|
-
const aggregate =
|
|
358
|
+
const aggregate = cwSum ? cwScore / cwSum : 0;
|
|
359
|
+
const qualityAggregate = qwSum ? qwScore / qwSum : 0;
|
|
102
360
|
return {
|
|
103
361
|
harnessScore: Math.round(aggregate * 1000) / 10,
|
|
104
362
|
aggregate,
|
|
363
|
+
qualityScore: Math.round(qualityAggregate * 1000) / 10,
|
|
364
|
+
qualityAggregate,
|
|
105
365
|
results,
|
|
106
366
|
byPrinciple: [...principleAcc.entries()]
|
|
107
367
|
.sort((a, b) => a[0] - b[0])
|