@vyuhlabs/dxkit 2.5.1 → 2.6.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.
Files changed (200) hide show
  1. package/CHANGELOG.md +318 -0
  2. package/README.md +150 -28
  3. package/dist/allowlist/categories.d.ts +120 -0
  4. package/dist/allowlist/categories.d.ts.map +1 -0
  5. package/dist/allowlist/categories.js +194 -0
  6. package/dist/allowlist/categories.js.map +1 -0
  7. package/dist/allowlist/cli.d.ts +95 -0
  8. package/dist/allowlist/cli.d.ts.map +1 -0
  9. package/dist/allowlist/cli.js +454 -0
  10. package/dist/allowlist/cli.js.map +1 -0
  11. package/dist/allowlist/diff.d.ts +67 -0
  12. package/dist/allowlist/diff.d.ts.map +1 -0
  13. package/dist/allowlist/diff.js +147 -0
  14. package/dist/allowlist/diff.js.map +1 -0
  15. package/dist/allowlist/file.d.ts +249 -0
  16. package/dist/allowlist/file.d.ts.map +1 -0
  17. package/dist/allowlist/file.js +497 -0
  18. package/dist/allowlist/file.js.map +1 -0
  19. package/dist/allowlist/gather.d.ts +61 -0
  20. package/dist/allowlist/gather.d.ts.map +1 -0
  21. package/dist/allowlist/gather.js +143 -0
  22. package/dist/allowlist/gather.js.map +1 -0
  23. package/dist/allowlist/hint.d.ts +80 -0
  24. package/dist/allowlist/hint.d.ts.map +1 -0
  25. package/dist/allowlist/hint.js +271 -0
  26. package/dist/allowlist/hint.js.map +1 -0
  27. package/dist/allowlist/inline.d.ts +149 -0
  28. package/dist/allowlist/inline.d.ts.map +1 -0
  29. package/dist/allowlist/inline.js +306 -0
  30. package/dist/allowlist/inline.js.map +1 -0
  31. package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
  32. package/dist/analyzers/tools/tool-registry.js +25 -8
  33. package/dist/analyzers/tools/tool-registry.js.map +1 -1
  34. package/dist/baseline/baseline-file.d.ts +7 -0
  35. package/dist/baseline/baseline-file.d.ts.map +1 -1
  36. package/dist/baseline/baseline-file.js +22 -1
  37. package/dist/baseline/baseline-file.js.map +1 -1
  38. package/dist/baseline/check-renderers.d.ts +13 -1
  39. package/dist/baseline/check-renderers.d.ts.map +1 -1
  40. package/dist/baseline/check-renderers.js +67 -1
  41. package/dist/baseline/check-renderers.js.map +1 -1
  42. package/dist/baseline/check.d.ts +33 -7
  43. package/dist/baseline/check.d.ts.map +1 -1
  44. package/dist/baseline/check.js +90 -64
  45. package/dist/baseline/check.js.map +1 -1
  46. package/dist/baseline/create.d.ts +35 -7
  47. package/dist/baseline/create.d.ts.map +1 -1
  48. package/dist/baseline/create.js +43 -5
  49. package/dist/baseline/create.js.map +1 -1
  50. package/dist/baseline/entry-to-located.d.ts +6 -1
  51. package/dist/baseline/entry-to-located.d.ts.map +1 -1
  52. package/dist/baseline/entry-to-located.js +20 -2
  53. package/dist/baseline/entry-to-located.js.map +1 -1
  54. package/dist/baseline/finding-identity.d.ts.map +1 -1
  55. package/dist/baseline/finding-identity.js +15 -13
  56. package/dist/baseline/finding-identity.js.map +1 -1
  57. package/dist/baseline/modes.d.ts +140 -0
  58. package/dist/baseline/modes.d.ts.map +1 -0
  59. package/dist/baseline/modes.js +179 -0
  60. package/dist/baseline/modes.js.map +1 -0
  61. package/dist/baseline/policy.d.ts +64 -0
  62. package/dist/baseline/policy.d.ts.map +1 -1
  63. package/dist/baseline/policy.js +102 -1
  64. package/dist/baseline/policy.js.map +1 -1
  65. package/dist/baseline/producers/health.d.ts +2 -2
  66. package/dist/baseline/producers/health.d.ts.map +1 -1
  67. package/dist/baseline/producers/health.js.map +1 -1
  68. package/dist/baseline/producers/index.d.ts +11 -5
  69. package/dist/baseline/producers/index.d.ts.map +1 -1
  70. package/dist/baseline/producers/index.js +12 -9
  71. package/dist/baseline/producers/index.js.map +1 -1
  72. package/dist/baseline/producers/quality.d.ts +3 -3
  73. package/dist/baseline/producers/quality.d.ts.map +1 -1
  74. package/dist/baseline/producers/quality.js.map +1 -1
  75. package/dist/baseline/producers/secret-hmac.d.ts +2 -2
  76. package/dist/baseline/producers/secret-hmac.d.ts.map +1 -1
  77. package/dist/baseline/producers/secret-hmac.js.map +1 -1
  78. package/dist/baseline/producers/security.d.ts +2 -2
  79. package/dist/baseline/producers/security.d.ts.map +1 -1
  80. package/dist/baseline/producers/security.js.map +1 -1
  81. package/dist/baseline/producers/stale-allow.d.ts +70 -0
  82. package/dist/baseline/producers/stale-allow.d.ts.map +1 -0
  83. package/dist/baseline/producers/stale-allow.js +111 -0
  84. package/dist/baseline/producers/stale-allow.js.map +1 -0
  85. package/dist/baseline/producers/tests.d.ts +2 -2
  86. package/dist/baseline/producers/tests.d.ts.map +1 -1
  87. package/dist/baseline/producers/tests.js.map +1 -1
  88. package/dist/baseline/ref-baseline.d.ts +114 -0
  89. package/dist/baseline/ref-baseline.d.ts.map +1 -0
  90. package/dist/baseline/ref-baseline.js +260 -0
  91. package/dist/baseline/ref-baseline.js.map +1 -0
  92. package/dist/baseline/sanitize.d.ts +80 -0
  93. package/dist/baseline/sanitize.d.ts.map +1 -0
  94. package/dist/baseline/sanitize.js +91 -0
  95. package/dist/baseline/sanitize.js.map +1 -0
  96. package/dist/baseline/show.d.ts.map +1 -1
  97. package/dist/baseline/show.js +9 -3
  98. package/dist/baseline/show.js.map +1 -1
  99. package/dist/baseline/types.d.ts +73 -26
  100. package/dist/baseline/types.d.ts.map +1 -1
  101. package/dist/baseline/types.js +7 -1
  102. package/dist/baseline/types.js.map +1 -1
  103. package/dist/baseline/visibility.d.ts +61 -0
  104. package/dist/baseline/visibility.d.ts.map +1 -0
  105. package/dist/baseline/visibility.js +121 -0
  106. package/dist/baseline/visibility.js.map +1 -0
  107. package/dist/cli.d.ts.map +1 -1
  108. package/dist/cli.js +154 -13
  109. package/dist/cli.js.map +1 -1
  110. package/dist/constants.d.ts.map +1 -1
  111. package/dist/constants.js +0 -10
  112. package/dist/constants.js.map +1 -1
  113. package/dist/detect.d.ts.map +1 -1
  114. package/dist/detect.js +0 -15
  115. package/dist/detect.js.map +1 -1
  116. package/dist/doctor.d.ts +78 -1
  117. package/dist/doctor.d.ts.map +1 -1
  118. package/dist/doctor.js +590 -101
  119. package/dist/doctor.js.map +1 -1
  120. package/dist/generator.d.ts.map +1 -1
  121. package/dist/generator.js +15 -0
  122. package/dist/generator.js.map +1 -1
  123. package/dist/issue-cli.d.ts +62 -0
  124. package/dist/issue-cli.d.ts.map +1 -0
  125. package/dist/issue-cli.js +252 -0
  126. package/dist/issue-cli.js.map +1 -0
  127. package/dist/languages/csharp.d.ts.map +1 -1
  128. package/dist/languages/csharp.js +2 -0
  129. package/dist/languages/csharp.js.map +1 -1
  130. package/dist/languages/go.d.ts.map +1 -1
  131. package/dist/languages/go.js +2 -0
  132. package/dist/languages/go.js.map +1 -1
  133. package/dist/languages/index.d.ts +25 -0
  134. package/dist/languages/index.d.ts.map +1 -1
  135. package/dist/languages/index.js +44 -0
  136. package/dist/languages/index.js.map +1 -1
  137. package/dist/languages/java.d.ts.map +1 -1
  138. package/dist/languages/java.js +2 -0
  139. package/dist/languages/java.js.map +1 -1
  140. package/dist/languages/kotlin.d.ts.map +1 -1
  141. package/dist/languages/kotlin.js +2 -0
  142. package/dist/languages/kotlin.js.map +1 -1
  143. package/dist/languages/python.d.ts.map +1 -1
  144. package/dist/languages/python.js +11 -1
  145. package/dist/languages/python.js.map +1 -1
  146. package/dist/languages/ruby.d.ts.map +1 -1
  147. package/dist/languages/ruby.js +2 -0
  148. package/dist/languages/ruby.js.map +1 -1
  149. package/dist/languages/rust.d.ts.map +1 -1
  150. package/dist/languages/rust.js +2 -0
  151. package/dist/languages/rust.js.map +1 -1
  152. package/dist/languages/types.d.ts +45 -0
  153. package/dist/languages/types.d.ts.map +1 -1
  154. package/dist/languages/typescript.d.ts.map +1 -1
  155. package/dist/languages/typescript.js +2 -0
  156. package/dist/languages/typescript.js.map +1 -1
  157. package/dist/prompts.d.ts.map +1 -1
  158. package/dist/prompts.js +0 -5
  159. package/dist/prompts.js.map +1 -1
  160. package/dist/setup-branch-protection.d.ts +34 -0
  161. package/dist/setup-branch-protection.d.ts.map +1 -0
  162. package/dist/setup-branch-protection.js +190 -0
  163. package/dist/setup-branch-protection.js.map +1 -0
  164. package/dist/setup-gh.d.ts +75 -0
  165. package/dist/setup-gh.d.ts.map +1 -0
  166. package/dist/setup-gh.js +213 -0
  167. package/dist/setup-gh.js.map +1 -0
  168. package/dist/setup-prebuild.d.ts +34 -0
  169. package/dist/setup-prebuild.d.ts.map +1 -0
  170. package/dist/setup-prebuild.js +181 -0
  171. package/dist/setup-prebuild.js.map +1 -0
  172. package/dist/ship-installers.d.ts.map +1 -1
  173. package/dist/ship-installers.js +19 -4
  174. package/dist/ship-installers.js.map +1 -1
  175. package/dist/types.d.ts +24 -6
  176. package/dist/types.d.ts.map +1 -1
  177. package/dist/update.d.ts +41 -0
  178. package/dist/update.d.ts.map +1 -1
  179. package/dist/update.js +154 -15
  180. package/dist/update.js.map +1 -1
  181. package/dist/upgrade.d.ts +88 -0
  182. package/dist/upgrade.d.ts.map +1 -0
  183. package/dist/upgrade.js +324 -0
  184. package/dist/upgrade.js.map +1 -0
  185. package/package.json +1 -1
  186. package/templates/.claude/skills/dxkit-action/SKILL.md +111 -17
  187. package/templates/.claude/skills/dxkit-config/SKILL.md +7 -7
  188. package/templates/.claude/skills/dxkit-fix/SKILL.md +165 -0
  189. package/templates/.claude/skills/dxkit-hooks/SKILL.md +8 -8
  190. package/templates/.claude/skills/dxkit-init/SKILL.md +3 -3
  191. package/templates/.claude/skills/dxkit-learn/SKILL.md +9 -9
  192. package/templates/.claude/skills/dxkit-onboard/SKILL.md +274 -0
  193. package/templates/.claude/skills/dxkit-reports/SKILL.md +18 -18
  194. package/templates/.claude/skills/dxkit-update/SKILL.md +164 -0
  195. package/templates/.devcontainer/devcontainer.json +6 -15
  196. package/templates/.devcontainer/post-create.sh +19 -4
  197. package/dist/baseline/producers/licenses.d.ts +0 -23
  198. package/dist/baseline/producers/licenses.d.ts.map +0 -1
  199. package/dist/baseline/producers/licenses.js +0 -46
  200. package/dist/baseline/producers/licenses.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,324 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.6.0] - 2026-05-23
11
+
12
+ The "per-finding suppression + public-repo-safe baselines" release.
13
+ Adds the typed-category allowlist surface for false-positive /
14
+ test-fixture / mitigated-externally / accepted-risk / deferred
15
+ suppression with inline + file-level modes; retires license
16
+ findings from the baseline (~73% size drop on real customer repos);
17
+ introduces three baseline modes with visibility-aware defaults so
18
+ public repos no longer leak file paths, package names, and
19
+ advisory IDs through a committed baseline.
20
+
21
+ ### Added
22
+
23
+ - **Per-finding allowlist** — `vyuh-dxkit allowlist add/list/show/audit/prune`.
24
+ Typed-category suppression (`false-positive`, `test-fixture`,
25
+ `mitigated-externally`, `accepted-risk`, `deferred`) with required
26
+ reason + (where relevant) expiry. Two surfaces: inline
27
+ `// dxkit-allow:<category> reason="..."` annotations and a
28
+ file-level `.dxkit/allowlist.json`. `accepted-risk` and `deferred`
29
+ require expiry (default 90 days). See
30
+ [docs/commands/allowlist.md](docs/commands/allowlist.md).
31
+ - **Strict stale-annotation detection** — orphaned `dxkit-allow:`
32
+ annotations (where the underlying finding is now gone) emit a
33
+ new `stale-allow` baseline kind on the next scan. The
34
+ TypeScript `@ts-expect-error` pattern, applied to suppressions —
35
+ forces cleanup, prevents the annotation graveyard. Allowlisting
36
+ a `stale-allow` finding is forbidden; only remediation is to
37
+ remove the orphaned comment.
38
+ - **Allowlist activity in PR comments** — the
39
+ `dxkit-guardrails.yml` workflow's sticky PR comment now includes
40
+ an "Allowlist activity" section listing every entry added (or
41
+ removed) on this branch versus the baseline commit. Reviewers
42
+ see new suppressions being introduced and can sanity-check
43
+ category + reason + expiry before approving.
44
+ - **`vyuh-dxkit issue`** — pre-filled GitHub Issues for false
45
+ positives, missing findings, bugs, feature requests, and docs
46
+ gaps. Nothing submits automatically — the CLI opens the
47
+ customer's browser at a new-issue URL with env metadata
48
+ pre-populated, customer reviews + clicks "Submit." See
49
+ [docs/commands/issue.md](docs/commands/issue.md).
50
+ - **`commentSyntax` on language packs** — each pack declares its
51
+ line-comment marker (`#` for python/ruby; `//` for
52
+ typescript/go/rust/csharp/kotlin/java). Drives the inline
53
+ allowlist-annotation generator across every language uniformly.
54
+ Recipe-enforced: scaffolder ships an empty placeholder so
55
+ unfilled packs fail the contract test until populated.
56
+ - Three preemptive architecture rules in `scripts/check-architecture.sh`
57
+ lock down the allowlist canonical entry points: no `createHash`
58
+ inside `src/allowlist/`, no direct `allowlist.json` IO outside
59
+ the canonical loader, no language-comment fallback literals
60
+ (`?? '//'`) anywhere in the module.
61
+
62
+ ### Changed
63
+
64
+ - **License findings retired from the baseline.** Per-package
65
+ license attributions no longer flow through the baseline
66
+ producer registry — they were informational, not regression
67
+ material, and dominated baselines on real customer repos
68
+ (~73% of entries). The canonical license inventory now lives
69
+ solely in `.dxkit/bom.json` (`vyuh-dxkit bom`), which already
70
+ carries richer per-package data (licenseType, licenseText,
71
+ sourceUrl, supplier, releaseDate). Lenient migration:
72
+ baselines written by older dxkit versions still load — the
73
+ reader silently filters retired `license` entries on the way
74
+ in (no file rewrite until the next `baseline create --force`).
75
+ Dependency vulnerability tracking is unchanged — `dep-vuln`
76
+ is a separate identity kind on a separate producer and still
77
+ blocks via the guardrail check.
78
+ - **Sanitization machinery for baseline entries.** New pure
79
+ module `src/baseline/sanitize.ts` introduces a stripped
80
+ `SanitizedBaselineEntry` variant (`{ id, kind, sanitized: true }`)
81
+ carrying identity + kind only. The `sanitizeEntry` /
82
+ `sanitizeFile` pass collapses every rich field; cross-run
83
+ matching still works at full confidence via the fingerprint
84
+ multiset pass. Producers now emit the rich
85
+ `RichBaselineEntry` shape (a `BaselineEntry` excluding the
86
+ sanitized variant); sanitization is a write-time
87
+ transformation, never a producer concern. Consumers walking
88
+ a baseline narrow via the `isSanitized` type guard before
89
+ switching on `entry.kind`. Write-path wiring + visibility-
90
+ aware mode selection ship in a follow-up commit.
91
+
92
+ ### Added
93
+
94
+ - **Three baseline modes with visibility-aware defaults.**
95
+ `committed-full` (today's behavior, rich entries), `committed-
96
+ sanitized` (stripped per-entry payload via the sanitization
97
+ pass), and `ref-based` (no committed file; guardrail check
98
+ recomputes the prior side from a git ref via `git worktree
99
+ add`). The mode is picked by a single resolver
100
+ (`src/baseline/modes.ts`) with precedence: CLI flag →
101
+ `.dxkit/policy.json:baseline.mode` → visibility-derived default
102
+ (public repos auto-pick `ref-based`; everything else picks
103
+ `committed-full`). `committed-sanitized` is never auto-picked
104
+ — it's the explicit opt-in for compliance-conscious private
105
+ repos.
106
+ - `vyuh-dxkit baseline create [--mode <m>] [--ref <r>]` and
107
+ `vyuh-dxkit guardrail check [--mode <m>] [--ref <r>]` — flags
108
+ override `policy.json` for one-off runs.
109
+ - `gh repo view --json visibility` probe + per-process cache
110
+ in `src/baseline/visibility.ts`. Every failure path returns
111
+ `'unknown'`; the resolver treats unknown as private to avoid
112
+ surprise sanitization when `gh auth` lapses.
113
+ - Ref-based gather mechanics in `src/baseline/ref-baseline.ts` —
114
+ `withRefWorktree(opts, fn)` is the reusable primitive; tears
115
+ down the worktree on success + failure. Mirrors file-mode
116
+ `.dxkit/salt` into the worktree so secret-HMAC entries pair
117
+ across cwd + worktree.
118
+
119
+ ### Architectural notes
120
+
121
+ - New CLAUDE.md rule 11: baseline mode resolution flows through
122
+ `resolveBaselineMode`. Two arch-check rules lock the contract:
123
+ no `gh repo view --json visibility` outside
124
+ `src/baseline/visibility.ts`; no `git worktree add` / `remove`
125
+ outside `src/baseline/ref-baseline.ts`.
126
+ - `resolvePolicy` lifted from `check.ts` to `policy.ts` so
127
+ `createBaseline` and `runGuardrailCheck` share one canonical
128
+ loader.
129
+
130
+ ### Discovery surfaces
131
+
132
+ - **PR-comment markdown** now shows the resolved baseline mode in
133
+ the sticky footer (`_Mode_: \`ref-based\` (ref: \`origin/main\`)`).
134
+ Reviewers see WHY a guardrail run picked a given posture.
135
+ - **JSON renderer** carries `baseline.mode = { value, source,
136
+ explanation, ref? }` so agents + dashboards can read the audit
137
+ trail without re-deriving it.
138
+ - **`vyuh-dxkit doctor`** has two new operational checks:
139
+ - "baseline mode: ref-based" / "baseline captured (mode: ...)" —
140
+ the existing baseline-captured check now understands ref-based
141
+ mode (where no on-disk file is expected) so the doctor stops
142
+ reporting a false-negative on public repos.
143
+ - "baseline mode aligned with repo visibility" — warns when an
144
+ explicit `committed-full` pin is in use on a public repo (the
145
+ posture leaks file paths + package names; the auto-picker
146
+ would have chosen ref-based).
147
+ - **`dxkit-onboard` skill** — step 5 now ASKs about disclosure
148
+ posture before running `baseline create`, walks customers through
149
+ the three modes, and offers a one-shot `.dxkit/policy.json` snippet
150
+ for pinning the choice repo-wide.
151
+ - **`dxkit-action` skill** — new section explains how to act on a
152
+ blocked finding when the baseline is sanitized / ref-based
153
+ (locator stripped at write time; re-run the analyzer for full
154
+ context or allowlist by fingerprint).
155
+ - **README + getting-started.md** — call out the public-repo
156
+ posture explicitly so customers don't accidentally commit a
157
+ rich baseline to an open-source repo.
158
+
159
+ ### Architectural notes
160
+
161
+ - Added `stale-allow` as a new `IdentityKind` (Rule 9 + Rule 10
162
+ compliant: identityFor case + producer + fixture row +
163
+ removed from `DEFERRED_KINDS` once the gather pass landed).
164
+ - The hint formatter (block-time guidance for blocked findings)
165
+ consumes the canonical `BaselineEntry` discriminated union
166
+ directly — no invented intermediate "BlockingFinding" shape.
167
+ TypeScript exhaustiveness across 6+ switches guarantees new
168
+ finding kinds can't ship without matching cases.
169
+ - `dxkit-action` skill extended with the typed-category +
170
+ surfaces description; SAST recipe redirects from semgrep's
171
+ `// nosemgrep:` to dxkit's `// dxkit-allow:` (single canonical
172
+ suppression surface across all scanners).
173
+
174
+ ## [2.5.2] - 2026-05-22
175
+
176
+ The "scaffold UX + lifecycle skills + setup automation" release. Closes
177
+ every defect surfaced during the 2026-05-21 guided Codespaces UX
178
+ walkthrough (D145–D156) plus a vestigial-cleanup pass and adds three
179
+ new CLI subcommands + three new lifecycle skills.
180
+
181
+ Companion release: **`@vyuhlabs/create-dxkit@0.2.0`** ships alongside
182
+ this version, picking up the create-dxkit shim improvements (quieter
183
+ ERESOLVE handling, `--no-audit`, `.npmrc legacy-peer-deps` persistence).
184
+ Tag: `create-dxkit@v0.2.0`. Run `npm init @vyuhlabs/dxkit` to get
185
+ the new combined experience.
186
+
187
+ Validated end-to-end with two cross-stack walkthroughs on 2026-05-22:
188
+ `vyuhlabs-platform` (python + typescript) and `dpl-studio` (csharp).
189
+ Both stacks: defect closures verified, per-pack devcontainer adapts
190
+ correctly, doctor's new tier-3 surfaces operational gaps with
191
+ actionable fix commands.
192
+
193
+ ### Added
194
+
195
+ - Three new lifecycle skills under `.claude/skills/`, completing
196
+ the orthogonal customer-journey trio:
197
+ - **`dxkit-fix`** — reactive repair. Consumes
198
+ `vyuh-dxkit doctor --json` output and walks the customer
199
+ through each fixable check with per-step confirmation.
200
+ - **`dxkit-update`** — existing-install upgrade orchestrator.
201
+ Consumes `vyuh-dxkit upgrade --plan --json` and drives a
202
+ conversational upgrade with version-delta analysis, breaking-
203
+ change warnings, and per-step confirmation. Hands off to
204
+ `dxkit-fix` on post-upgrade doctor failures.
205
+ - **`dxkit-onboard`** — fresh-install orchestrator. Walks the
206
+ full first-time customer journey end-to-end (install → doctor
207
+ → fix gaps → baseline → hooks → branch protection → Codespaces
208
+ prebuild → final verify). Delegates to focused skills for
209
+ sub-decisions.
210
+ - Three new CLI subcommands:
211
+ - **`vyuh-dxkit upgrade [--plan [--json] | --yes | --target=X.Y.Z |
212
+ --dry-run]`** — combined binary + scaffold refresh. `--plan`
213
+ mode emits structured `upgrade-plan.v1` JSON consumed by the
214
+ `dxkit-update` skill. Execution mode runs `npm install`
215
+ + `vyuh-dxkit update` + `vyuh-dxkit doctor` in sequence with
216
+ a devcontainer-rebuild reminder if applicable.
217
+ - **`vyuh-dxkit setup-branch-protection [--branch X]
218
+ [--require-reviews N] [--force]`** — wraps `gh api` to mark
219
+ `dxkit-guardrails` as a required status check on the default
220
+ branch. Idempotent merge with existing required-checks list.
221
+ - **`vyuh-dxkit setup-prebuild [--branch X] [--regions=R1,R2]
222
+ [--force]`** — wraps `gh api` to configure Codespaces
223
+ prebuilds. Fresh Codespaces start in ~30s instead of running
224
+ the full devcontainer build (~7 min after per-stack feature).
225
+ - Doctor third tier — **Operational health**. Six runtime checks
226
+ (`git hooks active`, `baseline captured`, `vyuh-dxkit on PATH`,
227
+ `scanner toolchain healthy`, `.npmrc legacy-peer-deps
228
+ persistence`, `CI guardrails workflow`) each carrying structured
229
+ fix metadata (hint + command + skill). Plus a new `--json`
230
+ output mode emitting the `doctor.v1` schema for `dxkit-fix`
231
+ consumption.
232
+ - `manifest.installFlags` — persists the customer's `init`
233
+ flag choices in `.vyuh-dxkit.json` so `vyuh-dxkit update`
234
+ knows exactly which surfaces to refresh. Self-migrates legacy
235
+ pre-2.5.2 manifests by stamping detected flags back on first
236
+ update run.
237
+ - Per-pack `LanguageSupport.devcontainerExtensions?` field.
238
+ Each language pack contributes its VSCode editor extensions;
239
+ the installer unions across active packs only. Pure-Python
240
+ Codespaces no longer install Go / Rust / C# / Java / Kotlin /
241
+ Ruby editor extensions on every container start.
242
+ - Architecture rule (`scripts/check-architecture.sh`) that catches
243
+ dead `IF_*` template conditions in `constants.ts`. The
244
+ type-correct compute-without-consumer class of dead code sat
245
+ for days before the rule landed; rule now blocks new
246
+ occurrences at pre-commit time.
247
+ - Three new doc pages: `docs/commands/upgrade.md`,
248
+ `docs/commands/setup-branch-protection.md`,
249
+ `docs/commands/setup-prebuild.md`.
250
+
251
+ ### Changed
252
+
253
+ - **`vyuh-dxkit update` actually refreshes everything now.**
254
+ Pre-this-release, update only re-ran the template generator and
255
+ silently passed `withDxkitAgents=false`. Customers on 2.5.1 had
256
+ no path to receive new dxkit-* skills, per-stack devcontainer
257
+ extensions, doctor pivot, or any other scaffold-side change.
258
+ `update` now detects which install surfaces the customer
259
+ originally landed (via `manifest.installFlags` or workspace
260
+ detection) and re-runs every relevant installer.
261
+ - `vyuh-dxkit doctor` — three-tier framing (Reports + Agent DX +
262
+ Operational health, was two-tier). Tier 1 + 2 labels +
263
+ exit-code behavior preserved verbatim; tier 3 is additive.
264
+ - All six existing dxkit-* skill prose files standardized on
265
+ `npx vyuh-dxkit X` invocations (was a mix of bare + npx forms).
266
+ Robust to customers whose shell PATH doesn't have dxkit
267
+ globally installed.
268
+ - Python devcontainer feature switched from `installTools: true`
269
+ → `false`. The upstream feature's bundled installTools list
270
+ added ~3 min to every devcontainer build with no dxkit
271
+ consumer. Saves ~3 min per Codespaces rebuild on python-stack
272
+ projects.
273
+ - `osv-scanner` install switched from `go install` to GitHub
274
+ releases binary fetch. Pre-this-release, customers on any
275
+ non-Go stack silently lost `osv-scanner` (the canonical
276
+ Tier-2 dep-vuln scanner) because the install command failed
277
+ without a Go toolchain.
278
+ - `post-create.sh` always runs a global `npm install -g
279
+ @vyuhlabs/dxkit` in addition to whatever project-local install
280
+ happened. Without this, `vyuh-dxkit` wasn't on the customer's
281
+ shell PATH in Codespaces.
282
+ - Init's closing summary surfaces `Next: run vyuh-dxkit
283
+ baseline create` as a prominent info-level call-to-action
284
+ immediately after `Done!`, instead of burying it in a dim
285
+ three-line footer.
286
+ - `create-dxkit` shim: stderr from the first `npm install`
287
+ attempt is now captured (not streamed) so a peer-dep
288
+ `ERESOLVE` doesn't print a multi-line error wall before the
289
+ silent `--legacy-peer-deps` fallback succeeds. `--no-audit`
290
+ passed to both install attempts so the host project's
291
+ pre-existing vulnerability count doesn't surface mid-init.
292
+ Fallback choice persisted to `.npmrc` so the customer's next
293
+ `npm install <pkg>` doesn't re-hit the same ERESOLVE wall.
294
+ - CI: `actions/cache@v4` on the scanner toolchain
295
+ (`~/.local/{pipx,bin,share/{detekt,pmd}}`). Saves ~2 min per
296
+ CI run.
297
+ - Publish workflows (`publish.yml` + `publish-create-dxkit.yml`):
298
+ verify-shasum poll window 18s → 180s. First-publishes of
299
+ scoped packages commonly need 30–90s for CDN propagation;
300
+ the wider window prevents the "publish succeeded but workflow
301
+ reports failure" mode that bit both 2.5.1 publishes.
302
+ - README, getting-started, docs/README, commands/init.md
303
+ refreshed to reflect: `npm init @vyuhlabs/dxkit` as canonical
304
+ first install, 9 lifecycle skills (was 6), postinstall
305
+ auto-activation of hooks, per-stack devcontainer.
306
+
307
+ ### Removed
308
+
309
+ - Vestigial `DetectedStack.tools.{gcloud, pulumi, infisical,
310
+ ghCli}` field. Computed at every detect call since the 2026-
311
+ 05-19 generator simplification removed the `.project.yaml`
312
+ consumers; nothing referenced them post-cleanup. Doctor's
313
+ pre-pivot tier-2 `gcloud` + `infisical` availability checks
314
+ removed alongside (no manifest field to gate on).
315
+ - Six dead `IF_*` template conditions in `constants.ts`:
316
+ `IF_POSTGRES`, `IF_REDIS`, `IF_HAS_SERVICES`, `IF_DOCKER`,
317
+ `IF_CLAUDE_CODE`, `IF_COVERAGE_ENABLED`. Computed but no
318
+ template referenced them; same 2026-05-19 cleanup left them
319
+ behind. Arch-check rule (above) prevents new occurrences.
320
+
321
+ ### Fixed
322
+
323
+ - Dispatcher deadline test (`test/dispatcher-deadline.test.ts`):
324
+ lower-bound assertion 40ms → 25ms. Test was occasionally
325
+ flaking on fast CI runners where `setTimeout`'s ~1-2ms
326
+ granularity could fire at 38-39ms.
327
+
10
328
  ## [2.5.1] - 2026-05-20
11
329
 
12
330
  ### Added
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
@@ -215,6 +234,86 @@ The classifier distinguishes:
215
234
  Customize via [`.dxkit/policy.json`](docs/configuration/policy.md) —
216
235
  auto-discovered when present, compiled-in defaults otherwise.
217
236
 
237
+ ### Baseline modes — public vs private repos
238
+
239
+ The baseline file is committed to git. On public repos that
240
+ disclosure surface matters: a `committed-full` baseline tells anyone
241
+ reading the repo which file/line each finding lives on, which
242
+ private packages you depend on, and which advisory IDs you're
243
+ sitting on unpatched. dxkit ships three modes:
244
+
245
+ | Mode | On-disk content | Auto-default for |
246
+ | --------------------- | -------------------------------------------------------- | ---------------- |
247
+ | `committed-full` | Rich entries (file/line/rule/package/advisory) | private repos |
248
+ | `committed-sanitized` | Stripped to `{ id, kind }` per finding | opt-in |
249
+ | `ref-based` | No file — guardrail recomputes prior side from a git ref | public repos |
250
+
251
+ `vyuh-dxkit baseline create` auto-picks via
252
+ `gh repo view --json visibility`. Pin the choice repo-wide in
253
+ `.dxkit/policy.json`:
254
+
255
+ ```json
256
+ { "baseline": { "mode": "ref-based", "ref": "origin/main" } }
257
+ ```
258
+
259
+ The cross-run matching contract (fingerprint identity) is identical
260
+ across all three modes — sanitization only strips human-readable
261
+ locators, it doesn't change which findings pair across runs. See
262
+ [docs/commands/baseline.md](docs/commands/baseline.md#modes) for the
263
+ full trade-off discussion.
264
+
265
+ ---
266
+
267
+ ## Allowlist: per-finding suppression
268
+
269
+ The baseline handles codebase-wide brownfield acceptance ("today's
270
+ mess is grandfathered; tomorrow's must be net-new improvement").
271
+ For per-finding decisions — false positives, intentional test
272
+ fixtures, externally-mitigated risks, deliberately deferred work —
273
+ use the [allowlist](docs/commands/allowlist.md).
274
+
275
+ Five typed categories signal **why** a finding is suppressed:
276
+
277
+ | Category | Meaning | Expiry |
278
+ | ---------------------- | ------------------------------------------------- | ------------------------------ |
279
+ | `false-positive` | Scanner is wrong about this finding | Optional |
280
+ | `test-fixture` | Intentional pattern in fixture / test code | Optional |
281
+ | `mitigated-externally` | Real risk neutralized at runtime (WAF, env, etc.) | Optional |
282
+ | `accepted-risk` | Real risk, team accepts, signed off | **Required** (default 90 days) |
283
+ | `deferred` | Real, will fix later, tracked work | **Required** |
284
+
285
+ Two surfaces. Inline annotation for source-anchored findings:
286
+
287
+ ```python
288
+ api_key = "sk_test_xxxx" # dxkit-allow:test-fixture reason="placeholder in unit test"
289
+ ```
290
+
291
+ File-level (`.dxkit/allowlist.json`) for cross-file findings or any
292
+ suppression that needs an expiry. New entries appear in the PR-
293
+ comment automation so reviewers see suppressions being introduced
294
+ and can sanity-check the rationale before approving. `audit` /
295
+ `prune` subcommands handle stale + soon-to-expire entries.
296
+
297
+ **Strict cleanup**: orphaned `dxkit-allow:` annotations become
298
+ `stale-allow` findings on the next scan. dxkit refuses to allowlist
299
+ those — the only remediation is to remove the annotation. This is
300
+ the TypeScript `@ts-expect-error` pattern: tools that surface their
301
+ own stale suppressions force cleanup, preventing the annotation
302
+ graveyard.
303
+
304
+ ```bash
305
+ # The block message from `guardrail check` prints the exact command
306
+ # to paste for any blocked finding — file:line for inline-compatible
307
+ # kinds, --fingerprint for everything else.
308
+ vyuh-dxkit allowlist add src/auth/oauth.ts:42 \
309
+ --category=test-fixture --reason="placeholder in unit test"
310
+
311
+ vyuh-dxkit allowlist audit # find stale + soon-to-expire entries
312
+ ```
313
+
314
+ See [`vyuh-dxkit allowlist`](docs/commands/allowlist.md) for the
315
+ full surface.
316
+
218
317
  ---
219
318
 
220
319
  ## Git-aware identity matching
@@ -420,8 +519,9 @@ dxkit is local-first.
420
519
  - [x] Git hooks (pre-push default; pre-commit opt-in)
421
520
  - [x] GitHub Actions PR-gate + gated baseline-refresh workflows
422
521
  - [x] Devcontainer with pinned toolchains
423
- - [ ] First-class scaffolding for every major coding agent
424
- per-agent skills + entry-point file conventions (2.6)
522
+ - [x] Nine dxkit-\* skills + AGENTS.md (open-standard, read by every
523
+ AGENTS.md-compliant agent Claude Code, Codex, Cursor, Aider)
524
+ - [ ] First-class plugin packaging for the Claude Code marketplace + MCP server for cross-agent reach (2.6, decision-pending)
425
525
  - [ ] Scoped + incremental scanning — fast pre-commit on monorepos
426
526
  (2.6)
427
527
  - [ ] Symbol-level coverage gaps across all 8 packs (2.6)
@@ -439,6 +539,28 @@ dxkit is local-first.
439
539
 
440
540
  ---
441
541
 
542
+ ## Reporting issues
543
+
544
+ If a scanner is too noisy, a finding is missing, dxkit itself is
545
+ broken, or the docs are unclear, the fastest path to the dxkit team
546
+ is the built-in issue subcommand:
547
+
548
+ ```bash
549
+ vyuh-dxkit issue --type=false-positive \
550
+ --fingerprint=<id> \
551
+ --about="the scanner flags my intentional X as a Y"
552
+
553
+ vyuh-dxkit issue --type=bug --about="vyuh-dxkit doctor crashes on macOS arm64"
554
+
555
+ vyuh-dxkit issue --type=feature-request --about="add SARIF export"
556
+ ```
557
+
558
+ It opens a pre-filled [GitHub issue](https://github.com/vyuh-labs/dxkit/issues)
559
+ in your browser with dxkit version + platform info already populated.
560
+ Nothing is submitted until you click "Submit" — you review the
561
+ prefill first. See [`vyuh-dxkit issue`](docs/commands/issue.md) for
562
+ the full reference.
563
+
442
564
  ## Contributing
443
565
 
444
566
  dxkit aims to be the standard agentic-development layer for any
@@ -466,7 +588,7 @@ MIT. See [LICENSE](LICENSE).
466
588
  ## Try it
467
589
 
468
590
  ```bash
469
- npx @vyuhlabs/dxkit@latest init --full
591
+ npm init @vyuhlabs/dxkit
470
592
  ```
471
593
 
472
594
  If dxkit helps you ship AI-assisted changes more safely, star the