@vyuhlabs/dxkit 2.5.0 → 2.5.1
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/CHANGELOG.md +77 -0
- package/dist/analyzers/tools/graphify.d.ts.map +1 -1
- package/dist/analyzers/tools/graphify.js +9 -5
- package/dist/analyzers/tools/graphify.js.map +1 -1
- package/dist/analyzers/tools/tool-registry.d.ts +19 -1
- package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
- package/dist/analyzers/tools/tool-registry.js +25 -0
- package/dist/analyzers/tools/tool-registry.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +38 -1
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +18 -11
- package/dist/doctor.js.map +1 -1
- package/dist/generator.d.ts +1 -1
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +81 -135
- package/dist/generator.js.map +1 -1
- package/dist/hooks-cli.d.ts +20 -0
- package/dist/hooks-cli.d.ts.map +1 -0
- package/dist/hooks-cli.js +145 -0
- package/dist/hooks-cli.js.map +1 -0
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +4 -0
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +4 -0
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/index.d.ts +18 -0
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +32 -0
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/java.d.ts.map +1 -1
- package/dist/languages/java.js +4 -0
- package/dist/languages/java.js.map +1 -1
- package/dist/languages/kotlin.d.ts.map +1 -1
- package/dist/languages/kotlin.js +9 -0
- package/dist/languages/kotlin.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +4 -0
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/ruby.d.ts.map +1 -1
- package/dist/languages/ruby.js +4 -0
- package/dist/languages/ruby.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +4 -0
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/types.d.ts +27 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +5 -0
- package/dist/languages/typescript.js.map +1 -1
- package/dist/ship-installers.d.ts +6 -0
- package/dist/ship-installers.d.ts.map +1 -1
- package/dist/ship-installers.js +120 -5
- package/dist/ship-installers.js.map +1 -1
- package/dist/tools-cli.d.ts.map +1 -1
- package/dist/tools-cli.js +45 -9
- package/dist/tools-cli.js.map +1 -1
- package/package.json +1 -1
- package/templates/.claude/skills/dxkit-action/SKILL.md +150 -0
- package/templates/.claude/skills/dxkit-config/SKILL.md +124 -0
- package/templates/.claude/skills/dxkit-hooks/SKILL.md +109 -0
- package/templates/.claude/skills/dxkit-init/SKILL.md +93 -0
- package/templates/.claude/skills/dxkit-learn/SKILL.md +84 -0
- package/templates/.claude/skills/dxkit-reports/SKILL.md +111 -0
- package/templates/.devcontainer/devcontainer.json +7 -33
- package/templates/.devcontainer/post-create.sh +18 -4
- package/templates/AGENTS.md.template +137 -0
- package/templates/CLAUDE.md.template +16 -111
- package/dist/codebase-scanner.d.ts +0 -36
- package/dist/codebase-scanner.d.ts.map +0 -1
- package/dist/codebase-scanner.js +0 -687
- package/dist/codebase-scanner.js.map +0 -1
- package/templates/.claude/agents/doc-writer.md +0 -107
- package/templates/.claude/agents/knowledge-bot.md +0 -64
- package/templates/.claude/agents/onboarding.md +0 -62
- package/templates/.claude/agents/quality-reviewer.md +0 -85
- package/templates/.claude/agents-available/code-reviewer.md +0 -29
- package/templates/.claude/agents-available/codebase-explorer.md +0 -100
- package/templates/.claude/agents-available/dashboard-builder.md +0 -433
- package/templates/.claude/agents-available/debugger.md +0 -29
- package/templates/.claude/agents-available/dependency-mapper.md +0 -80
- package/templates/.claude/agents-available/dev-report.md +0 -108
- package/templates/.claude/agents-available/doc-writer.md +0 -107
- package/templates/.claude/agents-available/feature-builder.md +0 -163
- package/templates/.claude/agents-available/feature-planner.md +0 -185
- package/templates/.claude/agents-available/health-auditor.md +0 -95
- package/templates/.claude/agents-available/hooks-configurator.md +0 -211
- package/templates/.claude/agents-available/knowledge-bot.md +0 -62
- package/templates/.claude/agents-available/plan-executor.md +0 -133
- package/templates/.claude/agents-available/strategic-planner.md +0 -141
- package/templates/.claude/agents-available/test-gap-finder.md +0 -67
- package/templates/.claude/agents-available/test-writer.md +0 -34
- package/templates/.claude/agents-available/vulnerability-scanner.md +0 -173
- package/templates/.claude/commands/ask.md +0 -7
- package/templates/.claude/commands/build-feature.md +0 -26
- package/templates/.claude/commands/build.md.template +0 -30
- package/templates/.claude/commands/check.md.template +0 -43
- package/templates/.claude/commands/dashboard.md +0 -28
- package/templates/.claude/commands/deps.md +0 -15
- package/templates/.claude/commands/dev-report.md +0 -50
- package/templates/.claude/commands/docs.md +0 -21
- package/templates/.claude/commands/doctor.md +0 -29
- package/templates/.claude/commands/enable-agent.md +0 -12
- package/templates/.claude/commands/execute-plan.md +0 -25
- package/templates/.claude/commands/explore-codebase.md +0 -12
- package/templates/.claude/commands/export-pdf.md +0 -30
- package/templates/.claude/commands/feature.md +0 -25
- package/templates/.claude/commands/fix-issue.md +0 -12
- package/templates/.claude/commands/fix.md.template +0 -32
- package/templates/.claude/commands/health.md +0 -58
- package/templates/.claude/commands/help.md +0 -36
- package/templates/.claude/commands/learn.md +0 -48
- package/templates/.claude/commands/onboarding.md +0 -21
- package/templates/.claude/commands/plan.md +0 -20
- package/templates/.claude/commands/quality.md.template +0 -65
- package/templates/.claude/commands/session-end.md +0 -40
- package/templates/.claude/commands/session-start.md +0 -30
- package/templates/.claude/commands/setup-hooks.md +0 -18
- package/templates/.claude/commands/stealth-mode.md +0 -17
- package/templates/.claude/commands/test-gaps.md +0 -49
- package/templates/.claude/commands/test.md.template +0 -40
- package/templates/.claude/commands/vulnerabilities.md +0 -49
- package/templates/.claude/skills/build/SKILL.md.template +0 -90
- package/templates/.claude/skills/deploy/SKILL.md.template +0 -111
- package/templates/.claude/skills/deploy/references/gotchas.md +0 -5
- package/templates/.claude/skills/doctor/SKILL.md +0 -31
- package/templates/.claude/skills/gcloud/SKILL.md +0 -66
- package/templates/.claude/skills/gcloud/references/gotchas.md +0 -5
- package/templates/.claude/skills/learned/SKILL.md +0 -55
- package/templates/.claude/skills/learned/references/conventions.md +0 -11
- package/templates/.claude/skills/learned/references/deny-recommendations.md +0 -18
- package/templates/.claude/skills/learned/references/gotchas.md +0 -11
- package/templates/.claude/skills/pulumi/SKILL.md +0 -73
- package/templates/.claude/skills/quality/SKILL.md.template +0 -89
- package/templates/.claude/skills/quality/references/gotchas.md +0 -5
- package/templates/.claude/skills/review/SKILL.md.template +0 -74
- package/templates/.claude/skills/scaffold/SKILL.md.template +0 -113
- package/templates/.claude/skills/secrets/SKILL.md +0 -51
- package/templates/.claude/skills/session/SKILL.md +0 -32
- package/templates/.claude/skills/test/SKILL.md.template +0 -116
- package/templates/.claude/skills/test/references/gotchas.md +0 -5
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dxkit-config
|
|
3
|
+
description: Edit dxkit configuration — add/remove paths in .dxkit-ignore, tune .vyuh-dxkit.json, adjust .dxkit/policy.json guardrail severity. Use when the user wants to exclude a directory from scanning, change scoring thresholds, or modify what blocks a PR.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dxkit-config
|
|
7
|
+
|
|
8
|
+
This skill modifies the three configuration files dxkit reads. Reach for it when the user asks to "ignore this vendored directory," "stop flagging X," "make the guardrail stricter/laxer," or "what controls Y."
|
|
9
|
+
|
|
10
|
+
## The three config files
|
|
11
|
+
|
|
12
|
+
| File | Purpose | When to edit |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `.dxkit-ignore` | Extra paths dxkit's analyzers should skip (gitignore-style format) | Vendored code, generated code, test fixtures, large data files |
|
|
15
|
+
| `.vyuh-dxkit.json` | Manifest of detected stack + custom settings (regenerated by `init` / `update`) | Rare — usually let `dxkit update` regenerate. Override version pins or framework detection here. |
|
|
16
|
+
| `.dxkit/policy.json` | Severity policy for guardrail check | Customize what blocks a PR (e.g., demote `medium` to warning) |
|
|
17
|
+
|
|
18
|
+
## Adding a path to `.dxkit-ignore`
|
|
19
|
+
|
|
20
|
+
Format mirrors `.gitignore`: directory/, file-glob, multi-segment paths.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Append a vendored directory
|
|
24
|
+
echo 'vendor/' >> .dxkit-ignore
|
|
25
|
+
|
|
26
|
+
# Append a generated-code dir
|
|
27
|
+
echo 'src/generated/' >> .dxkit-ignore
|
|
28
|
+
|
|
29
|
+
# Append a glob (auto-generated TypeScript types)
|
|
30
|
+
echo '*.generated.ts' >> .dxkit-ignore
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or use Edit to add multiple entries cleanly. The file accepts comments (`#`).
|
|
34
|
+
|
|
35
|
+
After editing, the **next** `baseline create` picks up the change. Existing baselines stay valid (the file's content hash is recorded in the baseline envelope, so a mismatch surfaces as a "baseline regenerated against newer .dxkit-ignore" note rather than an error).
|
|
36
|
+
|
|
37
|
+
### Common exclusions
|
|
38
|
+
|
|
39
|
+
```gitignore
|
|
40
|
+
# Vendored third-party code committed to git
|
|
41
|
+
vendor/
|
|
42
|
+
third_party/
|
|
43
|
+
|
|
44
|
+
# Generated code
|
|
45
|
+
generated/
|
|
46
|
+
*.generated.ts
|
|
47
|
+
*.designer.cs
|
|
48
|
+
*.pb.go
|
|
49
|
+
src/proto-types/
|
|
50
|
+
|
|
51
|
+
# Legacy code you don't want to track findings against
|
|
52
|
+
legacy/
|
|
53
|
+
deprecated/
|
|
54
|
+
|
|
55
|
+
# Test fixtures that inflate metrics
|
|
56
|
+
fixtures/large/
|
|
57
|
+
test/fixtures/
|
|
58
|
+
|
|
59
|
+
# Build artifacts (most are gitignored already, but defensive)
|
|
60
|
+
dist/
|
|
61
|
+
build/
|
|
62
|
+
target/
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Tuning `.vyuh-dxkit.json`
|
|
66
|
+
|
|
67
|
+
This file is mostly auto-generated. Common manual edits:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"framework": "express", // Override if auto-detection picked wrong
|
|
72
|
+
"languages": {
|
|
73
|
+
"typescript": true,
|
|
74
|
+
"python": false
|
|
75
|
+
},
|
|
76
|
+
"testRunner": {
|
|
77
|
+
"framework": "vitest", // Override auto-detected test runner
|
|
78
|
+
"command": "npm test"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
When you edit this file, run `vyuh-dxkit update` to propagate changes through the rest of the scaffold (per-language rules, devcontainer features, etc.). Use `--force` only if you've also edited evolving files — otherwise `update` preserves customer changes.
|
|
84
|
+
|
|
85
|
+
## Customizing `.dxkit/policy.json`
|
|
86
|
+
|
|
87
|
+
The policy file controls what severity counts as "blocking" for the guardrail. Default:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"code": { "block": ["critical", "high"], "warn": ["medium"] },
|
|
92
|
+
"dependency": { "block": ["critical", "high"], "warn": ["medium"] },
|
|
93
|
+
"secret": { "block": ["critical", "high", "medium", "low"] },
|
|
94
|
+
"test-gap": { "block": ["critical"], "warn": ["high"] },
|
|
95
|
+
"duplicate": { "warn": ["all"] }
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Each finding-kind has `block` (exit 1) and `warn` (log only) lists. Adjust to your team's tolerance:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
// Stricter — block medium SAST findings too
|
|
103
|
+
{ "code": { "block": ["critical", "high", "medium"] } }
|
|
104
|
+
|
|
105
|
+
// Laxer — make secret medium/low non-blocking (don't recommend)
|
|
106
|
+
{ "secret": { "block": ["critical", "high"] } }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Run `vyuh-dxkit guardrail check --policy=.dxkit/policy.json` to test the new policy. If no `policy.json` exists, dxkit uses the built-in defaults.
|
|
110
|
+
|
|
111
|
+
## Workflow
|
|
112
|
+
|
|
113
|
+
When the user asks for a config change:
|
|
114
|
+
|
|
115
|
+
1. Identify which file owns the concern (path exclusion → `.dxkit-ignore`; severity routing → `.dxkit/policy.json`; detection override → `.vyuh-dxkit.json`).
|
|
116
|
+
2. Open the file, propose the edit, confirm.
|
|
117
|
+
3. After writing, run `vyuh-dxkit baseline create --force` if exclusions changed (so the baseline doesn't carry stale findings from the now-excluded paths).
|
|
118
|
+
4. Commit both: the config file + the regenerated baseline.
|
|
119
|
+
|
|
120
|
+
## What NOT to do
|
|
121
|
+
|
|
122
|
+
- Don't edit `.dxkit/cache/` or `.dxkit/reports/` — they're regenerated on every run (gitignored).
|
|
123
|
+
- Don't manually mutate `.dxkit/baselines/main.json` — use `baseline create --force` to regenerate.
|
|
124
|
+
- Don't add `.dxkit/` to `.dxkit-ignore` — dxkit itself doesn't scan its own outputs.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dxkit-hooks
|
|
3
|
+
description: Install, configure, troubleshoot, or remove dxkit git hooks. Use when the user asks "set up hooks", "pre-push isn't firing", "how do I chain with husky", "bypass the hook", or anything about pre-commit/pre-push behavior in a dxkit-managed repo.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dxkit-hooks
|
|
7
|
+
|
|
8
|
+
This skill handles the git-hook surface dxkit ships. Use it to install hooks, debug "the hook didn't fire," chain dxkit with an existing hook system, or guide a bypass.
|
|
9
|
+
|
|
10
|
+
## What dxkit ships
|
|
11
|
+
|
|
12
|
+
`.githooks/pre-push` (default-on under `--full`) — runs the guardrail check before code leaves the developer's machine. Fast on warm scanner caches (~10-30s).
|
|
13
|
+
|
|
14
|
+
`.githooks/pre-commit` (opt-in via `--with-precommit-hook`) — same guardrail check but on every commit. Slower on large repos (~1-3 min on 500+ file repos). Not in `--full` by default because the wall-clock cost gates adoption.
|
|
15
|
+
|
|
16
|
+
Both run `vyuh-dxkit guardrail check`. The check exits 1 (blocking) on net-new findings vs. the baseline.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Pre-push only (recommended for most teams)
|
|
22
|
+
npx vyuh-dxkit init --with-hooks --yes
|
|
23
|
+
|
|
24
|
+
# Both pre-commit + pre-push
|
|
25
|
+
npx vyuh-dxkit init --with-hooks --with-precommit-hook --yes
|
|
26
|
+
|
|
27
|
+
# Add to an existing dxkit install (idempotent)
|
|
28
|
+
npx vyuh-dxkit init --with-precommit-hook --yes
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Existing hooks at `.githooks/<name>` or `.husky/<name>` trigger sidecar-write mode: dxkit puts its hook at `.githooks/<name>.dxkit` and emits a chain note instead of clobbering.
|
|
32
|
+
|
|
33
|
+
## Activation
|
|
34
|
+
|
|
35
|
+
Hooks activate by setting `core.hooksPath = .githooks` in the local git config. Dxkit wires this via `npm postinstall` so every clone + `npm install` runs it automatically. Manual:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Either of these works
|
|
39
|
+
vyuh-dxkit hooks activate
|
|
40
|
+
git config core.hooksPath .githooks
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`vyuh-dxkit hooks activate` is idempotent — refuses to clobber a custom hooksPath (husky's `.husky`, lefthook's `.lefthook`, etc.). Run it to confirm the current state.
|
|
44
|
+
|
|
45
|
+
## Troubleshooting "hook didn't fire"
|
|
46
|
+
|
|
47
|
+
Walk this checklist:
|
|
48
|
+
|
|
49
|
+
1. **Hook file exists**: `ls -la .githooks/pre-push` — should be executable.
|
|
50
|
+
2. **hooksPath is wired**: `git config --local --get core.hooksPath` should print `.githooks`. If empty or pointing elsewhere, run `vyuh-dxkit hooks activate`.
|
|
51
|
+
3. **dxkit binary is on PATH**: from the repo root, `which vyuh-dxkit` should resolve (either project-local `./node_modules/.bin/vyuh-dxkit` or global). The hook delegates to whichever it finds.
|
|
52
|
+
4. **Baseline exists**: `test -f .dxkit/baselines/main.json` — without a baseline the guardrail has nothing to compare against. Run `vyuh-dxkit baseline create`.
|
|
53
|
+
5. **Run the check by hand**: `vyuh-dxkit guardrail check` from the repo root. Expected: exits 1 on net-new findings (red), 0 on clean diff (green).
|
|
54
|
+
|
|
55
|
+
If all five pass and the hook still doesn't fire, the most common cause is a competing hook system. `git config --global --get core.hooksPath` could be set globally to something else.
|
|
56
|
+
|
|
57
|
+
## Chaining with husky / lefthook / other hook managers
|
|
58
|
+
|
|
59
|
+
When dxkit detects an existing hook (`.husky/pre-commit` or `.githooks/pre-commit`), it writes `.githooks/pre-commit.dxkit` instead and prints a chain note. To wire them together, add a line at the end of the existing hook:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# .husky/pre-commit (after husky's own logic)
|
|
63
|
+
sh .githooks/pre-commit.dxkit
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Order matters: run the fast lint/format hooks first, then dxkit's guardrail last (so dxkit sees the actual final diff).
|
|
67
|
+
|
|
68
|
+
For pre-push, same pattern with `.githooks/pre-push.dxkit`.
|
|
69
|
+
|
|
70
|
+
## Bypass (emergency)
|
|
71
|
+
|
|
72
|
+
When a hook blocks a push and the fix needs to land NOW (incident response, hotfix):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
git push --no-verify
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
This skips ALL git hooks (not just dxkit's). After the emergency:
|
|
79
|
+
|
|
80
|
+
1. Open the .dxkit/reports/ from the blocked push to understand what got bypassed.
|
|
81
|
+
2. Either fix the regression in a follow-up commit OR
|
|
82
|
+
3. Re-baseline if the regression is intentional and accepted:
|
|
83
|
+
```bash
|
|
84
|
+
vyuh-dxkit baseline create --force
|
|
85
|
+
git add .dxkit/baselines/main.json
|
|
86
|
+
git commit -m "chore(baseline): accept regression from <ref>"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Re-baselining is a deliberate action — it grants future scans permission to keep the regression. Don't do it casually; use the policy file to suppress noisy finding kinds instead.
|
|
90
|
+
|
|
91
|
+
## Disabling pre-commit (keeping pre-push)
|
|
92
|
+
|
|
93
|
+
If pre-commit becomes a wall-clock blocker:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
rm .githooks/pre-commit
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`git config core.hooksPath` stays pointed at `.githooks/` (don't unset it). Future `init` calls won't re-add pre-commit unless `--with-precommit-hook` is passed.
|
|
100
|
+
|
|
101
|
+
## Removing dxkit hooks entirely
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
git config --local --unset core.hooksPath
|
|
105
|
+
rm -rf .githooks
|
|
106
|
+
# Also remove the postinstall line from package.json if you want a clean uninstall
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The CI workflows in `.github/workflows/dxkit-*.yml` continue to enforce the guardrail at PR-time, so removing local hooks doesn't disable the safety guarantees — just shifts them to CI-only.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dxkit-init
|
|
3
|
+
description: Walk the user through installing and configuring dxkit on a fresh repo. Use when the user asks "how do I install dxkit?", "set up dxkit on this repo", "what flags should I use?", or wants to scaffold the guardrail surface. Defers to dxkit-config / dxkit-hooks for post-install tuning.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dxkit-init
|
|
7
|
+
|
|
8
|
+
This skill scaffolds dxkit on a repo: chooses flags, runs `init`, captures a baseline, and points at the next steps.
|
|
9
|
+
|
|
10
|
+
## Decision tree
|
|
11
|
+
|
|
12
|
+
Ask the user what they want, then pick the right invocation:
|
|
13
|
+
|
|
14
|
+
1. **"Just give me everything"** → `npm init @vyuhlabs/dxkit` (collapses install + init), or if dxkit is already a devDep: `npx vyuh-dxkit init --full --yes`
|
|
15
|
+
2. **"I only want the agent context, no guardrails yet"** → `npx vyuh-dxkit init --with-dxkit-agents --yes`
|
|
16
|
+
3. **"I want guardrails but no CI"** → `npx vyuh-dxkit init --with-hooks --with-dxkit-agents --yes`
|
|
17
|
+
4. **"I want the full setup but no pre-commit"** → `--full --yes` already does this (pre-commit is opt-in via `--with-precommit-hook` because it's slow on large repos)
|
|
18
|
+
5. **"Interactive — talk me through it"** → `npx vyuh-dxkit init` (no `--yes`) and let it prompt
|
|
19
|
+
|
|
20
|
+
## Flag reference
|
|
21
|
+
|
|
22
|
+
| Flag | What it ships | Default under `--full`? |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `--with-dxkit-agents` | The 6 dxkit-* skills + AGENTS.md + CLAUDE.md shim | Yes |
|
|
25
|
+
| `--with-hooks` | `.githooks/pre-push` + postinstall activation wire-up | Yes |
|
|
26
|
+
| `--with-precommit-hook` | Adds `.githooks/pre-commit` (slow on large repos) | No (still opt-in) |
|
|
27
|
+
| `--with-devcontainer` | `.devcontainer/devcontainer.json` (per-stack features) + post-create.sh | Yes |
|
|
28
|
+
| `--with-ci` | `.github/workflows/dxkit-guardrails.yml` (PR gate) | Yes |
|
|
29
|
+
| `--with-baseline-refresh` | `.github/workflows/dxkit-baseline-refresh.yml` (post-merge regen) | Yes |
|
|
30
|
+
| `--with-pr-review` | `.github/workflows/pr-review.yml` (AI PR review; needs `ANTHROPIC_API_KEY`) | No (still opt-in) |
|
|
31
|
+
|
|
32
|
+
`--yes` accepts all prompts; `--force` overwrites existing files instead of writing `.dxkit` sidecars on conflict.
|
|
33
|
+
|
|
34
|
+
## Steps
|
|
35
|
+
|
|
36
|
+
1. **Detect the stack** before installing — let the user confirm:
|
|
37
|
+
```bash
|
|
38
|
+
npx vyuh-dxkit init --detect
|
|
39
|
+
```
|
|
40
|
+
This auto-detects and previews what `init --full` would do without writing anything.
|
|
41
|
+
|
|
42
|
+
2. **Run init**:
|
|
43
|
+
```bash
|
|
44
|
+
# Most common case — full setup, no prompts
|
|
45
|
+
npx vyuh-dxkit init --full --yes
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
3. **Capture the brownfield baseline** — must do this before hooks/CI become useful:
|
|
49
|
+
```bash
|
|
50
|
+
npx vyuh-dxkit baseline create
|
|
51
|
+
git add .dxkit/baselines/
|
|
52
|
+
git commit -m "chore: capture dxkit baseline"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
4. **Verify the install**:
|
|
56
|
+
```bash
|
|
57
|
+
npx vyuh-dxkit doctor
|
|
58
|
+
```
|
|
59
|
+
This checks: hooks active, baseline present, workflows installed, scanner toolchain available.
|
|
60
|
+
|
|
61
|
+
5. **Hand off**:
|
|
62
|
+
- For policy / exclusions / scoring thresholds → `dxkit-config` skill
|
|
63
|
+
- For hook troubleshooting → `dxkit-hooks` skill
|
|
64
|
+
- For running reports → `dxkit-reports` skill
|
|
65
|
+
- For branch protection (manual today, automated in next release): GitHub repo settings → Branches → require `dxkit guardrails` check + require PR review
|
|
66
|
+
|
|
67
|
+
## Common pitfalls
|
|
68
|
+
|
|
69
|
+
- **No package.json**: `npm init @vyuhlabs/dxkit` seeds a minimal one. For Python-only / Go-only repos, install dxkit globally instead: `npm install -g @vyuhlabs/dxkit && vyuh-dxkit init --full --yes`.
|
|
70
|
+
- **Existing .claude/ from 2.5.0**: dxkit init is additive — your existing `.claude/` files are preserved. To switch to the new dxkit-specific shape, delete the old `.claude/` dir first, then re-init.
|
|
71
|
+
- **Peer-dep ERESOLVE during `npm install`**: `npm init @vyuhlabs/dxkit` automatically retries with `--legacy-peer-deps`. Manual installs may need that flag.
|
|
72
|
+
- **Brownfield repo with thousands of existing findings**: that's normal — the baseline records them all once. Guardrail only blocks net-new findings.
|
|
73
|
+
|
|
74
|
+
## What `init --full` writes
|
|
75
|
+
|
|
76
|
+
A complete install lays down ~15-20 files (down from the 2.5.0 ~73-file scaffold). Per-repo:
|
|
77
|
+
|
|
78
|
+
- `.dxkit/baselines/main.json` (after `baseline create`)
|
|
79
|
+
- `.dxkit-ignore` (starter template)
|
|
80
|
+
- `.vyuh-dxkit.json` (manifest)
|
|
81
|
+
- `.githooks/pre-push`
|
|
82
|
+
- `.github/workflows/dxkit-guardrails.yml`
|
|
83
|
+
- `.github/workflows/dxkit-baseline-refresh.yml`
|
|
84
|
+
- `.devcontainer/devcontainer.json` (per-stack features)
|
|
85
|
+
- `.devcontainer/post-create.sh`
|
|
86
|
+
- `.devcontainer/install-agent-clis.sh`
|
|
87
|
+
- `.claude/skills/dxkit-{learn,init,config,hooks,reports,action}/SKILL.md`
|
|
88
|
+
- `.claude/rules/<lang>.md` (per active language pack)
|
|
89
|
+
- `.claude/settings.json` (narrowed: dxkit-binary permissions only)
|
|
90
|
+
- `AGENTS.md` (project prose context for any agent — Claude, Codex, Cursor, Aider)
|
|
91
|
+
- `CLAUDE.md` (shim pointing at AGENTS.md)
|
|
92
|
+
- `package.json` (postinstall = `vyuh-dxkit hooks activate`)
|
|
93
|
+
- `.gitignore` (additive: `.dxkit/reports/`, `.dxkit/cache/`, `graphify-out/`)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dxkit-learn
|
|
3
|
+
description: Answer questions about dxkit — what each scanner does, what a baseline is, what the 6 health dimensions score, how guardrails work. Use when the user asks "what does dxkit X do?", "what's a baseline?", "what's the slop score?", "how do hooks fit in?", or anything else about dxkit concepts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dxkit-learn
|
|
7
|
+
|
|
8
|
+
This skill explains how dxkit works. Reach for it when the user asks about dxkit concepts before they take an action.
|
|
9
|
+
|
|
10
|
+
## Mental model
|
|
11
|
+
|
|
12
|
+
dxkit measures a codebase along **6 dimensions** (Security, Code Quality, Tests, Documentation, Maintainability, Developer Experience) using deterministic scanners (gitleaks, semgrep, cloc, jscpd, graphify, ruff, eslint, …). Findings are anchored to a **baseline** (`.dxkit/baselines/main.json`) so today's pre-existing issues don't block tomorrow's PR. A **guardrail check** diffs current state against the baseline and blocks net-new regressions. Hooks + CI wire the guardrail into the developer's workflow.
|
|
13
|
+
|
|
14
|
+
The three contracts to remember:
|
|
15
|
+
|
|
16
|
+
1. **Baseline = the brownfield anchor**. Pre-existing findings are recorded once; future scans only block on *additions*.
|
|
17
|
+
2. **Hooks fire fast (pre-push); CI fires thorough**. Both use the same guardrail logic.
|
|
18
|
+
3. **Reports are deterministic** — same code + same baseline = same findings. The salt mode (`deterministic` vs `random`) controls per-finding identity stability across runs.
|
|
19
|
+
|
|
20
|
+
## The 6 dimensions
|
|
21
|
+
|
|
22
|
+
Each dimension is a 0-100 score with letter grade (A≥80, B≥60, C≥40, D≥20, E<20):
|
|
23
|
+
|
|
24
|
+
| Dimension | What scores it down |
|
|
25
|
+
|---|---|
|
|
26
|
+
| **Security** | Secret leaks (gitleaks), SAST findings (semgrep), dependency vulns (osv-scanner / npm-audit / pip-audit / etc.), TLS-bypass patterns |
|
|
27
|
+
| **Code Quality** | Lint findings (eslint / ruff / golangci-lint / clippy / detekt / rubocop / dotnet-format), high duplication (jscpd), code-pattern slop |
|
|
28
|
+
| **Tests** | Missing test coverage on primary-architecture files; missing test runner config; below-threshold line coverage |
|
|
29
|
+
| **Documentation** | Missing/empty README; missing doc-comments on public APIs (XML-doc/JSDoc/TSDoc/godoc/etc.); below-threshold comment ratio |
|
|
30
|
+
| **Maintainability** | Function/file size outliers, deep cyclomatic complexity, god-objects, high orphan-module count, dead imports |
|
|
31
|
+
| **Developer Experience** | Missing `.gitignore` / `.editorconfig` / `package.json` engines pin / devcontainer / hooks / CI workflow |
|
|
32
|
+
|
|
33
|
+
Run `vyuh-dxkit health` to see all six at once. Each dimension report has a "top actions" list — the changes that would lift the score the most.
|
|
34
|
+
|
|
35
|
+
## The scanner toolchain
|
|
36
|
+
|
|
37
|
+
dxkit doesn't write parsers — it orchestrates established tools and computes scores. The full list is in `TOOL_DEFS` (or run `vyuh-dxkit tools list`). Key ones:
|
|
38
|
+
|
|
39
|
+
- **gitleaks** — secret scanning (API keys, AWS credentials, GitHub tokens)
|
|
40
|
+
- **semgrep** — multi-language SAST (auto config picks rulesets per active language pack)
|
|
41
|
+
- **cloc** — language-aware line counting (excludes comments + blanks)
|
|
42
|
+
- **jscpd** — copy-paste detection
|
|
43
|
+
- **graphify** — AST-based metrics (functions, classes, cohesion, god-nodes, dead imports)
|
|
44
|
+
- **osv-scanner** — dependency vulnerabilities (npm/pip/cargo/go/gem/maven via OSV.dev)
|
|
45
|
+
- Per-language linters: eslint (TS), ruff (Python), golangci-lint (Go), clippy (Rust), dotnet-format (C#), detekt (Kotlin), pmd (Java), rubocop (Ruby)
|
|
46
|
+
|
|
47
|
+
If a tool isn't installed, dxkit degrades gracefully (the affected dimension reports a partial score with a "missing tool" note instead of crashing).
|
|
48
|
+
|
|
49
|
+
## Baselines explained
|
|
50
|
+
|
|
51
|
+
A baseline is the per-finding identity snapshot of a scan. Every finding has a **fingerprint** (SHA-1[0:16] of file+rule+line-window+content). The baseline stores those fingerprints. The guardrail diffs today's scan against the baseline:
|
|
52
|
+
|
|
53
|
+
- Fingerprint in scan + in baseline → **existing** (ignored)
|
|
54
|
+
- Fingerprint in scan + NOT in baseline → **added** (blocks)
|
|
55
|
+
- Fingerprint in baseline + NOT in scan → **removed** (silently good)
|
|
56
|
+
|
|
57
|
+
That's why "fix a critical, leave the medium" works — the medium's fingerprint stays in the baseline; only net-new findings count.
|
|
58
|
+
|
|
59
|
+
Commands:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
vyuh-dxkit baseline create # Capture current state into .dxkit/baselines/main.json
|
|
63
|
+
vyuh-dxkit baseline show # Summarize what's recorded
|
|
64
|
+
vyuh-dxkit baseline show --kind secret # Drill into a specific finding kind
|
|
65
|
+
vyuh-dxkit guardrail check # Diff current scan vs baseline; exit 1 on net-new
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Hooks
|
|
69
|
+
|
|
70
|
+
Two hooks ship under `.githooks/`:
|
|
71
|
+
|
|
72
|
+
- **pre-push** (always-on under `--full`): runs the guardrail check before code leaves the developer's machine. Fast on warm scanner caches (~10-30s).
|
|
73
|
+
- **pre-commit** (opt-in via `--with-precommit-hook`): same logic, fires on every commit. Slower on large repos until incremental scanning lands.
|
|
74
|
+
|
|
75
|
+
Activation is wired via `npm postinstall` so `npm install` after `git clone` sets `core.hooksPath = .githooks` automatically.
|
|
76
|
+
|
|
77
|
+
## How to learn more
|
|
78
|
+
|
|
79
|
+
- `vyuh-dxkit <subcommand> --help` — flag reference
|
|
80
|
+
- `vyuh-dxkit baseline show` — what your repo already has recorded
|
|
81
|
+
- `.dxkit/reports/` — every analyzer's markdown + JSON output from the last run
|
|
82
|
+
- `vyuh-dxkit dashboard` — single HTML view of every report
|
|
83
|
+
|
|
84
|
+
When the user asks specifically about a scanner or a finding type, point them at the relevant report or run the relevant analyzer command directly.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dxkit-reports
|
|
3
|
+
description: Run dxkit reports and explain their output. Use when the user asks "run health", "check security", "show me the dashboard", "what does this score mean", or anything about generating / reading dxkit analyzer output. Hands off to dxkit-action for fixing findings.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dxkit-reports
|
|
7
|
+
|
|
8
|
+
This skill runs dxkit analyzers and reads their output back to the user. It's the "tell me how my codebase is doing" surface.
|
|
9
|
+
|
|
10
|
+
## Command map
|
|
11
|
+
|
|
12
|
+
| User asks | Command | Output |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| "Overall health" / "give me the score" | `vyuh-dxkit health` | 6-dimension score table + top actions per dimension |
|
|
15
|
+
| "Check security" / "find vulns" | `vyuh-dxkit vulnerabilities` | Code-level SAST + dep-vuln + secret findings, grouped by severity |
|
|
16
|
+
| "Test coverage gaps" | `vyuh-dxkit test-gaps` | Source files without matching tests, prioritized by architectural role |
|
|
17
|
+
| "Code quality" | `vyuh-dxkit quality` | Lint findings + duplication + slop score |
|
|
18
|
+
| "Who's been working on what" | `vyuh-dxkit dev-report` | Per-author activity, hot files, churn |
|
|
19
|
+
| "License inventory" | `vyuh-dxkit licenses` | Every dependency's declared license |
|
|
20
|
+
| "Bill of materials" | `vyuh-dxkit bom` | Licenses + dep vulnerabilities joined (15-col XLSX-ready output) |
|
|
21
|
+
| "Run everything" | `vyuh-dxkit report` | Every analyzer in one shot, ~3-5 min |
|
|
22
|
+
| "Show me the dashboard" | `vyuh-dxkit dashboard` | Single HTML view of all reports — opens at `.dxkit/reports/dashboard.html` |
|
|
23
|
+
|
|
24
|
+
## Where output lands
|
|
25
|
+
|
|
26
|
+
Every analyzer writes to `.dxkit/reports/` with a date-stamped filename:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
.dxkit/reports/
|
|
30
|
+
health-2026-05-19.md
|
|
31
|
+
health-2026-05-19.json
|
|
32
|
+
vulnerability-scan-2026-05-19.md
|
|
33
|
+
vulnerability-scan-2026-05-19-detailed.json
|
|
34
|
+
...
|
|
35
|
+
dashboard.html
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The `.md` files are human-readable; the `.json` files are machine-readable (for CI consumption or custom tooling). Reports are gitignored by default — they regenerate on every run.
|
|
39
|
+
|
|
40
|
+
## Reading the health report
|
|
41
|
+
|
|
42
|
+
The 6 dimensions each get an A-E grade. Below each grade the "top actions" list shows what would lift the score the most (sorted by potential uplift). Example:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Security: B (72)
|
|
46
|
+
Top actions:
|
|
47
|
+
1. Pin @types/node to ≥18.19.0 (closes 2 dep-vuln entries)
|
|
48
|
+
2. Add gitleaks pre-commit hook (closes 1 secret-scan finding)
|
|
49
|
+
3. Replace `Math.random()` in src/auth/token.ts (closes 1 SAST finding)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Score → rating: A ≥ 80, B ≥ 60, C ≥ 40, D ≥ 20, E < 20. **Cap tiers** can pin a score below its arithmetic value when trust is broken (e.g., uncommitted state caps at 79). The report explains the cap if one fires.
|
|
53
|
+
|
|
54
|
+
## Common patterns
|
|
55
|
+
|
|
56
|
+
### Quick health check (warm cache)
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
vyuh-dxkit health
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Re-uses cached scanner outputs where possible. ~5-15s on warm cache, ~30-60s cold.
|
|
63
|
+
|
|
64
|
+
### Pre-merge audit (thorough)
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
vyuh-dxkit health --with-coverage # Runs tests + materializes coverage before scoring
|
|
68
|
+
vyuh-dxkit vulnerabilities # Always re-runs the deep security scan
|
|
69
|
+
vyuh-dxkit dashboard # Renders the latest reports into one HTML view
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`--with-coverage` is slow (runs your test suite) but switches the Tests dimension from heuristic ("files match a test pattern") to real ("line coverage from your reporter"). Worth it for pre-merge audits.
|
|
73
|
+
|
|
74
|
+
### Per-PR scope
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
vyuh-dxkit guardrail check
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Diffs the current scan vs the baseline. Exit 1 on net-new findings (the same logic the pre-push hook uses).
|
|
81
|
+
|
|
82
|
+
### Failing CI on a threshold
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
vyuh-dxkit health --fail-on-score=70 # Exit 1 if overall score < 70
|
|
86
|
+
vyuh-dxkit vulnerabilities --fail-on-severity=high # Exit 1 if any high-severity finding
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Use these in CI for hard floors.
|
|
90
|
+
|
|
91
|
+
## Reading dependency findings
|
|
92
|
+
|
|
93
|
+
`vulnerabilities` (and `bom`) carry severity + CVSS where available. The severity column is computed via OSV.dev's enrichment — when OSV reports no severity, dxkit assigns one via CVSS v4.0 base-score math (see `src/analyzers/tools/cvss-v4.ts`).
|
|
94
|
+
|
|
95
|
+
When the user asks "is this CVE worth fixing today" the answer depends on:
|
|
96
|
+
1. **Reachability** — does the codebase actually call the vulnerable function? (Today: heuristic via graphify call-graph; reachability tiers are a roadmap item.)
|
|
97
|
+
2. **Exploitability** — public PoC? Authentication required? Network exposure?
|
|
98
|
+
3. **Patch availability** — is there a fixed version?
|
|
99
|
+
|
|
100
|
+
Surface those three when summarizing a dep-vuln finding. The detailed JSON has the OSV/GHSA reference URL — link to it.
|
|
101
|
+
|
|
102
|
+
## When the user wants to ACT on findings
|
|
103
|
+
|
|
104
|
+
Hand off to the `dxkit-action` skill — that's the workflow for prioritizing + fixing + re-baselining. This skill stops at "here's what's wrong."
|
|
105
|
+
|
|
106
|
+
## Troubleshooting
|
|
107
|
+
|
|
108
|
+
- **"Scanner X unavailable"** → run `vyuh-dxkit tools list` to see status; `vyuh-dxkit tools install` to install missing ones.
|
|
109
|
+
- **"N/A for this stack"** → applicability-guard fired (e.g., vitest-coverage on a mocha repo). Not a problem; the scanner doesn't apply here.
|
|
110
|
+
- **Report looks stale** → `.dxkit/reports/` is keyed by date. Re-run the analyzer to get a fresh date-stamped file.
|
|
111
|
+
- **Numbers don't match between two reports** → check whether `--with-coverage` was used. Without it, Tests dimension uses heuristic; with it, real coverage. They legitimately differ.
|
|
@@ -1,41 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dxkit dev environment",
|
|
3
3
|
|
|
4
|
-
// Universal base + composable features.
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
4
|
+
// Universal base + per-stack composable features. The features
|
|
5
|
+
// block below is generated by `vyuh-dxkit init` from the detected
|
|
6
|
+
// stack — only toolchains your project actually uses get installed.
|
|
7
|
+
// Always-on: Node (dxkit's own runtime) + GitHub CLI. Add or
|
|
8
|
+
// remove entries by hand if you want to over- or under-ride the
|
|
9
|
+
// auto-detected set.
|
|
9
10
|
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-22.04",
|
|
10
11
|
|
|
11
|
-
"features":
|
|
12
|
-
"ghcr.io/devcontainers/features/node:1": {
|
|
13
|
-
"version": "22",
|
|
14
|
-
"nvmVersion": "latest"
|
|
15
|
-
},
|
|
16
|
-
"ghcr.io/devcontainers/features/python:1": {
|
|
17
|
-
"version": "3.12",
|
|
18
|
-
"installTools": true
|
|
19
|
-
},
|
|
20
|
-
"ghcr.io/devcontainers/features/go:1": {
|
|
21
|
-
"version": "1.21"
|
|
22
|
-
},
|
|
23
|
-
"ghcr.io/devcontainers/features/dotnet:2": {
|
|
24
|
-
"version": "8.0"
|
|
25
|
-
},
|
|
26
|
-
"ghcr.io/devcontainers/features/ruby:1": {
|
|
27
|
-
"version": "3.3"
|
|
28
|
-
},
|
|
29
|
-
"ghcr.io/devcontainers/features/java:1": {
|
|
30
|
-
"version": "17",
|
|
31
|
-
"installGradle": true
|
|
32
|
-
},
|
|
33
|
-
"ghcr.io/devcontainers/features/rust:1": {
|
|
34
|
-
"version": "stable",
|
|
35
|
-
"profile": "default"
|
|
36
|
-
},
|
|
37
|
-
"ghcr.io/devcontainers/features/github-cli:1": {}
|
|
38
|
-
},
|
|
12
|
+
"features": __DXKIT_DEVCONTAINER_FEATURES__,
|
|
39
13
|
|
|
40
14
|
// Reproducibility note: language toolchains are pinned in the
|
|
41
15
|
// features block above. Scanner tools (gitleaks, semgrep, cloc,
|
|
@@ -23,15 +23,29 @@ echo "==> dxkit post-create starting in $(pwd)"
|
|
|
23
23
|
# annoying but shouldn't take down the rest of the post-create. The
|
|
24
24
|
# user can re-run `npm install` after authenticating or fixing the
|
|
25
25
|
# lockfile.
|
|
26
|
+
#
|
|
27
|
+
# The fallback chain layers three install strategies before giving up:
|
|
28
|
+
#
|
|
29
|
+
# 1. `npm ci` (lockfile path only) — strict, fast, uses the lockfile
|
|
30
|
+
# verbatim. Happy path on a healthy tree.
|
|
31
|
+
# 2. `npm install` — looser; rebuilds lockfile entries if the
|
|
32
|
+
# lockfile drifted (lockfile vs package.json mismatch after a
|
|
33
|
+
# merge, for example).
|
|
34
|
+
# 3. `npm install --legacy-peer-deps` — last resort. npm v7+ defaults
|
|
35
|
+
# to strict peer-dep resolution; brownfield monorepos almost
|
|
36
|
+
# always carry unresolved peers (eslint 8↔10, react cross-pkg
|
|
37
|
+
# peer mismatches, etc.) which fail both prior steps with
|
|
38
|
+
# multi-line ERESOLVE dumps. Legacy mode skips the peer-dep
|
|
39
|
+
# check and gets a working node_modules/.
|
|
26
40
|
if [ -f package.json ]; then
|
|
27
41
|
echo "==> Installing project dependencies..."
|
|
28
42
|
if [ -f package-lock.json ]; then
|
|
29
|
-
npm ci || npm install || {
|
|
30
|
-
echo "WARN: project dependency install failed — re-run 'npm install' manually
|
|
43
|
+
npm ci || npm install || npm install --legacy-peer-deps || {
|
|
44
|
+
echo "WARN: project dependency install failed even with --legacy-peer-deps — re-run 'npm install --legacy-peer-deps' manually after fixing the cause." >&2
|
|
31
45
|
}
|
|
32
46
|
else
|
|
33
|
-
npm install || {
|
|
34
|
-
echo "WARN: project dependency install failed — re-run 'npm install' manually
|
|
47
|
+
npm install || npm install --legacy-peer-deps || {
|
|
48
|
+
echo "WARN: project dependency install failed even with --legacy-peer-deps — re-run 'npm install --legacy-peer-deps' manually after fixing the cause." >&2
|
|
35
49
|
}
|
|
36
50
|
fi
|
|
37
51
|
fi
|