@vyuhlabs/dxkit 2.5.0 → 2.5.2

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.
Files changed (179) hide show
  1. package/CHANGELOG.md +231 -0
  2. package/README.md +48 -28
  3. package/dist/analyzers/tools/graphify.d.ts.map +1 -1
  4. package/dist/analyzers/tools/graphify.js +9 -5
  5. package/dist/analyzers/tools/graphify.js.map +1 -1
  6. package/dist/analyzers/tools/tool-registry.d.ts +19 -1
  7. package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
  8. package/dist/analyzers/tools/tool-registry.js +50 -8
  9. package/dist/analyzers/tools/tool-registry.js.map +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +104 -11
  12. package/dist/cli.js.map +1 -1
  13. package/dist/constants.d.ts.map +1 -1
  14. package/dist/constants.js +0 -10
  15. package/dist/constants.js.map +1 -1
  16. package/dist/detect.d.ts.map +1 -1
  17. package/dist/detect.js +0 -15
  18. package/dist/detect.js.map +1 -1
  19. package/dist/doctor.d.ts +78 -1
  20. package/dist/doctor.d.ts.map +1 -1
  21. package/dist/doctor.js +509 -103
  22. package/dist/doctor.js.map +1 -1
  23. package/dist/generator.d.ts +1 -1
  24. package/dist/generator.d.ts.map +1 -1
  25. package/dist/generator.js +96 -135
  26. package/dist/generator.js.map +1 -1
  27. package/dist/hooks-cli.d.ts +20 -0
  28. package/dist/hooks-cli.d.ts.map +1 -0
  29. package/dist/hooks-cli.js +145 -0
  30. package/dist/hooks-cli.js.map +1 -0
  31. package/dist/languages/csharp.d.ts.map +1 -1
  32. package/dist/languages/csharp.js +5 -0
  33. package/dist/languages/csharp.js.map +1 -1
  34. package/dist/languages/go.d.ts.map +1 -1
  35. package/dist/languages/go.js +5 -0
  36. package/dist/languages/go.js.map +1 -1
  37. package/dist/languages/index.d.ts +43 -0
  38. package/dist/languages/index.d.ts.map +1 -1
  39. package/dist/languages/index.js +76 -0
  40. package/dist/languages/index.js.map +1 -1
  41. package/dist/languages/java.d.ts.map +1 -1
  42. package/dist/languages/java.js +5 -0
  43. package/dist/languages/java.js.map +1 -1
  44. package/dist/languages/kotlin.d.ts.map +1 -1
  45. package/dist/languages/kotlin.js +10 -0
  46. package/dist/languages/kotlin.js.map +1 -1
  47. package/dist/languages/python.d.ts.map +1 -1
  48. package/dist/languages/python.js +13 -0
  49. package/dist/languages/python.js.map +1 -1
  50. package/dist/languages/ruby.d.ts.map +1 -1
  51. package/dist/languages/ruby.js +5 -0
  52. package/dist/languages/ruby.js.map +1 -1
  53. package/dist/languages/rust.d.ts.map +1 -1
  54. package/dist/languages/rust.js +5 -0
  55. package/dist/languages/rust.js.map +1 -1
  56. package/dist/languages/types.d.ts +47 -0
  57. package/dist/languages/types.d.ts.map +1 -1
  58. package/dist/languages/typescript.d.ts.map +1 -1
  59. package/dist/languages/typescript.js +6 -0
  60. package/dist/languages/typescript.js.map +1 -1
  61. package/dist/prompts.d.ts.map +1 -1
  62. package/dist/prompts.js +0 -5
  63. package/dist/prompts.js.map +1 -1
  64. package/dist/setup-branch-protection.d.ts +34 -0
  65. package/dist/setup-branch-protection.d.ts.map +1 -0
  66. package/dist/setup-branch-protection.js +190 -0
  67. package/dist/setup-branch-protection.js.map +1 -0
  68. package/dist/setup-gh.d.ts +75 -0
  69. package/dist/setup-gh.d.ts.map +1 -0
  70. package/dist/setup-gh.js +213 -0
  71. package/dist/setup-gh.js.map +1 -0
  72. package/dist/setup-prebuild.d.ts +34 -0
  73. package/dist/setup-prebuild.d.ts.map +1 -0
  74. package/dist/setup-prebuild.js +181 -0
  75. package/dist/setup-prebuild.js.map +1 -0
  76. package/dist/ship-installers.d.ts +6 -0
  77. package/dist/ship-installers.d.ts.map +1 -1
  78. package/dist/ship-installers.js +135 -5
  79. package/dist/ship-installers.js.map +1 -1
  80. package/dist/tools-cli.d.ts.map +1 -1
  81. package/dist/tools-cli.js +45 -9
  82. package/dist/tools-cli.js.map +1 -1
  83. package/dist/types.d.ts +24 -6
  84. package/dist/types.d.ts.map +1 -1
  85. package/dist/update.d.ts +41 -0
  86. package/dist/update.d.ts.map +1 -1
  87. package/dist/update.js +154 -15
  88. package/dist/update.js.map +1 -1
  89. package/dist/upgrade.d.ts +88 -0
  90. package/dist/upgrade.d.ts.map +1 -0
  91. package/dist/upgrade.js +324 -0
  92. package/dist/upgrade.js.map +1 -0
  93. package/package.json +1 -1
  94. package/templates/.claude/skills/dxkit-action/SKILL.md +150 -0
  95. package/templates/.claude/skills/dxkit-config/SKILL.md +124 -0
  96. package/templates/.claude/skills/dxkit-fix/SKILL.md +165 -0
  97. package/templates/.claude/skills/dxkit-hooks/SKILL.md +109 -0
  98. package/templates/.claude/skills/dxkit-init/SKILL.md +93 -0
  99. package/templates/.claude/skills/dxkit-learn/SKILL.md +84 -0
  100. package/templates/.claude/skills/dxkit-onboard/SKILL.md +246 -0
  101. package/templates/.claude/skills/dxkit-reports/SKILL.md +111 -0
  102. package/templates/.claude/skills/dxkit-update/SKILL.md +164 -0
  103. package/templates/.devcontainer/devcontainer.json +13 -48
  104. package/templates/.devcontainer/post-create.sh +37 -8
  105. package/templates/AGENTS.md.template +137 -0
  106. package/templates/CLAUDE.md.template +16 -111
  107. package/dist/codebase-scanner.d.ts +0 -36
  108. package/dist/codebase-scanner.d.ts.map +0 -1
  109. package/dist/codebase-scanner.js +0 -687
  110. package/dist/codebase-scanner.js.map +0 -1
  111. package/templates/.claude/agents/doc-writer.md +0 -107
  112. package/templates/.claude/agents/knowledge-bot.md +0 -64
  113. package/templates/.claude/agents/onboarding.md +0 -62
  114. package/templates/.claude/agents/quality-reviewer.md +0 -85
  115. package/templates/.claude/agents-available/code-reviewer.md +0 -29
  116. package/templates/.claude/agents-available/codebase-explorer.md +0 -100
  117. package/templates/.claude/agents-available/dashboard-builder.md +0 -433
  118. package/templates/.claude/agents-available/debugger.md +0 -29
  119. package/templates/.claude/agents-available/dependency-mapper.md +0 -80
  120. package/templates/.claude/agents-available/dev-report.md +0 -108
  121. package/templates/.claude/agents-available/doc-writer.md +0 -107
  122. package/templates/.claude/agents-available/feature-builder.md +0 -163
  123. package/templates/.claude/agents-available/feature-planner.md +0 -185
  124. package/templates/.claude/agents-available/health-auditor.md +0 -95
  125. package/templates/.claude/agents-available/hooks-configurator.md +0 -211
  126. package/templates/.claude/agents-available/knowledge-bot.md +0 -62
  127. package/templates/.claude/agents-available/plan-executor.md +0 -133
  128. package/templates/.claude/agents-available/strategic-planner.md +0 -141
  129. package/templates/.claude/agents-available/test-gap-finder.md +0 -67
  130. package/templates/.claude/agents-available/test-writer.md +0 -34
  131. package/templates/.claude/agents-available/vulnerability-scanner.md +0 -173
  132. package/templates/.claude/commands/ask.md +0 -7
  133. package/templates/.claude/commands/build-feature.md +0 -26
  134. package/templates/.claude/commands/build.md.template +0 -30
  135. package/templates/.claude/commands/check.md.template +0 -43
  136. package/templates/.claude/commands/dashboard.md +0 -28
  137. package/templates/.claude/commands/deps.md +0 -15
  138. package/templates/.claude/commands/dev-report.md +0 -50
  139. package/templates/.claude/commands/docs.md +0 -21
  140. package/templates/.claude/commands/doctor.md +0 -29
  141. package/templates/.claude/commands/enable-agent.md +0 -12
  142. package/templates/.claude/commands/execute-plan.md +0 -25
  143. package/templates/.claude/commands/explore-codebase.md +0 -12
  144. package/templates/.claude/commands/export-pdf.md +0 -30
  145. package/templates/.claude/commands/feature.md +0 -25
  146. package/templates/.claude/commands/fix-issue.md +0 -12
  147. package/templates/.claude/commands/fix.md.template +0 -32
  148. package/templates/.claude/commands/health.md +0 -58
  149. package/templates/.claude/commands/help.md +0 -36
  150. package/templates/.claude/commands/learn.md +0 -48
  151. package/templates/.claude/commands/onboarding.md +0 -21
  152. package/templates/.claude/commands/plan.md +0 -20
  153. package/templates/.claude/commands/quality.md.template +0 -65
  154. package/templates/.claude/commands/session-end.md +0 -40
  155. package/templates/.claude/commands/session-start.md +0 -30
  156. package/templates/.claude/commands/setup-hooks.md +0 -18
  157. package/templates/.claude/commands/stealth-mode.md +0 -17
  158. package/templates/.claude/commands/test-gaps.md +0 -49
  159. package/templates/.claude/commands/test.md.template +0 -40
  160. package/templates/.claude/commands/vulnerabilities.md +0 -49
  161. package/templates/.claude/skills/build/SKILL.md.template +0 -90
  162. package/templates/.claude/skills/deploy/SKILL.md.template +0 -111
  163. package/templates/.claude/skills/deploy/references/gotchas.md +0 -5
  164. package/templates/.claude/skills/doctor/SKILL.md +0 -31
  165. package/templates/.claude/skills/gcloud/SKILL.md +0 -66
  166. package/templates/.claude/skills/gcloud/references/gotchas.md +0 -5
  167. package/templates/.claude/skills/learned/SKILL.md +0 -55
  168. package/templates/.claude/skills/learned/references/conventions.md +0 -11
  169. package/templates/.claude/skills/learned/references/deny-recommendations.md +0 -18
  170. package/templates/.claude/skills/learned/references/gotchas.md +0 -11
  171. package/templates/.claude/skills/pulumi/SKILL.md +0 -73
  172. package/templates/.claude/skills/quality/SKILL.md.template +0 -89
  173. package/templates/.claude/skills/quality/references/gotchas.md +0 -5
  174. package/templates/.claude/skills/review/SKILL.md.template +0 -74
  175. package/templates/.claude/skills/scaffold/SKILL.md.template +0 -113
  176. package/templates/.claude/skills/secrets/SKILL.md +0 -51
  177. package/templates/.claude/skills/session/SKILL.md +0 -32
  178. package/templates/.claude/skills/test/SKILL.md.template +0 -116
  179. package/templates/.claude/skills/test/references/gotchas.md +0 -5
package/CHANGELOG.md CHANGED
@@ -7,6 +7,237 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.5.2] - 2026-05-22
11
+
12
+ The "scaffold UX + lifecycle skills + setup automation" release. Closes
13
+ every defect surfaced during the 2026-05-21 guided Codespaces UX
14
+ walkthrough (D145–D156) plus a vestigial-cleanup pass and adds three
15
+ new CLI subcommands + three new lifecycle skills.
16
+
17
+ Companion release: **`@vyuhlabs/create-dxkit@0.2.0`** ships alongside
18
+ this version, picking up the create-dxkit shim improvements (quieter
19
+ ERESOLVE handling, `--no-audit`, `.npmrc legacy-peer-deps` persistence).
20
+ Tag: `create-dxkit@v0.2.0`. Run `npm init @vyuhlabs/dxkit` to get
21
+ the new combined experience.
22
+
23
+ Validated end-to-end with two cross-stack walkthroughs on 2026-05-22:
24
+ `vyuhlabs-platform` (python + typescript) and `dpl-studio` (csharp).
25
+ Both stacks: defect closures verified, per-pack devcontainer adapts
26
+ correctly, doctor's new tier-3 surfaces operational gaps with
27
+ actionable fix commands.
28
+
29
+ ### Added
30
+
31
+ - Three new lifecycle skills under `.claude/skills/`, completing
32
+ the orthogonal customer-journey trio:
33
+ - **`dxkit-fix`** — reactive repair. Consumes
34
+ `vyuh-dxkit doctor --json` output and walks the customer
35
+ through each fixable check with per-step confirmation.
36
+ - **`dxkit-update`** — existing-install upgrade orchestrator.
37
+ Consumes `vyuh-dxkit upgrade --plan --json` and drives a
38
+ conversational upgrade with version-delta analysis, breaking-
39
+ change warnings, and per-step confirmation. Hands off to
40
+ `dxkit-fix` on post-upgrade doctor failures.
41
+ - **`dxkit-onboard`** — fresh-install orchestrator. Walks the
42
+ full first-time customer journey end-to-end (install → doctor
43
+ → fix gaps → baseline → hooks → branch protection → Codespaces
44
+ prebuild → final verify). Delegates to focused skills for
45
+ sub-decisions.
46
+ - Three new CLI subcommands:
47
+ - **`vyuh-dxkit upgrade [--plan [--json] | --yes | --target=X.Y.Z |
48
+ --dry-run]`** — combined binary + scaffold refresh. `--plan`
49
+ mode emits structured `upgrade-plan.v1` JSON consumed by the
50
+ `dxkit-update` skill. Execution mode runs `npm install`
51
+ + `vyuh-dxkit update` + `vyuh-dxkit doctor` in sequence with
52
+ a devcontainer-rebuild reminder if applicable.
53
+ - **`vyuh-dxkit setup-branch-protection [--branch X]
54
+ [--require-reviews N] [--force]`** — wraps `gh api` to mark
55
+ `dxkit-guardrails` as a required status check on the default
56
+ branch. Idempotent merge with existing required-checks list.
57
+ - **`vyuh-dxkit setup-prebuild [--branch X] [--regions=R1,R2]
58
+ [--force]`** — wraps `gh api` to configure Codespaces
59
+ prebuilds. Fresh Codespaces start in ~30s instead of running
60
+ the full devcontainer build (~7 min after per-stack feature).
61
+ - Doctor third tier — **Operational health**. Six runtime checks
62
+ (`git hooks active`, `baseline captured`, `vyuh-dxkit on PATH`,
63
+ `scanner toolchain healthy`, `.npmrc legacy-peer-deps
64
+ persistence`, `CI guardrails workflow`) each carrying structured
65
+ fix metadata (hint + command + skill). Plus a new `--json`
66
+ output mode emitting the `doctor.v1` schema for `dxkit-fix`
67
+ consumption.
68
+ - `manifest.installFlags` — persists the customer's `init`
69
+ flag choices in `.vyuh-dxkit.json` so `vyuh-dxkit update`
70
+ knows exactly which surfaces to refresh. Self-migrates legacy
71
+ pre-2.5.2 manifests by stamping detected flags back on first
72
+ update run.
73
+ - Per-pack `LanguageSupport.devcontainerExtensions?` field.
74
+ Each language pack contributes its VSCode editor extensions;
75
+ the installer unions across active packs only. Pure-Python
76
+ Codespaces no longer install Go / Rust / C# / Java / Kotlin /
77
+ Ruby editor extensions on every container start.
78
+ - Architecture rule (`scripts/check-architecture.sh`) that catches
79
+ dead `IF_*` template conditions in `constants.ts`. The
80
+ type-correct compute-without-consumer class of dead code sat
81
+ for days before the rule landed; rule now blocks new
82
+ occurrences at pre-commit time.
83
+ - Three new doc pages: `docs/commands/upgrade.md`,
84
+ `docs/commands/setup-branch-protection.md`,
85
+ `docs/commands/setup-prebuild.md`.
86
+
87
+ ### Changed
88
+
89
+ - **`vyuh-dxkit update` actually refreshes everything now.**
90
+ Pre-this-release, update only re-ran the template generator and
91
+ silently passed `withDxkitAgents=false`. Customers on 2.5.1 had
92
+ no path to receive new dxkit-* skills, per-stack devcontainer
93
+ extensions, doctor pivot, or any other scaffold-side change.
94
+ `update` now detects which install surfaces the customer
95
+ originally landed (via `manifest.installFlags` or workspace
96
+ detection) and re-runs every relevant installer.
97
+ - `vyuh-dxkit doctor` — three-tier framing (Reports + Agent DX +
98
+ Operational health, was two-tier). Tier 1 + 2 labels +
99
+ exit-code behavior preserved verbatim; tier 3 is additive.
100
+ - All six existing dxkit-* skill prose files standardized on
101
+ `npx vyuh-dxkit X` invocations (was a mix of bare + npx forms).
102
+ Robust to customers whose shell PATH doesn't have dxkit
103
+ globally installed.
104
+ - Python devcontainer feature switched from `installTools: true`
105
+ → `false`. The upstream feature's bundled installTools list
106
+ added ~3 min to every devcontainer build with no dxkit
107
+ consumer. Saves ~3 min per Codespaces rebuild on python-stack
108
+ projects.
109
+ - `osv-scanner` install switched from `go install` to GitHub
110
+ releases binary fetch. Pre-this-release, customers on any
111
+ non-Go stack silently lost `osv-scanner` (the canonical
112
+ Tier-2 dep-vuln scanner) because the install command failed
113
+ without a Go toolchain.
114
+ - `post-create.sh` always runs a global `npm install -g
115
+ @vyuhlabs/dxkit` in addition to whatever project-local install
116
+ happened. Without this, `vyuh-dxkit` wasn't on the customer's
117
+ shell PATH in Codespaces.
118
+ - Init's closing summary surfaces `Next: run vyuh-dxkit
119
+ baseline create` as a prominent info-level call-to-action
120
+ immediately after `Done!`, instead of burying it in a dim
121
+ three-line footer.
122
+ - `create-dxkit` shim: stderr from the first `npm install`
123
+ attempt is now captured (not streamed) so a peer-dep
124
+ `ERESOLVE` doesn't print a multi-line error wall before the
125
+ silent `--legacy-peer-deps` fallback succeeds. `--no-audit`
126
+ passed to both install attempts so the host project's
127
+ pre-existing vulnerability count doesn't surface mid-init.
128
+ Fallback choice persisted to `.npmrc` so the customer's next
129
+ `npm install <pkg>` doesn't re-hit the same ERESOLVE wall.
130
+ - CI: `actions/cache@v4` on the scanner toolchain
131
+ (`~/.local/{pipx,bin,share/{detekt,pmd}}`). Saves ~2 min per
132
+ CI run.
133
+ - Publish workflows (`publish.yml` + `publish-create-dxkit.yml`):
134
+ verify-shasum poll window 18s → 180s. First-publishes of
135
+ scoped packages commonly need 30–90s for CDN propagation;
136
+ the wider window prevents the "publish succeeded but workflow
137
+ reports failure" mode that bit both 2.5.1 publishes.
138
+ - README, getting-started, docs/README, commands/init.md
139
+ refreshed to reflect: `npm init @vyuhlabs/dxkit` as canonical
140
+ first install, 9 lifecycle skills (was 6), postinstall
141
+ auto-activation of hooks, per-stack devcontainer.
142
+
143
+ ### Removed
144
+
145
+ - Vestigial `DetectedStack.tools.{gcloud, pulumi, infisical,
146
+ ghCli}` field. Computed at every detect call since the 2026-
147
+ 05-19 generator simplification removed the `.project.yaml`
148
+ consumers; nothing referenced them post-cleanup. Doctor's
149
+ pre-pivot tier-2 `gcloud` + `infisical` availability checks
150
+ removed alongside (no manifest field to gate on).
151
+ - Six dead `IF_*` template conditions in `constants.ts`:
152
+ `IF_POSTGRES`, `IF_REDIS`, `IF_HAS_SERVICES`, `IF_DOCKER`,
153
+ `IF_CLAUDE_CODE`, `IF_COVERAGE_ENABLED`. Computed but no
154
+ template referenced them; same 2026-05-19 cleanup left them
155
+ behind. Arch-check rule (above) prevents new occurrences.
156
+
157
+ ### Fixed
158
+
159
+ - Dispatcher deadline test (`test/dispatcher-deadline.test.ts`):
160
+ lower-bound assertion 40ms → 25ms. Test was occasionally
161
+ flaking on fast CI runners where `setTimeout`'s ~1-2ms
162
+ granularity could fire at 38-39ms.
163
+
164
+ ## [2.5.1] - 2026-05-20
165
+
166
+ ### Added
167
+
168
+ - New `vyuh-dxkit hooks activate` CLI subcommand. Idempotently sets
169
+ `core.hooksPath = .githooks`. Wired into `init`'s scaffolded
170
+ `package.json` as a `postinstall` script so every clone plus
171
+ `npm install` activates the dxkit hooks transparently — no more
172
+ one-time-per-clone manual step.
173
+ - New `--with-dxkit-agents` `init` flag (default-on under `--full`).
174
+ Installs six dxkit-specific skills under `.claude/skills/dxkit-*/`
175
+ (`learn` / `init` / `config` / `hooks` / `reports` / `action`)
176
+ alongside `AGENTS.md` (open-standard project context) and a small
177
+ `CLAUDE.md` shim. The skills wrap the `vyuh-dxkit` CLI as
178
+ workflow-aware surfaces that Claude Code auto-discovers via skill
179
+ frontmatter.
180
+ - New optional `LanguageSupport.devcontainerFeature?` field. Each
181
+ language pack declares its canonical `ghcr.io/devcontainers/features`
182
+ entry; `installDevcontainer` renders the per-stack features block.
183
+ Cold devcontainer rebuilds drop from ~25 minutes (every supported
184
+ toolchain installed) to ~7 minutes on a pure-TypeScript repo
185
+ (only the toolchains the repo actually needs).
186
+ - New optional `ToolDefinition.applicabilityGuard?` field. Tools
187
+ whose preconditions aren't met on the current repo
188
+ (e.g. `vitest-coverage` on a mocha-based codebase) now report as
189
+ `n/a` with an inline reason instead of inflating the
190
+ missing-count. `tools install` filters n/a entries from the
191
+ install loop.
192
+ - New `@vyuhlabs/create-dxkit` shim package (zero dependencies; code
193
+ shipped under `packages/create-dxkit/`). First npm publish is a
194
+ manual tag-and-release step after this version lands on main.
195
+ Once published, `npm init @vyuhlabs/dxkit` will collapse the
196
+ prior two-step first install (`npm i -D @vyuhlabs/dxkit && npx
197
+ vyuh-dxkit init`) into one command.
198
+
199
+ ### Changed
200
+
201
+ - The generic 73-file `.claude/` scaffold (`agents/`,
202
+ `agents-available/`, `commands/`, generic skills, etc.) is replaced
203
+ with six dxkit-specific skills plus `AGENTS.md` and the
204
+ `CLAUDE.md` shim. Customers upgrading keep their existing
205
+ `.claude/` (`init` is additive — won't overwrite without
206
+ `--force`). Fresh `--full` installs now land ~20 files instead of
207
+ ~73, focused entirely on equipping coding agents to drive the
208
+ dxkit CLI safely.
209
+ - `post-create.sh` now falls back through a three-step npm install
210
+ chain (`npm ci` → `npm install` → `npm install --legacy-peer-deps`)
211
+ so brownfield Node monorepos with peer-dep tangles survive the
212
+ devcontainer post-create cleanly.
213
+ - `doctor` no longer checks for the deleted generic scaffold files.
214
+ It now reports an `X/6 dxkit-* skills present` tally plus an
215
+ `AGENTS.md` presence check, giving customers a clearer signal of
216
+ what's missing on partially-scaffolded repos.
217
+
218
+ ### Fixed
219
+
220
+ - Graphify's on-disk cache no longer leaks `graphify-out/cache/` into
221
+ consumer repos. The temp-dir redirection monkey-patch now fires
222
+ before the first graphify call; `graphify-out/` is also added to
223
+ the scaffolded `.gitignore` defensively.
224
+
225
+ ### Deferred to next polish release
226
+
227
+ The following items rolled out of this release and will ship in
228
+ 2.5.2 (or bundle into 2.6 depending on the marketplace decision):
229
+
230
+ - `vyuh-dxkit setup-branch-protection` CLI (wraps `gh api` for
231
+ branch-protection enforcement).
232
+ - `vyuh-dxkit setup-prebuild` CLI (wraps `gh api` for Codespaces
233
+ prebuilds — cold-start cuts from ~25 minutes to ~30 seconds).
234
+ - Full `doctor` pivot to onboarding-health checks (hooks active,
235
+ branch protection set, baseline current). This release partially
236
+ shipped the pivot — the generic-scaffold checks were dropped — but
237
+ the new positive checks await the two CLI subcommands above.
238
+ - CI tool cache via `actions/cache@v4` on the scanner toolchain in
239
+ `dxkit-guardrails.yml`.
240
+
10
241
  ## [2.5.0] - 2026-05-18
11
242
 
12
243
  ### Summary
package/README.md CHANGED
@@ -9,7 +9,7 @@ agent DX; one baseline turns on the guardrails.** Works across major
9
9
  language stacks, greenfield or brownfield.
10
10
 
11
11
  ```bash
12
- npx @vyuhlabs/dxkit@latest init --full
12
+ npm init @vyuhlabs/dxkit
13
13
  ```
14
14
 
15
15
  <p>
@@ -45,28 +45,37 @@ the grading path.
45
45
 
46
46
  ---
47
47
 
48
- ## What `init --full` creates
48
+ ## What `npm init @vyuhlabs/dxkit` creates
49
49
 
50
50
  ```bash
51
- npx @vyuhlabs/dxkit@latest init --full
51
+ npm init @vyuhlabs/dxkit
52
52
  ```
53
53
 
54
- `init --full` lands a coordinated set of pieces:
54
+ This collapses install + scaffold into a single command: it installs
55
+ `@vyuhlabs/dxkit` as a devDep and runs `vyuh-dxkit init --full --yes`.
56
+ The full install lands a coordinated set of pieces:
55
57
 
56
58
  ```text
57
- .devcontainer/ Reproducible environment — pinned language
58
- toolchains, dxkit's scanner toolchain auto-
59
- installed, install scripts for AI agent CLIs
60
- (auth stays user-owned).
61
- .githooks/ pre-push guardrail hook (pre-commit opt-in
62
- via --with-precommit-hook).
59
+ .devcontainer/ Reproducible environment — per-stack pinned
60
+ toolchains (only the languages your project
61
+ uses), dxkit's scanner toolchain auto-installed,
62
+ install scripts for AI agent CLIs (auth stays
63
+ user-owned).
64
+ .githooks/ pre-push guardrail hook (pre-commit opt-in via
65
+ --with-precommit-hook). Postinstall auto-
66
+ activates `core.hooksPath` so teammates who
67
+ clone + `npm install` get hooks wired too.
63
68
  .github/workflows/ PR-gate workflow + post-merge baseline-refresh
64
69
  workflow (refresh runs only after the PR-gate
65
70
  passes — see "Safety + trust" below).
66
- agent scaffolding Entry-point doc, project skills, slash commands,
67
- per-language conventions, and specialized
68
- subagents for the currently supported agent
69
- (broader agent coverage in 2.6).
71
+ AGENTS.md Open-standard project context file read by
72
+ Claude Code, Codex, Cursor, Aider, and any
73
+ AGENTS.md-compliant agent.
74
+ CLAUDE.md Claude Code shim that points at AGENTS.md.
75
+ .claude/skills/ Nine dxkit-* skills covering the full lifecycle:
76
+ learn / init / config / hooks / reports /
77
+ action / fix / update / onboard. Claude Code
78
+ auto-discovers via skill frontmatter.
70
79
  .dxkit/ reports, baselines, and (optional) policy.
71
80
  .vyuh-dxkit.json install manifest.
72
81
  ```
@@ -74,7 +83,6 @@ agent scaffolding Entry-point doc, project skills, slash commands,
74
83
  After install:
75
84
 
76
85
  ```bash
77
- git config core.hooksPath .githooks # activate the hooks
78
86
  vyuh-dxkit baseline create # capture today's state
79
87
  git add .dxkit/baselines/main.json .githooks .github/workflows/dxkit-*.yml
80
88
  git commit -m "chore: enable dxkit guardrails"
@@ -108,9 +116,9 @@ rm .githooks/pre-commit # disable just pre-commit (keep pre-push)
108
116
  ## 60-second demo
109
117
 
110
118
  ```text
111
- $ npx @vyuhlabs/dxkit@latest init --full
112
- ✓ Created: 73 files
113
- ✓ Git hooks: installed 2 file(s)
119
+ $ npm init @vyuhlabs/dxkit
120
+ ✓ Created: 11 files (AGENTS.md, CLAUDE.md, .claude/skills/dxkit-*, ...)
121
+ ✓ Git hooks: installed 1 file(s)
114
122
  ✓ Devcontainer: installed 3 file(s)
115
123
  ✓ CI guardrails workflow: installed 1 file(s)
116
124
  ✓ CI baseline-refresh workflow: installed 1 file(s)
@@ -119,8 +127,8 @@ $ vyuh-dxkit baseline create
119
127
  ✓ Wrote .dxkit/baselines/main.json — 89 findings (32s)
120
128
  ```
121
129
 
122
- Your AI agent has access to dxkit's reports and the bundled
123
- subagents that init scaffolded. A typical request to the agent:
130
+ Your AI agent has access to dxkit's reports and the nine lifecycle
131
+ skills that init scaffolded. A typical request to the agent:
124
132
 
125
133
  ```text
126
134
  Read the latest dxkit health report. Pick one safe quality
@@ -166,27 +174,38 @@ Summary
166
174
  ## Quickstart
167
175
 
168
176
  ```bash
169
- # One-shot, no install
170
- npx @vyuhlabs/dxkit@latest init --full
177
+ # Canonical first install — collapses install + scaffold into one step
178
+ npm init @vyuhlabs/dxkit
171
179
 
172
- # Or install + use repeatedly
180
+ # Or install dxkit globally + scaffold manually
173
181
  npm install -g @vyuhlabs/dxkit
174
182
  vyuh-dxkit init --full
175
183
  vyuh-dxkit baseline create
176
184
  vyuh-dxkit guardrail check --changed-only
185
+
186
+ # Upgrade an existing install later
187
+ vyuh-dxkit upgrade # plan + execute combined
177
188
  ```
178
189
 
179
190
  À la carte if you only want specific pieces:
180
191
 
181
192
  ```bash
182
- vyuh-dxkit init --with-hooks # just the pre-push hook (default for hooks)
193
+ vyuh-dxkit init --with-dxkit-agents # just the nine dxkit-* skills + AGENTS.md
194
+ vyuh-dxkit init --with-hooks # just the pre-push hook
183
195
  vyuh-dxkit init --with-precommit-hook # add the pre-commit hook (opt-in; slow on large repos)
184
- vyuh-dxkit init --with-devcontainer # just the devcontainer
196
+ vyuh-dxkit init --with-devcontainer # just the per-stack devcontainer
185
197
  vyuh-dxkit init --with-ci # just the PR-gate workflow
186
198
  vyuh-dxkit init --with-baseline-refresh # just the auto-refresh
187
199
  vyuh-dxkit init --with-pr-review # AI PR-review workflow (opt-in, needs API key)
188
200
  ```
189
201
 
202
+ Post-install, two more CLIs polish the safety surface:
203
+
204
+ ```bash
205
+ vyuh-dxkit setup-branch-protection # mark dxkit-guardrails as required check on default branch
206
+ vyuh-dxkit setup-prebuild # configure Codespaces prebuild (cold-start ~7 min → ~30s)
207
+ ```
208
+
190
209
  ---
191
210
 
192
211
  ## Baseline mode: greenfield to 10-year-old codebases
@@ -420,8 +439,9 @@ dxkit is local-first.
420
439
  - [x] Git hooks (pre-push default; pre-commit opt-in)
421
440
  - [x] GitHub Actions PR-gate + gated baseline-refresh workflows
422
441
  - [x] Devcontainer with pinned toolchains
423
- - [ ] First-class scaffolding for every major coding agent
424
- per-agent skills + entry-point file conventions (2.6)
442
+ - [x] Nine dxkit-\* skills + AGENTS.md (open-standard, read by every
443
+ AGENTS.md-compliant agent Claude Code, Codex, Cursor, Aider)
444
+ - [ ] First-class plugin packaging for the Claude Code marketplace + MCP server for cross-agent reach (2.6, decision-pending)
425
445
  - [ ] Scoped + incremental scanning — fast pre-commit on monorepos
426
446
  (2.6)
427
447
  - [ ] Symbol-level coverage gaps across all 8 packs (2.6)
@@ -466,7 +486,7 @@ MIT. See [LICENSE](LICENSE).
466
486
  ## Try it
467
487
 
468
488
  ```bash
469
- npx @vyuhlabs/dxkit@latest init --full
489
+ npm init @vyuhlabs/dxkit
470
490
  ```
471
491
 
472
492
  If dxkit helps you ship AI-assisted changes more safely, star the
@@ -1 +1 @@
1
- {"version":3,"file":"graphify.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/graphify.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAE3E,UAAU,cAAc;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAgLD;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAa5C;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAMxF;AA6ED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAiBzF;AAED;;;;GAIG;AAOH,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,GAAG;IACpE,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAU9D,CAAC"}
1
+ {"version":3,"file":"graphify.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/graphify.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAE3E,UAAU,cAAc;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAoLD;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAa5C;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAMxF;AA6ED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAiBzF;AAED;;;;GAIG;AAOH,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,GAAG;IACpE,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAU9D,CAAC"}
@@ -80,6 +80,15 @@ except ImportError:
80
80
  print(json.dumps({"error": "graphify not installed"}))
81
81
  sys.exit(0)
82
82
 
83
+ # Redirect graphify's on-disk cache BEFORE any graphify function runs.
84
+ # collect_files() eagerly resolves cache_dir() during enumeration, so
85
+ # the patch has to land before the first graphify call — not after.
86
+ # Pre-patch, a 'graphify-out/cache/' directory was created in the
87
+ # customer's repo every time the analyzer touched a project.
88
+ import graphify.cache as _gc
89
+ _gc.cache_dir = lambda root=None: _cache_dir / "cache"
90
+ (_cache_dir / "cache").mkdir(parents=True, exist_ok=True)
91
+
83
92
  target = Path(sys.argv[1])
84
93
 
85
94
  # Three-axis exclusion. EXCLUDE_DIRS is basename-only (any path
@@ -145,11 +154,6 @@ if not files:
145
154
  print(json.dumps({"error": "no files found"}))
146
155
  sys.exit(0)
147
156
 
148
- # Monkey-patch cache to use /tmp instead of target repo
149
- import graphify.cache as _gc
150
- _gc.cache_dir = lambda root=None: _cache_dir / "cache"
151
- (_cache_dir / "cache").mkdir(parents=True, exist_ok=True)
152
-
153
157
  # Suppress progress output by redirecting stdout during extraction
154
158
  import io
155
159
  _real_stdout = sys.stdout
@@ -1 +1 @@
1
- {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../../src/analyzers/tools/graphify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../../src/analyzers/tools/graphify.ts"],"names":[],"mappings":"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"}
@@ -41,14 +41,32 @@ export interface ToolDefinition extends ToolRequirement {
41
41
  };
42
42
  /** Command that prints version info (used to verify tool works). */
43
43
  versionCheck?: string;
44
+ /**
45
+ * Optional applicability gate. Returns a short human-readable reason
46
+ * string when the tool is NOT applicable to the project at `cwd`
47
+ * (e.g. `@vitest/coverage-v8` on a mocha-based repo). Returns null
48
+ * when the tool IS applicable — detection then proceeds normally.
49
+ *
50
+ * The gate runs BEFORE binary/probe lookup so non-applicable tools
51
+ * never get reported as "missing." The CLI surfaces them as "n/a"
52
+ * with the reason string and excludes them from missing-count math
53
+ * so customers don't chase a non-fixable warning.
54
+ */
55
+ applicabilityGuard?: (cwd: string) => string | null;
44
56
  }
45
57
  export interface ToolStatus {
46
58
  name: string;
47
59
  available: boolean;
48
60
  path: string | null;
49
61
  version: string | null;
50
- source: 'path' | 'brew' | 'npm-g' | 'pipx' | 'cargo' | 'go' | 'probe' | 'missing';
62
+ source: 'path' | 'brew' | 'npm-g' | 'pipx' | 'cargo' | 'go' | 'probe' | 'missing' | 'n/a';
51
63
  requirement: ToolDefinition;
64
+ /**
65
+ * Populated when `source === 'n/a'`. Carries the reason from the
66
+ * applicabilityGuard so renderers can show e.g. "no vitest in this
67
+ * repo" alongside the n/a status.
68
+ */
69
+ notApplicableReason?: string;
52
70
  }
53
71
  /**
54
72
  * Find a tool across multiple installation methods.
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/tool-registry.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,QAA2D,CAAC;AA2BnF,MAAM,WAAW,cAAe,SAAQ,eAAe;IACrD,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,eAAe,EAAE;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,CAAC;IAClF,WAAW,EAAE,cAAc,CAAC;CAC7B;AA2KD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,CAqGtE;AAkBD,wDAAwD;AACxD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAO7D;AAMD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAgepD,CAAC;AAMF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,eAAe,EAAE,CA8B3F;AAED,sDAAsD;AACtD,wBAAgB,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAgB/F"}
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/tool-registry.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,QAA2D,CAAC;AA2BnF,MAAM,WAAW,cAAe,SAAQ,eAAe;IACrD,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,eAAe,EAAE;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,CAAC;IAC1F,WAAW,EAAE,cAAc,CAAC;IAC5B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AA2KD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,CAuHtE;AAkBD,wDAAwD;AACxD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAO7D;AAMD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CA2fpD,CAAC;AAMF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,eAAe,EAAE,CA8B3F;AAED,sDAAsD;AACtD,wBAAgB,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAgB/F"}
@@ -267,6 +267,23 @@ function findGraphifyPython(cwd) {
267
267
  * Returns the first matching absolute path, or null.
268
268
  */
269
269
  function findTool(def, cwd) {
270
+ // Applicability gate runs first. Non-applicable tools (e.g.
271
+ // vitest-coverage on a mocha repo) get an explicit "n/a" status so
272
+ // they never inflate the missing-count.
273
+ if (def.applicabilityGuard) {
274
+ const reason = def.applicabilityGuard(cwd || process.cwd());
275
+ if (reason) {
276
+ return {
277
+ name: def.name,
278
+ available: false,
279
+ path: null,
280
+ version: null,
281
+ source: 'n/a',
282
+ requirement: def,
283
+ notApplicableReason: reason,
284
+ };
285
+ }
286
+ }
270
287
  // Special case: graphify is a Python module, not a binary
271
288
  if (def.name === 'graphify') {
272
289
  const pyPath = findGraphifyPython(cwd || process.cwd());
@@ -511,21 +528,38 @@ exports.TOOL_DEFS = {
511
528
  'osv-scanner': {
512
529
  name: 'osv-scanner',
513
530
  description: 'OSV.dev dependency scanner + fix planner — populates structured upgradePlan on dep-vuln findings (Tier-2, Node/npm pack)',
514
- install: 'go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest',
531
+ install: 'brew install osv-scanner',
515
532
  check: 'osv-scanner --version',
516
533
  for: 'node',
517
534
  layer: 'language',
518
535
  binaries: ['osv-scanner'],
519
- // Go installs to $GOBIN (→ $GOPATH/bin by default, or ~/go/bin) which
520
- // is typically in $PATH on dev machines. Probe the canonical default
521
- // explicitly so detection works on machines that only have `go` in
522
- // PATH but not `go/bin`.
536
+ // ~/go/bin retained for backward-compat: machines that already
537
+ // installed osv-scanner via `go install` before this change get
538
+ // picked up without re-installing. ~/.local/bin (where the new
539
+ // install lands) is already in getSystemPaths(), so no explicit
540
+ // probe needed there.
523
541
  probePaths: [path.join(os.homedir(), 'go', 'bin')],
524
542
  versionCheck: 'osv-scanner --version 2>/dev/null',
543
+ // Install via GitHub releases binary (mirrors the gitleaks pattern):
544
+ // the prior `go install` path silently failed on every customer
545
+ // container without a Go toolchain (the majority of stacks — Node,
546
+ // Python, Ruby, .NET, JVM, etc.), leaving dep-vuln reports without
547
+ // osv-scanner's structured upgradePlan enrichment. GitHub release
548
+ // binaries are statically linked + need only curl + chmod.
549
+ //
550
+ // Version pinned here, NOT in the URL on the macOS line — Homebrew
551
+ // tracks its own version; we only need our own pin for the curl
552
+ // fallback. Bumping requires editing this line, copy-package, and
553
+ // dist/ rebuild.
525
554
  installCommands: {
526
- macos: 'brew install osv-scanner || go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest',
527
- linux: 'go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest',
528
- windows: 'go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest',
555
+ macos: 'brew install osv-scanner || ' +
556
+ '(mkdir -p ~/.local/bin && ' +
557
+ 'curl -sSfL https://github.com/google/osv-scanner/releases/download/v2.3.8/osv-scanner_darwin_amd64 -o ~/.local/bin/osv-scanner && ' +
558
+ 'chmod +x ~/.local/bin/osv-scanner)',
559
+ linux: 'mkdir -p ~/.local/bin && ' +
560
+ 'curl -sSfL https://github.com/google/osv-scanner/releases/download/v2.3.8/osv-scanner_linux_amd64 -o ~/.local/bin/osv-scanner && ' +
561
+ 'chmod +x ~/.local/bin/osv-scanner',
562
+ windows: 'scoop install osv-scanner',
529
563
  },
530
564
  },
531
565
  'license-checker-rseidelsohn': {
@@ -775,6 +809,14 @@ exports.TOOL_DEFS = {
775
809
  installScope: 'project-local',
776
810
  binaries: [],
777
811
  nodePackage: '@vitest/coverage-v8',
812
+ // Non-applicable on mocha/jest/ava-only repos: the V8 coverage
813
+ // provider is a peer of vitest itself, so installing it without
814
+ // vitest just adds dead weight and makes `tools list` report a
815
+ // misleading "missing" entry. Guard against that by checking for
816
+ // vitest in the consumer's tree first.
817
+ applicabilityGuard: (cwd) => fs.existsSync(path.join(cwd, 'node_modules', 'vitest', 'package.json'))
818
+ ? null
819
+ : 'no vitest in this repo',
778
820
  // Version auto-detect via `require('vitest/package.json')` assumed
779
821
  // vitest was present in the target repo. Repos using mocha/jest/ava
780
822
  // hit a MODULE_NOT_FOUND crash (pre-2.3.1 failure mode). Gate with