claudex-setup 1.5.0 → 1.7.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 +16 -0
- package/README.md +90 -7
- package/bin/cli.js +214 -11
- package/package.json +1 -1
- package/src/activity.js +60 -0
- package/src/analyze.js +397 -0
- package/src/audit.js +25 -20
- package/src/benchmark.js +176 -0
- package/src/governance.js +192 -0
- package/src/index.js +13 -1
- package/src/interactive.js +2 -2
- package/src/plans.js +355 -0
- package/src/setup.js +198 -52
- package/src/techniques.js +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.7.0] - 2026-03-31
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `augment` / `suggest-only` repo-aware analysis with strengths, gaps, top actions, risk notes, and rollout order
|
|
7
|
+
- `plan` command for exportable proposal bundles with file previews and diff-style output
|
|
8
|
+
- `apply` command for selective starter-safe apply flows with rollback manifests and activity artifacts
|
|
9
|
+
- `governance` command with permission profiles, hook registry, policy packs, and pilot rollout guidance
|
|
10
|
+
- `benchmark` command that measures before/after impact in an isolated temp copy and exports evidence reports
|
|
11
|
+
- claims governance and pilot rollout docs in `content/`
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- `setup` now exposes reusable planning primitives and returns written/preserved file summaries
|
|
15
|
+
- CLI now supports `--out`, `--plan`, `--only`, and `--dry-run`
|
|
16
|
+
- README and docs now reflect the actual product surface instead of only audit/setup flows
|
|
17
|
+
- benchmark and proposal workflows now preserve existing files by default and treat mature repos as review-first
|
|
18
|
+
|
|
3
19
|
## [0.2.0] - 2026-03-31
|
|
4
20
|
|
|
5
21
|
### Added
|
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)
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
```bash
|
|
12
12
|
npx claudex-setup # Audit your project (10 seconds)
|
|
13
13
|
npx claudex-setup setup # Auto-fix everything
|
|
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 benchmark # Measure before/after in an isolated temp copy
|
|
17
|
+
npx claudex-setup --threshold 60 # Fail CI if score is below 60
|
|
14
18
|
```
|
|
15
19
|
|
|
16
20
|
No install. No config. No dependencies.
|
|
@@ -36,12 +40,12 @@ No install. No config. No dependencies.
|
|
|
36
40
|
CI pipeline configured
|
|
37
41
|
→ Add .github/workflows/ for automated testing
|
|
38
42
|
|
|
39
|
-
⚡
|
|
40
|
-
1. Add
|
|
41
|
-
2.
|
|
43
|
+
⚡ Best next fixes
|
|
44
|
+
1. Add CLAUDE.md verification criteria
|
|
45
|
+
2. Configure safe permissions + deny rules
|
|
42
46
|
|
|
43
47
|
Weakest areas:
|
|
44
|
-
|
|
48
|
+
design: none (0/2)
|
|
45
49
|
devops: none (0/4)
|
|
46
50
|
|
|
47
51
|
29/63 checks passing
|
|
@@ -52,9 +56,17 @@ No install. No config. No dependencies.
|
|
|
52
56
|
|
|
53
57
|
| Command | What it does |
|
|
54
58
|
|---------|-------------|
|
|
55
|
-
| `npx claudex-setup` | **
|
|
56
|
-
| `npx claudex-setup
|
|
59
|
+
| `npx claudex-setup` | **Discover** - Score 0-100 against 63 checks |
|
|
60
|
+
| `npx claudex-setup discover` | **Discover** - Alias for audit mode |
|
|
61
|
+
| `npx claudex-setup setup` | **Starter** - Smart CLAUDE.md + hooks + commands + agents |
|
|
62
|
+
| `npx claudex-setup starter` | **Starter** - Alias for setup mode |
|
|
57
63
|
| `npx claudex-setup setup --auto` | **Auto-setup** - No prompts, apply all |
|
|
64
|
+
| `npx claudex-setup augment` | **Augment** - Repo-aware improvement plan, no writes |
|
|
65
|
+
| `npx claudex-setup suggest-only` | **Suggest-Only** - Structured recommendation report, no writes |
|
|
66
|
+
| `npx claudex-setup plan` | **Plan** - Export proposal bundles with previews, rationale, and file-level changes |
|
|
67
|
+
| `npx claudex-setup apply` | **Apply** - Apply ready proposal bundles with rollback + activity artifacts |
|
|
68
|
+
| `npx claudex-setup governance` | **Governance** - Permission profiles, hook registry, policy packs, pilot kit |
|
|
69
|
+
| `npx claudex-setup benchmark` | **Benchmark** - Before/after evidence from an isolated temp copy |
|
|
58
70
|
| `npx claudex-setup interactive` | **Wizard** - Step-by-step guided tour |
|
|
59
71
|
| `npx claudex-setup watch` | **Watch** - Live monitoring with score delta |
|
|
60
72
|
| `npx claudex-setup badge` | **Badge** - Generate shields.io badge for README |
|
|
@@ -65,8 +77,14 @@ No install. No config. No dependencies.
|
|
|
65
77
|
|
|
66
78
|
| Flag | Effect |
|
|
67
79
|
|------|--------|
|
|
80
|
+
| `--threshold N` | Exit with code 1 if score is below `N` (great for CI) |
|
|
81
|
+
| `--out FILE` | Write JSON or markdown output to a file |
|
|
82
|
+
| `--plan FILE` | Load a previously exported plan file |
|
|
83
|
+
| `--only A,B` | Limit plan/apply to selected proposal ids |
|
|
84
|
+
| `--dry-run` | Preview apply without writing files |
|
|
68
85
|
| `--verbose` | Show all recommendations (not just critical/high) |
|
|
69
86
|
| `--json` | Machine-readable JSON output (for CI) |
|
|
87
|
+
| `--auto` | Apply setup files without prompts |
|
|
70
88
|
| `--insights` | Enable anonymous usage insights (off by default) |
|
|
71
89
|
|
|
72
90
|
## Smart CLAUDE.md Generation
|
|
@@ -74,11 +92,75 @@ No install. No config. No dependencies.
|
|
|
74
92
|
Not a generic template. The `setup` command actually analyzes your project:
|
|
75
93
|
|
|
76
94
|
- **Reads package.json** - includes your actual test, build, lint, dev commands
|
|
95
|
+
- **Reads pyproject.toml** - uses Python project name/description when package.json does not exist
|
|
77
96
|
- **Detects framework** - Next.js Server Components, Django models, FastAPI Pydantic, React hooks
|
|
78
97
|
- **TypeScript-aware** - detects strict mode, adds TS-specific rules
|
|
79
98
|
- **Auto Mermaid diagram** - scans directories and generates architecture visualization (Mermaid diagrams are more token-efficient than prose descriptions, per Anthropic docs)
|
|
80
99
|
- **XML constraint blocks** - adds `<constraints>` and `<verification>` with context-aware rules
|
|
81
100
|
- **Verification criteria** - auto-generates checklist from your actual commands
|
|
101
|
+
- **Safer settings.json** - generated hooks config now includes `acceptEdits` plus deny rules for dangerous or secret-sensitive operations
|
|
102
|
+
|
|
103
|
+
## Mode Model
|
|
104
|
+
|
|
105
|
+
- **Discover**: score the repo, surface critical issues, and show the best next actions
|
|
106
|
+
- **Starter**: generate a safe baseline when the repo has little or no Claude setup
|
|
107
|
+
- **Augment**: inspect the current repo and build a structured improvement plan without writing files
|
|
108
|
+
- **Suggest-Only**: same no-write analysis, optimized for sharing or manual review
|
|
109
|
+
- **Governance**: surface permission profiles, shipped hooks, policy packs, and pilot guidance
|
|
110
|
+
- **Benchmark**: prove value on an isolated copy before touching the real repo
|
|
111
|
+
|
|
112
|
+
## Proposal + Apply Workflow
|
|
113
|
+
|
|
114
|
+
Use `plan` when you want a file-by-file proposal bundle before any write happens:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npx claudex-setup plan --out claudex-plan.json
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Each proposal bundle includes:
|
|
121
|
+
|
|
122
|
+
- trigger reasons tied to failed checks
|
|
123
|
+
- file previews and diff-style output
|
|
124
|
+
- `create` vs `manual-review` classification
|
|
125
|
+
- risk/confidence labels
|
|
126
|
+
|
|
127
|
+
Apply only the bundles you want:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npx claudex-setup apply --plan claudex-plan.json --only claude-md,hooks
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`apply` creates rollback manifests and activity artifacts under `.claude/claudex-setup/`, so every applied batch has a paper trail and a delete-based rollback path.
|
|
134
|
+
|
|
135
|
+
## Governance And Pilot Readiness
|
|
136
|
+
|
|
137
|
+
Use `governance` when the question is "can we pilot this safely?" instead of "what files can you generate?".
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npx claudex-setup governance
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
It exposes:
|
|
144
|
+
|
|
145
|
+
- permission profiles: `read-only`, `suggest-only`, `safe-write`, `power-user`, `internal-research`
|
|
146
|
+
- hook registry with trigger point, purpose, side effects, risk, and rollback path
|
|
147
|
+
- policy packs for baseline engineering, security-sensitive repos, OSS, and regulated-lite teams
|
|
148
|
+
- a pilot rollout kit with scope, approvals, success metrics, and rollback expectations
|
|
149
|
+
|
|
150
|
+
## Benchmark And Evidence
|
|
151
|
+
|
|
152
|
+
Use `benchmark` to measure the impact of starter-safe improvements without modifying your working repo:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
npx claudex-setup benchmark --out benchmark.md
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Benchmark mode:
|
|
159
|
+
|
|
160
|
+
- runs a baseline audit on your repo
|
|
161
|
+
- copies the repo to an isolated temp workspace
|
|
162
|
+
- applies starter-safe artifacts only in the copy
|
|
163
|
+
- reruns the audit and emits before/after deltas, a case-study summary, and an executive recommendation
|
|
82
164
|
|
|
83
165
|
## 63 Checks Across 14 Categories
|
|
84
166
|
|
|
@@ -172,6 +254,7 @@ These checks evaluate **quality**, not just existence. A well-configured project
|
|
|
172
254
|
|
|
173
255
|
- **Zero dependencies** - nothing to audit
|
|
174
256
|
- **Runs 100% locally** - no cloud processing
|
|
257
|
+
- **Benchmark uses an isolated temp copy** - your live repo is not touched
|
|
175
258
|
- **Anonymous insights** - opt-in, no PII, no file contents (enable with `--insights`)
|
|
176
259
|
- **MIT Licensed** - use anywhere
|
|
177
260
|
|
package/bin/cli.js
CHANGED
|
@@ -2,11 +2,115 @@
|
|
|
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 } = 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 commandSet = false;
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
64
|
+
const arg = rawArgs[i];
|
|
65
|
+
|
|
66
|
+
if (arg === '--threshold' || arg === '--out' || arg === '--plan' || arg === '--only') {
|
|
67
|
+
const value = rawArgs[i + 1];
|
|
68
|
+
if (!value || value.startsWith('--')) {
|
|
69
|
+
throw new Error(`${arg} requires a value`);
|
|
70
|
+
}
|
|
71
|
+
if (arg === '--threshold') threshold = value;
|
|
72
|
+
if (arg === '--out') out = value;
|
|
73
|
+
if (arg === '--plan') planFile = value;
|
|
74
|
+
if (arg === '--only') only = value.split(',').map(item => item.trim()).filter(Boolean);
|
|
75
|
+
i++;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (arg.startsWith('--threshold=')) {
|
|
80
|
+
threshold = arg.split('=')[1];
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (arg.startsWith('--out=')) {
|
|
85
|
+
out = arg.split('=').slice(1).join('=');
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (arg.startsWith('--plan=')) {
|
|
90
|
+
planFile = arg.split('=').slice(1).join('=');
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (arg.startsWith('--only=')) {
|
|
95
|
+
only = arg.split('=').slice(1).join('=').split(',').map(item => item.trim()).filter(Boolean);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (arg.startsWith('--')) {
|
|
100
|
+
flags.push(arg);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!commandSet) {
|
|
105
|
+
command = arg;
|
|
106
|
+
commandSet = true;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const normalizedCommand = COMMAND_ALIASES[command] || command;
|
|
111
|
+
|
|
112
|
+
return { flags, command, normalizedCommand, threshold, out, planFile, only };
|
|
113
|
+
}
|
|
10
114
|
|
|
11
115
|
const HELP = `
|
|
12
116
|
claudex-setup v${version}
|
|
@@ -15,23 +119,63 @@ const HELP = `
|
|
|
15
119
|
|
|
16
120
|
Usage:
|
|
17
121
|
npx claudex-setup Run audit on current directory
|
|
122
|
+
npx claudex-setup discover Discover the highest-value improvements
|
|
18
123
|
npx claudex-setup audit Same as above
|
|
124
|
+
npx claudex-setup starter Alias for setup
|
|
19
125
|
npx claudex-setup setup Apply recommended configuration
|
|
20
126
|
npx claudex-setup setup --auto Apply all without prompts
|
|
21
|
-
npx claudex-setup
|
|
127
|
+
npx claudex-setup augment Repo-aware augment plan (no writes)
|
|
128
|
+
npx claudex-setup suggest-only Structured suggestion report (no writes)
|
|
129
|
+
npx claudex-setup plan Exportable proposal bundles with file previews
|
|
130
|
+
npx claudex-setup apply Apply ready proposal bundles with rollback manifest
|
|
131
|
+
npx claudex-setup governance Profiles, hooks, and pilot rollout guidance
|
|
132
|
+
npx claudex-setup benchmark Measure before/after impact in an isolated temp copy
|
|
133
|
+
npx claudex-setup deep-review AI-powered config review (uses Claude Code or API key)
|
|
22
134
|
npx claudex-setup interactive Step-by-step guided wizard
|
|
23
135
|
npx claudex-setup watch Monitor changes and re-audit live
|
|
24
136
|
npx claudex-setup badge Generate shields.io badge markdown
|
|
25
137
|
|
|
26
138
|
Options:
|
|
139
|
+
--threshold N Exit with code 1 if score is below N (useful for CI)
|
|
140
|
+
--out FILE Write JSON or markdown output to a file
|
|
141
|
+
--plan FILE Load a previously exported plan file
|
|
142
|
+
--only A,B Limit plan/apply to selected proposal ids or technique keys
|
|
143
|
+
--dry-run Preview apply without writing files
|
|
27
144
|
--verbose Show all recommendations (not just critical/high)
|
|
28
145
|
--json Output as JSON (for CI pipelines)
|
|
29
|
-
--
|
|
146
|
+
--auto Apply all generated setup files without prompting
|
|
147
|
+
--insights Enable anonymous usage insights (off by default)
|
|
30
148
|
--help Show this help
|
|
31
149
|
--version Show version
|
|
150
|
+
|
|
151
|
+
Examples:
|
|
152
|
+
npx claudex-setup
|
|
153
|
+
npx claudex-setup augment
|
|
154
|
+
npx claudex-setup suggest-only --json
|
|
155
|
+
npx claudex-setup plan --out claudex-plan.json
|
|
156
|
+
npx claudex-setup apply --plan claudex-plan.json --only hooks,commands
|
|
157
|
+
npx claudex-setup governance --json
|
|
158
|
+
npx claudex-setup benchmark --out benchmark.md
|
|
159
|
+
npx claudex-setup --json --threshold 60
|
|
160
|
+
npx claudex-setup setup --auto
|
|
161
|
+
npx claudex-setup interactive
|
|
162
|
+
|
|
163
|
+
Exit codes:
|
|
164
|
+
0 Success
|
|
165
|
+
1 Error, unknown command, or score below --threshold
|
|
32
166
|
`;
|
|
33
167
|
|
|
34
168
|
async function main() {
|
|
169
|
+
let parsed;
|
|
170
|
+
try {
|
|
171
|
+
parsed = parseArgs(args);
|
|
172
|
+
} catch (err) {
|
|
173
|
+
console.error(`\n Error: ${err.message}\n`);
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const { flags, command, normalizedCommand } = parsed;
|
|
178
|
+
|
|
35
179
|
if (flags.includes('--help') || command === 'help') {
|
|
36
180
|
console.log(HELP);
|
|
37
181
|
process.exit(0);
|
|
@@ -46,9 +190,29 @@ async function main() {
|
|
|
46
190
|
verbose: flags.includes('--verbose'),
|
|
47
191
|
json: flags.includes('--json'),
|
|
48
192
|
auto: flags.includes('--auto'),
|
|
193
|
+
dryRun: flags.includes('--dry-run'),
|
|
194
|
+
threshold: parsed.threshold !== null ? Number(parsed.threshold) : null,
|
|
195
|
+
out: parsed.out,
|
|
196
|
+
planFile: parsed.planFile,
|
|
197
|
+
only: parsed.only,
|
|
49
198
|
dir: process.cwd()
|
|
50
199
|
};
|
|
51
200
|
|
|
201
|
+
if (options.threshold !== null && (!Number.isFinite(options.threshold) || options.threshold < 0 || options.threshold > 100)) {
|
|
202
|
+
console.error('\n Error: --threshold must be a number between 0 and 100.\n');
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (!KNOWN_COMMANDS.includes(normalizedCommand)) {
|
|
207
|
+
const suggestion = suggestCommand(command);
|
|
208
|
+
console.error(`\n Error: Unknown command '${command}'.`);
|
|
209
|
+
if (suggestion) {
|
|
210
|
+
console.error(` Did you mean '${suggestion}'?`);
|
|
211
|
+
}
|
|
212
|
+
console.error(' Run claudex-setup --help for usage.\n');
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
|
|
52
216
|
if (!require('fs').existsSync(options.dir)) {
|
|
53
217
|
console.error(`\n Error: Directory not found: ${options.dir}`);
|
|
54
218
|
console.error(' Run claudex-setup from inside your project directory.\n');
|
|
@@ -56,14 +220,14 @@ async function main() {
|
|
|
56
220
|
}
|
|
57
221
|
|
|
58
222
|
try {
|
|
59
|
-
if (
|
|
223
|
+
if (normalizedCommand === 'badge') {
|
|
60
224
|
const { getBadgeMarkdown } = require('../src/badge');
|
|
61
225
|
const result = await audit({ ...options, silent: true });
|
|
62
226
|
console.log(getBadgeMarkdown(result.score));
|
|
63
227
|
console.log('');
|
|
64
228
|
console.log('Add this to your README.md');
|
|
65
229
|
process.exit(0);
|
|
66
|
-
} else if (
|
|
230
|
+
} else if (normalizedCommand === 'insights') {
|
|
67
231
|
const https = require('https');
|
|
68
232
|
const url = 'https://claudex-insights.claudex.workers.dev/v1/stats';
|
|
69
233
|
https.get(url, (res) => {
|
|
@@ -98,19 +262,58 @@ async function main() {
|
|
|
98
262
|
console.log(' Could not reach insights server. Run locally: npx claudex-setup');
|
|
99
263
|
});
|
|
100
264
|
return; // keep process alive for http
|
|
101
|
-
} else if (
|
|
265
|
+
} else if (normalizedCommand === 'augment' || normalizedCommand === 'suggest-only') {
|
|
266
|
+
const report = await analyzeProject({ ...options, mode: normalizedCommand });
|
|
267
|
+
printAnalysis(report, options);
|
|
268
|
+
} else if (normalizedCommand === 'plan') {
|
|
269
|
+
const bundle = await buildProposalBundle(options);
|
|
270
|
+
let artifact = null;
|
|
271
|
+
if (options.out) {
|
|
272
|
+
artifact = writePlanFile(bundle, options.out);
|
|
273
|
+
}
|
|
274
|
+
printProposalBundle(bundle, options);
|
|
275
|
+
if (options.out && !options.json) {
|
|
276
|
+
console.log(` Plan written to ${options.out}`);
|
|
277
|
+
if (artifact) {
|
|
278
|
+
console.log(` Activity log: ${artifact.relativePath}`);
|
|
279
|
+
}
|
|
280
|
+
console.log('');
|
|
281
|
+
}
|
|
282
|
+
} else if (normalizedCommand === 'apply') {
|
|
283
|
+
const result = await applyProposalBundle(options);
|
|
284
|
+
printApplyResult(result, options);
|
|
285
|
+
} else if (normalizedCommand === 'governance') {
|
|
286
|
+
const summary = getGovernanceSummary();
|
|
287
|
+
printGovernanceSummary(summary, options);
|
|
288
|
+
} else if (normalizedCommand === 'benchmark') {
|
|
289
|
+
const report = await runBenchmark(options);
|
|
290
|
+
if (options.out) {
|
|
291
|
+
writeBenchmarkReport(report, options.out);
|
|
292
|
+
}
|
|
293
|
+
printBenchmark(report, options);
|
|
294
|
+
if (options.out && !options.json) {
|
|
295
|
+
console.log(` Benchmark report written to ${options.out}`);
|
|
296
|
+
console.log('');
|
|
297
|
+
}
|
|
298
|
+
} else if (normalizedCommand === 'deep-review') {
|
|
102
299
|
const { deepReview } = require('../src/deep-review');
|
|
103
300
|
await deepReview(options);
|
|
104
|
-
} else if (
|
|
301
|
+
} else if (normalizedCommand === 'interactive') {
|
|
105
302
|
const { interactive } = require('../src/interactive');
|
|
106
303
|
await interactive(options);
|
|
107
|
-
} else if (
|
|
304
|
+
} else if (normalizedCommand === 'watch') {
|
|
108
305
|
const { watch } = require('../src/watch');
|
|
109
306
|
await watch(options);
|
|
110
|
-
} else if (
|
|
307
|
+
} else if (normalizedCommand === 'setup') {
|
|
111
308
|
await setup(options);
|
|
112
309
|
} else {
|
|
113
|
-
await audit(options);
|
|
310
|
+
const result = await audit(options);
|
|
311
|
+
if (options.threshold !== null && result.score < options.threshold) {
|
|
312
|
+
if (!options.json) {
|
|
313
|
+
console.error(` Threshold failed: score ${result.score}/100 is below required ${options.threshold}/100.\n`);
|
|
314
|
+
}
|
|
315
|
+
process.exit(1);
|
|
316
|
+
}
|
|
114
317
|
}
|
|
115
318
|
} catch (err) {
|
|
116
319
|
console.error(`\n Error: ${err.message}`);
|
package/package.json
CHANGED
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
|
+
};
|