plumbbob 0.9.3 → 0.9.5
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 +1 -1
- package/README.md +15 -13
- package/dist/cli-core.js +19 -2
- package/dist/lib/check.js +46 -13
- package/dist/lib/intent.js +1 -1
- package/dist/lib/latch.js +3 -3
- package/dist/lib/reentry.js +70 -0
- package/dist/verbs/agent.js +2 -2
- package/dist/verbs/doctor.js +4 -4
- package/dist/verbs/finish.js +1 -1
- package/dist/verbs/recover.js +297 -0
- package/dist/verbs/revert.js +2 -2
- package/dist/verbs/spike.js +8 -2
- package/hooks/post-edit.sh +4 -4
- package/hooks/pre-bash-commit.sh +3 -3
- package/node_modules/checkride/.claude-plugin/plugin.json +11 -0
- package/node_modules/checkride/CHANGELOG.md +1003 -0
- package/node_modules/checkride/LICENSE +201 -21
- package/node_modules/checkride/README.md +171 -30
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.d.ts +15 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.d.ts.map +1 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.js +17 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.js.map +1 -0
- package/node_modules/checkride/dist/adapters.d.ts +18 -6
- package/node_modules/checkride/dist/adapters.d.ts.map +1 -1
- package/node_modules/checkride/dist/adapters.js +42 -23
- package/node_modules/checkride/dist/adapters.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/claude.d.ts +88 -0
- package/node_modules/checkride/dist/agent-setup/claude.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/claude.js +305 -0
- package/node_modules/checkride/dist/agent-setup/claude.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/command.d.ts +43 -0
- package/node_modules/checkride/dist/agent-setup/command.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/command.js +77 -0
- package/node_modules/checkride/dist/agent-setup/command.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/cursor.d.ts +61 -0
- package/node_modules/checkride/dist/agent-setup/cursor.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/cursor.js +189 -0
- package/node_modules/checkride/dist/agent-setup/cursor.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/files.d.ts +50 -0
- package/node_modules/checkride/dist/agent-setup/files.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/files.js +80 -0
- package/node_modules/checkride/dist/agent-setup/files.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/harness.d.ts +101 -0
- package/node_modules/checkride/dist/agent-setup/harness.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/harness.js +84 -0
- package/node_modules/checkride/dist/agent-setup/harness.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/hook.d.ts +45 -52
- package/node_modules/checkride/dist/agent-setup/hook.d.ts.map +1 -1
- package/node_modules/checkride/dist/agent-setup/hook.js +64 -95
- package/node_modules/checkride/dist/agent-setup/hook.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/index.d.ts +10 -4
- package/node_modules/checkride/dist/agent-setup/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/agent-setup/index.js +9 -4
- package/node_modules/checkride/dist/agent-setup/index.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/scripts.d.ts +58 -0
- package/node_modules/checkride/dist/agent-setup/scripts.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/scripts.js +299 -0
- package/node_modules/checkride/dist/agent-setup/scripts.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/skills.d.ts +31 -0
- package/node_modules/checkride/dist/agent-setup/skills.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/skills.js +56 -0
- package/node_modules/checkride/dist/agent-setup/skills.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/configured.d.ts +30 -0
- package/node_modules/checkride/dist/artifacts/configured.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/configured.js +45 -0
- package/node_modules/checkride/dist/artifacts/configured.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/format.d.ts +33 -0
- package/node_modules/checkride/dist/artifacts/format.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/format.js +56 -0
- package/node_modules/checkride/dist/artifacts/format.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/freshness.d.ts +32 -0
- package/node_modules/checkride/dist/artifacts/freshness.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/freshness.js +37 -0
- package/node_modules/checkride/dist/artifacts/freshness.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/index.d.ts +22 -0
- package/node_modules/checkride/dist/artifacts/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/index.js +19 -0
- package/node_modules/checkride/dist/artifacts/index.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/json.d.ts +31 -0
- package/node_modules/checkride/dist/artifacts/json.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/json.js +47 -0
- package/node_modules/checkride/dist/artifacts/json.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/raw.d.ts +60 -0
- package/node_modules/checkride/dist/artifacts/raw.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/raw.js +91 -0
- package/node_modules/checkride/dist/artifacts/raw.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/summary.d.ts +69 -0
- package/node_modules/checkride/dist/artifacts/summary.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/summary.js +108 -0
- package/node_modules/checkride/dist/artifacts/summary.js.map +1 -0
- package/node_modules/checkride/dist/atomic.d.ts +16 -1
- package/node_modules/checkride/dist/atomic.d.ts.map +1 -1
- package/node_modules/checkride/dist/atomic.js +25 -3
- package/node_modules/checkride/dist/atomic.js.map +1 -1
- package/node_modules/checkride/dist/baseline/fallow.d.ts +9 -5
- package/node_modules/checkride/dist/baseline/fallow.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/fallow.js +161 -58
- package/node_modules/checkride/dist/baseline/fallow.js.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts +7 -7
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.js +16 -19
- package/node_modules/checkride/dist/baseline/fingerprint.js.map +1 -1
- package/node_modules/checkride/dist/baseline/index.d.ts +4 -4
- package/node_modules/checkride/dist/baseline/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/index.js +4 -4
- package/node_modules/checkride/dist/baseline/index.js.map +1 -1
- package/node_modules/checkride/dist/baseline/store.d.ts +12 -4
- package/node_modules/checkride/dist/baseline/store.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/store.js +16 -9
- package/node_modules/checkride/dist/baseline/store.js.map +1 -1
- package/node_modules/checkride/dist/baseline-command.d.ts +5 -5
- package/node_modules/checkride/dist/baseline-command.js +7 -7
- package/node_modules/checkride/dist/baseline-command.js.map +1 -1
- package/node_modules/checkride/dist/cli.d.ts +17 -4
- package/node_modules/checkride/dist/cli.d.ts.map +1 -1
- package/node_modules/checkride/dist/cli.js +259 -18
- package/node_modules/checkride/dist/cli.js.map +1 -1
- package/node_modules/checkride/dist/config.d.ts +84 -8
- package/node_modules/checkride/dist/config.d.ts.map +1 -1
- package/node_modules/checkride/dist/config.js +122 -18
- package/node_modules/checkride/dist/config.js.map +1 -1
- package/node_modules/checkride/dist/digest/digest.d.ts +5 -5
- package/node_modules/checkride/dist/digest/digest.js +5 -5
- package/node_modules/checkride/dist/digest/index.d.ts +2 -2
- package/node_modules/checkride/dist/digest/index.js +2 -2
- package/node_modules/checkride/dist/doctor.d.ts +25 -6
- package/node_modules/checkride/dist/doctor.d.ts.map +1 -1
- package/node_modules/checkride/dist/doctor.js +193 -27
- package/node_modules/checkride/dist/doctor.js.map +1 -1
- package/node_modules/checkride/dist/gate.d.ts +135 -0
- package/node_modules/checkride/dist/gate.d.ts.map +1 -0
- package/node_modules/checkride/dist/gate.js +490 -0
- package/node_modules/checkride/dist/gate.js.map +1 -0
- package/node_modules/checkride/dist/init.d.ts +72 -12
- package/node_modules/checkride/dist/init.d.ts.map +1 -1
- package/node_modules/checkride/dist/init.js +324 -81
- package/node_modules/checkride/dist/init.js.map +1 -1
- package/node_modules/checkride/dist/json.d.ts +21 -0
- package/node_modules/checkride/dist/json.d.ts.map +1 -0
- package/node_modules/checkride/dist/json.js +21 -0
- package/node_modules/checkride/dist/json.js.map +1 -0
- package/node_modules/checkride/dist/links.d.ts +31 -5
- package/node_modules/checkride/dist/links.d.ts.map +1 -1
- package/node_modules/checkride/dist/links.js +141 -32
- package/node_modules/checkride/dist/links.js.map +1 -1
- package/node_modules/checkride/dist/node-pin.d.ts +129 -0
- package/node_modules/checkride/dist/node-pin.d.ts.map +1 -0
- package/node_modules/checkride/dist/node-pin.js +211 -0
- package/node_modules/checkride/dist/node-pin.js.map +1 -0
- package/node_modules/checkride/dist/orchestrator.d.ts +40 -10
- package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -1
- package/node_modules/checkride/dist/orchestrator.js +196 -102
- package/node_modules/checkride/dist/orchestrator.js.map +1 -1
- package/node_modules/checkride/dist/pack.d.ts +8 -9
- package/node_modules/checkride/dist/pack.d.ts.map +1 -1
- package/node_modules/checkride/dist/pack.js +53 -17
- package/node_modules/checkride/dist/pack.js.map +1 -1
- package/node_modules/checkride/dist/pm/detect.d.ts +6 -1
- package/node_modules/checkride/dist/pm/detect.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/detect.js +6 -1
- package/node_modules/checkride/dist/pm/detect.js.map +1 -1
- package/node_modules/checkride/dist/pm/index.d.ts +6 -2
- package/node_modules/checkride/dist/pm/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/index.js +6 -2
- package/node_modules/checkride/dist/pm/index.js.map +1 -1
- package/node_modules/checkride/dist/pm/launch.d.ts +51 -0
- package/node_modules/checkride/dist/pm/launch.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/launch.js +92 -0
- package/node_modules/checkride/dist/pm/launch.js.map +1 -0
- package/node_modules/checkride/dist/pm/tools.d.ts +73 -0
- package/node_modules/checkride/dist/pm/tools.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/tools.js +124 -0
- package/node_modules/checkride/dist/pm/tools.js.map +1 -0
- package/node_modules/checkride/dist/pm/translate.d.ts +35 -9
- package/node_modules/checkride/dist/pm/translate.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/translate.js +78 -18
- package/node_modules/checkride/dist/pm/translate.js.map +1 -1
- package/node_modules/checkride/dist/proc.d.ts +30 -0
- package/node_modules/checkride/dist/proc.d.ts.map +1 -0
- package/node_modules/checkride/dist/proc.js +42 -0
- package/node_modules/checkride/dist/proc.js.map +1 -0
- package/node_modules/checkride/dist/qa/cli.d.ts +20 -0
- package/node_modules/checkride/dist/qa/cli.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/cli.js +24 -0
- package/node_modules/checkride/dist/qa/cli.js.map +1 -0
- package/node_modules/checkride/dist/qa/dead.d.ts +39 -0
- package/node_modules/checkride/dist/qa/dead.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/dead.js +88 -0
- package/node_modules/checkride/dist/qa/dead.js.map +1 -0
- package/node_modules/checkride/dist/qa/dupes.d.ts +45 -0
- package/node_modules/checkride/dist/qa/dupes.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/dupes.js +62 -0
- package/node_modules/checkride/dist/qa/dupes.js.map +1 -0
- package/node_modules/checkride/dist/qa/health.d.ts +85 -0
- package/node_modules/checkride/dist/qa/health.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/health.js +109 -0
- package/node_modules/checkride/dist/qa/health.js.map +1 -0
- package/node_modules/checkride/dist/qa/index.d.ts +23 -0
- package/node_modules/checkride/dist/qa/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/index.js +22 -0
- package/node_modules/checkride/dist/qa/index.js.map +1 -0
- package/node_modules/checkride/dist/qa/mutation.d.ts +80 -0
- package/node_modules/checkride/dist/qa/mutation.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/mutation.js +195 -0
- package/node_modules/checkride/dist/qa/mutation.js.map +1 -0
- package/node_modules/checkride/dist/qa/qa.d.ts +71 -0
- package/node_modules/checkride/dist/qa/qa.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/qa.js +158 -0
- package/node_modules/checkride/dist/qa/qa.js.map +1 -0
- package/node_modules/checkride/dist/qa/read.d.ts +40 -0
- package/node_modules/checkride/dist/qa/read.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/read.js +47 -0
- package/node_modules/checkride/dist/qa/read.js.map +1 -0
- package/node_modules/checkride/dist/qa/render.d.ts +26 -0
- package/node_modules/checkride/dist/qa/render.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/render.js +310 -0
- package/node_modules/checkride/dist/qa/render.js.map +1 -0
- package/node_modules/checkride/dist/security.d.ts +45 -0
- package/node_modules/checkride/dist/security.d.ts.map +1 -0
- package/node_modules/checkride/dist/security.js +86 -0
- package/node_modules/checkride/dist/security.js.map +1 -0
- package/node_modules/checkride/dist/smoke.d.ts +5 -5
- package/node_modules/checkride/dist/smoke.js +5 -5
- package/node_modules/checkride/dist/snippets.d.ts +26 -29
- package/node_modules/checkride/dist/snippets.d.ts.map +1 -1
- package/node_modules/checkride/dist/snippets.js +26 -30
- package/node_modules/checkride/dist/snippets.js.map +1 -1
- package/node_modules/checkride/dist/tool-json.d.ts +33 -0
- package/node_modules/checkride/dist/tool-json.d.ts.map +1 -0
- package/node_modules/checkride/dist/tool-json.js +58 -0
- package/node_modules/checkride/dist/tool-json.js.map +1 -0
- package/node_modules/checkride/dist/triage/cli.d.ts +21 -0
- package/node_modules/checkride/dist/triage/cli.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/cli.js +26 -0
- package/node_modules/checkride/dist/triage/cli.js.map +1 -0
- package/node_modules/checkride/dist/triage/doctor-fold.d.ts +51 -0
- package/node_modules/checkride/dist/triage/doctor-fold.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/doctor-fold.js +88 -0
- package/node_modules/checkride/dist/triage/doctor-fold.js.map +1 -0
- package/node_modules/checkride/dist/triage/env.d.ts +54 -0
- package/node_modules/checkride/dist/triage/env.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/env.js +81 -0
- package/node_modules/checkride/dist/triage/env.js.map +1 -0
- package/node_modules/checkride/dist/triage/gate.d.ts +61 -0
- package/node_modules/checkride/dist/triage/gate.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/gate.js +121 -0
- package/node_modules/checkride/dist/triage/gate.js.map +1 -0
- package/node_modules/checkride/dist/triage/index.d.ts +22 -0
- package/node_modules/checkride/dist/triage/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/index.js +20 -0
- package/node_modules/checkride/dist/triage/index.js.map +1 -0
- package/node_modules/checkride/dist/triage/render.d.ts +19 -0
- package/node_modules/checkride/dist/triage/render.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/render.js +419 -0
- package/node_modules/checkride/dist/triage/render.js.map +1 -0
- package/node_modules/checkride/dist/triage/triage.d.ts +83 -0
- package/node_modules/checkride/dist/triage/triage.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/triage.js +131 -0
- package/node_modules/checkride/dist/triage/triage.js.map +1 -0
- package/node_modules/checkride/package.json +17 -15
- package/node_modules/checkride/schema/checkride.config.schema.json +62 -5
- package/node_modules/checkride/schema/checkride.summary.schema.json +1 -1
- package/node_modules/checkride/skills/check/SKILL.md +257 -0
- package/node_modules/checkride/skills/qa/SKILL.md +231 -0
- package/node_modules/checkride/templates/shared/cspell.json +1 -0
- package/node_modules/checkride/templates/shared/oxlintrc.json +1 -1
- package/package.json +2 -2
- package/skills/build/SKILL.md +23 -19
- package/skills/finish/SKILL.md +3 -1
- package/skills/harvest/SKILL.md +2 -1
- package/skills/plan/SKILL.md +8 -7
- package/skills/recover/SKILL.md +28 -0
- package/skills/refine/SKILL.md +5 -4
- package/skills/spike/SKILL.md +1 -1
- package/skills/step/SKILL.md +4 -4
- package/skills/verify/SKILL.md +19 -14
- package/templates/intent.md +8 -7
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rendering a {@link QaReport} as Markdown, under the same 8 KB ceiling
|
|
3
|
+
* `--digest` uses.
|
|
4
|
+
*
|
|
5
|
+
* The ledger is the head and never drops: which artifacts are evidence, which
|
|
6
|
+
* are days old, and which were never produced is the answer, not the preamble
|
|
7
|
+
* (D14). Each ledger row carries its own headline number, so even if the byte
|
|
8
|
+
* ceiling trims a detail section the score behind it survives.
|
|
9
|
+
*
|
|
10
|
+
* Detail sections follow in the order the skill reasons about them — surviving
|
|
11
|
+
* mutants, then dead code, then duplication, then complexity — and each is
|
|
12
|
+
* internally capped by its extractor, so the ceiling is a backstop rather than
|
|
13
|
+
* the usual path. When it does bind, whole sections drop from the end and are
|
|
14
|
+
* named; nothing is silently truncated mid-thought.
|
|
15
|
+
*
|
|
16
|
+
* No artifact's *contents* appear here beyond located samples and file names.
|
|
17
|
+
* The one place source text surfaces at all is a clipped mutant replacement,
|
|
18
|
+
* which is the only way a line number becomes actionable without opening a
|
|
19
|
+
* 2.3 MB file.
|
|
20
|
+
*/
|
|
21
|
+
import { formatBytes, formatDuration } from '../artifacts/index.js';
|
|
22
|
+
/** Matches `--digest`'s ceiling: a report that reads in one gulp. */
|
|
23
|
+
export const QA_MAX_BYTES = 8000;
|
|
24
|
+
const NOT_READ_NOTE = 'Not read: the full contents of any `.check/` artifact. Every list above is capped and every ' +
|
|
25
|
+
'count is from a full pass, so a short list is a *ranked* list, never a complete one — open the ' +
|
|
26
|
+
'named artifact when a specific finding is the one you are working on.';
|
|
27
|
+
const NOTHING_RUN_NOTE = 'This reader ran nothing. Every number above is whatever the last run left in `.check/`, which ' +
|
|
28
|
+
'may be a narrow run — check `covered` above before treating a clean artifact as a clean repo.';
|
|
29
|
+
function bullets(items) {
|
|
30
|
+
return items.map((item) => `- ${item}`).join('\n');
|
|
31
|
+
}
|
|
32
|
+
function table(head, rows) {
|
|
33
|
+
return [`| ${head.join(' | ')} |`, `| ${head.map(() => '---').join(' | ')} |`, ...rows].join('\n');
|
|
34
|
+
}
|
|
35
|
+
/** `70.96%`, or `—` when nothing was measurable. `places` matches the tool's. */
|
|
36
|
+
function pct(value, places = 1) {
|
|
37
|
+
return value === null ? '—' : `${value.toFixed(places)}%`;
|
|
38
|
+
}
|
|
39
|
+
function count(value) {
|
|
40
|
+
return value === null ? '—' : String(value);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A code span whose fence outgrows any backtick run inside `text`. Mutant
|
|
44
|
+
* replacements are source, and stryker's `StringLiteral` mutator turns a
|
|
45
|
+
* template literal into one made of backticks — a fixed single-backtick span
|
|
46
|
+
* would break and swallow the rest of the line.
|
|
47
|
+
*/
|
|
48
|
+
function code(text) {
|
|
49
|
+
const runs = [...text.matchAll(/`+/g)].map((match) => match[0].length);
|
|
50
|
+
const fence = '`'.repeat(Math.max(0, ...runs) + 1);
|
|
51
|
+
const pad = text.startsWith('`') || text.endsWith('`') ? ' ' : '';
|
|
52
|
+
return `${fence}${pad}${text}${pad}${fence}`;
|
|
53
|
+
}
|
|
54
|
+
/* -------------------------------------------------------------- the ledger */
|
|
55
|
+
/** The four-state answer, plus the two ways a file can be unusable. */
|
|
56
|
+
function stateOf(entry) {
|
|
57
|
+
if (entry.problem === 'absent')
|
|
58
|
+
return entry.optedIn === false ? 'not opted in' : 'absent';
|
|
59
|
+
if (entry.problem !== null)
|
|
60
|
+
return entry.problem;
|
|
61
|
+
return entry.file?.freshness.state === 'stale' ? 'STALE' : 'read';
|
|
62
|
+
}
|
|
63
|
+
function ageOf(entry) {
|
|
64
|
+
const freshness = entry.file?.freshness;
|
|
65
|
+
if (freshness === undefined)
|
|
66
|
+
return '—';
|
|
67
|
+
if (freshness.state === 'stale')
|
|
68
|
+
return formatDuration(freshness.ageMs ?? 0);
|
|
69
|
+
return freshness.state === 'fresh' ? 'fresh' : '?';
|
|
70
|
+
}
|
|
71
|
+
function mutationHeadline(extract) {
|
|
72
|
+
return `score ${pct(extract.score, 2)} · ${extract.survived} survived · ${extract.noCoverage} no-coverage`;
|
|
73
|
+
}
|
|
74
|
+
function deadHeadline(extract) {
|
|
75
|
+
return `${count(extract.totalIssues)} issue(s) · ${extract.buckets.length} non-empty bucket(s)`;
|
|
76
|
+
}
|
|
77
|
+
function dupesHeadline(extract) {
|
|
78
|
+
return `${pct(extract.duplicationPercentage)} duplicated · ${extract.cloneGroups} clone group(s)`;
|
|
79
|
+
}
|
|
80
|
+
function healthHeadline(extract) {
|
|
81
|
+
const over = extract.totalFindings;
|
|
82
|
+
return `${extract.score === null ? '—' : extract.score.toFixed(1)}/${extract.grade} · ${over} function(s) over threshold`;
|
|
83
|
+
}
|
|
84
|
+
function headlineFor(report, slot) {
|
|
85
|
+
if (slot === 'mutation')
|
|
86
|
+
return report.mutation === null ? '—' : mutationHeadline(report.mutation);
|
|
87
|
+
if (slot === 'dead')
|
|
88
|
+
return report.dead === null ? '—' : deadHeadline(report.dead);
|
|
89
|
+
if (slot === 'dupes')
|
|
90
|
+
return report.dupes === null ? '—' : dupesHeadline(report.dupes);
|
|
91
|
+
return report.health === null ? '—' : healthHeadline(report.health);
|
|
92
|
+
}
|
|
93
|
+
function ledgerRow(report, entry) {
|
|
94
|
+
const size = entry.file === null ? '—' : formatBytes(entry.file.bytes);
|
|
95
|
+
return `| \`.check/${entry.artifact}\` | ${stateOf(entry)} | ${size} | ${ageOf(entry)} | ${headlineFor(report, entry.slot)} |`;
|
|
96
|
+
}
|
|
97
|
+
/** Where this artifact came from, when that is not "the run described above". */
|
|
98
|
+
function provenanceReason(entry) {
|
|
99
|
+
if (entry.optedIn === false) {
|
|
100
|
+
return `\`${entry.slot}\` is not named in \`checkride.config.json\`, so no \`checkride\` run produces it`;
|
|
101
|
+
}
|
|
102
|
+
if (!entry.ranThisRun) {
|
|
103
|
+
return `\`${entry.slot}\` has no entry in the summary on disk, so nothing here is from that run`;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function stalenessReason(entry) {
|
|
108
|
+
const freshness = entry.file?.freshness;
|
|
109
|
+
if (freshness?.state !== 'stale')
|
|
110
|
+
return null;
|
|
111
|
+
return `the file is ${formatDuration(freshness.ageMs ?? 0)} older than that run's start`;
|
|
112
|
+
}
|
|
113
|
+
/** Why the fold produced nothing. Every problem state names itself. */
|
|
114
|
+
const PROBLEM_REASON = {
|
|
115
|
+
absent: () => 'nothing is on disk',
|
|
116
|
+
'too-large': () => "the file is past this reader's parse ceiling",
|
|
117
|
+
unreadable: (entry) => `the file is ${entry.detail ?? 'unparseable'}`,
|
|
118
|
+
unrecognized: () => 'the file parsed but is not the report this slot writes',
|
|
119
|
+
};
|
|
120
|
+
function problemReason(entry) {
|
|
121
|
+
return entry.problem === null ? null : (PROBLEM_REASON[entry.problem]?.(entry) ?? null);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The prose beside a row that is not plain evidence — provenance first, then
|
|
125
|
+
* age, then why nothing was folded, then the remedy. A row with nothing to say
|
|
126
|
+
* produces no note at all, so a clean ledger is a bare table.
|
|
127
|
+
*/
|
|
128
|
+
function ledgerNote(entry) {
|
|
129
|
+
const why = [provenanceReason(entry), stalenessReason(entry), problemReason(entry)].filter((reason) => reason !== null);
|
|
130
|
+
return why.length === 0 ? null : `**${entry.slot}** — ${why.join('; ')}. ${entry.remedy}`;
|
|
131
|
+
}
|
|
132
|
+
function renderLedger(report) {
|
|
133
|
+
const rows = report.ledger.map((entry) => ledgerRow(report, entry));
|
|
134
|
+
const notes = report.ledger.map(ledgerNote).filter((note) => note !== null);
|
|
135
|
+
const body = table(['artifact', 'state', 'size', 'age', 'headline'], rows);
|
|
136
|
+
return notes.length === 0 ? body : `${body}\n\n${bullets(notes)}`;
|
|
137
|
+
}
|
|
138
|
+
/* --------------------------------------------------------------- the head */
|
|
139
|
+
/**
|
|
140
|
+
* How long ago the run finished. A summary stamped in the *future* is a real
|
|
141
|
+
* condition — a skewed clock on the machine that wrote it — and saying so beats
|
|
142
|
+
* printing a negative duration, because the same skew is what will have made
|
|
143
|
+
* every artifact beside it look stale.
|
|
144
|
+
*/
|
|
145
|
+
function ageClause(ageMs) {
|
|
146
|
+
if (ageMs === null)
|
|
147
|
+
return 'age unknown';
|
|
148
|
+
if (ageMs < 0)
|
|
149
|
+
return `stamped ${formatDuration(-ageMs)} IN THE FUTURE — the writing clock is ahead`;
|
|
150
|
+
return `${formatDuration(ageMs)} ago`;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Why the summary is unusable, in the words that distinguish the cases. An
|
|
154
|
+
* absent `schema_version` means a stranger wrote this file, which is a
|
|
155
|
+
* different report from a checkride that is simply newer than this reader.
|
|
156
|
+
*/
|
|
157
|
+
function summaryProblem(summary) {
|
|
158
|
+
if (summary.state === 'foreign')
|
|
159
|
+
return 'no `schema_version` field — NOT written by checkride';
|
|
160
|
+
if (summary.state === 'schema-mismatch')
|
|
161
|
+
return `\`schema_version\` is ${JSON.stringify(summary.found)}, not 1; STOP`;
|
|
162
|
+
return summary.state;
|
|
163
|
+
}
|
|
164
|
+
/** Provenance first: what wrote these artifacts, when, and over which slots. */
|
|
165
|
+
function renderHead(report) {
|
|
166
|
+
const { summary } = report;
|
|
167
|
+
const at = '`.check/summary.json`';
|
|
168
|
+
const provenance = summary.state === 'ok'
|
|
169
|
+
? `${at} — \`schema_version\` 1, ${ageClause(report.summaryAgeMs)}, ${formatDuration(summary.summary.total_duration_ms)}`
|
|
170
|
+
: `${at} — ${summaryProblem(summary)}`;
|
|
171
|
+
const covered = report.covered.length === 0
|
|
172
|
+
? 'covered: nothing — no readable summary, so the artifacts below belong to no known run'
|
|
173
|
+
: `covered: ${report.covered.length} slot(s) ran — ${report.covered.join(', ')}`;
|
|
174
|
+
const lines = [`summary: ${provenance}`, covered];
|
|
175
|
+
if (report.skipped.length > 0)
|
|
176
|
+
lines.push(`skipped: ${report.skipped.join(', ')}`);
|
|
177
|
+
return `# checkride qa\n\n${bullets(lines)}\n\n## artifacts\n\n${renderLedger(report)}\n`;
|
|
178
|
+
}
|
|
179
|
+
/* ----------------------------------------------------------- the sections */
|
|
180
|
+
function mutationRow(file) {
|
|
181
|
+
const mutators = file.mutators.map((m) => `${m.mutator} ${m.count}`).join(', ');
|
|
182
|
+
return `| \`${file.path}\` | ${pct(file.score, 1)} | ${file.survived} | ${file.noCoverage} | ${file.tested} | ${mutators} |`;
|
|
183
|
+
}
|
|
184
|
+
function sampleLine(sample) {
|
|
185
|
+
const where = `\`${sample.path}\`${sample.line === null ? '' : `:${sample.line}`}`;
|
|
186
|
+
return `${where} — ${sample.mutator} → ${code(sample.replacement)} (${sample.status})`;
|
|
187
|
+
}
|
|
188
|
+
function renderMutation(report) {
|
|
189
|
+
const m = report.mutation;
|
|
190
|
+
if (m === null)
|
|
191
|
+
return '';
|
|
192
|
+
const counts = `Score **${pct(m.score, 2)}** (detected ÷ tested — stryker's own headline), ${pct(m.scoreCovered, 2)} ` +
|
|
193
|
+
`counting only mutants a test reaches.\n\n` +
|
|
194
|
+
`${m.killed} killed · ${m.timeout} timeout · **${m.survived} survived** · **${m.noCoverage} no-coverage** · ` +
|
|
195
|
+
`${m.ignored} ignored${m.other > 0 ? ` · ${m.other} errored` : ''} — ${m.total} mutant(s) over ${m.totalFiles} file(s).\n\n` +
|
|
196
|
+
'No-coverage means no test reaches the line at all; survived means a test reaches it and asserts ' +
|
|
197
|
+
'nothing that would notice the change. They want different fixes.';
|
|
198
|
+
const rows = m.files.map(mutationRow);
|
|
199
|
+
const ranking = `\nRanked by undetected (survived + no-coverage) count${m.omittedFiles > 0 ? `; ${m.omittedFiles} more file(s) not shown` : ''}.`;
|
|
200
|
+
const mutators = `\nUndetected by mutator: ${m.mutators.map((x) => `${x.mutator} ${x.count}`).join(', ')}.`;
|
|
201
|
+
const samples = m.samples.length === 0 ? '' : `\n\nLocated samples (worst files only):\n\n${bullets(m.samples.map(sampleLine))}`;
|
|
202
|
+
return `${counts}\n\n${table(['file', 'score', 'survived', 'no-cov', 'tested', 'top undetected mutators'], rows)}\n${ranking}\n${mutators}${samples}`;
|
|
203
|
+
}
|
|
204
|
+
function renderDead(report) {
|
|
205
|
+
const d = report.dead;
|
|
206
|
+
if (d === null)
|
|
207
|
+
return '';
|
|
208
|
+
const head = `${count(d.totalIssues)} issue(s) across ${count(d.entryPoints)} entry point(s).`;
|
|
209
|
+
if (d.buckets.length === 0)
|
|
210
|
+
return `${head} No finding bucket is non-empty.`;
|
|
211
|
+
const rows = d.buckets.map((b) => `| ${b.name} | ${b.count} | ${b.samples.map((s) => `\`${s}\``).join(', ')} |`);
|
|
212
|
+
const omitted = d.omittedBuckets > 0 ? `\n\n${d.omittedBuckets} more non-empty bucket(s) not shown.` : '';
|
|
213
|
+
return `${head}\n\n${table(['bucket', 'count', 'first few'], rows)}${omitted}`;
|
|
214
|
+
}
|
|
215
|
+
function renderDupes(report) {
|
|
216
|
+
const d = report.dupes;
|
|
217
|
+
if (d === null)
|
|
218
|
+
return '';
|
|
219
|
+
const head = `${pct(d.duplicationPercentage)} duplicated — ${count(d.duplicatedLines)} of ${count(d.totalLines)} line(s) ` +
|
|
220
|
+
`across ${count(d.totalFiles)} file(s); ${d.cloneGroups} clone group(s) in ${d.totalFamilies} families.`;
|
|
221
|
+
if (d.families.length === 0)
|
|
222
|
+
return head;
|
|
223
|
+
const rows = d.families.map((f) => {
|
|
224
|
+
const files = [...f.files, ...(f.omittedFiles > 0 ? [`+${f.omittedFiles} more`] : [])];
|
|
225
|
+
return `| ${files.map((x) => `\`${x}\``).join(', ')} | ${f.groups} | ${count(f.lines)} | ${count(f.tokens)} |`;
|
|
226
|
+
});
|
|
227
|
+
const omitted = d.omittedFamilies > 0 ? `\n\n${d.omittedFamilies} more families not shown.` : '';
|
|
228
|
+
return `${head}\n\n${table(['files', 'groups', 'lines', 'tokens'], rows)}${omitted}`;
|
|
229
|
+
}
|
|
230
|
+
function healthFindingRow(finding) {
|
|
231
|
+
return `| \`${finding.path}\`:${count(finding.line)} | ${finding.name} | ${finding.exceeded} | ${finding.severity} | ${count(finding.cyclomatic)} | ${count(finding.cognitive)} | ${count(finding.lineCount)} |`;
|
|
232
|
+
}
|
|
233
|
+
function hotspotRow(hotspot) {
|
|
234
|
+
return `| \`${hotspot.path}\` | ${count(hotspot.score)} | ${count(hotspot.commits)} | ${count(hotspot.complexityDensity)} | ${hotspot.trend} |`;
|
|
235
|
+
}
|
|
236
|
+
function healthFindings(h) {
|
|
237
|
+
const { cyclomatic, cognitive, crap, unitSize } = h.thresholds;
|
|
238
|
+
const thresholds = `Thresholds — cyclomatic ${count(cyclomatic)}, cognitive ${count(cognitive)}, CRAP ${count(crap)}, unit size ${count(unitSize)}.`;
|
|
239
|
+
if (h.totalFindings === 0)
|
|
240
|
+
return `${thresholds} No function is over any of them.`;
|
|
241
|
+
const grouped = h.byThreshold.map((g) => `${g.exceeded} ${g.count}`).join(', ');
|
|
242
|
+
const omitted = h.omittedFindings > 0 ? `\n\n${h.omittedFindings} more finding(s) not shown.` : '';
|
|
243
|
+
return (`${thresholds} ${h.totalFindings} function(s) over — by threshold: ${grouped}.\n\n` +
|
|
244
|
+
`${table(['function', 'name', 'exceeded', 'severity', 'cyc', 'cog', 'lines'], h.findings.map(healthFindingRow))}${omitted}`);
|
|
245
|
+
}
|
|
246
|
+
function renderHealth(report) {
|
|
247
|
+
const h = report.health;
|
|
248
|
+
if (h === null)
|
|
249
|
+
return '';
|
|
250
|
+
const penalties = h.penalties.length === 0
|
|
251
|
+
? 'No penalty is non-zero.'
|
|
252
|
+
: `Penalties: ${h.penalties.map((p) => `**${p.name} ${p.points}**`).join(', ')}${h.zeroPenalties > 0 ? ` (${h.zeroPenalties} more at zero)` : ''}.`;
|
|
253
|
+
const head = `Score **${h.score === null ? '—' : h.score.toFixed(1)}** (grade ${h.grade}, formula v${count(h.formulaVersion)}) ` +
|
|
254
|
+
`over ${count(h.filesAnalyzed)} file(s) and ${count(h.functionsAnalyzed)} function(s); ` +
|
|
255
|
+
`average maintainability ${count(h.averageMaintainability)}.\n\n${penalties} ` +
|
|
256
|
+
'The score is 100 minus these, so the non-zero ones are the whole explanation of the grade.';
|
|
257
|
+
const hotspots = h.hotspots.length === 0
|
|
258
|
+
? ''
|
|
259
|
+
: `\n\nHotspots — complex *and* frequently changed (${h.hotspots.length} of ${h.totalHotspots}):\n\n${table(['file', 'score', 'commits', 'complexity density', 'trend'], h.hotspots.map(hotspotRow))}`;
|
|
260
|
+
return `${head}\n\n${healthFindings(h)}${hotspots}`;
|
|
261
|
+
}
|
|
262
|
+
function assemble(head, all, kept, maxBytes) {
|
|
263
|
+
const keeping = new Set(kept);
|
|
264
|
+
const dropped = all.filter((section) => !keeping.has(section)).map((section) => section.title);
|
|
265
|
+
const body = kept.map((section) => `\n## ${section.title}\n\n${section.body}\n`).join('');
|
|
266
|
+
const note = dropped.length === 0
|
|
267
|
+
? ''
|
|
268
|
+
: `\n_Trimmed to fit ${maxBytes} bytes; section(s) omitted: ${dropped.join(', ')}. ` +
|
|
269
|
+
'Their headline numbers are in the ledger above; read the named artifact for the rest._\n';
|
|
270
|
+
return `${head}${body}${note}\n## reading this\n\n${bullets([NOTHING_RUN_NOTE, NOT_READ_NOTE])}\n`;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Fill the budget in priority order: take each section that still fits, skip
|
|
274
|
+
* the ones that do not, and name what was skipped.
|
|
275
|
+
*
|
|
276
|
+
* Greedy rather than dropping from the end, because the sections are wildly
|
|
277
|
+
* uneven — `mutation` is most of the bytes and `dupes` is a line or two — so
|
|
278
|
+
* trimming the tail frees nothing until it reaches the one section worth
|
|
279
|
+
* keeping, and then overshoots the budget by half. Skipping only what does not
|
|
280
|
+
* fit keeps the most important section *and* whatever small ones fit around it.
|
|
281
|
+
*
|
|
282
|
+
* The ledger in `head` is never at risk, so every headline number survives any
|
|
283
|
+
* amount of trimming. The second pass exists because the "omitted" note is
|
|
284
|
+
* itself bytes: a section admitted before the note existed can stop fitting
|
|
285
|
+
* once it does, and dropping from the end there converges (the note stops
|
|
286
|
+
* growing once everything is dropped).
|
|
287
|
+
*/
|
|
288
|
+
function fit(head, sections, maxBytes) {
|
|
289
|
+
const over = (kept) => Buffer.byteLength(assemble(head, sections, kept, maxBytes), 'utf8') > maxBytes;
|
|
290
|
+
const kept = [];
|
|
291
|
+
for (const section of sections) {
|
|
292
|
+
kept.push(section);
|
|
293
|
+
if (over(kept))
|
|
294
|
+
kept.pop();
|
|
295
|
+
}
|
|
296
|
+
while (kept.length > 0 && over(kept))
|
|
297
|
+
kept.pop();
|
|
298
|
+
return assemble(head, sections, kept, maxBytes);
|
|
299
|
+
}
|
|
300
|
+
/** Render the whole report. Deterministic: same report in, same bytes out. */
|
|
301
|
+
export function renderQa(report, maxBytes = QA_MAX_BYTES) {
|
|
302
|
+
const sections = [
|
|
303
|
+
{ title: 'mutation', body: renderMutation(report) },
|
|
304
|
+
{ title: 'dead', body: renderDead(report) },
|
|
305
|
+
{ title: 'dupes', body: renderDupes(report) },
|
|
306
|
+
{ title: 'health', body: renderHealth(report) },
|
|
307
|
+
].filter((section) => section.body !== '');
|
|
308
|
+
return fit(renderHead(report), sections, maxBytes);
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/qa/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in `security` check — `pnpm audit` with checkride owning the verdict.
|
|
3
|
+
*
|
|
4
|
+
* pnpm's JSON mode exits 1 on *any* advisory regardless of `--audit-level`
|
|
5
|
+
* (only table mode lets the level gate the exit code), so judging this slot by
|
|
6
|
+
* exit code made it gate at zero advisories of any severity — not the level
|
|
7
|
+
* the adapter's args declare. The evaluator here runs the audit with `--json`,
|
|
8
|
+
* parses `metadata.vulnerabilities`, and fails only when advisories sit at or
|
|
9
|
+
* above the threshold parsed from the args themselves, so a consumer override
|
|
10
|
+
* of `--audit-level` keeps meaning what it says.
|
|
11
|
+
*
|
|
12
|
+
* "Could not run" (registry unreachable, malformed output) is distinguished
|
|
13
|
+
* from "ran; everything below the level": the former fails with the error
|
|
14
|
+
* surfaced, the latter is green. The raw audit JSON is passed through on
|
|
15
|
+
* stdout, so the orchestrator persists `.check/security.json` as before.
|
|
16
|
+
*/
|
|
17
|
+
import type { CheckOutcome } from './links.js';
|
|
18
|
+
/** The audit subprocess spawner — same signature as the orchestrator's `spawnCheck`. */
|
|
19
|
+
export type AuditSpawn = (command: string, args: string[], cwd: string, timeoutSec?: number) => Promise<CheckOutcome>;
|
|
20
|
+
/** `--audit-level` vocabulary, weakest first. `info` never gates (as in pnpm). */
|
|
21
|
+
declare const LEVELS: readonly ["low", "moderate", "high", "critical"];
|
|
22
|
+
export type AuditLevel = (typeof LEVELS)[number];
|
|
23
|
+
/**
|
|
24
|
+
* The gate threshold the args declare. Absent flag → `'low'`, mirroring the
|
|
25
|
+
* tool's own default so the invocation and the verdict can never disagree; an
|
|
26
|
+
* unrecognized value also falls back to `'low'` (gate wider, never narrower,
|
|
27
|
+
* on a typo).
|
|
28
|
+
*/
|
|
29
|
+
export declare function auditLevelFromArgs(args: readonly string[]): AuditLevel;
|
|
30
|
+
/**
|
|
31
|
+
* Run the `security` check against `cwd`. `args` are the resolved adapter args
|
|
32
|
+
* (`audit --audit-level=<l> …`, config overrides included); `--json` is
|
|
33
|
+
* appended when an override dropped it, since the evaluator needs the payload.
|
|
34
|
+
* Never throws: a spawn failure or unparseable output resolves to a failing
|
|
35
|
+
* outcome that surfaces the tool's own message.
|
|
36
|
+
*/
|
|
37
|
+
export declare function checkSecurity(opts: {
|
|
38
|
+
cwd: string;
|
|
39
|
+
command: string;
|
|
40
|
+
args: readonly string[];
|
|
41
|
+
spawn: AuditSpawn;
|
|
42
|
+
timeoutSec?: number;
|
|
43
|
+
}): Promise<CheckOutcome>;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,wFAAwF;AACxF,MAAM,MAAM,UAAU,GAAG,CACvB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,MAAM,KAChB,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B,kFAAkF;AAClF,QAAA,MAAM,MAAM,kDAAmD,CAAC;AAChE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAItE;AAoBD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,YAAY,CAAC,CAqCxB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in `security` check — `pnpm audit` with checkride owning the verdict.
|
|
3
|
+
*
|
|
4
|
+
* pnpm's JSON mode exits 1 on *any* advisory regardless of `--audit-level`
|
|
5
|
+
* (only table mode lets the level gate the exit code), so judging this slot by
|
|
6
|
+
* exit code made it gate at zero advisories of any severity — not the level
|
|
7
|
+
* the adapter's args declare. The evaluator here runs the audit with `--json`,
|
|
8
|
+
* parses `metadata.vulnerabilities`, and fails only when advisories sit at or
|
|
9
|
+
* above the threshold parsed from the args themselves, so a consumer override
|
|
10
|
+
* of `--audit-level` keeps meaning what it says.
|
|
11
|
+
*
|
|
12
|
+
* "Could not run" (registry unreachable, malformed output) is distinguished
|
|
13
|
+
* from "ran; everything below the level": the former fails with the error
|
|
14
|
+
* surfaced, the latter is green. The raw audit JSON is passed through on
|
|
15
|
+
* stdout, so the orchestrator persists `.check/security.json` as before.
|
|
16
|
+
*/
|
|
17
|
+
import { isRecord } from './json.js';
|
|
18
|
+
import { parseToolJson } from './tool-json.js';
|
|
19
|
+
/** `--audit-level` vocabulary, weakest first. `info` never gates (as in pnpm). */
|
|
20
|
+
const LEVELS = ['low', 'moderate', 'high', 'critical'];
|
|
21
|
+
/**
|
|
22
|
+
* The gate threshold the args declare. Absent flag → `'low'`, mirroring the
|
|
23
|
+
* tool's own default so the invocation and the verdict can never disagree; an
|
|
24
|
+
* unrecognized value also falls back to `'low'` (gate wider, never narrower,
|
|
25
|
+
* on a typo).
|
|
26
|
+
*/
|
|
27
|
+
export function auditLevelFromArgs(args) {
|
|
28
|
+
const flag = args.find((a) => a.startsWith('--audit-level='));
|
|
29
|
+
const value = flag?.slice('--audit-level='.length);
|
|
30
|
+
return LEVELS.find((l) => l === value) ?? 'low';
|
|
31
|
+
}
|
|
32
|
+
/** Per-severity advisory counts out of `metadata.vulnerabilities`, absent keys as 0. */
|
|
33
|
+
function severityCounts(value) {
|
|
34
|
+
if (!isRecord(value))
|
|
35
|
+
return null;
|
|
36
|
+
const metadata = value['metadata'];
|
|
37
|
+
if (!isRecord(metadata))
|
|
38
|
+
return null;
|
|
39
|
+
const vulnerabilities = metadata['vulnerabilities'];
|
|
40
|
+
if (!isRecord(vulnerabilities))
|
|
41
|
+
return null;
|
|
42
|
+
const counts = {};
|
|
43
|
+
for (const [severity, count] of Object.entries(vulnerabilities)) {
|
|
44
|
+
counts[severity] = typeof count === 'number' ? count : 0;
|
|
45
|
+
}
|
|
46
|
+
return counts;
|
|
47
|
+
}
|
|
48
|
+
function fail(stdout, stderr) {
|
|
49
|
+
return { ok: false, exit_code: 1, stdout, stderr };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Run the `security` check against `cwd`. `args` are the resolved adapter args
|
|
53
|
+
* (`audit --audit-level=<l> …`, config overrides included); `--json` is
|
|
54
|
+
* appended when an override dropped it, since the evaluator needs the payload.
|
|
55
|
+
* Never throws: a spawn failure or unparseable output resolves to a failing
|
|
56
|
+
* outcome that surfaces the tool's own message.
|
|
57
|
+
*/
|
|
58
|
+
export async function checkSecurity(opts) {
|
|
59
|
+
const { cwd, command, spawn, timeoutSec } = opts;
|
|
60
|
+
const args = opts.args.includes('--json') ? [...opts.args] : [...opts.args, '--json'];
|
|
61
|
+
const level = auditLevelFromArgs(args);
|
|
62
|
+
const outcome = await spawn(command, args, cwd, timeoutSec);
|
|
63
|
+
const json = parseToolJson(outcome.stdout);
|
|
64
|
+
const counts = json ? severityCounts(json.value) : null;
|
|
65
|
+
if (!counts) {
|
|
66
|
+
// No parseable verdict — the audit didn't run (registry down, bad flag,
|
|
67
|
+
// timeout), which is a failure to verify, never a pass.
|
|
68
|
+
const detail = outcome.stderr.trim() || outcome.stdout.trim();
|
|
69
|
+
return fail(outcome.stdout, `check-security: ${command} audit produced no readable JSON verdict (exit ${outcome.exit_code})${detail ? `\n${detail.slice(0, 500)}` : ''}\n`);
|
|
70
|
+
}
|
|
71
|
+
const gating = LEVELS.slice(LEVELS.indexOf(level));
|
|
72
|
+
const above = gating.map((s) => [s, counts[s] ?? 0]).filter(([, n]) => n > 0);
|
|
73
|
+
const total = Object.values(counts).reduce((a, b) => a + b, 0);
|
|
74
|
+
if (above.length === 0) {
|
|
75
|
+
const note = total > 0 ? `${total} advisor${total === 1 ? 'y' : 'ies'} below --audit-level=${level}` : 'no advisories';
|
|
76
|
+
return {
|
|
77
|
+
ok: true,
|
|
78
|
+
exit_code: 0,
|
|
79
|
+
stdout: outcome.stdout,
|
|
80
|
+
stderr: `check-security: ${note}; gate clean\n`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const breakdown = above.map(([s, n]) => `${n} ${s}`).join(', ');
|
|
84
|
+
return fail(outcome.stdout, `check-security: advisories at or above --audit-level=${level}: ${breakdown}\n`);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Built-in `smoke` check
|
|
2
|
+
* Built-in `smoke` check — a **liveness** probe of the built package, not a
|
|
3
3
|
* type check (runtime *shapes* stay attw's job; the slots don't overlap).
|
|
4
4
|
*
|
|
5
5
|
* It enumerates the manifest's `exports` subpaths (falling back to `main`),
|
|
6
6
|
* writes a self-contained probe script under `.check/`, and spawns a fresh
|
|
7
7
|
* `node` on it (never in-process — isolation, the per-check timeout, and the
|
|
8
|
-
* orchestrator's SIGTERM→SIGKILL reaping all apply
|
|
8
|
+
* orchestrator's SIGTERM→SIGKILL reaping all apply). The probe asserts,
|
|
9
9
|
* for every literal subpath:
|
|
10
10
|
*
|
|
11
11
|
* - the built entry `await import()`s without throwing, and (for a dual
|
|
12
12
|
* package, i.e. a subpath carrying an explicit `require` condition) also
|
|
13
13
|
* `require()`s cleanly — both through package **self-reference**
|
|
14
14
|
* (`import '<pkg>/<subpath>'`), exercising the real `exports`-map resolution
|
|
15
|
-
* a consumer would hit
|
|
15
|
+
* a consumer would hit;
|
|
16
16
|
* - every **value** export named in the matching dist `.d.ts` is present at
|
|
17
17
|
* runtime. Export names come from a conservative, dependency-free `.d.ts`
|
|
18
18
|
* scanner ({@link scanValueExports}) that errs toward *under*-collection: a
|
|
@@ -52,7 +52,7 @@ export type SmokeTarget = {
|
|
|
52
52
|
hasRequire: boolean;
|
|
53
53
|
};
|
|
54
54
|
/**
|
|
55
|
-
* Enumerate the smoke targets from a manifest
|
|
55
|
+
* Enumerate the smoke targets from a manifest: every literal `exports`
|
|
56
56
|
* subpath, or the `main` entry when there is no `exports` field. Wildcard and
|
|
57
57
|
* `null` subpaths are skipped with a reason (they name no single file). The
|
|
58
58
|
* self-reference `specifier` is derived from the package `name`.
|
|
@@ -62,7 +62,7 @@ export declare function enumerateExports(manifest: Record<string, unknown>): {
|
|
|
62
62
|
skipped: SmokeSkip[];
|
|
63
63
|
};
|
|
64
64
|
/**
|
|
65
|
-
* Scan a dist `.d.ts` for the **value** exports a live module must expose
|
|
65
|
+
* Scan a dist `.d.ts` for the **value** exports a live module must expose:
|
|
66
66
|
* `export declare function|const|class|enum` and the non-`type` specifiers of
|
|
67
67
|
* `export { … }` (aliases resolve to the exported name). Type-only forms —
|
|
68
68
|
* `export type`, `export interface`, `export type { … }`, and `{ type X }`
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Built-in `smoke` check
|
|
2
|
+
* Built-in `smoke` check — a **liveness** probe of the built package, not a
|
|
3
3
|
* type check (runtime *shapes* stay attw's job; the slots don't overlap).
|
|
4
4
|
*
|
|
5
5
|
* It enumerates the manifest's `exports` subpaths (falling back to `main`),
|
|
6
6
|
* writes a self-contained probe script under `.check/`, and spawns a fresh
|
|
7
7
|
* `node` on it (never in-process — isolation, the per-check timeout, and the
|
|
8
|
-
* orchestrator's SIGTERM→SIGKILL reaping all apply
|
|
8
|
+
* orchestrator's SIGTERM→SIGKILL reaping all apply). The probe asserts,
|
|
9
9
|
* for every literal subpath:
|
|
10
10
|
*
|
|
11
11
|
* - the built entry `await import()`s without throwing, and (for a dual
|
|
12
12
|
* package, i.e. a subpath carrying an explicit `require` condition) also
|
|
13
13
|
* `require()`s cleanly — both through package **self-reference**
|
|
14
14
|
* (`import '<pkg>/<subpath>'`), exercising the real `exports`-map resolution
|
|
15
|
-
* a consumer would hit
|
|
15
|
+
* a consumer would hit;
|
|
16
16
|
* - every **value** export named in the matching dist `.d.ts` is present at
|
|
17
17
|
* runtime. Export names come from a conservative, dependency-free `.d.ts`
|
|
18
18
|
* scanner ({@link scanValueExports}) that errs toward *under*-collection: a
|
|
@@ -142,7 +142,7 @@ function mainTarget(manifest) {
|
|
|
142
142
|
return { subpath: '.', specifier: null, importFile: normalize(main), requireFile: null, typesFile, hasRequire: false };
|
|
143
143
|
}
|
|
144
144
|
/**
|
|
145
|
-
* Enumerate the smoke targets from a manifest
|
|
145
|
+
* Enumerate the smoke targets from a manifest: every literal `exports`
|
|
146
146
|
* subpath, or the `main` entry when there is no `exports` field. Wildcard and
|
|
147
147
|
* `null` subpaths are skipped with a reason (they name no single file). The
|
|
148
148
|
* self-reference `specifier` is derived from the package `name`.
|
|
@@ -196,7 +196,7 @@ function namedExportBinding(spec) {
|
|
|
196
196
|
return exported !== undefined && /^[A-Za-z_$][\w$]*$/.test(exported) ? exported : null;
|
|
197
197
|
}
|
|
198
198
|
/**
|
|
199
|
-
* Scan a dist `.d.ts` for the **value** exports a live module must expose
|
|
199
|
+
* Scan a dist `.d.ts` for the **value** exports a live module must expose:
|
|
200
200
|
* `export declare function|const|class|enum` and the non-`type` specifiers of
|
|
201
201
|
* `export { … }` (aliases resolve to the exported name). Type-only forms —
|
|
202
202
|
* `export type`, `export interface`, `export type { … }`, and `{ type X }`
|