plumbbob 0.6.6 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +2 -2
- package/README.md +24 -7
- package/dist/cli-core.js +7 -2
- package/dist/lib/buildlog.js +5 -2
- package/dist/lib/check.js +33 -1
- package/dist/lib/git.js +17 -0
- package/dist/lib/latch.js +97 -0
- package/dist/lib/orient.js +24 -0
- package/dist/lib/settings.js +3 -9
- package/dist/lib/sidecar.js +169 -18
- package/dist/verbs/build.js +5 -1
- package/dist/verbs/checkpoint.js +51 -2
- package/dist/verbs/doctor.js +40 -5
- package/dist/verbs/finish.js +61 -11
- package/dist/verbs/revert.js +19 -1
- package/dist/verbs/start.js +38 -7
- package/dist/verbs/status.js +10 -3
- package/dist/verbs/turn.js +106 -0
- package/dist/verbs/use.js +4 -5
- package/hooks/hooks.json +15 -0
- package/hooks/post-edit.sh +7 -7
- package/hooks/pre-bash-commit.sh +68 -0
- package/node_modules/checkride/CHANGELOG.md +111 -0
- package/node_modules/checkride/README.md +185 -20
- package/node_modules/checkride/dist/adapters.d.ts +9 -4
- package/node_modules/checkride/dist/adapters.d.ts.map +1 -1
- package/node_modules/checkride/dist/adapters.js +62 -2
- package/node_modules/checkride/dist/adapters.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/hook.d.ts +63 -0
- package/node_modules/checkride/dist/agent-setup/hook.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/hook.js +92 -0
- package/node_modules/checkride/dist/agent-setup/hook.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/index.d.ts +8 -0
- package/node_modules/checkride/dist/agent-setup/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/index.js +7 -0
- package/node_modules/checkride/dist/agent-setup/index.js.map +1 -0
- package/node_modules/checkride/dist/atomic.d.ts +13 -0
- package/node_modules/checkride/dist/atomic.d.ts.map +1 -0
- package/node_modules/checkride/dist/atomic.js +24 -0
- package/node_modules/checkride/dist/atomic.js.map +1 -0
- package/node_modules/checkride/dist/baseline/command.d.ts +42 -0
- package/node_modules/checkride/dist/baseline/command.d.ts.map +1 -0
- package/node_modules/checkride/dist/baseline/command.js +58 -0
- package/node_modules/checkride/dist/baseline/command.js.map +1 -0
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts +41 -0
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts.map +1 -0
- package/node_modules/checkride/dist/baseline/fingerprint.js +119 -0
- package/node_modules/checkride/dist/baseline/fingerprint.js.map +1 -0
- package/node_modules/checkride/dist/baseline/index.d.ts +13 -0
- package/node_modules/checkride/dist/baseline/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/baseline/index.js +10 -0
- package/node_modules/checkride/dist/baseline/index.js.map +1 -0
- package/node_modules/checkride/dist/baseline/store.d.ts +67 -0
- package/node_modules/checkride/dist/baseline/store.d.ts.map +1 -0
- package/node_modules/checkride/dist/baseline/store.js +110 -0
- package/node_modules/checkride/dist/baseline/store.js.map +1 -0
- package/node_modules/checkride/dist/cli.d.ts.map +1 -1
- package/node_modules/checkride/dist/cli.js +37 -3
- package/node_modules/checkride/dist/cli.js.map +1 -1
- package/node_modules/checkride/dist/config.d.ts +43 -3
- package/node_modules/checkride/dist/config.d.ts.map +1 -1
- package/node_modules/checkride/dist/config.js +95 -22
- package/node_modules/checkride/dist/config.js.map +1 -1
- package/node_modules/checkride/dist/digest/digest.d.ts +52 -0
- package/node_modules/checkride/dist/digest/digest.d.ts.map +1 -0
- package/node_modules/checkride/dist/digest/digest.js +147 -0
- package/node_modules/checkride/dist/digest/digest.js.map +1 -0
- package/node_modules/checkride/dist/digest/index.d.ts +8 -0
- package/node_modules/checkride/dist/digest/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/digest/index.js +7 -0
- package/node_modules/checkride/dist/digest/index.js.map +1 -0
- package/node_modules/checkride/dist/doctor.d.ts +4 -0
- package/node_modules/checkride/dist/doctor.d.ts.map +1 -1
- package/node_modules/checkride/dist/doctor.js +33 -10
- package/node_modules/checkride/dist/doctor.js.map +1 -1
- package/node_modules/checkride/dist/index.d.ts +1 -1
- package/node_modules/checkride/dist/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/index.js +1 -1
- package/node_modules/checkride/dist/index.js.map +1 -1
- package/node_modules/checkride/dist/init.d.ts +38 -0
- package/node_modules/checkride/dist/init.d.ts.map +1 -1
- package/node_modules/checkride/dist/init.js +97 -8
- package/node_modules/checkride/dist/init.js.map +1 -1
- package/node_modules/checkride/dist/orchestrator.d.ts +58 -1
- package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -1
- package/node_modules/checkride/dist/orchestrator.js +155 -27
- package/node_modules/checkride/dist/orchestrator.js.map +1 -1
- package/node_modules/checkride/dist/pm/detect.d.ts +21 -0
- package/node_modules/checkride/dist/pm/detect.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/detect.js +60 -0
- package/node_modules/checkride/dist/pm/detect.js.map +1 -0
- package/node_modules/checkride/dist/pm/index.d.ts +10 -0
- package/node_modules/checkride/dist/pm/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/index.js +9 -0
- package/node_modules/checkride/dist/pm/index.js.map +1 -0
- package/node_modules/checkride/dist/pm/translate.d.ts +28 -0
- package/node_modules/checkride/dist/pm/translate.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/translate.js +40 -0
- package/node_modules/checkride/dist/pm/translate.js.map +1 -0
- package/node_modules/checkride/package.json +20 -17
- package/node_modules/checkride/schema/checkride.config.schema.json +97 -0
- package/node_modules/checkride/schema/checkride.summary.schema.json +57 -0
- package/node_modules/checkride/templates/shared/cspell.json +1 -0
- package/node_modules/checkride/templates/shared/prettierrc.json +6 -0
- package/package.json +8 -4
- package/skills/pb-build/SKILL.md +31 -1
- package/skills/pb-finish/SKILL.md +2 -1
- package/skills/pb-plan/SKILL.md +17 -0
- package/skills/pb-verify/SKILL.md +32 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The baseline artifact: its on-disk shape and the pure read / write / apply /
|
|
3
|
+
* ratchet operations a baseline-aware run (step 6) is built from.
|
|
4
|
+
*
|
|
5
|
+
* This file imports nothing from the orchestrator on purpose: the `baseline`
|
|
6
|
+
* command (command.ts) bridges to the run pipeline, but a *run* only needs to
|
|
7
|
+
* mask and ratchet an already-captured baseline, so the orchestrator can depend
|
|
8
|
+
* on these helpers without a load-order cycle. Keeping the file I/O and the
|
|
9
|
+
* set algebra here (not in the orchestrator) also preserves the orchestrator's
|
|
10
|
+
* "never parse diagnostics" thesis — fingerprinting stays inside this module.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { writeFileAtomic } from '../atomic.js';
|
|
15
|
+
/** The committed baseline artifact, at repo root beside `checkride.config.json`. */
|
|
16
|
+
export const BASELINE_FILE = 'checkride.baseline.json';
|
|
17
|
+
/** Schema version of the baseline file; independent of the summary schema (D8). */
|
|
18
|
+
export const BASELINE_SCHEMA_VERSION = 1;
|
|
19
|
+
/** Narrow to a plain object so fields can be read without an unsafe assertion. */
|
|
20
|
+
function isRecord(value) {
|
|
21
|
+
return typeof value === 'object' && value !== null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Read `checkride.baseline.json` from `cwd`; `null` when absent or unusable. The
|
|
25
|
+
* baseline is a committed file a run reads on every invocation, so a malformed
|
|
26
|
+
* one is coerced into a clean shape (or dropped) rather than thrown — a corrupt
|
|
27
|
+
* baseline must never break `checkride`.
|
|
28
|
+
*/
|
|
29
|
+
export function loadBaseline(cwd) {
|
|
30
|
+
const path = join(cwd, BASELINE_FILE);
|
|
31
|
+
if (!existsSync(path))
|
|
32
|
+
return null;
|
|
33
|
+
try {
|
|
34
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
35
|
+
if (!isRecord(parsed) || !isRecord(parsed['slots']))
|
|
36
|
+
return null;
|
|
37
|
+
const slots = {};
|
|
38
|
+
for (const [slot, keys] of Object.entries(parsed['slots'])) {
|
|
39
|
+
if (Array.isArray(keys))
|
|
40
|
+
slots[slot] = keys.filter((k) => typeof k === 'string');
|
|
41
|
+
}
|
|
42
|
+
const version = parsed['schema_version'];
|
|
43
|
+
return { schema_version: typeof version === 'number' ? version : BASELINE_SCHEMA_VERSION, slots };
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Serialize and write the baseline to `cwd` (pretty-printed, trailing newline, atomic). */
|
|
50
|
+
export async function writeBaseline(cwd, baseline) {
|
|
51
|
+
await writeFileAtomic(join(cwd, BASELINE_FILE), `${JSON.stringify(baseline, null, 2)}\n`);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Mask one slot's current fingerprint with its grandfathered keys. Masking is
|
|
55
|
+
* pure set subtraction: `newKeys` are the current diagnostics the baseline does
|
|
56
|
+
* not cover, `baselined` counts the ones it does.
|
|
57
|
+
*
|
|
58
|
+
* The failure flips to a pass *only* when there are current diagnostics and none
|
|
59
|
+
* of them are new — a tool that produced no parseable diagnostics (a crash, empty
|
|
60
|
+
* output that fingerprints to the empty set) is never masked, so a genuine
|
|
61
|
+
* breakage still fails even while a baseline is active. Correctness beats
|
|
62
|
+
* precision: better to re-surface a masked finding than to silently green a crash.
|
|
63
|
+
*/
|
|
64
|
+
export function applyBaseline(current, baselinedKeys, rawOk) {
|
|
65
|
+
const grandfathered = new Set(baselinedKeys);
|
|
66
|
+
const newKeys = [];
|
|
67
|
+
let baselined = 0;
|
|
68
|
+
for (const k of current) {
|
|
69
|
+
if (grandfathered.has(k))
|
|
70
|
+
baselined += 1;
|
|
71
|
+
else
|
|
72
|
+
newKeys.push(k);
|
|
73
|
+
}
|
|
74
|
+
const ok = rawOk || (current.size > 0 && newKeys.length === 0);
|
|
75
|
+
return { ok, baselined, newKeys: newKeys.toSorted() };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Ratchet the baseline against a fully-observed run: for every slot observed this
|
|
79
|
+
* run, keep only the grandfathered keys still present (a fixed diagnostic is
|
|
80
|
+
* dropped); a slot absent from `observed` — disabled, without an extractor, or
|
|
81
|
+
* not run — is preserved untouched. The result never grows: genuinely new findings
|
|
82
|
+
* are the run's failures, not new debt, so only a `checkride baseline` capture
|
|
83
|
+
* ever adds keys. Callers gate this on a full run (no `--only`/`--skip`/
|
|
84
|
+
* `--changed`, no early `--bail` break) so a partial run can't prune keys it
|
|
85
|
+
* simply didn't observe (a1).
|
|
86
|
+
*/
|
|
87
|
+
export function ratchet(baseline, observed) {
|
|
88
|
+
const slots = {};
|
|
89
|
+
for (const [slot, keys] of Object.entries(baseline.slots)) {
|
|
90
|
+
const current = observed.get(slot);
|
|
91
|
+
slots[slot] = current === undefined ? keys : keys.filter((k) => current.has(k)).toSorted();
|
|
92
|
+
}
|
|
93
|
+
return { schema_version: baseline.schema_version, slots };
|
|
94
|
+
}
|
|
95
|
+
/** Total grandfathered diagnostics across every slot. */
|
|
96
|
+
export function countBaselineKeys(baseline) {
|
|
97
|
+
return Object.values(baseline.slots).reduce((n, keys) => n + keys.length, 0);
|
|
98
|
+
}
|
|
99
|
+
/** Canonical string form (sorted slots and keys) for order-independent compare. */
|
|
100
|
+
function canonicalBaseline(base) {
|
|
101
|
+
const slots = {};
|
|
102
|
+
for (const key of Object.keys(base.slots).toSorted())
|
|
103
|
+
slots[key] = [...(base.slots[key] ?? [])].toSorted();
|
|
104
|
+
return JSON.stringify({ schema_version: base.schema_version, slots });
|
|
105
|
+
}
|
|
106
|
+
/** Order-independent structural equality, so an unchanged ratchet skips its write. */
|
|
107
|
+
export function baselinesEqual(a, b) {
|
|
108
|
+
return canonicalBaseline(a) === canonicalBaseline(b);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/baseline/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAQH,OAAO,KAAK,EAAqB,WAAW,EAAS,MAAM,WAAW,CAAC;AAEvE,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGvD,+DAA+D;AAC/D,MAAM,MAAM,OAAO,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,CAAC;AAqGhE,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAejF;AAQD,gDAAgD;AAChD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAgBlE;AAuCD,gEAAgE;AAChE,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC3E"}
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
import { readFileSync, realpathSync } from 'node:fs';
|
|
13
13
|
import { parseArgs } from 'node:util';
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { runBaseline } from './baseline/index.js';
|
|
15
16
|
import { runDoctor } from './doctor.js';
|
|
16
|
-
import { runInit } from './init.js';
|
|
17
|
+
import { runAgentSetup, runInit } from './init.js';
|
|
17
18
|
import { runChecks, runFix } from './orchestrator.js';
|
|
18
19
|
const RUN_OPTIONS = {
|
|
19
20
|
bail: { type: 'boolean', default: false },
|
|
@@ -23,6 +24,8 @@ const RUN_OPTIONS = {
|
|
|
23
24
|
include: { type: 'string' },
|
|
24
25
|
all: { type: 'boolean', default: false },
|
|
25
26
|
changed: { type: 'boolean', default: false },
|
|
27
|
+
digest: { type: 'boolean', default: false },
|
|
28
|
+
strict: { type: 'boolean', default: false },
|
|
26
29
|
};
|
|
27
30
|
const INIT_OPTIONS = {
|
|
28
31
|
shape: { type: 'string' },
|
|
@@ -32,6 +35,8 @@ const INIT_OPTIONS = {
|
|
|
32
35
|
author: { type: 'string' },
|
|
33
36
|
'dry-run': { type: 'boolean', default: false },
|
|
34
37
|
add: { type: 'string' },
|
|
38
|
+
baseline: { type: 'boolean', default: false },
|
|
39
|
+
'no-hook': { type: 'boolean', default: false },
|
|
35
40
|
};
|
|
36
41
|
const HELP_TEXT = `checkride — an agent harness for TypeScript repositories
|
|
37
42
|
|
|
@@ -39,18 +44,25 @@ Usage: checkride [command] [options]
|
|
|
39
44
|
|
|
40
45
|
Commands:
|
|
41
46
|
(default) Run the checks. Exit 0 pass / 1 fail / 2 error.
|
|
42
|
-
init Set up a project (new or existing — auto-detected).
|
|
47
|
+
init Set up a project (new or existing — auto-detected). Writes a
|
|
48
|
+
Claude Code Stop hook (--no-hook to skip). Existing mode:
|
|
49
|
+
--baseline grandfathers current debt.
|
|
43
50
|
doctor Verify the environment and every slot's status (read-only).
|
|
44
51
|
fix Run every active adapter's fix command.
|
|
52
|
+
baseline Record current diagnostics as a committed baseline.
|
|
53
|
+
agent-setup Add the AGENTS.md stanza + Claude Code Stop hook to an
|
|
54
|
+
existing repo (--no-hook to skip the hook).
|
|
45
55
|
|
|
46
56
|
Run options:
|
|
47
57
|
--only <a,b> Run only these slots
|
|
48
58
|
--skip <a,b> Skip these slots
|
|
49
|
-
--include <a,b> Add opt-in slots (mutation, security) to the run
|
|
59
|
+
--include <a,b> Add opt-in slots (format, mutation, security) to the run
|
|
50
60
|
--all Include every opt-in slot
|
|
51
61
|
--changed Affected-only mode (incremental)
|
|
52
62
|
--bail Stop at the first failure
|
|
53
63
|
--json Emit the summary as JSON on stdout
|
|
64
|
+
--digest Write a capped failure excerpt to .check/digest.md
|
|
65
|
+
--strict Zero checks actually running is an error (exit 2), not a pass
|
|
54
66
|
-h, --help Show this help
|
|
55
67
|
-V, --version Show the version
|
|
56
68
|
|
|
@@ -105,6 +117,8 @@ export function parseCliArgs(argv) {
|
|
|
105
117
|
json: values.json,
|
|
106
118
|
all: values.all,
|
|
107
119
|
changed: values.changed,
|
|
120
|
+
digest: values.digest,
|
|
121
|
+
strict: values.strict,
|
|
108
122
|
only: parseList(values.only),
|
|
109
123
|
skip: parseList(values.skip),
|
|
110
124
|
include: parseList(values.include),
|
|
@@ -136,6 +150,10 @@ export function parseInitArgs(argv) {
|
|
|
136
150
|
opts.author = values.author;
|
|
137
151
|
if (values['dry-run'])
|
|
138
152
|
opts.dryRun = true;
|
|
153
|
+
if (values.baseline)
|
|
154
|
+
opts.baseline = true;
|
|
155
|
+
if (values['no-hook'])
|
|
156
|
+
opts.hook = false;
|
|
139
157
|
const add = parseList(values.add);
|
|
140
158
|
if (add)
|
|
141
159
|
opts.add = add;
|
|
@@ -160,6 +178,20 @@ async function dispatchFix(argv, deps) {
|
|
|
160
178
|
const result = await runFix({ ...flags, cwd: deps.cwd, stderr: deps.stderr });
|
|
161
179
|
return result.exitCode;
|
|
162
180
|
}
|
|
181
|
+
async function dispatchBaseline(_argv, deps) {
|
|
182
|
+
const result = await runBaseline({ cwd: deps.cwd, stdout: deps.stdout, stderr: deps.stderr });
|
|
183
|
+
return result.exitCode;
|
|
184
|
+
}
|
|
185
|
+
async function dispatchAgentSetup(argv, deps) {
|
|
186
|
+
const parsed = parseInitArgs(argv);
|
|
187
|
+
const opts = { cwd: deps.cwd, stdout: deps.stdout };
|
|
188
|
+
if (parsed.hook !== undefined)
|
|
189
|
+
opts.hook = parsed.hook;
|
|
190
|
+
if (parsed.dryRun)
|
|
191
|
+
opts.dryRun = true;
|
|
192
|
+
const result = await runAgentSetup(opts);
|
|
193
|
+
return result.exitCode;
|
|
194
|
+
}
|
|
163
195
|
/** Dispatch a CLI invocation; returns the process exit code. */
|
|
164
196
|
export async function runCli(argv, deps) {
|
|
165
197
|
if (argv.includes('--help') || argv.includes('-h')) {
|
|
@@ -176,6 +208,8 @@ export async function runCli(argv, deps) {
|
|
|
176
208
|
init: dispatchInit,
|
|
177
209
|
doctor: dispatchDoctor,
|
|
178
210
|
fix: dispatchFix,
|
|
211
|
+
baseline: dispatchBaseline,
|
|
212
|
+
'agent-setup': dispatchAgentSetup,
|
|
179
213
|
};
|
|
180
214
|
const handler = dispatch[command];
|
|
181
215
|
if (!handler) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,15 @@ export type CustomCheck = {
|
|
|
21
21
|
fixArgs?: string[];
|
|
22
22
|
timeout?: number;
|
|
23
23
|
name?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Marker files that gate a config-only custom check: it runs only when at
|
|
26
|
+
* least one listed file exists, and is skipped (`'no detect file present'`,
|
|
27
|
+
* not failed) otherwise. This keeps a shared preset safe across heterogeneous
|
|
28
|
+
* repos — a check for a tool a given repo doesn't use quietly stands down
|
|
29
|
+
* instead of lighting up red. Ignored on entries that fill a catalogue slot —
|
|
30
|
+
* those always run.
|
|
31
|
+
*/
|
|
32
|
+
detect?: string[];
|
|
24
33
|
/**
|
|
25
34
|
* Where a config-only custom check runs relative to the built-in catalogue:
|
|
26
35
|
* `'first'` (ahead of every built-in check) or `'last'` (after them, the
|
|
@@ -44,25 +53,56 @@ export type UseConfig = {
|
|
|
44
53
|
export type SlotConfig = string | false | UseConfig | CustomCheck;
|
|
45
54
|
/** Shape of `checkride.config.json`. */
|
|
46
55
|
export type CheckrideConfig = {
|
|
56
|
+
/** URL of the JSON Schema for this file, for editor validation. Ignored by the runner. */
|
|
57
|
+
$schema?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Preset(s) to inherit: a file path (`./base.json`) or a package specifier
|
|
60
|
+
* (`@acme/preset`), or an array of them. Bases merge left-to-right and the
|
|
61
|
+
* local config wins over all of them; objects deep-merge, arrays and scalars
|
|
62
|
+
* replace (arrays are not concatenated). Resolved and folded away by
|
|
63
|
+
* `loadConfig` — the runner never sees it.
|
|
64
|
+
*/
|
|
65
|
+
extends?: string | string[];
|
|
47
66
|
checks?: Record<string, SlotConfig>;
|
|
48
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Default per-check timeout in seconds. When unset, checks fall back to the
|
|
69
|
+
* built-in 600s cap (`DEFAULT_TIMEOUT_SECONDS`); `0` here or on a check
|
|
70
|
+
* disables the cap.
|
|
71
|
+
*/
|
|
49
72
|
timeout?: number;
|
|
50
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* The version-pinned URL of the published config schema, for the `$schema`
|
|
76
|
+
* pointer `init` writes into generated configs. The `v<version>` git tag must
|
|
77
|
+
* exist at release for the URL to resolve.
|
|
78
|
+
*/
|
|
79
|
+
export declare function configSchemaUrl(version: string): string;
|
|
51
80
|
/** A slot resolved to a concrete adapter, or marked skipped with a reason. */
|
|
52
81
|
export type ResolvedCheck = {
|
|
53
82
|
slot: string;
|
|
54
83
|
optIn: boolean;
|
|
55
84
|
adapter: Adapter | null;
|
|
56
85
|
skip: string | null;
|
|
86
|
+
/**
|
|
87
|
+
* True when `checks` names this slot explicitly (a non-`false` config entry).
|
|
88
|
+
* An explicit entry opts an otherwise opt-in slot into the default run — so
|
|
89
|
+
* `"format": "prettier"` runs without `--include` (see `selectChecks`).
|
|
90
|
+
*/
|
|
91
|
+
explicit?: boolean;
|
|
57
92
|
};
|
|
58
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* Read and resolve `checkride.config.json` from `cwd`, or `null` when absent.
|
|
95
|
+
* Any `extends` presets (file paths or package specifiers) are resolved and
|
|
96
|
+
* merged in — local keys win, arrays replace — with `extends` folded away.
|
|
97
|
+
*/
|
|
59
98
|
export declare function loadConfig(cwd: string): CheckrideConfig | null;
|
|
60
99
|
/**
|
|
61
100
|
* Resolve every catalogue slot (in order) to an adapter or a skip reason, and
|
|
62
101
|
* fold in any config-only custom checks (an object with a `command`, keyed by a
|
|
63
102
|
* name not in the catalogue — e.g. a project's `"licenses"` check). Each custom
|
|
64
103
|
* check runs ahead of the catalogue (`order: 'first'`) or after it (`'last'`,
|
|
65
|
-
* the default); within a group, config key order is preserved.
|
|
104
|
+
* the default); within a group, config key order is preserved. A custom check
|
|
105
|
+
* that declares `detect` files is skipped when none of them are present.
|
|
66
106
|
*/
|
|
67
107
|
export declare function resolveChecks(input: {
|
|
68
108
|
slots: readonly Slot[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEnD,2DAA2D;AAC3D,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,yFAAyF;AACzF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,CAAC;AAElE,wCAAwC;AACxC,MAAM,MAAM,eAAe,GAAG;IAC5B,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,8EAA8E;AAC9E,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA2EF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAI9D;AAyFD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACxC,GAAG,aAAa,EAAE,CAwBlB"}
|
|
@@ -11,22 +11,88 @@
|
|
|
11
11
|
* 3. otherwise the slot is skipped (skipped ≠ failed).
|
|
12
12
|
*/
|
|
13
13
|
import { existsSync, readFileSync } from 'node:fs';
|
|
14
|
-
import {
|
|
14
|
+
import { createRequire } from 'node:module';
|
|
15
|
+
import { join, relative } from 'node:path';
|
|
16
|
+
/**
|
|
17
|
+
* The version-pinned URL of the published config schema, for the `$schema`
|
|
18
|
+
* pointer `init` writes into generated configs. The `v<version>` git tag must
|
|
19
|
+
* exist at release for the URL to resolve.
|
|
20
|
+
*/
|
|
21
|
+
export function configSchemaUrl(version) {
|
|
22
|
+
return `https://raw.githubusercontent.com/robmclarty/checkride/v${version}/schema/checkride.config.schema.json`;
|
|
23
|
+
}
|
|
15
24
|
const CONFIG_FILE = 'checkride.config.json';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
function isPlainObject(v) {
|
|
26
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Recursive deep-merge with local-wins semantics: plain objects merge key by
|
|
30
|
+
* key; arrays, scalars, and type mismatches from `over` replace `base` (arrays
|
|
31
|
+
* are never concatenated).
|
|
32
|
+
*/
|
|
33
|
+
function deepMerge(base, over) {
|
|
34
|
+
const out = { ...base };
|
|
35
|
+
for (const [k, v] of Object.entries(over)) {
|
|
36
|
+
const b = out[k];
|
|
37
|
+
out[k] = isPlainObject(b) && isPlainObject(v) ? deepMerge(b, v) : v;
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/** Throw the friendly `invalid checkride.config.json: <reason>` error. */
|
|
42
|
+
function invalidConfig(reason, cause) {
|
|
43
|
+
throw new Error(`invalid ${CONFIG_FILE}: ${reason}`, cause ? { cause } : undefined);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Read, parse, and fully resolve a config file's `extends` chain into a single
|
|
47
|
+
* merged object. `stack` holds the absolute paths currently being resolved, so
|
|
48
|
+
* a config that (transitively) extends itself is caught as a cycle. `label`
|
|
49
|
+
* names the file in error messages — the root config's own filename for the
|
|
50
|
+
* entry point, or a repo-relative path for an inherited base.
|
|
51
|
+
*/
|
|
52
|
+
function resolveConfigFile(absPath, stack, label) {
|
|
53
|
+
if (stack.includes(absPath)) {
|
|
54
|
+
invalidConfig(`circular extends: ${[...stack, absPath].map((p) => relative(process.cwd(), p)).join(' -> ')}`);
|
|
55
|
+
}
|
|
56
|
+
let raw;
|
|
22
57
|
try {
|
|
23
|
-
|
|
24
|
-
return config;
|
|
58
|
+
raw = JSON.parse(readFileSync(absPath, 'utf8'));
|
|
25
59
|
}
|
|
26
60
|
catch (err) {
|
|
27
61
|
const reason = err instanceof Error ? err.message : String(err);
|
|
28
|
-
|
|
62
|
+
invalidConfig(label === CONFIG_FILE ? reason : `${reason} (in ${label})`, err);
|
|
29
63
|
}
|
|
64
|
+
if (!isPlainObject(raw))
|
|
65
|
+
invalidConfig(`${label} is not a JSON object`);
|
|
66
|
+
const { extends: ext, ...own } = raw;
|
|
67
|
+
const specs = ext === undefined ? [] : Array.isArray(ext) ? ext : [ext];
|
|
68
|
+
const require = createRequire(absPath);
|
|
69
|
+
let merged = {};
|
|
70
|
+
for (const spec of specs) {
|
|
71
|
+
if (typeof spec !== 'string')
|
|
72
|
+
invalidConfig(`extends entries must be strings (in ${label})`);
|
|
73
|
+
let baseAbs;
|
|
74
|
+
try {
|
|
75
|
+
baseAbs = require.resolve(spec);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
79
|
+
invalidConfig(`cannot resolve extends "${spec}" (in ${label}): ${reason}`, err);
|
|
80
|
+
}
|
|
81
|
+
const base = resolveConfigFile(baseAbs, [...stack, absPath], relative(process.cwd(), baseAbs));
|
|
82
|
+
merged = deepMerge(merged, base);
|
|
83
|
+
}
|
|
84
|
+
return deepMerge(merged, own);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Read and resolve `checkride.config.json` from `cwd`, or `null` when absent.
|
|
88
|
+
* Any `extends` presets (file paths or package specifiers) are resolved and
|
|
89
|
+
* merged in — local keys win, arrays replace — with `extends` folded away.
|
|
90
|
+
*/
|
|
91
|
+
export function loadConfig(cwd) {
|
|
92
|
+
const path = join(cwd, CONFIG_FILE);
|
|
93
|
+
if (!existsSync(path))
|
|
94
|
+
return null;
|
|
95
|
+
return resolveConfigFile(path, [], CONFIG_FILE);
|
|
30
96
|
}
|
|
31
97
|
function byName(name, adapters) {
|
|
32
98
|
return adapters.find((a) => a.name === name) ?? null;
|
|
@@ -58,7 +124,7 @@ function customAdapter(slot, c) {
|
|
|
58
124
|
name: c.name ?? `custom:${slot}`,
|
|
59
125
|
slot,
|
|
60
126
|
description: c.description ?? `Custom ${slot} check`,
|
|
61
|
-
detect: [],
|
|
127
|
+
detect: c.detect ?? [],
|
|
62
128
|
command: c.command,
|
|
63
129
|
args: c.args ?? [],
|
|
64
130
|
outputFile: c.outputFile ?? null,
|
|
@@ -68,31 +134,34 @@ function customAdapter(slot, c) {
|
|
|
68
134
|
devDeps: {},
|
|
69
135
|
};
|
|
70
136
|
}
|
|
71
|
-
function active(slot, adapter) {
|
|
72
|
-
return { slot: slot.name, optIn: slot.optIn ?? false, adapter, skip: null };
|
|
137
|
+
function active(slot, adapter, explicit = false) {
|
|
138
|
+
return { slot: slot.name, optIn: slot.optIn ?? false, adapter, skip: null, explicit };
|
|
73
139
|
}
|
|
74
|
-
function skipped(slot, reason) {
|
|
75
|
-
return { slot: slot.name, optIn: slot.optIn ?? false, adapter: null, skip: reason };
|
|
140
|
+
function skipped(slot, reason, explicit = false) {
|
|
141
|
+
return { slot: slot.name, optIn: slot.optIn ?? false, adapter: null, skip: reason, explicit };
|
|
76
142
|
}
|
|
77
143
|
function resolveOne(slot, entry, adapters, fileExists) {
|
|
144
|
+
// Any non-`false` config entry is an explicit opt-in for this slot (`false`
|
|
145
|
+
// disables it, so it never runs regardless). Detection (no entry) is not.
|
|
146
|
+
const explicit = entry !== undefined && entry !== false;
|
|
78
147
|
if (entry === false) {
|
|
79
148
|
return skipped(slot, 'disabled in checkride.config.json');
|
|
80
149
|
}
|
|
81
150
|
if (typeof entry === 'string') {
|
|
82
151
|
const adapter = byName(entry, adapters);
|
|
83
152
|
return adapter
|
|
84
|
-
? active(slot, adapter)
|
|
85
|
-
: skipped(slot, `configured adapter '${entry}' is not in the registry
|
|
153
|
+
? active(slot, adapter, explicit)
|
|
154
|
+
: skipped(slot, `configured adapter '${entry}' is not in the registry`, explicit);
|
|
86
155
|
}
|
|
87
156
|
if (entry && typeof entry === 'object') {
|
|
88
157
|
if ('use' in entry) {
|
|
89
158
|
const base = byName(entry.use, adapters);
|
|
90
159
|
return base
|
|
91
|
-
? active(slot, applyOverrides(base, entry))
|
|
92
|
-
: skipped(slot, `configured adapter '${entry.use}' is not in the registry
|
|
160
|
+
? active(slot, applyOverrides(base, entry), explicit)
|
|
161
|
+
: skipped(slot, `configured adapter '${entry.use}' is not in the registry`, explicit);
|
|
93
162
|
}
|
|
94
163
|
if ('command' in entry) {
|
|
95
|
-
return active(slot, customAdapter(slot.name, entry));
|
|
164
|
+
return active(slot, customAdapter(slot.name, entry), explicit);
|
|
96
165
|
}
|
|
97
166
|
}
|
|
98
167
|
const detected = detectAdapter(slot.name, adapters, fileExists);
|
|
@@ -103,7 +172,8 @@ function resolveOne(slot, entry, adapters, fileExists) {
|
|
|
103
172
|
* fold in any config-only custom checks (an object with a `command`, keyed by a
|
|
104
173
|
* name not in the catalogue — e.g. a project's `"licenses"` check). Each custom
|
|
105
174
|
* check runs ahead of the catalogue (`order: 'first'`) or after it (`'last'`,
|
|
106
|
-
* the default); within a group, config key order is preserved.
|
|
175
|
+
* the default); within a group, config key order is preserved. A custom check
|
|
176
|
+
* that declares `detect` files is skipped when none of them are present.
|
|
107
177
|
*/
|
|
108
178
|
export function resolveChecks(input) {
|
|
109
179
|
const cwd = input.cwd ?? process.cwd();
|
|
@@ -117,7 +187,10 @@ export function resolveChecks(input) {
|
|
|
117
187
|
if (catalogueNames.has(name))
|
|
118
188
|
continue;
|
|
119
189
|
if (entry && typeof entry === 'object' && !('use' in entry) && 'command' in entry) {
|
|
120
|
-
const
|
|
190
|
+
const detect = entry.detect ?? [];
|
|
191
|
+
const resolved = detect.length > 0 && !detect.some((f) => fileExists(f))
|
|
192
|
+
? skipped({ name }, 'no detect file present')
|
|
193
|
+
: active({ name }, customAdapter(name, entry));
|
|
121
194
|
(entry.order === 'first' ? firsts : lasts).push(resolved);
|
|
122
195
|
}
|
|
123
196
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token-bounded failure digest (step 11).
|
|
3
|
+
*
|
|
4
|
+
* After a run, `--digest` writes a capped Markdown excerpt of the *failing*
|
|
5
|
+
* slots to `.check/digest.md` so an agent working through a big red repo spends
|
|
6
|
+
* its context on a bounded index instead of every raw `.check/<slot>.json`. The
|
|
7
|
+
* digest is an INDEX, never a replacement: it truncates (the first N findings
|
|
8
|
+
* per slot, a total byte budget) and never normalizes — each section points
|
|
9
|
+
* back at the authoritative raw file, which this module never touches.
|
|
10
|
+
*
|
|
11
|
+
* It reuses step 4's per-adapter fingerprint extractors to list a slot's
|
|
12
|
+
* findings (render the first N of the same items); a slot whose adapter has no
|
|
13
|
+
* extractor falls back to a tail of its raw text (b6). A green run has nothing
|
|
14
|
+
* to digest, so {@link writeDigest} removes any stale `.check/digest.md` — the
|
|
15
|
+
* file's presence always means "this run had failures".
|
|
16
|
+
*
|
|
17
|
+
* The `../digest` barrel (`index.ts`) is this module's only public surface (C2);
|
|
18
|
+
* siblings import from there, never from this file directly.
|
|
19
|
+
*/
|
|
20
|
+
import type { CheckRun, SummaryCheck } from '../orchestrator.js';
|
|
21
|
+
/** The digest file, beside `summary.json` under the gitignored `.check/`. */
|
|
22
|
+
export declare const DIGEST_FILE = "digest.md";
|
|
23
|
+
/** Caps that keep the digest token-bounded. Truncation, never normalization. */
|
|
24
|
+
export type DigestBudget = {
|
|
25
|
+
/** Max findings rendered per failing slot; the rest collapse to a "… N more" line. */
|
|
26
|
+
maxItemsPerSlot: number;
|
|
27
|
+
/** Max total bytes of the rendered Markdown; whole sections drop past it. */
|
|
28
|
+
maxBytes: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Conservative defaults: ~10 findings a slot and an 8 KB ceiling keep even a
|
|
32
|
+
* fully-red repo's digest to roughly two thousand tokens — small enough to read
|
|
33
|
+
* in one gulp, with the raw files a click away for the rest.
|
|
34
|
+
*/
|
|
35
|
+
export declare const DEFAULT_BUDGET: DigestBudget;
|
|
36
|
+
/**
|
|
37
|
+
* Build the Markdown digest for a completed run, or `null` when nothing failed.
|
|
38
|
+
* A check is "failing" when the summary marks it `ok: false` and not skipped —
|
|
39
|
+
* so a slot whose findings a baseline fully grandfathers (still `ok: true`) is
|
|
40
|
+
* correctly absent. Sections are added in summary (cheapest-first) order until
|
|
41
|
+
* the byte budget is spent; any remaining failing slots are named in a trailing
|
|
42
|
+
* note rather than silently dropped.
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildDigest(runs: readonly CheckRun[], checks: readonly SummaryCheck[], budget?: DigestBudget): string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Persist the digest for a completed run. Writes `.check/digest.md` when a slot
|
|
47
|
+
* failed; on a green run removes any stale digest so the file's presence always
|
|
48
|
+
* means "this run failed". `cwd/.check/` is assumed to exist — the orchestrator
|
|
49
|
+
* creates it before running. Returns whether a digest file now exists.
|
|
50
|
+
*/
|
|
51
|
+
export declare function writeDigest(cwd: string, runs: readonly CheckRun[], checks: readonly SummaryCheck[], budget?: DigestBudget): Promise<boolean>;
|
|
52
|
+
//# sourceMappingURL=digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../../src/digest/digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjE,6EAA6E;AAC7E,eAAO,MAAM,WAAW,cAAc,CAAC;AAEvC,gFAAgF;AAChF,MAAM,MAAM,YAAY,GAAG;IACzB,sFAAsF;IACtF,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,YAAsD,CAAC;AAkEpF;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,QAAQ,EAAE,EACzB,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,MAAM,GAAE,YAA6B,GACpC,MAAM,GAAG,IAAI,CA+Bf;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,QAAQ,EAAE,EACzB,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,MAAM,GAAE,YAA6B,GACpC,OAAO,CAAC,OAAO,CAAC,CASlB"}
|