plumbbob 0.9.3 → 0.10.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/.claude-plugin/plugin.json +1 -1
- package/README.md +92 -89
- package/dist/cli-core.js +25 -8
- package/dist/cli.js +1 -1
- package/dist/lib/agents.js +26 -26
- package/dist/lib/buildlog.js +11 -11
- package/dist/lib/buildlogsync.js +8 -8
- package/dist/lib/check.js +55 -22
- package/dist/lib/commitbody.js +72 -0
- package/dist/lib/commitmsg.js +7 -7
- package/dist/lib/git.js +44 -15
- package/dist/lib/intent.js +21 -20
- package/dist/lib/latch.js +19 -19
- package/dist/lib/orient.js +36 -17
- package/dist/lib/reentry.js +70 -0
- package/dist/lib/settings.js +16 -16
- package/dist/lib/sidecar.js +54 -54
- package/dist/lib/templates.js +1 -1
- package/dist/verbs/agent.js +27 -27
- package/dist/verbs/build.js +9 -9
- package/dist/verbs/check.js +6 -6
- package/dist/verbs/checkpoint.js +48 -47
- package/dist/verbs/doctor.js +31 -30
- package/dist/verbs/finish.js +28 -41
- package/dist/verbs/handoff.js +9 -8
- package/dist/verbs/init.js +9 -9
- package/dist/verbs/park.js +3 -3
- package/dist/verbs/recover.js +297 -0
- package/dist/verbs/revert.js +13 -13
- package/dist/verbs/spike.js +25 -19
- package/dist/verbs/start.js +49 -19
- package/dist/verbs/status.js +8 -8
- package/dist/verbs/turn.js +16 -16
- package/dist/verbs/use.js +4 -4
- 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 +1404 -0
- package/node_modules/checkride/LICENSE +201 -21
- package/node_modules/checkride/README.md +197 -38
- 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 +30 -10
- package/node_modules/checkride/dist/adapters.d.ts.map +1 -1
- package/node_modules/checkride/dist/adapters.js +62 -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 +69 -0
- package/node_modules/checkride/dist/agent-setup/cursor.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/cursor.js +247 -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 +93 -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 +81 -0
- package/node_modules/checkride/dist/agent-setup/scripts.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/scripts.js +604 -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 +163 -60
- package/node_modules/checkride/dist/baseline/fallow.js.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts +20 -11
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.js +73 -23
- package/node_modules/checkride/dist/baseline/fingerprint.js.map +1 -1
- package/node_modules/checkride/dist/baseline/history.d.ts +98 -0
- package/node_modules/checkride/dist/baseline/history.d.ts.map +1 -0
- package/node_modules/checkride/dist/baseline/history.js +232 -0
- package/node_modules/checkride/dist/baseline/history.js.map +1 -0
- package/node_modules/checkride/dist/baseline/index.d.ts +7 -5
- package/node_modules/checkride/dist/baseline/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/index.js +5 -4
- package/node_modules/checkride/dist/baseline/index.js.map +1 -1
- package/node_modules/checkride/dist/baseline/store.d.ts +41 -10
- package/node_modules/checkride/dist/baseline/store.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/store.js +65 -24
- 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 +21 -4
- package/node_modules/checkride/dist/cli.d.ts.map +1 -1
- package/node_modules/checkride/dist/cli.js +350 -36
- package/node_modules/checkride/dist/cli.js.map +1 -1
- package/node_modules/checkride/dist/config.d.ts +114 -9
- package/node_modules/checkride/dist/config.d.ts.map +1 -1
- package/node_modules/checkride/dist/config.js +142 -23
- 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 +6 -6
- 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 +27 -6
- package/node_modules/checkride/dist/doctor.d.ts.map +1 -1
- package/node_modules/checkride/dist/doctor.js +231 -27
- package/node_modules/checkride/dist/doctor.js.map +1 -1
- package/node_modules/checkride/dist/gate.d.ts +180 -0
- package/node_modules/checkride/dist/gate.d.ts.map +1 -0
- package/node_modules/checkride/dist/gate.js +617 -0
- package/node_modules/checkride/dist/gate.js.map +1 -0
- package/node_modules/checkride/dist/init.d.ts +79 -12
- package/node_modules/checkride/dist/init.d.ts.map +1 -1
- package/node_modules/checkride/dist/init.js +385 -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 +53 -10
- package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -1
- package/node_modules/checkride/dist/orchestrator.js +312 -113
- 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 +7 -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 +72 -0
- package/node_modules/checkride/dist/pm/launch.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/launch.js +108 -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/recover.d.ts +48 -0
- package/node_modules/checkride/dist/recover.d.ts.map +1 -0
- package/node_modules/checkride/dist/recover.js +220 -0
- package/node_modules/checkride/dist/recover.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 +6 -6
- package/node_modules/checkride/dist/smoke.js +6 -6
- package/node_modules/checkride/dist/snippets.d.ts +27 -30
- 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 +18 -15
- package/node_modules/checkride/schema/checkride.config.schema.json +70 -5
- package/node_modules/checkride/schema/checkride.summary.schema.json +1 -1
- package/node_modules/checkride/skills/check/SKILL.md +265 -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/node_modules/checkride/templates/shared/styles/Repo/Drift.yml +41 -0
- package/node_modules/checkride/templates/shared/styles/Repo/Latin.yml +14 -0
- package/node_modules/checkride/templates/shared/styles/Repo/LyHyphen.yml +28 -0
- package/node_modules/checkride/templates/shared/styles/Repo/Minted.yml +33 -0
- package/node_modules/checkride/templates/shared/styles/Repo/ThereIs.yml +16 -0
- package/node_modules/checkride/templates/shared/styles/Repo/Weasel.yml +26 -0
- package/node_modules/checkride/templates/shared/vale.ini +34 -0
- package/package.json +10 -9
- package/skills/build/SKILL.md +85 -76
- package/skills/doctor/SKILL.md +11 -11
- package/skills/finish/SKILL.md +21 -18
- package/skills/harvest/SKILL.md +13 -11
- package/skills/park/SKILL.md +10 -10
- package/skills/plan/SKILL.md +69 -59
- package/skills/recover/SKILL.md +28 -0
- package/skills/refine/SKILL.md +21 -18
- package/skills/revert/SKILL.md +6 -6
- package/skills/spike/SKILL.md +9 -9
- package/skills/status/SKILL.md +5 -5
- package/skills/step/SKILL.md +20 -15
- package/skills/verify/SKILL.md +56 -46
- package/templates/build-log.md +7 -7
- package/templates/intent.md +52 -41
- package/templates/spike-report.md +10 -10
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Launch refusals — the package manager declining to start the script at all.
|
|
3
|
+
*
|
|
4
|
+
* Every caller that runs the repo's `check` script reads a non-zero exit as
|
|
5
|
+
* "the pipeline is red". That reading is wrong for a whole class of exits,
|
|
6
|
+
* because a package manager refuses *before* the script runs and still exits
|
|
7
|
+
* non-zero: pnpm answers an `engines.node` mismatch with
|
|
8
|
+
* `ERR_PNPM_UNSUPPORTED_ENGINE` and exit 1, exactly as it answers a failing
|
|
9
|
+
* test. The difference is invisible in the status code and obvious in the
|
|
10
|
+
* output, so the output is what is read here.
|
|
11
|
+
*
|
|
12
|
+
* The distinction is not cosmetic. A pipeline red is cleared by fixing code and
|
|
13
|
+
* points at `.check/`; a launch refusal cannot be cleared by any code change and
|
|
14
|
+
* points at nothing, because nothing ran and no artifact was written. Reporting
|
|
15
|
+
* the second as the first sends the reader — human or agent — to an artifact
|
|
16
|
+
* that does not describe this run, which is the failure this table exists to
|
|
17
|
+
* prevent.
|
|
18
|
+
*
|
|
19
|
+
* Each refusal also carries {@link RefusalFix}, because "no code change clears
|
|
20
|
+
* it" is true of only *some* of them. That field is what lets the gate block on
|
|
21
|
+
* the ones an agent can fix and stand down on the ones it cannot, instead of
|
|
22
|
+
* blocking on both and looping forever on the second.
|
|
23
|
+
*
|
|
24
|
+
* **Every pattern here must be one a check's own output cannot contain.** A
|
|
25
|
+
* false positive is worse than the bug being fixed: it would tell someone their
|
|
26
|
+
* environment is broken while their code is what failed. The patterns are all
|
|
27
|
+
* package-manager error *codes*, and the one caller-supplied sentinel checkride
|
|
28
|
+
* writes itself; callers additionally gate on "this run wrote no summary", so a
|
|
29
|
+
* pipeline that demonstrably ran can never be reclassified by a tool that merely
|
|
30
|
+
* printed one of these strings.
|
|
31
|
+
*/
|
|
32
|
+
/** The sentinel a caller writes when the package-manager binary itself never started. */
|
|
33
|
+
export const SPAWN_FAILED_MARKER = 'checkride: could not start';
|
|
34
|
+
/**
|
|
35
|
+
* Markers that mean the script never started, most specific first.
|
|
36
|
+
*
|
|
37
|
+
* npm is the delicate one: it prints `EBADENGINE` as a *warning* on a version
|
|
38
|
+
* mismatch and runs the script anyway, and only `engine-strict` turns it into an
|
|
39
|
+
* error. Matching the bare code would reclassify a genuine red in any repo whose
|
|
40
|
+
* dependency tree carries one stale `engines` field — so the two error spellings
|
|
41
|
+
* npm has shipped are matched, and the warning is not.
|
|
42
|
+
*
|
|
43
|
+
* Only pnpm's and npm's spellings are listed, because those are the two the
|
|
44
|
+
* behavior above was verified against. Yarn's and bun's equivalents are
|
|
45
|
+
* deliberately absent rather than guessed: an unmatched refusal degrades to
|
|
46
|
+
* today's report (a red), while a wrong pattern degrades to a false diagnosis.
|
|
47
|
+
* Add one when a real output line is in hand, not before.
|
|
48
|
+
*/
|
|
49
|
+
const REFUSALS = [
|
|
50
|
+
{
|
|
51
|
+
marker: 'ERR_PNPM_UNSUPPORTED_ENGINE',
|
|
52
|
+
cause: "the repo's `engines` pin does not match the Node or pnpm running this process, and pnpm refuses to run a script under it",
|
|
53
|
+
fixable: 'environment',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
marker: 'npm error code EBADENGINE',
|
|
57
|
+
cause: "the repo's `engines` pin does not match the Node running this process, and npm is configured `engine-strict`",
|
|
58
|
+
fixable: 'environment',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
marker: 'npm ERR! code EBADENGINE',
|
|
62
|
+
cause: "the repo's `engines` pin does not match the Node running this process, and npm is configured `engine-strict`",
|
|
63
|
+
fixable: 'environment',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
// `repo`, and deliberately: a missing `check` script is one edit away, and it
|
|
67
|
+
// is the one refusal an agent could otherwise *create* to escape the gate.
|
|
68
|
+
// Standing down here would make "delete the check script" a way out.
|
|
69
|
+
marker: 'ERR_PNPM_NO_SCRIPT',
|
|
70
|
+
cause: 'this repo has no `check` script for the gate to run',
|
|
71
|
+
fixable: 'repo',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
marker: 'Missing script:',
|
|
75
|
+
cause: 'this repo has no `check` script for the gate to run',
|
|
76
|
+
fixable: 'repo',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
marker: 'ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND',
|
|
80
|
+
cause: 'there is no package.json here, so the package manager has nothing to run',
|
|
81
|
+
fixable: 'repo',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
// corepack verifying a `packageManager` field against its bundled signing
|
|
85
|
+
// keys. Common after a corepack upgrade, and total: nothing runs.
|
|
86
|
+
marker: 'Cannot find matching keyid',
|
|
87
|
+
cause: 'corepack could not verify the package manager named in `packageManager`, so it never launched',
|
|
88
|
+
fixable: 'environment',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
marker: SPAWN_FAILED_MARKER,
|
|
92
|
+
cause: 'the package-manager binary is not on this process’s PATH',
|
|
93
|
+
fixable: 'environment',
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
/**
|
|
97
|
+
* Classify `output` — whatever the child printed on either stream — as a launch
|
|
98
|
+
* refusal, or `null` when nothing in it says the script failed to start.
|
|
99
|
+
*
|
|
100
|
+
* `null` is the safe answer and the common one: an unrecognized refusal reads as
|
|
101
|
+
* a pipeline red, which is the behavior that predates this module. A new package
|
|
102
|
+
* manager or a reworded error therefore degrades to today's report rather than
|
|
103
|
+
* to a wrong one.
|
|
104
|
+
*/
|
|
105
|
+
export function launchRefusal(output) {
|
|
106
|
+
return REFUSALS.find((r) => output.includes(r.marker)) ?? null;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../../src/pm/launch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,yFAAyF;AACzF,MAAM,CAAC,MAAM,mBAAmB,GAAG,4BAA4B,CAAC;AA4BhE;;;;;;;;;;;;;;GAcG;AACH,MAAM,QAAQ,GAA6B;IACzC;QACE,MAAM,EAAE,6BAA6B;QACrC,KAAK,EAAE,0HAA0H;QACjI,OAAO,EAAE,aAAa;KACvB;IACD;QACE,MAAM,EAAE,2BAA2B;QACnC,KAAK,EAAE,8GAA8G;QACrH,OAAO,EAAE,aAAa;KACvB;IACD;QACE,MAAM,EAAE,0BAA0B;QAClC,KAAK,EAAE,8GAA8G;QACrH,OAAO,EAAE,aAAa;KACvB;IACD;QACE,8EAA8E;QAC9E,2EAA2E;QAC3E,qEAAqE;QACrE,MAAM,EAAE,oBAAoB;QAC5B,KAAK,EAAE,qDAAqD;QAC5D,OAAO,EAAE,MAAM;KAChB;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,KAAK,EAAE,qDAAqD;QAC5D,OAAO,EAAE,MAAM;KAChB;IACD;QACE,MAAM,EAAE,qCAAqC;QAC7C,KAAK,EAAE,0EAA0E;QACjF,OAAO,EAAE,MAAM;KAChB;IACD;QACE,0EAA0E;QAC1E,kEAAkE;QAClE,MAAM,EAAE,4BAA4B;QACpC,KAAK,EAAE,+FAA+F;QACtG,OAAO,EAAE,aAAa;KACvB;IACD;QACE,MAAM,EAAE,mBAAmB;QAC3B,KAAK,EAAE,0DAA0D;QACjE,OAAO,EAAE,aAAa;KACvB;CACF,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slot-tool resolution — where a check's tool has to be for the gate to run it,
|
|
3
|
+
* and how to install it when it isn't.
|
|
4
|
+
*
|
|
5
|
+
* `translate.ts` decides *how* a tool is spawned; this decides *whether it may
|
|
6
|
+
* be*. The two are deliberately separate. `--no-install` bounds the download
|
|
7
|
+
* but not the launcher's per-user cache, so the spawn alone cannot promise the
|
|
8
|
+
* tool came from this repo: a copy an unrelated `npx` left behind months ago
|
|
9
|
+
* satisfies the launcher just as well as a declared dependency. Resolving the
|
|
10
|
+
* binary in the local tree first is what makes a slot's verdict depend on the
|
|
11
|
+
* committed lockfile rather than on one machine's accumulated cache — the
|
|
12
|
+
* property that lets a green run mean the same thing locally and in CI.
|
|
13
|
+
*/
|
|
14
|
+
import type { PackageManager } from './detect.js';
|
|
15
|
+
/**
|
|
16
|
+
* The `<tool>` in a canonical `pnpm exec <tool> …` adapter invocation, or `null`
|
|
17
|
+
* for anything else — `pnpm audit`, `pnpm run <script>`, a built-in, or a config
|
|
18
|
+
* custom check's own command. Those either have no tool to resolve or resolve it
|
|
19
|
+
* themselves, so they are never pre-flighted.
|
|
20
|
+
*
|
|
21
|
+
* This is the same prefix test {@link translateExec} keys on, named once so the
|
|
22
|
+
* run path, the fix path and `doctor` cannot drift on what counts as a tool.
|
|
23
|
+
*/
|
|
24
|
+
export declare function execTool(command: string, args: readonly string[]): string | null;
|
|
25
|
+
/** The command that would declare `tool` as a dev dependency under `pm`. */
|
|
26
|
+
export declare function installCommand(pm: PackageManager, tool: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Find `tool`'s binary in the local tree, walking `cwd` upward the way the
|
|
29
|
+
* package managers themselves do — and stopping at the repo root.
|
|
30
|
+
*
|
|
31
|
+
* The walk is what makes this correct in a workspace: pnpm and npm both hoist a
|
|
32
|
+
* shared tool's bin to the workspace root, so a check running in
|
|
33
|
+
* `packages/web` finds it two directories up and a root-only check finds it
|
|
34
|
+
* immediately. Checking `cwd` alone would report every hoisted tool missing in
|
|
35
|
+
* every monorepo — which is most of the repos with a workspace preset.
|
|
36
|
+
*
|
|
37
|
+
* The boundary matters as much as the walk. An unbounded search would accept a
|
|
38
|
+
* `node_modules/.bin/<tool>` sitting in some parent of the checkout — a stray
|
|
39
|
+
* install in a home or projects directory — and that is the same defect as
|
|
40
|
+
* trusting the launcher cache, reached by a different route: the slot passes for
|
|
41
|
+
* whoever happens to have that directory above their clone and fails on the
|
|
42
|
+
* clean checkout. Stopping at the root keeps the verdict a property of the repo.
|
|
43
|
+
* The root itself is searched before the walk ends; a tree with no marker at all
|
|
44
|
+
* (a synthetic one, or a directory outside any repo) walks to the filesystem
|
|
45
|
+
* root as before.
|
|
46
|
+
*
|
|
47
|
+
* `exists` is injected so the walk is testable against a synthetic tree.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveSlotTool(cwd: string, tool: string, exists?: (p: string) => boolean): string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Whether this project is installed under Yarn PnP, where there is no
|
|
52
|
+
* `node_modules/` tree at all.
|
|
53
|
+
*
|
|
54
|
+
* Every path-based test for "is it installed" is wrong here: a healthy PnP repo
|
|
55
|
+
* has no `node_modules/` and no `node_modules/.bin/<tool>`, so asserting either
|
|
56
|
+
* reports a correctly installed project as broken. Callers use this to pick a
|
|
57
|
+
* different question — the install artifact rather than the directory, and the
|
|
58
|
+
* package manager's own resolution rather than a path — instead of guessing.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isPnPInstall(cwd: string, exists?: (p: string) => boolean): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Whether `pm`'s exec launcher can supply a tool this repo never declared.
|
|
63
|
+
*
|
|
64
|
+
* True for exactly the two launchers that keep a per-user package cache: `npx`
|
|
65
|
+
* and `bunx` will run a cached copy even under `--no-install`. `pnpm exec` and
|
|
66
|
+
* `yarn` resolve from the project tree only, so they already give the stronger
|
|
67
|
+
* guarantee and need no pre-flight — and Yarn PnP has no `node_modules/.bin`
|
|
68
|
+
* to resolve against at all, so pre-flighting it would report every tool
|
|
69
|
+
* missing. Kept in lockstep with `translate.ts`'s `EXEC` table by a test: any
|
|
70
|
+
* PM carrying `--no-install` must be listed here.
|
|
71
|
+
*/
|
|
72
|
+
export declare function execUsesGlobalCache(pm: PackageManager): boolean;
|
|
73
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/pm/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAGhF;AAaD,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvE;AAcD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAoB,GAAG,MAAM,GAAG,IAAI,CAUrH;AASD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAoB,GAAG,OAAO,CAE9F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAE/D"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slot-tool resolution — where a check's tool has to be for the gate to run it,
|
|
3
|
+
* and how to install it when it isn't.
|
|
4
|
+
*
|
|
5
|
+
* `translate.ts` decides *how* a tool is spawned; this decides *whether it may
|
|
6
|
+
* be*. The two are deliberately separate. `--no-install` bounds the download
|
|
7
|
+
* but not the launcher's per-user cache, so the spawn alone cannot promise the
|
|
8
|
+
* tool came from this repo: a copy an unrelated `npx` left behind months ago
|
|
9
|
+
* satisfies the launcher just as well as a declared dependency. Resolving the
|
|
10
|
+
* binary in the local tree first is what makes a slot's verdict depend on the
|
|
11
|
+
* committed lockfile rather than on one machine's accumulated cache — the
|
|
12
|
+
* property that lets a green run mean the same thing locally and in CI.
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync } from 'node:fs';
|
|
15
|
+
import { dirname, join } from 'node:path';
|
|
16
|
+
import { LOCKFILE_NAMES } from './detect.js';
|
|
17
|
+
/**
|
|
18
|
+
* The `<tool>` in a canonical `pnpm exec <tool> …` adapter invocation, or `null`
|
|
19
|
+
* for anything else — `pnpm audit`, `pnpm run <script>`, a built-in, or a config
|
|
20
|
+
* custom check's own command. Those either have no tool to resolve or resolve it
|
|
21
|
+
* themselves, so they are never pre-flighted.
|
|
22
|
+
*
|
|
23
|
+
* This is the same prefix test {@link translateExec} keys on, named once so the
|
|
24
|
+
* run path, the fix path and `doctor` cannot drift on what counts as a tool.
|
|
25
|
+
*/
|
|
26
|
+
export function execTool(command, args) {
|
|
27
|
+
if (command !== 'pnpm' || args[0] !== 'exec')
|
|
28
|
+
return null;
|
|
29
|
+
return args[1] ?? null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* How each PM installs a tool as a dev dependency — the remediation a missing
|
|
33
|
+
* tool points at. `bun` spells the flag `-d`; the rest take `-D`.
|
|
34
|
+
*/
|
|
35
|
+
const INSTALL = {
|
|
36
|
+
pnpm: 'pnpm add -D',
|
|
37
|
+
npm: 'npm install -D',
|
|
38
|
+
yarn: 'yarn add -D',
|
|
39
|
+
bun: 'bun add -d',
|
|
40
|
+
};
|
|
41
|
+
/** The command that would declare `tool` as a dev dependency under `pm`. */
|
|
42
|
+
export function installCommand(pm, tool) {
|
|
43
|
+
return `${INSTALL[pm]} ${tool}`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* What marks the top of a repository: its VCS directory, or a lockfile. `.git`
|
|
47
|
+
* is a file rather than a directory inside a worktree, which `existsSync`
|
|
48
|
+
* answers the same either way.
|
|
49
|
+
*/
|
|
50
|
+
const ROOT_MARKERS = ['.git', ...LOCKFILE_NAMES];
|
|
51
|
+
/** Is `dir` the top of a repository — the last directory a tool search may look in? */
|
|
52
|
+
function isRepoRoot(dir, exists) {
|
|
53
|
+
return ROOT_MARKERS.some((m) => exists(join(dir, m)));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Find `tool`'s binary in the local tree, walking `cwd` upward the way the
|
|
57
|
+
* package managers themselves do — and stopping at the repo root.
|
|
58
|
+
*
|
|
59
|
+
* The walk is what makes this correct in a workspace: pnpm and npm both hoist a
|
|
60
|
+
* shared tool's bin to the workspace root, so a check running in
|
|
61
|
+
* `packages/web` finds it two directories up and a root-only check finds it
|
|
62
|
+
* immediately. Checking `cwd` alone would report every hoisted tool missing in
|
|
63
|
+
* every monorepo — which is most of the repos with a workspace preset.
|
|
64
|
+
*
|
|
65
|
+
* The boundary matters as much as the walk. An unbounded search would accept a
|
|
66
|
+
* `node_modules/.bin/<tool>` sitting in some parent of the checkout — a stray
|
|
67
|
+
* install in a home or projects directory — and that is the same defect as
|
|
68
|
+
* trusting the launcher cache, reached by a different route: the slot passes for
|
|
69
|
+
* whoever happens to have that directory above their clone and fails on the
|
|
70
|
+
* clean checkout. Stopping at the root keeps the verdict a property of the repo.
|
|
71
|
+
* The root itself is searched before the walk ends; a tree with no marker at all
|
|
72
|
+
* (a synthetic one, or a directory outside any repo) walks to the filesystem
|
|
73
|
+
* root as before.
|
|
74
|
+
*
|
|
75
|
+
* `exists` is injected so the walk is testable against a synthetic tree.
|
|
76
|
+
*/
|
|
77
|
+
export function resolveSlotTool(cwd, tool, exists = existsSync) {
|
|
78
|
+
let dir = cwd;
|
|
79
|
+
for (;;) {
|
|
80
|
+
const bin = join(dir, 'node_modules', '.bin', tool);
|
|
81
|
+
if (exists(bin))
|
|
82
|
+
return bin;
|
|
83
|
+
if (isRepoRoot(dir, exists))
|
|
84
|
+
return null;
|
|
85
|
+
const parent = dirname(dir);
|
|
86
|
+
if (parent === dir)
|
|
87
|
+
return null;
|
|
88
|
+
dir = parent;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The artifacts a Yarn Plug'n'Play install writes in place of `node_modules/`.
|
|
93
|
+
* `.pnp.cjs` is the current name, `.pnp.js` the Yarn 2 one; `.pnp.data.json`
|
|
94
|
+
* rides alongside the loader when the manifest is split out.
|
|
95
|
+
*/
|
|
96
|
+
const PNP_FILES = ['.pnp.cjs', '.pnp.js', '.pnp.data.json'];
|
|
97
|
+
/**
|
|
98
|
+
* Whether this project is installed under Yarn PnP, where there is no
|
|
99
|
+
* `node_modules/` tree at all.
|
|
100
|
+
*
|
|
101
|
+
* Every path-based test for "is it installed" is wrong here: a healthy PnP repo
|
|
102
|
+
* has no `node_modules/` and no `node_modules/.bin/<tool>`, so asserting either
|
|
103
|
+
* reports a correctly installed project as broken. Callers use this to pick a
|
|
104
|
+
* different question — the install artifact rather than the directory, and the
|
|
105
|
+
* package manager's own resolution rather than a path — instead of guessing.
|
|
106
|
+
*/
|
|
107
|
+
export function isPnPInstall(cwd, exists = existsSync) {
|
|
108
|
+
return PNP_FILES.some((f) => exists(join(cwd, f)));
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Whether `pm`'s exec launcher can supply a tool this repo never declared.
|
|
112
|
+
*
|
|
113
|
+
* True for exactly the two launchers that keep a per-user package cache: `npx`
|
|
114
|
+
* and `bunx` will run a cached copy even under `--no-install`. `pnpm exec` and
|
|
115
|
+
* `yarn` resolve from the project tree only, so they already give the stronger
|
|
116
|
+
* guarantee and need no pre-flight — and Yarn PnP has no `node_modules/.bin`
|
|
117
|
+
* to resolve against at all, so pre-flighting it would report every tool
|
|
118
|
+
* missing. Kept in lockstep with `translate.ts`'s `EXEC` table by a test: any
|
|
119
|
+
* PM carrying `--no-install` must be listed here.
|
|
120
|
+
*/
|
|
121
|
+
export function execUsesGlobalCache(pm) {
|
|
122
|
+
return pm === 'npm' || pm === 'bun';
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/pm/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAAuB;IAC/D,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC1D,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,GAAmC;IAC9C,IAAI,EAAE,aAAa;IACnB,GAAG,EAAE,gBAAgB;IACrB,IAAI,EAAE,aAAa;IACnB,GAAG,EAAE,YAAY;CAClB,CAAC;AAEF,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,EAAkB,EAAE,IAAY;IAC7D,OAAO,GAAG,OAAO,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,YAAY,GAAsB,CAAC,MAAM,EAAE,GAAG,cAAc,CAAC,CAAC;AAEpE,uFAAuF;AACvF,SAAS,UAAU,CAAC,GAAW,EAAE,MAA8B;IAC7D,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,IAAY,EAAE,SAAiC,UAAU;IACpG,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,SAAS,CAAC;QACR,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACpD,IAAI,MAAM,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;QAC5B,IAAI,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,SAAS,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,gBAAgB,CAAU,CAAC;AAErE;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,SAAiC,UAAU;IACnF,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAkB;IACpD,OAAO,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,KAAK,CAAC;AACtC,CAAC"}
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Exec-prefix translation.
|
|
3
3
|
*
|
|
4
4
|
* The adapter registry keeps its canonical `pnpm exec <tool>` / `pnpm run
|
|
5
|
-
* <script>` form
|
|
5
|
+
* <script>` form; this is the single seam that rewrites that prefix for
|
|
6
6
|
* whichever package manager a repo actually uses. Only the `pnpm exec` and `pnpm
|
|
7
7
|
* run` prefixes are translated — `pnpm audit`, custom-check commands, and
|
|
8
|
-
* built-ins pass through untouched
|
|
9
|
-
*
|
|
8
|
+
* built-ins pass through untouched. Under pnpm itself the prefix is unchanged
|
|
9
|
+
* and only {@link VERIFY_DEPS_OFF} is prepended.
|
|
10
10
|
*/
|
|
11
11
|
import type { PackageManager } from './detect.js';
|
|
12
12
|
/**
|
|
@@ -15,21 +15,47 @@ import type { PackageManager } from './detect.js';
|
|
|
15
15
|
* check's own command, a built-in) is returned unchanged, and so is every
|
|
16
16
|
* invocation under `pnpm` itself — the default stays exactly as it was.
|
|
17
17
|
*
|
|
18
|
-
* `exec` swaps the launcher
|
|
19
|
-
* oxlint`); `run` keeps its
|
|
20
|
-
*
|
|
21
|
-
* build`).
|
|
18
|
+
* `exec` swaps the launcher, drops the keyword, and prepends the launcher's own
|
|
19
|
+
* flags (`pnpm exec oxlint` → `npx --no-install oxlint`); `run` keeps its
|
|
20
|
+
* keyword and only swaps the launcher, since all four package managers spell it
|
|
21
|
+
* `<pm> run <script>` (`pnpm run build` → `npm run build`). Under pnpm the
|
|
22
|
+
* invocation is unchanged but for `VERIFY_DEPS_OFF`, which keeps pnpm's
|
|
23
|
+
* dependency-check narration off the tool's stdout.
|
|
22
24
|
*/
|
|
23
25
|
export declare function translateExec(command: string, args: readonly string[], pm: PackageManager): {
|
|
24
26
|
command: string;
|
|
25
27
|
args: string[];
|
|
26
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* How `pm` invokes a package.json script, as a command line.
|
|
31
|
+
*
|
|
32
|
+
* Bare `pnpm <script>` is pnpm's own shorthand and the form checkride's docs
|
|
33
|
+
* use; the other three need the `run` keyword, and not merely for tidiness —
|
|
34
|
+
* `npm check` is not a command at all, and `yarn check` resolves to Yarn 1's
|
|
35
|
+
* built-in integrity checker rather than the repo's script, so both fail in a
|
|
36
|
+
* way that looks like checkride is broken. `<pm> run <script>` is correct
|
|
37
|
+
* everywhere, which is why it is the fallback for all of them.
|
|
38
|
+
*/
|
|
39
|
+
export declare function runScript(pm: PackageManager, script: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* A canonical `pnpm exec <tool> …` rendered as one command line for `pm`.
|
|
42
|
+
*
|
|
43
|
+
* `quiet` decides whether {@link VERIFY_DEPS_OFF} survives into the rendered
|
|
44
|
+
* string, and the two callers want opposite answers. A generated script whose
|
|
45
|
+
* stdout checkride parses needs it, or pnpm's narration lands in front of the
|
|
46
|
+
* JSON. Prose — the AGENTS.md stanza, a doc — does not: nothing parses that
|
|
47
|
+
* output, and a documented command carrying
|
|
48
|
+
* `--config.verify-deps-before-run=false` is a line nobody wants to retype.
|
|
49
|
+
*/
|
|
50
|
+
export declare function execCommand(pm: PackageManager, args: readonly string[], opts?: {
|
|
51
|
+
quiet?: boolean;
|
|
52
|
+
}): string;
|
|
27
53
|
/**
|
|
28
54
|
* Can this adapter run under `pm`? Audit is package-manager-specific — its
|
|
29
55
|
* flags and JSON shape don't port — so `pnpm audit` (the `security` slot) is
|
|
30
|
-
* unavailable on a non-pnpm PM until a per-PM audit adapter lands
|
|
56
|
+
* unavailable on a non-pnpm PM until a per-PM audit adapter lands. The
|
|
31
57
|
* `pack` slot's built-in speaks only npm's and pnpm's `pack --dry-run --json`
|
|
32
|
-
* (yarn/bun pack differently) — unavailable-until-adapter, same precedent
|
|
58
|
+
* (yarn/bun pack differently) — unavailable-until-adapter, same precedent.
|
|
33
59
|
* Everything else is PM-agnostic once its exec prefix is translated.
|
|
34
60
|
*/
|
|
35
61
|
export declare function isAvailableUnder(command: string, args: readonly string[], pm: PackageManager): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../src/pm/translate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../src/pm/translate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA6BlD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,EAAE,cAAc,GACjB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAQrC;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAI/G;AAYD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,cAAc,GAAG,OAAO,CAItG"}
|
|
@@ -2,46 +2,106 @@
|
|
|
2
2
|
* Exec-prefix translation.
|
|
3
3
|
*
|
|
4
4
|
* The adapter registry keeps its canonical `pnpm exec <tool>` / `pnpm run
|
|
5
|
-
* <script>` form
|
|
5
|
+
* <script>` form; this is the single seam that rewrites that prefix for
|
|
6
6
|
* whichever package manager a repo actually uses. Only the `pnpm exec` and `pnpm
|
|
7
7
|
* run` prefixes are translated — `pnpm audit`, custom-check commands, and
|
|
8
|
-
* built-ins pass through untouched
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
* built-ins pass through untouched. Under pnpm itself the prefix is unchanged
|
|
9
|
+
* and only {@link VERIFY_DEPS_OFF} is prepended.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* What each non-pnpm PM uses in place of `pnpm exec`, and the flags that ride
|
|
13
|
+
* along. `--no-install` is load-bearing: `npx` and `bunx` otherwise fetch a
|
|
14
|
+
* missing tool from the registry and run it, and a check has no TTY to be
|
|
15
|
+
* prompted through — so the gate would silently execute an unpinned `latest`.
|
|
16
|
+
* It bounds the download, not every fallback: a copy already in the launcher's
|
|
17
|
+
* global cache still runs (see `docs/tools.md` §Package managers). `yarn`
|
|
18
|
+
* neither auto-installs nor accepts the flag.
|
|
19
|
+
*/
|
|
20
|
+
const EXEC = {
|
|
21
|
+
npm: { command: 'npx', flags: ['--no-install'] },
|
|
22
|
+
yarn: { command: 'yarn', flags: [] },
|
|
23
|
+
bun: { command: 'bunx', flags: ['--no-install'] },
|
|
16
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Keeps pnpm's dependency-check narration (`Already up to date`) off **stdout**,
|
|
27
|
+
* where it would land in front of a tool's JSON and make it unparseable.
|
|
28
|
+
*
|
|
29
|
+
* This exact spelling, in this position, is the only form that works — not
|
|
30
|
+
* `--silent`, not the environment variable, and not after `exec`. Applied to
|
|
31
|
+
* every supported pnpm rather than version-gated. The full account, including
|
|
32
|
+
* the failure that found it, is in `docs/tools.md` §Launcher quirks; read it
|
|
33
|
+
* before touching this line.
|
|
34
|
+
*/
|
|
35
|
+
const VERIFY_DEPS_OFF = '--config.verify-deps-before-run=false';
|
|
17
36
|
/**
|
|
18
37
|
* Rewrite a canonical `pnpm exec <tool> …` or `pnpm run <script>` invocation for
|
|
19
38
|
* `pm`. Anything that is not one of those prefixes (a `pnpm audit`, a custom
|
|
20
39
|
* check's own command, a built-in) is returned unchanged, and so is every
|
|
21
40
|
* invocation under `pnpm` itself — the default stays exactly as it was.
|
|
22
41
|
*
|
|
23
|
-
* `exec` swaps the launcher
|
|
24
|
-
* oxlint`); `run` keeps its
|
|
25
|
-
*
|
|
26
|
-
* build`).
|
|
42
|
+
* `exec` swaps the launcher, drops the keyword, and prepends the launcher's own
|
|
43
|
+
* flags (`pnpm exec oxlint` → `npx --no-install oxlint`); `run` keeps its
|
|
44
|
+
* keyword and only swaps the launcher, since all four package managers spell it
|
|
45
|
+
* `<pm> run <script>` (`pnpm run build` → `npm run build`). Under pnpm the
|
|
46
|
+
* invocation is unchanged but for `VERIFY_DEPS_OFF`, which keeps pnpm's
|
|
47
|
+
* dependency-check narration off the tool's stdout.
|
|
27
48
|
*/
|
|
28
49
|
export function translateExec(command, args, pm) {
|
|
29
|
-
if (command !== 'pnpm'
|
|
50
|
+
if (command !== 'pnpm')
|
|
30
51
|
return { command, args: [...args] };
|
|
31
|
-
|
|
52
|
+
if (pm === 'pnpm')
|
|
53
|
+
return { command, args: quieted(args) };
|
|
54
|
+
// Drop 'exec'; keep <tool> and its arguments, for example `npx --no-install oxlint --type-aware`.
|
|
32
55
|
if (args[0] === 'exec')
|
|
33
|
-
return { command:
|
|
56
|
+
return { command: EXEC[pm].command, args: [...EXEC[pm].flags, ...args.slice(1)] };
|
|
34
57
|
// `<pm> run <script>` is universal; only the launcher changes.
|
|
35
58
|
if (args[0] === 'run')
|
|
36
59
|
return { command: pm, args: [...args] };
|
|
37
60
|
return { command, args: [...args] };
|
|
38
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* How `pm` invokes a package.json script, as a command line.
|
|
64
|
+
*
|
|
65
|
+
* Bare `pnpm <script>` is pnpm's own shorthand and the form checkride's docs
|
|
66
|
+
* use; the other three need the `run` keyword, and not merely for tidiness —
|
|
67
|
+
* `npm check` is not a command at all, and `yarn check` resolves to Yarn 1's
|
|
68
|
+
* built-in integrity checker rather than the repo's script, so both fail in a
|
|
69
|
+
* way that looks like checkride is broken. `<pm> run <script>` is correct
|
|
70
|
+
* everywhere, which is why it is the fallback for all of them.
|
|
71
|
+
*/
|
|
72
|
+
export function runScript(pm, script) {
|
|
73
|
+
return pm === 'pnpm' ? `${pm} ${script}` : `${pm} run ${script}`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A canonical `pnpm exec <tool> …` rendered as one command line for `pm`.
|
|
77
|
+
*
|
|
78
|
+
* `quiet` decides whether {@link VERIFY_DEPS_OFF} survives into the rendered
|
|
79
|
+
* string, and the two callers want opposite answers. A generated script whose
|
|
80
|
+
* stdout checkride parses needs it, or pnpm's narration lands in front of the
|
|
81
|
+
* JSON. Prose — the AGENTS.md stanza, a doc — does not: nothing parses that
|
|
82
|
+
* output, and a documented command carrying
|
|
83
|
+
* `--config.verify-deps-before-run=false` is a line nobody wants to retype.
|
|
84
|
+
*/
|
|
85
|
+
export function execCommand(pm, args, opts = {}) {
|
|
86
|
+
const translated = translateExec('pnpm', ['exec', ...args], pm);
|
|
87
|
+
const rest = opts.quiet === true ? translated.args : translated.args.filter((a) => a !== VERIFY_DEPS_OFF);
|
|
88
|
+
return [translated.command, ...rest].join(' ');
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Prepend `VERIFY_DEPS_OFF` to the two pnpm subcommands that verify first.
|
|
92
|
+
* `pnpm audit` and `pnpm pack` never do, so they are left exactly as written —
|
|
93
|
+
* the flag is added where it changes something, not everywhere it is harmless.
|
|
94
|
+
*/
|
|
95
|
+
function quieted(args) {
|
|
96
|
+
const verifies = args[0] === 'exec' || args[0] === 'run';
|
|
97
|
+
return verifies ? [VERIFY_DEPS_OFF, ...args] : [...args];
|
|
98
|
+
}
|
|
39
99
|
/**
|
|
40
100
|
* Can this adapter run under `pm`? Audit is package-manager-specific — its
|
|
41
101
|
* flags and JSON shape don't port — so `pnpm audit` (the `security` slot) is
|
|
42
|
-
* unavailable on a non-pnpm PM until a per-PM audit adapter lands
|
|
102
|
+
* unavailable on a non-pnpm PM until a per-PM audit adapter lands. The
|
|
43
103
|
* `pack` slot's built-in speaks only npm's and pnpm's `pack --dry-run --json`
|
|
44
|
-
* (yarn/bun pack differently) — unavailable-until-adapter, same precedent
|
|
104
|
+
* (yarn/bun pack differently) — unavailable-until-adapter, same precedent.
|
|
45
105
|
* Everything else is PM-agnostic once its exec prefix is translated.
|
|
46
106
|
*/
|
|
47
107
|
export function isAvailableUnder(command, args, pm) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../../src/pm/translate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH
|
|
1
|
+
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../../src/pm/translate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;;;;;;;GAQG;AACH,MAAM,IAAI,GAA2F;IACnG,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,cAAc,CAAC,EAAE;IAChD,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;IACpC,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,cAAc,CAAC,EAAE;CAClD,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,eAAe,GAAG,uCAAuC,CAAC;AAEhE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,IAAuB,EACvB,EAAkB;IAElB,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5D,IAAI,EAAE,KAAK,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3D,kGAAkG;IAClG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1G,+DAA+D;IAC/D,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;IAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;AACtC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,EAAkB,EAAE,MAAc;IAC1D,OAAO,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,MAAM,EAAE,CAAC;AACnE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,EAAkB,EAAE,IAAuB,EAAE,OAA4B,EAAE;IACrG,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC;IAC1G,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,SAAS,OAAO,CAAC,IAAuB;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC;IACzD,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,IAAuB,EAAE,EAAkB;IAC3F,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO;QAAE,OAAO,EAAE,KAAK,MAAM,CAAC;IACpE,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM;QAAE,OAAO,EAAE,KAAK,MAAM,IAAI,EAAE,KAAK,KAAK,CAAC;IACnF,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Killing a spawned check, and everything it started.
|
|
3
|
+
*
|
|
4
|
+
* Every subprocess checkride spawns is `detached`, so it leads its own process
|
|
5
|
+
* group and a negated-pid signal reaches the whole tree — a wrapper's
|
|
6
|
+
* grandchildren included. That is the difference between a timed-out
|
|
7
|
+
* `sh -c 'slow-tool …'` leaving its real worker orphaned and alive, and taking
|
|
8
|
+
* the tree down with it.
|
|
9
|
+
*
|
|
10
|
+
* Both spawners need the same two-step escalation (SIGTERM, then SIGKILL after
|
|
11
|
+
* a grace), so it lives here rather than in either of them: the orchestrator's
|
|
12
|
+
* per-check timeout and fatal-signal reaping (`../orchestrator.ts`), and the
|
|
13
|
+
* triage reader's gate budget (`./triage/env.ts`).
|
|
14
|
+
*/
|
|
15
|
+
/** Grace between SIGTERM and SIGKILL when a process group won't die politely. */
|
|
16
|
+
export declare const KILL_GRACE_SECONDS = 5;
|
|
17
|
+
/**
|
|
18
|
+
* Signal a spawned process's whole group. ESRCH is swallowed: the group racing
|
|
19
|
+
* to exit on its own before we signal is success, not an error (and `pid` is
|
|
20
|
+
* absent only when the spawn itself failed).
|
|
21
|
+
*/
|
|
22
|
+
export declare function killGroup(pid: number | undefined, signal: NodeJS.Signals): void;
|
|
23
|
+
/**
|
|
24
|
+
* Ask a process group to stop, then insist. SIGTERM now; SIGKILL after
|
|
25
|
+
* {@link KILL_GRACE_SECONDS} if it is still there. Returns the escalation
|
|
26
|
+
* timer so the caller can clear it when the process closes first — a pending
|
|
27
|
+
* timer would otherwise hold the event loop open past the run.
|
|
28
|
+
*/
|
|
29
|
+
export declare function killGroupEscalating(pid: number | undefined): ReturnType<typeof setTimeout>;
|
|
30
|
+
//# sourceMappingURL=proc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proc.d.ts","sourceRoot":"","sources":["../src/proc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAO/E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAG1F"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Killing a spawned check, and everything it started.
|
|
3
|
+
*
|
|
4
|
+
* Every subprocess checkride spawns is `detached`, so it leads its own process
|
|
5
|
+
* group and a negated-pid signal reaches the whole tree — a wrapper's
|
|
6
|
+
* grandchildren included. That is the difference between a timed-out
|
|
7
|
+
* `sh -c 'slow-tool …'` leaving its real worker orphaned and alive, and taking
|
|
8
|
+
* the tree down with it.
|
|
9
|
+
*
|
|
10
|
+
* Both spawners need the same two-step escalation (SIGTERM, then SIGKILL after
|
|
11
|
+
* a grace), so it lives here rather than in either of them: the orchestrator's
|
|
12
|
+
* per-check timeout and fatal-signal reaping (`../orchestrator.ts`), and the
|
|
13
|
+
* triage reader's gate budget (`./triage/env.ts`).
|
|
14
|
+
*/
|
|
15
|
+
/** Grace between SIGTERM and SIGKILL when a process group won't die politely. */
|
|
16
|
+
export const KILL_GRACE_SECONDS = 5;
|
|
17
|
+
/**
|
|
18
|
+
* Signal a spawned process's whole group. ESRCH is swallowed: the group racing
|
|
19
|
+
* to exit on its own before we signal is success, not an error (and `pid` is
|
|
20
|
+
* absent only when the spawn itself failed).
|
|
21
|
+
*/
|
|
22
|
+
export function killGroup(pid, signal) {
|
|
23
|
+
if (pid === undefined)
|
|
24
|
+
return;
|
|
25
|
+
try {
|
|
26
|
+
process.kill(-pid, signal);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Group already gone (raced with a clean exit) — nothing left to kill.
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Ask a process group to stop, then insist. SIGTERM now; SIGKILL after
|
|
34
|
+
* {@link KILL_GRACE_SECONDS} if it is still there. Returns the escalation
|
|
35
|
+
* timer so the caller can clear it when the process closes first — a pending
|
|
36
|
+
* timer would otherwise hold the event loop open past the run.
|
|
37
|
+
*/
|
|
38
|
+
export function killGroupEscalating(pid) {
|
|
39
|
+
killGroup(pid, 'SIGTERM');
|
|
40
|
+
return setTimeout(() => { killGroup(pid, 'SIGKILL'); }, KILL_GRACE_SECONDS * 1000);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=proc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proc.js","sourceRoot":"","sources":["../src/proc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,iFAAiF;AACjF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,GAAuB,EAAE,MAAsB;IACvE,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO;IAC9B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAuB;IACzD,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC1B,OAAO,UAAU,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Executable form of the quality reader — what the bundled `/checkride:qa`
|
|
4
|
+
* skill invokes:
|
|
5
|
+
*
|
|
6
|
+
* ```
|
|
7
|
+
* node <plugin-root>/dist/qa/cli.js [cwd]
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* It ships in the package's existing `dist/`, so both the published tarball and
|
|
11
|
+
* an installed plugin cache already carry it and no consumer build step exists.
|
|
12
|
+
* It adds no CLI command, flag or config to checkride itself: `dist/cli.js`
|
|
13
|
+
* knows nothing about this file.
|
|
14
|
+
*
|
|
15
|
+
* Exit code 0 means *a report was rendered* — including one whose every
|
|
16
|
+
* artifact is missing, which is a legitimate answer about a repo and not a
|
|
17
|
+
* reader failure. Unlike the triage reader, this one spawns nothing at all.
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/qa/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG"}
|