claudex-setup 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +120 -15
- package/bin/cli.js +246 -12
- package/package.json +3 -2
- package/src/activity.js +60 -0
- package/src/analyze.js +423 -0
- package/src/audit.js +27 -22
- package/src/benchmark.js +250 -0
- package/src/context.js +3 -2
- package/src/domain-packs.js +160 -0
- package/src/governance.js +348 -0
- package/src/index.js +21 -1
- package/src/interactive.js +2 -2
- package/src/mcp-packs.js +85 -0
- package/src/plans.js +625 -0
- package/src/setup.js +201 -75
- package/src/techniques.js +27 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.8.0] - 2026-03-31
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- domain pack recommendations for backend, frontend, data, infra, OSS, and enterprise-governed repos
|
|
7
|
+
- MCP pack recommendations and merge support for `context7-docs` and `next-devtools`
|
|
8
|
+
- workflow-evidence coverage in benchmark reports
|
|
9
|
+
- runtime settings overlays so `apply --plan` still respects current `--profile` and `--mcp-pack` flags
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- benchmark now respects the selected profile and MCP pack options during isolated-copy runs
|
|
13
|
+
- governance and suggest-only outputs now expose domain packs and MCP packs directly
|
|
14
|
+
- README and docs clarify the local-vs-opt-in-network boundary for core flows vs `deep-review`
|
|
15
|
+
- audit output now frames `setup` as starter-safe generation instead of an automatic full fix
|
|
16
|
+
|
|
17
|
+
## [1.7.0] - 2026-03-31
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- `augment` / `suggest-only` repo-aware analysis with strengths, gaps, top actions, risk notes, and rollout order
|
|
21
|
+
- `plan` command for exportable proposal bundles with file previews and diff-style output
|
|
22
|
+
- `apply` command for selective starter-safe apply flows with rollback manifests and activity artifacts
|
|
23
|
+
- `governance` command with permission profiles, hook registry, policy packs, and pilot rollout guidance
|
|
24
|
+
- `benchmark` command that measures before/after impact in an isolated temp copy and exports evidence reports
|
|
25
|
+
- claims governance and pilot rollout docs in `content/`
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- `setup` now exposes reusable planning primitives and returns written/preserved file summaries
|
|
29
|
+
- CLI now supports `--out`, `--plan`, `--only`, and `--dry-run`
|
|
30
|
+
- README and docs now reflect the actual product surface instead of only audit/setup flows
|
|
31
|
+
- benchmark and proposal workflows now preserve existing files by default and treat mature repos as review-first
|
|
32
|
+
|
|
3
33
|
## [0.2.0] - 2026-03-31
|
|
4
34
|
|
|
5
35
|
### Added
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CLAUDEX Project
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# claudex-setup
|
|
2
2
|
|
|
3
|
-
> Score your project 0-100 for Claude Code readiness.
|
|
3
|
+
> Score your project 0-100 for Claude Code readiness. Discover gaps, export proposal bundles, apply safe starter changes with rollback, and benchmark the impact without touching your live repo.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/claudex-setup)
|
|
6
6
|
[](https://www.npmjs.com/package/claudex-setup)
|
|
@@ -10,7 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
npx claudex-setup # Audit your project (10 seconds)
|
|
13
|
-
npx claudex-setup setup #
|
|
13
|
+
npx claudex-setup setup # Create a starter-safe baseline
|
|
14
|
+
npx claudex-setup augment # Repo-aware plan, no writes
|
|
15
|
+
npx claudex-setup plan # Export proposal bundles with file previews
|
|
16
|
+
npx claudex-setup governance # See permission profiles, packs, and pilot guidance
|
|
17
|
+
npx claudex-setup benchmark # Measure before/after in an isolated temp copy
|
|
18
|
+
npx claudex-setup --threshold 60 # Fail CI if score is below 60
|
|
14
19
|
```
|
|
15
20
|
|
|
16
21
|
No install. No config. No dependencies.
|
|
@@ -36,25 +41,33 @@ No install. No config. No dependencies.
|
|
|
36
41
|
CI pipeline configured
|
|
37
42
|
→ Add .github/workflows/ for automated testing
|
|
38
43
|
|
|
39
|
-
⚡
|
|
40
|
-
1. Add
|
|
41
|
-
2.
|
|
44
|
+
⚡ Best next fixes
|
|
45
|
+
1. Add CLAUDE.md verification criteria
|
|
46
|
+
2. Configure safe permissions + deny rules
|
|
42
47
|
|
|
43
48
|
Weakest areas:
|
|
44
|
-
|
|
49
|
+
design: none (0/2)
|
|
45
50
|
devops: none (0/4)
|
|
46
51
|
|
|
47
|
-
29/
|
|
48
|
-
Run npx claudex-setup setup to
|
|
52
|
+
29/62 checks passing
|
|
53
|
+
Run npx claudex-setup setup to create a starter-safe baseline
|
|
49
54
|
```
|
|
50
55
|
|
|
51
56
|
## All Commands
|
|
52
57
|
|
|
53
58
|
| Command | What it does |
|
|
54
59
|
|---------|-------------|
|
|
55
|
-
| `npx claudex-setup` | **
|
|
56
|
-
| `npx claudex-setup
|
|
60
|
+
| `npx claudex-setup` | **Discover** - Score 0-100 against 62 checks |
|
|
61
|
+
| `npx claudex-setup discover` | **Discover** - Alias for audit mode |
|
|
62
|
+
| `npx claudex-setup setup` | **Starter** - Smart CLAUDE.md + hooks + commands + agents |
|
|
63
|
+
| `npx claudex-setup starter` | **Starter** - Alias for setup mode |
|
|
57
64
|
| `npx claudex-setup setup --auto` | **Auto-setup** - No prompts, apply all |
|
|
65
|
+
| `npx claudex-setup augment` | **Augment** - Repo-aware improvement plan, no writes |
|
|
66
|
+
| `npx claudex-setup suggest-only` | **Suggest-Only** - Structured recommendation report, no writes |
|
|
67
|
+
| `npx claudex-setup plan` | **Plan** - Export proposal bundles with previews, rationale, and file-level changes |
|
|
68
|
+
| `npx claudex-setup apply` | **Apply** - Apply ready proposal bundles with rollback + activity artifacts |
|
|
69
|
+
| `npx claudex-setup governance` | **Governance** - Permission profiles, hook registry, policy packs, pilot kit |
|
|
70
|
+
| `npx claudex-setup benchmark` | **Benchmark** - Before/after evidence from an isolated temp copy |
|
|
58
71
|
| `npx claudex-setup interactive` | **Wizard** - Step-by-step guided tour |
|
|
59
72
|
| `npx claudex-setup watch` | **Watch** - Live monitoring with score delta |
|
|
60
73
|
| `npx claudex-setup badge` | **Badge** - Generate shields.io badge for README |
|
|
@@ -65,8 +78,16 @@ No install. No config. No dependencies.
|
|
|
65
78
|
|
|
66
79
|
| Flag | Effect |
|
|
67
80
|
|------|--------|
|
|
81
|
+
| `--threshold N` | Exit with code 1 if score is below `N` (great for CI) |
|
|
82
|
+
| `--out FILE` | Write JSON or markdown output to a file |
|
|
83
|
+
| `--plan FILE` | Load a previously exported plan file |
|
|
84
|
+
| `--only A,B` | Limit plan/apply to selected proposal ids |
|
|
85
|
+
| `--profile NAME` | Choose a permission profile for write-capable flows |
|
|
86
|
+
| `--mcp-pack A,B` | Merge named MCP packs into generated or patched settings |
|
|
87
|
+
| `--dry-run` | Preview apply without writing files |
|
|
68
88
|
| `--verbose` | Show all recommendations (not just critical/high) |
|
|
69
89
|
| `--json` | Machine-readable JSON output (for CI) |
|
|
90
|
+
| `--auto` | Apply setup files without prompts |
|
|
70
91
|
| `--insights` | Enable anonymous usage insights (off by default) |
|
|
71
92
|
|
|
72
93
|
## Smart CLAUDE.md Generation
|
|
@@ -74,13 +95,95 @@ No install. No config. No dependencies.
|
|
|
74
95
|
Not a generic template. The `setup` command actually analyzes your project:
|
|
75
96
|
|
|
76
97
|
- **Reads package.json** - includes your actual test, build, lint, dev commands
|
|
98
|
+
- **Reads pyproject.toml** - uses Python project name/description when package.json does not exist
|
|
77
99
|
- **Detects framework** - Next.js Server Components, Django models, FastAPI Pydantic, React hooks
|
|
78
100
|
- **TypeScript-aware** - detects strict mode, adds TS-specific rules
|
|
79
101
|
- **Auto Mermaid diagram** - scans directories and generates architecture visualization (Mermaid diagrams are more token-efficient than prose descriptions, per Anthropic docs)
|
|
80
102
|
- **XML constraint blocks** - adds `<constraints>` and `<verification>` with context-aware rules
|
|
81
103
|
- **Verification criteria** - auto-generates checklist from your actual commands
|
|
104
|
+
- **Safer settings.json** - generated hooks config now includes `acceptEdits` plus deny rules for dangerous or secret-sensitive operations
|
|
82
105
|
|
|
83
|
-
##
|
|
106
|
+
## Mode Model
|
|
107
|
+
|
|
108
|
+
- **Discover**: score the repo, surface critical issues, and show the best next actions
|
|
109
|
+
- **Starter**: generate a safe baseline when the repo has little or no Claude setup
|
|
110
|
+
- **Augment**: inspect the current repo and build a structured improvement plan without writing files
|
|
111
|
+
- **Suggest-Only**: same no-write analysis, optimized for sharing or manual review
|
|
112
|
+
- **Governance**: surface permission profiles, shipped hooks, policy packs, and pilot guidance
|
|
113
|
+
- **Benchmark**: prove value on an isolated copy before touching the real repo
|
|
114
|
+
|
|
115
|
+
## Proposal + Apply Workflow
|
|
116
|
+
|
|
117
|
+
Use `plan` when you want a file-by-file proposal bundle before any write happens:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx claudex-setup plan --out claudex-plan.json
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Each proposal bundle includes:
|
|
124
|
+
|
|
125
|
+
- trigger reasons tied to failed checks
|
|
126
|
+
- file previews and diff-style output
|
|
127
|
+
- `create`, `patch`, or `manual-review` classification
|
|
128
|
+
- risk/confidence labels
|
|
129
|
+
|
|
130
|
+
Apply only the bundles you want:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx claudex-setup apply --plan claudex-plan.json --only claude-md,hooks
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`apply` creates rollback manifests and activity artifacts under `.claude/claudex-setup/`, so every applied batch has a paper trail and a create-or-patch rollback path.
|
|
137
|
+
|
|
138
|
+
## Governance And Pilot Readiness
|
|
139
|
+
|
|
140
|
+
Use `governance` when the question is "can we pilot this safely?" instead of "what files can you generate?".
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npx claudex-setup governance
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
It exposes:
|
|
147
|
+
|
|
148
|
+
- permission profiles: `read-only`, `suggest-only`, `safe-write`, `power-user`, `internal-research`
|
|
149
|
+
- hook registry with trigger point, purpose, side effects, risk, and rollback path
|
|
150
|
+
- policy packs for baseline engineering, security-sensitive repos, OSS, and regulated-lite teams
|
|
151
|
+
- domain packs for backend, frontend, data, infra, OSS, and enterprise-governed repos
|
|
152
|
+
- MCP packs for live docs and framework-aware tooling such as Context7 and Next.js devtools
|
|
153
|
+
- a pilot rollout kit with scope, approvals, success metrics, and rollback expectations
|
|
154
|
+
|
|
155
|
+
## Domain Packs And MCP Packs
|
|
156
|
+
|
|
157
|
+
`augment` and `suggest-only` now recommend repo-shaped guidance instead of giving every project the same advice.
|
|
158
|
+
|
|
159
|
+
- domain packs identify the repo shape: `backend-api`, `frontend-ui`, `data-pipeline`, `infra-platform`, `oss-library`, `enterprise-governed`
|
|
160
|
+
- MCP packs recommend current-tooling companions: `context7-docs` for live docs, `next-devtools` for Next.js repos
|
|
161
|
+
- write-capable flows can merge MCP packs directly into `.claude/settings.json`
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npx claudex-setup suggest-only --json
|
|
165
|
+
npx claudex-setup setup --mcp-pack context7-docs
|
|
166
|
+
npx claudex-setup apply --plan claudex-plan.json --only hooks --mcp-pack context7-docs,next-devtools
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Benchmark And Evidence
|
|
170
|
+
|
|
171
|
+
Use `benchmark` to measure the impact of starter-safe improvements without modifying your working repo:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
npx claudex-setup benchmark --out benchmark.md
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Benchmark mode:
|
|
178
|
+
|
|
179
|
+
- runs a baseline audit on your repo
|
|
180
|
+
- copies the repo to an isolated temp workspace
|
|
181
|
+
- applies starter-safe artifacts only in the copy
|
|
182
|
+
- reruns the audit and emits before/after deltas, workflow-evidence coverage, a case-study summary, and an executive recommendation
|
|
183
|
+
|
|
184
|
+
## 62 Checks Across 14 Categories
|
|
185
|
+
|
|
186
|
+
The exact applicable count can be lower on a given repo because stack-specific checks are skipped when they do not apply.
|
|
84
187
|
|
|
85
188
|
| Category | Checks | Key items |
|
|
86
189
|
|----------|-------:|-----------|
|
|
@@ -124,7 +227,7 @@ jobs:
|
|
|
124
227
|
runs-on: ubuntu-latest
|
|
125
228
|
steps:
|
|
126
229
|
- uses: actions/checkout@v4
|
|
127
|
-
- uses: DnaFin/claudex-setup@
|
|
230
|
+
- uses: DnaFin/claudex-setup@v1.8.0
|
|
128
231
|
with:
|
|
129
232
|
threshold: 50
|
|
130
233
|
```
|
|
@@ -148,7 +251,7 @@ Already have a solid CLAUDE.md and hooks? Two things for you:
|
|
|
148
251
|
npx claudex-setup deep-review
|
|
149
252
|
```
|
|
150
253
|
|
|
151
|
-
Claude reads your actual config and gives specific feedback: what's strong, what has issues, what's missing for your stack.
|
|
254
|
+
Claude reads your actual config and gives specific feedback: what's strong, what has issues, what's missing for your stack. This is an AI-assisted review, not a local heuristic audit. Your config goes to the Anthropic API only when you run this command; we do not receive it.
|
|
152
255
|
|
|
153
256
|
### Quality-Deep Checks
|
|
154
257
|
|
|
@@ -170,8 +273,10 @@ These checks evaluate **quality**, not just existence. A well-configured project
|
|
|
170
273
|
|
|
171
274
|
## Privacy
|
|
172
275
|
|
|
173
|
-
- **Zero dependencies** - nothing to audit
|
|
174
|
-
- **
|
|
276
|
+
- **Zero dependencies** - nothing extra to audit
|
|
277
|
+
- **Core flows run locally** - audit, setup, augment, plan, apply, governance, and benchmark run on your machine
|
|
278
|
+
- **Deep review is opt-in** - only `deep-review` sends selected config to Anthropic for analysis
|
|
279
|
+
- **Benchmark uses an isolated temp copy** - your live repo is not touched
|
|
175
280
|
- **Anonymous insights** - opt-in, no PII, no file contents (enable with `--insights`)
|
|
176
281
|
- **MIT Licensed** - use anywhere
|
|
177
282
|
|
package/bin/cli.js
CHANGED
|
@@ -2,36 +2,200 @@
|
|
|
2
2
|
|
|
3
3
|
const { audit } = require('../src/audit');
|
|
4
4
|
const { setup } = require('../src/setup');
|
|
5
|
+
const { analyzeProject, printAnalysis } = require('../src/analyze');
|
|
6
|
+
const { buildProposalBundle, printProposalBundle, writePlanFile, applyProposalBundle, printApplyResult } = require('../src/plans');
|
|
7
|
+
const { getGovernanceSummary, printGovernanceSummary, ensureWritableProfile } = require('../src/governance');
|
|
8
|
+
const { runBenchmark, printBenchmark, writeBenchmarkReport } = require('../src/benchmark');
|
|
5
9
|
const { version } = require('../package.json');
|
|
6
10
|
|
|
7
11
|
const args = process.argv.slice(2);
|
|
8
|
-
const
|
|
9
|
-
|
|
12
|
+
const COMMAND_ALIASES = {
|
|
13
|
+
review: 'deep-review',
|
|
14
|
+
wizard: 'interactive',
|
|
15
|
+
learn: 'insights',
|
|
16
|
+
discover: 'audit',
|
|
17
|
+
starter: 'setup',
|
|
18
|
+
suggest: 'suggest-only',
|
|
19
|
+
gov: 'governance',
|
|
20
|
+
};
|
|
21
|
+
const KNOWN_COMMANDS = ['audit', 'setup', 'augment', 'suggest-only', 'plan', 'apply', 'governance', 'benchmark', 'deep-review', 'interactive', 'watch', 'badge', 'insights', 'help', 'version'];
|
|
22
|
+
|
|
23
|
+
function levenshtein(a, b) {
|
|
24
|
+
const matrix = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0));
|
|
25
|
+
for (let i = 0; i <= a.length; i++) matrix[i][0] = i;
|
|
26
|
+
for (let j = 0; j <= b.length; j++) matrix[0][j] = j;
|
|
27
|
+
for (let i = 1; i <= a.length; i++) {
|
|
28
|
+
for (let j = 1; j <= b.length; j++) {
|
|
29
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
30
|
+
matrix[i][j] = Math.min(
|
|
31
|
+
matrix[i - 1][j] + 1,
|
|
32
|
+
matrix[i][j - 1] + 1,
|
|
33
|
+
matrix[i - 1][j - 1] + cost
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return matrix[a.length][b.length];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function suggestCommand(input) {
|
|
41
|
+
const candidates = [...KNOWN_COMMANDS, ...Object.keys(COMMAND_ALIASES)];
|
|
42
|
+
let best = null;
|
|
43
|
+
let bestDistance = Infinity;
|
|
44
|
+
for (const candidate of candidates) {
|
|
45
|
+
const distance = levenshtein(input, candidate);
|
|
46
|
+
if (distance < bestDistance) {
|
|
47
|
+
best = candidate;
|
|
48
|
+
bestDistance = distance;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return bestDistance <= 3 ? best : null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function parseArgs(rawArgs) {
|
|
55
|
+
const flags = [];
|
|
56
|
+
let command = 'audit';
|
|
57
|
+
let threshold = null;
|
|
58
|
+
let out = null;
|
|
59
|
+
let planFile = null;
|
|
60
|
+
let only = [];
|
|
61
|
+
let profile = 'safe-write';
|
|
62
|
+
let mcpPacks = [];
|
|
63
|
+
let commandSet = false;
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
66
|
+
const arg = rawArgs[i];
|
|
67
|
+
|
|
68
|
+
if (arg === '--threshold' || arg === '--out' || arg === '--plan' || arg === '--only' || arg === '--profile' || arg === '--mcp-pack') {
|
|
69
|
+
const value = rawArgs[i + 1];
|
|
70
|
+
if (!value || value.startsWith('--')) {
|
|
71
|
+
throw new Error(`${arg} requires a value`);
|
|
72
|
+
}
|
|
73
|
+
if (arg === '--threshold') threshold = value;
|
|
74
|
+
if (arg === '--out') out = value;
|
|
75
|
+
if (arg === '--plan') planFile = value;
|
|
76
|
+
if (arg === '--only') only = value.split(',').map(item => item.trim()).filter(Boolean);
|
|
77
|
+
if (arg === '--profile') profile = value.trim();
|
|
78
|
+
if (arg === '--mcp-pack') mcpPacks = value.split(',').map(item => item.trim()).filter(Boolean);
|
|
79
|
+
i++;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (arg.startsWith('--threshold=')) {
|
|
84
|
+
threshold = arg.split('=')[1];
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (arg.startsWith('--out=')) {
|
|
89
|
+
out = arg.split('=').slice(1).join('=');
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (arg.startsWith('--plan=')) {
|
|
94
|
+
planFile = arg.split('=').slice(1).join('=');
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (arg.startsWith('--only=')) {
|
|
99
|
+
only = arg.split('=').slice(1).join('=').split(',').map(item => item.trim()).filter(Boolean);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (arg.startsWith('--profile=')) {
|
|
104
|
+
profile = arg.split('=').slice(1).join('=').trim();
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (arg.startsWith('--mcp-pack=')) {
|
|
109
|
+
mcpPacks = arg.split('=').slice(1).join('=').split(',').map(item => item.trim()).filter(Boolean);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (arg.startsWith('--')) {
|
|
114
|
+
flags.push(arg);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!commandSet) {
|
|
119
|
+
command = arg;
|
|
120
|
+
commandSet = true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const normalizedCommand = COMMAND_ALIASES[command] || command;
|
|
125
|
+
|
|
126
|
+
return { flags, command, normalizedCommand, threshold, out, planFile, only, profile, mcpPacks };
|
|
127
|
+
}
|
|
10
128
|
|
|
11
129
|
const HELP = `
|
|
12
130
|
claudex-setup v${version}
|
|
13
131
|
Audit and optimize any project for Claude Code.
|
|
14
|
-
Backed by research
|
|
132
|
+
Backed by CLAUDEX research and evidence.
|
|
15
133
|
|
|
16
134
|
Usage:
|
|
17
135
|
npx claudex-setup Run audit on current directory
|
|
136
|
+
npx claudex-setup discover Discover the highest-value improvements
|
|
18
137
|
npx claudex-setup audit Same as above
|
|
138
|
+
npx claudex-setup starter Alias for setup
|
|
19
139
|
npx claudex-setup setup Apply recommended configuration
|
|
20
140
|
npx claudex-setup setup --auto Apply all without prompts
|
|
21
|
-
npx claudex-setup
|
|
141
|
+
npx claudex-setup augment Repo-aware augment plan (no writes)
|
|
142
|
+
npx claudex-setup suggest-only Structured suggestion report (no writes)
|
|
143
|
+
npx claudex-setup plan Exportable proposal bundles with file previews
|
|
144
|
+
npx claudex-setup apply Apply ready proposal bundles with rollback manifest
|
|
145
|
+
npx claudex-setup governance Profiles, hooks, and pilot rollout guidance
|
|
146
|
+
npx claudex-setup benchmark Measure before/after impact in an isolated temp copy
|
|
147
|
+
npx claudex-setup deep-review AI-powered config review (uses Claude Code or API key)
|
|
22
148
|
npx claudex-setup interactive Step-by-step guided wizard
|
|
23
149
|
npx claudex-setup watch Monitor changes and re-audit live
|
|
24
150
|
npx claudex-setup badge Generate shields.io badge markdown
|
|
25
151
|
|
|
26
152
|
Options:
|
|
153
|
+
--threshold N Exit with code 1 if score is below N (useful for CI)
|
|
154
|
+
--out FILE Write JSON or markdown output to a file
|
|
155
|
+
--plan FILE Load a previously exported plan file
|
|
156
|
+
--only A,B Limit plan/apply to selected proposal ids or technique keys
|
|
157
|
+
--profile NAME Choose permission profile (read-only, suggest-only, safe-write, power-user, internal-research)
|
|
158
|
+
--mcp-pack A,B Merge named MCP packs into generated settings (e.g. context7-docs,next-devtools)
|
|
159
|
+
--dry-run Preview apply without writing files
|
|
27
160
|
--verbose Show all recommendations (not just critical/high)
|
|
28
161
|
--json Output as JSON (for CI pipelines)
|
|
29
|
-
--
|
|
162
|
+
--auto Apply all generated setup files without prompting
|
|
163
|
+
--insights Enable anonymous usage insights (off by default)
|
|
30
164
|
--help Show this help
|
|
31
165
|
--version Show version
|
|
166
|
+
|
|
167
|
+
Examples:
|
|
168
|
+
npx claudex-setup
|
|
169
|
+
npx claudex-setup augment
|
|
170
|
+
npx claudex-setup suggest-only --json
|
|
171
|
+
npx claudex-setup plan --out claudex-plan.json
|
|
172
|
+
npx claudex-setup plan --profile safe-write
|
|
173
|
+
npx claudex-setup setup --mcp-pack context7-docs
|
|
174
|
+
npx claudex-setup apply --plan claudex-plan.json --only hooks,commands
|
|
175
|
+
npx claudex-setup apply --mcp-pack context7-docs,next-devtools --only hooks
|
|
176
|
+
npx claudex-setup apply --profile power-user --only claude-md,hooks
|
|
177
|
+
npx claudex-setup governance --json
|
|
178
|
+
npx claudex-setup benchmark --out benchmark.md
|
|
179
|
+
npx claudex-setup --json --threshold 60
|
|
180
|
+
npx claudex-setup setup --auto
|
|
181
|
+
npx claudex-setup interactive
|
|
182
|
+
|
|
183
|
+
Exit codes:
|
|
184
|
+
0 Success
|
|
185
|
+
1 Error, unknown command, or score below --threshold
|
|
32
186
|
`;
|
|
33
187
|
|
|
34
188
|
async function main() {
|
|
189
|
+
let parsed;
|
|
190
|
+
try {
|
|
191
|
+
parsed = parseArgs(args);
|
|
192
|
+
} catch (err) {
|
|
193
|
+
console.error(`\n Error: ${err.message}\n`);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const { flags, command, normalizedCommand } = parsed;
|
|
198
|
+
|
|
35
199
|
if (flags.includes('--help') || command === 'help') {
|
|
36
200
|
console.log(HELP);
|
|
37
201
|
process.exit(0);
|
|
@@ -46,24 +210,55 @@ async function main() {
|
|
|
46
210
|
verbose: flags.includes('--verbose'),
|
|
47
211
|
json: flags.includes('--json'),
|
|
48
212
|
auto: flags.includes('--auto'),
|
|
213
|
+
dryRun: flags.includes('--dry-run'),
|
|
214
|
+
threshold: parsed.threshold !== null ? Number(parsed.threshold) : null,
|
|
215
|
+
out: parsed.out,
|
|
216
|
+
planFile: parsed.planFile,
|
|
217
|
+
only: parsed.only,
|
|
218
|
+
profile: parsed.profile,
|
|
219
|
+
mcpPacks: parsed.mcpPacks,
|
|
49
220
|
dir: process.cwd()
|
|
50
221
|
};
|
|
51
222
|
|
|
223
|
+
if (options.threshold !== null && (!Number.isFinite(options.threshold) || options.threshold < 0 || options.threshold > 100)) {
|
|
224
|
+
console.error('\n Error: --threshold must be a number between 0 and 100.\n');
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!KNOWN_COMMANDS.includes(normalizedCommand)) {
|
|
229
|
+
const suggestion = suggestCommand(command);
|
|
230
|
+
console.error(`\n Error: Unknown command '${command}'.`);
|
|
231
|
+
if (suggestion) {
|
|
232
|
+
console.error(` Did you mean '${suggestion}'?`);
|
|
233
|
+
}
|
|
234
|
+
console.error(' Run claudex-setup --help for usage.\n');
|
|
235
|
+
process.exit(1);
|
|
236
|
+
}
|
|
237
|
+
|
|
52
238
|
if (!require('fs').existsSync(options.dir)) {
|
|
53
239
|
console.error(`\n Error: Directory not found: ${options.dir}`);
|
|
54
240
|
console.error(' Run claudex-setup from inside your project directory.\n');
|
|
55
241
|
process.exit(1);
|
|
56
242
|
}
|
|
57
243
|
|
|
244
|
+
if (['setup', 'apply', 'benchmark'].includes(normalizedCommand)) {
|
|
245
|
+
try {
|
|
246
|
+
ensureWritableProfile(options.profile, normalizedCommand, options.dryRun);
|
|
247
|
+
} catch (err) {
|
|
248
|
+
console.error(`\n Error: ${err.message}\n`);
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
58
253
|
try {
|
|
59
|
-
if (
|
|
254
|
+
if (normalizedCommand === 'badge') {
|
|
60
255
|
const { getBadgeMarkdown } = require('../src/badge');
|
|
61
256
|
const result = await audit({ ...options, silent: true });
|
|
62
257
|
console.log(getBadgeMarkdown(result.score));
|
|
63
258
|
console.log('');
|
|
64
259
|
console.log('Add this to your README.md');
|
|
65
260
|
process.exit(0);
|
|
66
|
-
} else if (
|
|
261
|
+
} else if (normalizedCommand === 'insights') {
|
|
67
262
|
const https = require('https');
|
|
68
263
|
const url = 'https://claudex-insights.claudex.workers.dev/v1/stats';
|
|
69
264
|
https.get(url, (res) => {
|
|
@@ -98,19 +293,58 @@ async function main() {
|
|
|
98
293
|
console.log(' Could not reach insights server. Run locally: npx claudex-setup');
|
|
99
294
|
});
|
|
100
295
|
return; // keep process alive for http
|
|
101
|
-
} else if (
|
|
296
|
+
} else if (normalizedCommand === 'augment' || normalizedCommand === 'suggest-only') {
|
|
297
|
+
const report = await analyzeProject({ ...options, mode: normalizedCommand });
|
|
298
|
+
printAnalysis(report, options);
|
|
299
|
+
} else if (normalizedCommand === 'plan') {
|
|
300
|
+
const bundle = await buildProposalBundle(options);
|
|
301
|
+
let artifact = null;
|
|
302
|
+
if (options.out) {
|
|
303
|
+
artifact = writePlanFile(bundle, options.out);
|
|
304
|
+
}
|
|
305
|
+
printProposalBundle(bundle, options);
|
|
306
|
+
if (options.out && !options.json) {
|
|
307
|
+
console.log(` Plan written to ${options.out}`);
|
|
308
|
+
if (artifact) {
|
|
309
|
+
console.log(` Activity log: ${artifact.relativePath}`);
|
|
310
|
+
}
|
|
311
|
+
console.log('');
|
|
312
|
+
}
|
|
313
|
+
} else if (normalizedCommand === 'apply') {
|
|
314
|
+
const result = await applyProposalBundle(options);
|
|
315
|
+
printApplyResult(result, options);
|
|
316
|
+
} else if (normalizedCommand === 'governance') {
|
|
317
|
+
const summary = getGovernanceSummary();
|
|
318
|
+
printGovernanceSummary(summary, options);
|
|
319
|
+
} else if (normalizedCommand === 'benchmark') {
|
|
320
|
+
const report = await runBenchmark(options);
|
|
321
|
+
if (options.out) {
|
|
322
|
+
writeBenchmarkReport(report, options.out);
|
|
323
|
+
}
|
|
324
|
+
printBenchmark(report, options);
|
|
325
|
+
if (options.out && !options.json) {
|
|
326
|
+
console.log(` Benchmark report written to ${options.out}`);
|
|
327
|
+
console.log('');
|
|
328
|
+
}
|
|
329
|
+
} else if (normalizedCommand === 'deep-review') {
|
|
102
330
|
const { deepReview } = require('../src/deep-review');
|
|
103
331
|
await deepReview(options);
|
|
104
|
-
} else if (
|
|
332
|
+
} else if (normalizedCommand === 'interactive') {
|
|
105
333
|
const { interactive } = require('../src/interactive');
|
|
106
334
|
await interactive(options);
|
|
107
|
-
} else if (
|
|
335
|
+
} else if (normalizedCommand === 'watch') {
|
|
108
336
|
const { watch } = require('../src/watch');
|
|
109
337
|
await watch(options);
|
|
110
|
-
} else if (
|
|
338
|
+
} else if (normalizedCommand === 'setup') {
|
|
111
339
|
await setup(options);
|
|
112
340
|
} else {
|
|
113
|
-
await audit(options);
|
|
341
|
+
const result = await audit(options);
|
|
342
|
+
if (options.threshold !== null && result.score < options.threshold) {
|
|
343
|
+
if (!options.json) {
|
|
344
|
+
console.error(` Threshold failed: score ${result.score}/100 is below required ${options.threshold}/100.\n`);
|
|
345
|
+
}
|
|
346
|
+
process.exit(1);
|
|
347
|
+
}
|
|
114
348
|
}
|
|
115
349
|
} catch (err) {
|
|
116
350
|
console.error(`\n Error: ${err.message}`);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudex-setup",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Audit and
|
|
3
|
+
"version": "1.8.0",
|
|
4
|
+
"description": "Audit and improve Claude Code readiness with discover, plan, apply, governance, and benchmark workflows.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"claudex-setup": "bin/cli.js"
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
16
|
"start": "node bin/cli.js",
|
|
17
|
+
"build": "npm pack --dry-run",
|
|
17
18
|
"test": "node test/run.js"
|
|
18
19
|
},
|
|
19
20
|
"keywords": [
|
package/src/activity.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function timestampId() {
|
|
5
|
+
return new Date().toISOString().replace(/[:.]/g, '-');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function ensureArtifactDirs(dir) {
|
|
9
|
+
const root = path.join(dir, '.claude', 'claudex-setup');
|
|
10
|
+
const activityDir = path.join(root, 'activity');
|
|
11
|
+
const rollbackDir = path.join(root, 'rollbacks');
|
|
12
|
+
fs.mkdirSync(activityDir, { recursive: true });
|
|
13
|
+
fs.mkdirSync(rollbackDir, { recursive: true });
|
|
14
|
+
return { root, activityDir, rollbackDir };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function writeJson(filePath, payload) {
|
|
18
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
19
|
+
fs.writeFileSync(filePath, JSON.stringify(payload, null, 2), 'utf8');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function writeActivityArtifact(dir, type, payload) {
|
|
23
|
+
const id = timestampId();
|
|
24
|
+
const { activityDir } = ensureArtifactDirs(dir);
|
|
25
|
+
const filePath = path.join(activityDir, `${id}-${type}.json`);
|
|
26
|
+
writeJson(filePath, {
|
|
27
|
+
id,
|
|
28
|
+
type,
|
|
29
|
+
createdAt: new Date().toISOString(),
|
|
30
|
+
...payload,
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
id,
|
|
34
|
+
filePath,
|
|
35
|
+
relativePath: path.relative(dir, filePath),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function writeRollbackArtifact(dir, payload) {
|
|
40
|
+
const id = timestampId();
|
|
41
|
+
const { rollbackDir } = ensureArtifactDirs(dir);
|
|
42
|
+
const filePath = path.join(rollbackDir, `${id}.json`);
|
|
43
|
+
writeJson(filePath, {
|
|
44
|
+
id,
|
|
45
|
+
createdAt: new Date().toISOString(),
|
|
46
|
+
rollbackType: 'delete-created-files',
|
|
47
|
+
...payload,
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
id,
|
|
51
|
+
filePath,
|
|
52
|
+
relativePath: path.relative(dir, filePath),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
57
|
+
ensureArtifactDirs,
|
|
58
|
+
writeActivityArtifact,
|
|
59
|
+
writeRollbackArtifact,
|
|
60
|
+
};
|