claudex-setup 0.1.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/.claude/agents/security-reviewer.md +11 -0
- package/.claude/commands/review.md +6 -0
- package/.claude/commands/test.md +6 -0
- package/.claude/hooks/on-edit-lint.sh +5 -0
- package/.claude/rules/frontend.md +4 -0
- package/.claude/skills/fix-issue/SKILL.md +11 -0
- package/APF.md +121 -0
- package/CLAUDE.md +22 -0
- package/README.md +92 -0
- package/bin/cli.js +59 -0
- package/package.json +33 -0
- package/src/audit.js +134 -0
- package/src/context.js +117 -0
- package/src/index.js +4 -0
- package/src/setup.js +195 -0
- package/src/techniques.js +180 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-reviewer
|
|
3
|
+
description: Reviews code for security vulnerabilities
|
|
4
|
+
tools: [Read, Grep, Glob]
|
|
5
|
+
model: sonnet
|
|
6
|
+
---
|
|
7
|
+
Review code for security issues:
|
|
8
|
+
- Injection vulnerabilities (SQL, XSS, command injection)
|
|
9
|
+
- Authentication and authorization flaws
|
|
10
|
+
- Secrets or credentials in code
|
|
11
|
+
- Insecure data handling
|
package/APF.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# CLAUDEX-SETUP: Autonomous Project Framework
|
|
2
|
+
|
|
3
|
+
## Project Definition
|
|
4
|
+
|
|
5
|
+
**Product:** `claudex-setup` - CLI tool that audits and optimizes any project for Claude Code
|
|
6
|
+
**Revenue model:** Free CLI (audience) + Premium newsletter (revenue) + Consulting (high-ticket)
|
|
7
|
+
**Unfair advantage:** 972 verified techniques, 773 tested. Nobody else has this.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Phase 0: Launch Parameters
|
|
12
|
+
|
|
13
|
+
- **Budget:** $0 initial (Claude Max already active, n8n running)
|
|
14
|
+
- **Revenue target:** First $100 within 30 days
|
|
15
|
+
- **Timeline:** MVP in 1 week, launch in 2 weeks
|
|
16
|
+
- **Human provides:** npm account, GitHub repo, social media publish (or n8n automation)
|
|
17
|
+
- **Claude handles:** Everything else
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Strategy: 3-Layer Revenue
|
|
22
|
+
|
|
23
|
+
### Layer 1: Free CLI (Audience Builder)
|
|
24
|
+
```
|
|
25
|
+
npx claudex-setup → audit + setup your project for Claude Code
|
|
26
|
+
```
|
|
27
|
+
- Free, open source, zero friction
|
|
28
|
+
- Goal: 1,000 downloads in first month
|
|
29
|
+
- Converts to newsletter subscribers
|
|
30
|
+
|
|
31
|
+
### Layer 2: Newsletter / Content (Recurring Revenue)
|
|
32
|
+
```
|
|
33
|
+
"Claude Code Weekly" - 5 techniques you missed this week
|
|
34
|
+
```
|
|
35
|
+
- Free tier: weekly email with 3 tips
|
|
36
|
+
- Premium: daily tips + full technique database access ($10/month)
|
|
37
|
+
- Source: 972 items = 2+ years of unique daily content
|
|
38
|
+
|
|
39
|
+
### Layer 3: One-time Products (Cash Injection)
|
|
40
|
+
```
|
|
41
|
+
"The Claude Code Playbook" - complete guide, $29
|
|
42
|
+
```
|
|
43
|
+
- PDF/Notion guide built from catalog + by-usecase.md
|
|
44
|
+
- Upsell from free CLI users
|
|
45
|
+
- Zero marginal cost
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Build Plan (Priority Order)
|
|
50
|
+
|
|
51
|
+
### Week 1: CLI MVP + GitHub
|
|
52
|
+
- [ ] Build `claudex-setup` CLI (audit + setup)
|
|
53
|
+
- [ ] Publish to npm
|
|
54
|
+
- [ ] GitHub repo with good README
|
|
55
|
+
- [ ] Test on 3 real projects
|
|
56
|
+
|
|
57
|
+
### Week 2: Landing Page + Content Pipeline
|
|
58
|
+
- [ ] Landing page (Vercel, free)
|
|
59
|
+
- [ ] Newsletter setup (Buttondown free tier or similar)
|
|
60
|
+
- [ ] Write first 10 newsletter issues from catalog
|
|
61
|
+
- [ ] n8n automation: scheduled content publishing
|
|
62
|
+
|
|
63
|
+
### Week 3: Launch
|
|
64
|
+
- [ ] Post on Reddit r/ClaudeAI, r/ChatGPTPro
|
|
65
|
+
- [ ] Post on Hacker News (Show HN)
|
|
66
|
+
- [ ] Post on Dev.to, Medium
|
|
67
|
+
- [ ] GitHub: add to awesome-claude-code lists
|
|
68
|
+
- [ ] Product Hunt launch
|
|
69
|
+
|
|
70
|
+
### Week 4: Measure + Iterate
|
|
71
|
+
- [ ] Track: downloads, stars, subscribers, revenue
|
|
72
|
+
- [ ] Analyze: which techniques get most engagement
|
|
73
|
+
- [ ] Decide: continue / pivot / expand
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## What I Need From You
|
|
78
|
+
|
|
79
|
+
### One-time setup (5 minutes total):
|
|
80
|
+
1. **npm account** - create at npmjs.com if don't have, give me auth token
|
|
81
|
+
2. **GitHub** - create repo `claudex-setup` (or I use existing account)
|
|
82
|
+
3. **Social media** - either:
|
|
83
|
+
- Give me access to post (Twitter/X, Reddit)
|
|
84
|
+
- OR: I prepare posts, n8n publishes automatically
|
|
85
|
+
- OR: I prepare posts, you copy-paste once a day (1 min)
|
|
86
|
+
|
|
87
|
+
### When I ask for budget approval:
|
|
88
|
+
- Domain (~$12) - optional, can start with github.io
|
|
89
|
+
- Newsletter service - free tier available
|
|
90
|
+
- Everything else: $0
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Success Metrics
|
|
95
|
+
|
|
96
|
+
| Metric | Week 1 | Week 2 | Week 4 | Month 2 | Pivot if below |
|
|
97
|
+
|--------|--------|--------|--------|---------|---------------|
|
|
98
|
+
| npm downloads | 50 | 200 | 500 | 2,000 | <100 at week 4 |
|
|
99
|
+
| GitHub stars | 10 | 30 | 100 | 300 | <20 at week 4 |
|
|
100
|
+
| Newsletter subs | 0 | 20 | 100 | 300 | <30 at week 4 |
|
|
101
|
+
| Revenue | $0 | $0 | $50 | $500 | <$50 at month 2 |
|
|
102
|
+
|
|
103
|
+
## Stop Criteria
|
|
104
|
+
- Week 4: <100 downloads AND <20 stars → pivot approach
|
|
105
|
+
- Month 2: <$50 revenue → reassess product-market fit
|
|
106
|
+
- Month 3: <$200 revenue → stop or major pivot
|
|
107
|
+
|
|
108
|
+
## Continue Criteria
|
|
109
|
+
- Week 4: 500+ downloads → accelerate content
|
|
110
|
+
- Month 2: $200+ revenue → invest in premium features
|
|
111
|
+
- Month 3: $1,000+ revenue → dedicated infrastructure
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Decision Log
|
|
116
|
+
|
|
117
|
+
| Date | Decision | Reasoning |
|
|
118
|
+
|------|----------|-----------|
|
|
119
|
+
| 2026-03-30 | Start with CLI + newsletter model | Lowest cost, fastest to market, leverages existing 972 items |
|
|
120
|
+
| 2026-03-30 | Free CLI, premium content | CLI builds audience, content monetizes. Proven model. |
|
|
121
|
+
| 2026-03-30 | n8n for automation | Already running on Docker, zero additional cost |
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Project Instructions
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
<!-- Add a Mermaid diagram of your project structure -->
|
|
5
|
+
|
|
6
|
+
## Stack
|
|
7
|
+
Node.js
|
|
8
|
+
|
|
9
|
+
## Build & Test
|
|
10
|
+
```bash
|
|
11
|
+
# Add your build command
|
|
12
|
+
# Add your test command
|
|
13
|
+
# Add your lint command
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Code Style
|
|
17
|
+
- Follow existing patterns in the codebase
|
|
18
|
+
- Write tests for new features
|
|
19
|
+
|
|
20
|
+
## Workflow
|
|
21
|
+
- Verify changes with tests before committing
|
|
22
|
+
- Use descriptive commit messages
|
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# claudex-setup
|
|
2
|
+
|
|
3
|
+
> Audit and optimize any project for Claude Code. Powered by 972 verified techniques.
|
|
4
|
+
|
|
5
|
+
One command to make your project Claude Code-ready.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Audit your project
|
|
11
|
+
npx claudex-setup
|
|
12
|
+
|
|
13
|
+
# Apply recommended configuration
|
|
14
|
+
npx claudex-setup setup
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## What it does
|
|
18
|
+
|
|
19
|
+
**Audit** scans your project and scores it against 12 critical Claude Code best practices:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
claudex-setup audit
|
|
23
|
+
═══════════════════════════════════════
|
|
24
|
+
Detected: React, TypeScript
|
|
25
|
+
|
|
26
|
+
██████████████░░░░░░ 71/100
|
|
27
|
+
|
|
28
|
+
✅ Passing
|
|
29
|
+
CLAUDE.md project instructions
|
|
30
|
+
Hooks for automation
|
|
31
|
+
Custom slash commands
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
🔴 Critical
|
|
35
|
+
Verification criteria in CLAUDE.md
|
|
36
|
+
→ Add test/lint commands so Claude can verify its own work.
|
|
37
|
+
|
|
38
|
+
Run npx claudex-setup setup to fix automatically
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Setup** creates the missing configuration automatically:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
✅ Created CLAUDE.md
|
|
45
|
+
✅ Created .claude/hooks/on-edit-lint.sh
|
|
46
|
+
✅ Created .claude/commands/test.md
|
|
47
|
+
✅ Created .claude/commands/review.md
|
|
48
|
+
✅ Created .claude/skills/fix-issue/SKILL.md
|
|
49
|
+
✅ Created .claude/agents/security-reviewer.md
|
|
50
|
+
|
|
51
|
+
7 files created.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## What it checks
|
|
55
|
+
|
|
56
|
+
| Check | Impact | What |
|
|
57
|
+
|-------|--------|------|
|
|
58
|
+
| CLAUDE.md | Critical | Project instructions for Claude |
|
|
59
|
+
| Verification | Critical | Test/lint commands for self-checking |
|
|
60
|
+
| Hooks | High | Automation on file edits |
|
|
61
|
+
| Commands | High | Custom slash commands |
|
|
62
|
+
| Mermaid diagram | High | Architecture visualization (73% token savings) |
|
|
63
|
+
| XML tags | High | Structured prompts |
|
|
64
|
+
| Skills | Medium | Domain-specific workflows |
|
|
65
|
+
| Rules | Medium | Path-specific coding conventions |
|
|
66
|
+
| Agents | Medium | Specialized subagents |
|
|
67
|
+
| MCP servers | Medium | External tool integration |
|
|
68
|
+
| Permissions | Medium | Security configuration |
|
|
69
|
+
| .gitignore | High | Track .claude/ in version control |
|
|
70
|
+
|
|
71
|
+
## Options
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx claudex-setup # Audit (default)
|
|
75
|
+
npx claudex-setup audit # Audit explicitly
|
|
76
|
+
npx claudex-setup audit --verbose # Show all recommendations
|
|
77
|
+
npx claudex-setup audit --json # JSON output
|
|
78
|
+
npx claudex-setup setup # Apply fixes
|
|
79
|
+
npx claudex-setup --help # Help
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Stack Detection
|
|
83
|
+
|
|
84
|
+
Automatically detects: React, Vue, Angular, Next.js, Python, Django, FastAPI, Node.js, TypeScript, Rust, Go, Docker — and tailors recommendations.
|
|
85
|
+
|
|
86
|
+
## Why
|
|
87
|
+
|
|
88
|
+
Claude Code is powerful but most projects are barely optimized for it. A proper CLAUDE.md, hooks, and skills can **3-5x your productivity**. This tool applies the knowledge from [CLAUDEX](https://github.com/DnaFin/claudex) — a research catalog of 972 verified Claude Code techniques.
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { audit } = require('../src/audit');
|
|
4
|
+
const { setup } = require('../src/setup');
|
|
5
|
+
const { version } = require('../package.json');
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const command = args[0] || 'audit';
|
|
9
|
+
const flags = args.filter(a => a.startsWith('--'));
|
|
10
|
+
|
|
11
|
+
const HELP = `
|
|
12
|
+
claudex-setup v${version}
|
|
13
|
+
Audit and optimize any project for Claude Code.
|
|
14
|
+
Powered by 972 verified techniques.
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
npx claudex-setup Run audit on current directory
|
|
18
|
+
npx claudex-setup audit Same as above
|
|
19
|
+
npx claudex-setup setup Apply recommended configuration
|
|
20
|
+
npx claudex-setup setup --auto Apply all recommendations without prompts
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
--verbose Show detailed analysis
|
|
24
|
+
--json Output as JSON
|
|
25
|
+
--help Show this help
|
|
26
|
+
--version Show version
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
async function main() {
|
|
30
|
+
if (flags.includes('--help') || command === 'help') {
|
|
31
|
+
console.log(HELP);
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (flags.includes('--version') || command === 'version') {
|
|
36
|
+
console.log(version);
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const options = {
|
|
41
|
+
verbose: flags.includes('--verbose'),
|
|
42
|
+
json: flags.includes('--json'),
|
|
43
|
+
auto: flags.includes('--auto'),
|
|
44
|
+
dir: process.cwd()
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
if (command === 'setup') {
|
|
49
|
+
await setup(options);
|
|
50
|
+
} else {
|
|
51
|
+
await audit(options);
|
|
52
|
+
}
|
|
53
|
+
} catch (err) {
|
|
54
|
+
console.error(`\n Error: ${err.message}`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claudex-setup",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Audit and optimize any project for Claude Code. Powered by 972 verified techniques.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"claudex-setup": "bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node bin/cli.js",
|
|
11
|
+
"test": "node test/run.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"claude",
|
|
15
|
+
"claude-code",
|
|
16
|
+
"anthropic",
|
|
17
|
+
"ai",
|
|
18
|
+
"developer-tools",
|
|
19
|
+
"productivity",
|
|
20
|
+
"audit",
|
|
21
|
+
"setup",
|
|
22
|
+
"cli"
|
|
23
|
+
],
|
|
24
|
+
"author": "CLAUDEX Project",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/DnaFin/claudex-setup"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18.0.0"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/audit.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit engine - evaluates project against CLAUDEX technique database.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { TECHNIQUES, STACKS } = require('./techniques');
|
|
6
|
+
const { ProjectContext } = require('./context');
|
|
7
|
+
|
|
8
|
+
const COLORS = {
|
|
9
|
+
reset: '\x1b[0m',
|
|
10
|
+
bold: '\x1b[1m',
|
|
11
|
+
dim: '\x1b[2m',
|
|
12
|
+
red: '\x1b[31m',
|
|
13
|
+
green: '\x1b[32m',
|
|
14
|
+
yellow: '\x1b[33m',
|
|
15
|
+
blue: '\x1b[36m',
|
|
16
|
+
magenta: '\x1b[35m',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function colorize(text, color) {
|
|
20
|
+
return `${COLORS[color] || ''}${text}${COLORS.reset}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function progressBar(score, max = 100, width = 20) {
|
|
24
|
+
const filled = Math.round((score / max) * width);
|
|
25
|
+
const empty = width - filled;
|
|
26
|
+
const color = score >= 70 ? 'green' : score >= 40 ? 'yellow' : 'red';
|
|
27
|
+
return colorize('█'.repeat(filled), color) + colorize('░'.repeat(empty), 'dim');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function audit(options) {
|
|
31
|
+
const ctx = new ProjectContext(options.dir);
|
|
32
|
+
const stacks = ctx.detectStacks(STACKS);
|
|
33
|
+
const results = [];
|
|
34
|
+
|
|
35
|
+
// Run all technique checks
|
|
36
|
+
for (const [key, technique] of Object.entries(TECHNIQUES)) {
|
|
37
|
+
const passed = technique.check(ctx);
|
|
38
|
+
results.push({
|
|
39
|
+
key,
|
|
40
|
+
...technique,
|
|
41
|
+
passed,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const passed = results.filter(r => r.passed);
|
|
46
|
+
const failed = results.filter(r => !r.passed);
|
|
47
|
+
const critical = failed.filter(r => r.impact === 'critical');
|
|
48
|
+
const high = failed.filter(r => r.impact === 'high');
|
|
49
|
+
const medium = failed.filter(r => r.impact === 'medium');
|
|
50
|
+
|
|
51
|
+
// Calculate score
|
|
52
|
+
const weights = { critical: 15, high: 10, medium: 5 };
|
|
53
|
+
const maxScore = results.reduce((sum, r) => sum + (weights[r.impact] || 5), 0);
|
|
54
|
+
const earnedScore = passed.reduce((sum, r) => sum + (weights[r.impact] || 5), 0);
|
|
55
|
+
const score = Math.round((earnedScore / maxScore) * 100);
|
|
56
|
+
|
|
57
|
+
if (options.json) {
|
|
58
|
+
console.log(JSON.stringify({ score, stacks, passed: passed.length, failed: failed.length, results }, null, 2));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Display results
|
|
63
|
+
console.log('');
|
|
64
|
+
console.log(colorize(' claudex-setup audit', 'bold'));
|
|
65
|
+
console.log(colorize(' ═══════════════════════════════════════', 'dim'));
|
|
66
|
+
console.log(colorize(` Scanning: ${options.dir}`, 'dim'));
|
|
67
|
+
|
|
68
|
+
if (stacks.length > 0) {
|
|
69
|
+
console.log(colorize(` Detected: ${stacks.map(s => s.label).join(', ')}`, 'blue'));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log('');
|
|
73
|
+
|
|
74
|
+
// Score
|
|
75
|
+
console.log(` ${progressBar(score)} ${colorize(`${score}/100`, 'bold')}`);
|
|
76
|
+
console.log('');
|
|
77
|
+
|
|
78
|
+
// Passed
|
|
79
|
+
if (passed.length > 0) {
|
|
80
|
+
console.log(colorize(' ✅ Passing', 'green'));
|
|
81
|
+
for (const r of passed) {
|
|
82
|
+
console.log(colorize(` ${r.name}`, 'dim'));
|
|
83
|
+
}
|
|
84
|
+
console.log('');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Failed - by priority
|
|
88
|
+
if (critical.length > 0) {
|
|
89
|
+
console.log(colorize(' 🔴 Critical (fix immediately)', 'red'));
|
|
90
|
+
for (const r of critical) {
|
|
91
|
+
console.log(` ${colorize(r.name, 'bold')}`);
|
|
92
|
+
console.log(colorize(` → ${r.fix}`, 'dim'));
|
|
93
|
+
}
|
|
94
|
+
console.log('');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (high.length > 0) {
|
|
98
|
+
console.log(colorize(' 🟡 High Impact', 'yellow'));
|
|
99
|
+
for (const r of high) {
|
|
100
|
+
console.log(` ${colorize(r.name, 'bold')}`);
|
|
101
|
+
console.log(colorize(` → ${r.fix}`, 'dim'));
|
|
102
|
+
}
|
|
103
|
+
console.log('');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (medium.length > 0 && options.verbose) {
|
|
107
|
+
console.log(colorize(' 🔵 Recommended', 'blue'));
|
|
108
|
+
for (const r of medium) {
|
|
109
|
+
console.log(` ${colorize(r.name, 'bold')}`);
|
|
110
|
+
console.log(colorize(` → ${r.fix}`, 'dim'));
|
|
111
|
+
}
|
|
112
|
+
console.log('');
|
|
113
|
+
} else if (medium.length > 0) {
|
|
114
|
+
console.log(colorize(` 🔵 ${medium.length} more recommendations (use --verbose)`, 'blue'));
|
|
115
|
+
console.log('');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Summary
|
|
119
|
+
console.log(colorize(' ─────────────────────────────────────', 'dim'));
|
|
120
|
+
console.log(` ${colorize(`${passed.length}/${results.length}`, 'bold')} checks passing`);
|
|
121
|
+
|
|
122
|
+
if (failed.length > 0) {
|
|
123
|
+
console.log(` Run ${colorize('npx claudex-setup setup', 'bold')} to fix automatically`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
console.log('');
|
|
127
|
+
console.log(colorize(' Powered by CLAUDEX - 972 verified Claude Code techniques', 'dim'));
|
|
128
|
+
console.log(colorize(' https://github.com/naorp/claudex-setup', 'dim'));
|
|
129
|
+
console.log('');
|
|
130
|
+
|
|
131
|
+
return { score, passed: passed.length, failed: failed.length, stacks };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
module.exports = { audit };
|
package/src/context.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project context scanner - reads project files to evaluate against techniques.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
class ProjectContext {
|
|
9
|
+
constructor(dir) {
|
|
10
|
+
this.dir = dir;
|
|
11
|
+
this.files = [];
|
|
12
|
+
this._cache = {};
|
|
13
|
+
this._scan();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_scan() {
|
|
17
|
+
try {
|
|
18
|
+
const entries = fs.readdirSync(this.dir, { withFileTypes: true });
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
if (entry.name.startsWith('.') && entry.name !== '.claude' && entry.name !== '.gitignore') continue;
|
|
21
|
+
if (entry.name === 'node_modules' || entry.name === '__pycache__') continue;
|
|
22
|
+
if (entry.isFile()) {
|
|
23
|
+
this.files.push(entry.name);
|
|
24
|
+
} else if (entry.isDirectory()) {
|
|
25
|
+
this.files.push(entry.name + '/');
|
|
26
|
+
// Scan .claude/ subdirectories
|
|
27
|
+
if (entry.name === '.claude') {
|
|
28
|
+
this._scanSubdir('.claude');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
} catch (err) {
|
|
33
|
+
// Directory might not be readable
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
_scanSubdir(subdir) {
|
|
38
|
+
try {
|
|
39
|
+
const fullPath = path.join(this.dir, subdir);
|
|
40
|
+
const entries = fs.readdirSync(fullPath, { withFileTypes: true });
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
if (entry.isDirectory()) {
|
|
43
|
+
this._scanSubdir(path.join(subdir, entry.name));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} catch (err) {
|
|
47
|
+
// Subdirectory might not exist
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
hasDir(dirPath) {
|
|
52
|
+
const fullPath = path.join(this.dir, dirPath);
|
|
53
|
+
try {
|
|
54
|
+
return fs.statSync(fullPath).isDirectory();
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
dirFiles(dirPath) {
|
|
61
|
+
const fullPath = path.join(this.dir, dirPath);
|
|
62
|
+
try {
|
|
63
|
+
return fs.readdirSync(fullPath).filter(f => !f.startsWith('.'));
|
|
64
|
+
} catch {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fileContent(filePath) {
|
|
70
|
+
if (this._cache[filePath] !== undefined) return this._cache[filePath];
|
|
71
|
+
const fullPath = path.join(this.dir, filePath);
|
|
72
|
+
try {
|
|
73
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
74
|
+
this._cache[filePath] = content;
|
|
75
|
+
return content;
|
|
76
|
+
} catch {
|
|
77
|
+
this._cache[filePath] = null;
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
jsonFile(filePath) {
|
|
83
|
+
const content = this.fileContent(filePath);
|
|
84
|
+
if (!content) return null;
|
|
85
|
+
try {
|
|
86
|
+
return JSON.parse(content);
|
|
87
|
+
} catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
detectStacks(STACKS) {
|
|
93
|
+
const detected = [];
|
|
94
|
+
for (const [key, stack] of Object.entries(STACKS)) {
|
|
95
|
+
const hasFile = stack.files.some(f => {
|
|
96
|
+
return this.files.some(pf => pf.startsWith(f));
|
|
97
|
+
});
|
|
98
|
+
if (!hasFile) continue;
|
|
99
|
+
|
|
100
|
+
let contentMatch = true;
|
|
101
|
+
for (const [file, needle] of Object.entries(stack.content)) {
|
|
102
|
+
const content = this.fileContent(file);
|
|
103
|
+
if (!content || !content.includes(needle)) {
|
|
104
|
+
contentMatch = false;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (hasFile && contentMatch) {
|
|
110
|
+
detected.push({ key, label: stack.label });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return detected;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = { ProjectContext };
|
package/src/index.js
ADDED
package/src/setup.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup engine - applies recommended Claude Code configuration to a project.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { TECHNIQUES, STACKS } = require('./techniques');
|
|
8
|
+
const { ProjectContext } = require('./context');
|
|
9
|
+
const { audit } = require('./audit');
|
|
10
|
+
|
|
11
|
+
const TEMPLATES = {
|
|
12
|
+
'claude-md': (stacks) => {
|
|
13
|
+
const stackNames = stacks.map(s => s.label).join(', ') || 'General';
|
|
14
|
+
return `# Project Instructions
|
|
15
|
+
|
|
16
|
+
## Architecture
|
|
17
|
+
<!-- Add a Mermaid diagram of your project structure -->
|
|
18
|
+
|
|
19
|
+
## Stack
|
|
20
|
+
${stackNames}
|
|
21
|
+
|
|
22
|
+
## Build & Test
|
|
23
|
+
\`\`\`bash
|
|
24
|
+
# Add your build command
|
|
25
|
+
# Add your test command
|
|
26
|
+
# Add your lint command
|
|
27
|
+
\`\`\`
|
|
28
|
+
|
|
29
|
+
## Code Style
|
|
30
|
+
- Follow existing patterns in the codebase
|
|
31
|
+
- Write tests for new features
|
|
32
|
+
|
|
33
|
+
## Workflow
|
|
34
|
+
- Verify changes with tests before committing
|
|
35
|
+
- Use descriptive commit messages
|
|
36
|
+
`;
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
'hooks': () => ({
|
|
40
|
+
'on-edit-lint.sh': `#!/bin/bash
|
|
41
|
+
# PostToolUse hook - auto-check after file edits
|
|
42
|
+
# Customize the linter command for your project
|
|
43
|
+
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
|
|
44
|
+
echo "[$TIMESTAMP] File changed: $(cat -)" >> .claude/logs/changes.txt
|
|
45
|
+
`,
|
|
46
|
+
}),
|
|
47
|
+
|
|
48
|
+
'commands': () => ({
|
|
49
|
+
'test.md': `Run the test suite and report results.
|
|
50
|
+
|
|
51
|
+
## Steps:
|
|
52
|
+
1. Run the project's test command
|
|
53
|
+
2. If tests fail, analyze the failures
|
|
54
|
+
3. Report: total, passed, failed, and any error details
|
|
55
|
+
`,
|
|
56
|
+
'review.md': `Review the current changes for quality and correctness.
|
|
57
|
+
|
|
58
|
+
## Steps:
|
|
59
|
+
1. Run \`git diff\` to see all changes
|
|
60
|
+
2. Check for: bugs, security issues, missing tests, code style
|
|
61
|
+
3. Provide actionable feedback
|
|
62
|
+
`,
|
|
63
|
+
}),
|
|
64
|
+
|
|
65
|
+
'skills': () => ({
|
|
66
|
+
'fix-issue/SKILL.md': `---
|
|
67
|
+
name: fix-issue
|
|
68
|
+
description: Fix a GitHub issue by number
|
|
69
|
+
---
|
|
70
|
+
Fix the GitHub issue: $ARGUMENTS
|
|
71
|
+
|
|
72
|
+
1. Read the issue details
|
|
73
|
+
2. Search the codebase for relevant files
|
|
74
|
+
3. Implement the fix
|
|
75
|
+
4. Write tests
|
|
76
|
+
5. Create a descriptive commit
|
|
77
|
+
`,
|
|
78
|
+
}),
|
|
79
|
+
|
|
80
|
+
'rules': (stacks) => {
|
|
81
|
+
const rules = {};
|
|
82
|
+
const hasTS = stacks.some(s => s.key === 'typescript');
|
|
83
|
+
const hasPython = stacks.some(s => s.key === 'python');
|
|
84
|
+
|
|
85
|
+
if (hasTS || stacks.some(s => ['react', 'vue', 'angular', 'nextjs', 'node'].includes(s.key))) {
|
|
86
|
+
rules['frontend.md'] = `When editing frontend files (*.tsx, *.jsx, *.vue):
|
|
87
|
+
- Use functional components with hooks
|
|
88
|
+
- Follow existing component patterns
|
|
89
|
+
- Add prop types or TypeScript interfaces
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
if (hasPython) {
|
|
93
|
+
rules['python.md'] = `When editing Python files:
|
|
94
|
+
- Use type hints for function signatures
|
|
95
|
+
- Follow PEP 8 conventions
|
|
96
|
+
- Use f-strings for formatting
|
|
97
|
+
`;
|
|
98
|
+
}
|
|
99
|
+
return rules;
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
'agents': () => ({
|
|
103
|
+
'security-reviewer.md': `---
|
|
104
|
+
name: security-reviewer
|
|
105
|
+
description: Reviews code for security vulnerabilities
|
|
106
|
+
tools: [Read, Grep, Glob]
|
|
107
|
+
model: sonnet
|
|
108
|
+
---
|
|
109
|
+
Review code for security issues:
|
|
110
|
+
- Injection vulnerabilities (SQL, XSS, command injection)
|
|
111
|
+
- Authentication and authorization flaws
|
|
112
|
+
- Secrets or credentials in code
|
|
113
|
+
- Insecure data handling
|
|
114
|
+
`,
|
|
115
|
+
}),
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
async function setup(options) {
|
|
119
|
+
const ctx = new ProjectContext(options.dir);
|
|
120
|
+
const stacks = ctx.detectStacks(STACKS);
|
|
121
|
+
|
|
122
|
+
console.log('');
|
|
123
|
+
console.log('\x1b[1m claudex-setup\x1b[0m');
|
|
124
|
+
console.log('\x1b[2m ═══════════════════════════════════════\x1b[0m');
|
|
125
|
+
|
|
126
|
+
if (stacks.length > 0) {
|
|
127
|
+
console.log(`\x1b[36m Detected: ${stacks.map(s => s.label).join(', ')}\x1b[0m`);
|
|
128
|
+
}
|
|
129
|
+
console.log('');
|
|
130
|
+
|
|
131
|
+
let created = 0;
|
|
132
|
+
|
|
133
|
+
for (const [key, technique] of Object.entries(TECHNIQUES)) {
|
|
134
|
+
if (technique.passed || technique.check(ctx)) continue;
|
|
135
|
+
if (!technique.template) continue;
|
|
136
|
+
|
|
137
|
+
const template = TEMPLATES[technique.template];
|
|
138
|
+
if (!template) continue;
|
|
139
|
+
|
|
140
|
+
const result = template(stacks);
|
|
141
|
+
|
|
142
|
+
if (typeof result === 'string') {
|
|
143
|
+
// Single file template (like CLAUDE.md)
|
|
144
|
+
const filePath = key === 'claudeMd' ? 'CLAUDE.md' : key;
|
|
145
|
+
const fullPath = path.join(options.dir, filePath);
|
|
146
|
+
|
|
147
|
+
if (!fs.existsSync(fullPath)) {
|
|
148
|
+
fs.writeFileSync(fullPath, result, 'utf8');
|
|
149
|
+
console.log(` \x1b[32m✅\x1b[0m Created ${filePath}`);
|
|
150
|
+
created++;
|
|
151
|
+
}
|
|
152
|
+
} else if (typeof result === 'object') {
|
|
153
|
+
// Multiple files template (hooks, commands, etc)
|
|
154
|
+
const dirMap = {
|
|
155
|
+
'hooks': '.claude/hooks',
|
|
156
|
+
'commands': '.claude/commands',
|
|
157
|
+
'skills': '.claude/skills',
|
|
158
|
+
'rules': '.claude/rules',
|
|
159
|
+
'agents': '.claude/agents',
|
|
160
|
+
};
|
|
161
|
+
const targetDir = dirMap[technique.template] || `.claude/${technique.template}`;
|
|
162
|
+
const fullDir = path.join(options.dir, targetDir);
|
|
163
|
+
|
|
164
|
+
if (!fs.existsSync(fullDir)) {
|
|
165
|
+
fs.mkdirSync(fullDir, { recursive: true });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
for (const [fileName, content] of Object.entries(result)) {
|
|
169
|
+
const filePath = path.join(fullDir, fileName);
|
|
170
|
+
const fileDir = path.dirname(filePath);
|
|
171
|
+
if (!fs.existsSync(fileDir)) {
|
|
172
|
+
fs.mkdirSync(fileDir, { recursive: true });
|
|
173
|
+
}
|
|
174
|
+
if (!fs.existsSync(filePath)) {
|
|
175
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
176
|
+
console.log(` \x1b[32m✅\x1b[0m Created ${path.relative(options.dir, filePath)}`);
|
|
177
|
+
created++;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (created === 0) {
|
|
184
|
+
console.log(' \x1b[32m✅\x1b[0m Project already well configured!');
|
|
185
|
+
} else {
|
|
186
|
+
console.log('');
|
|
187
|
+
console.log(` \x1b[1m${created} files created.\x1b[0m`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
console.log('');
|
|
191
|
+
console.log(' Run \x1b[1mnpx claudex-setup audit\x1b[0m to check your score.');
|
|
192
|
+
console.log('');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
module.exports = { setup };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLAUDEX Technique Database
|
|
3
|
+
* Curated from 972 verified techniques, filtered to actionable setup recommendations.
|
|
4
|
+
* Each technique includes: what to check, how to fix, impact level.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const TECHNIQUES = {
|
|
8
|
+
// === CRITICAL (must-have for any project) ===
|
|
9
|
+
claudeMd: {
|
|
10
|
+
id: 1,
|
|
11
|
+
name: 'CLAUDE.md project instructions',
|
|
12
|
+
check: (ctx) => ctx.files.includes('CLAUDE.md') || ctx.files.includes('.claude/CLAUDE.md'),
|
|
13
|
+
impact: 'critical',
|
|
14
|
+
rating: 5,
|
|
15
|
+
category: 'memory',
|
|
16
|
+
fix: 'Create CLAUDE.md with project-specific instructions, build commands, and coding conventions.',
|
|
17
|
+
template: 'claude-md'
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
hooks: {
|
|
21
|
+
id: 19,
|
|
22
|
+
name: 'Hooks for automation',
|
|
23
|
+
check: (ctx) => ctx.hasDir('.claude/hooks') && ctx.dirFiles('.claude/hooks').length > 0,
|
|
24
|
+
impact: 'high',
|
|
25
|
+
rating: 4,
|
|
26
|
+
category: 'automation',
|
|
27
|
+
fix: 'Add hooks for auto-lint, auto-test, or file change tracking.',
|
|
28
|
+
template: 'hooks'
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
customCommands: {
|
|
32
|
+
id: 20,
|
|
33
|
+
name: 'Custom slash commands',
|
|
34
|
+
check: (ctx) => ctx.hasDir('.claude/commands') && ctx.dirFiles('.claude/commands').length > 0,
|
|
35
|
+
impact: 'high',
|
|
36
|
+
rating: 4,
|
|
37
|
+
category: 'workflow',
|
|
38
|
+
fix: 'Create custom commands for repeated workflows (/test, /deploy, /review).',
|
|
39
|
+
template: 'commands'
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
skills: {
|
|
43
|
+
id: 21,
|
|
44
|
+
name: 'Custom skills',
|
|
45
|
+
check: (ctx) => ctx.hasDir('.claude/skills') && ctx.dirFiles('.claude/skills').length > 0,
|
|
46
|
+
impact: 'medium',
|
|
47
|
+
rating: 4,
|
|
48
|
+
category: 'workflow',
|
|
49
|
+
fix: 'Add skills for domain-specific workflows.',
|
|
50
|
+
template: 'skills'
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
pathRules: {
|
|
54
|
+
id: 3,
|
|
55
|
+
name: 'Path-specific rules',
|
|
56
|
+
check: (ctx) => ctx.hasDir('.claude/rules') && ctx.dirFiles('.claude/rules').length > 0,
|
|
57
|
+
impact: 'medium',
|
|
58
|
+
rating: 4,
|
|
59
|
+
category: 'memory',
|
|
60
|
+
fix: 'Add rules for different file types (frontend vs backend conventions).',
|
|
61
|
+
template: 'rules'
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
gitIgnoreClaudeTracked: {
|
|
65
|
+
id: 976,
|
|
66
|
+
name: '.claude/ tracked in git',
|
|
67
|
+
check: (ctx) => {
|
|
68
|
+
if (!ctx.fileContent('.gitignore')) return true; // no gitignore = ok
|
|
69
|
+
const content = ctx.fileContent('.gitignore');
|
|
70
|
+
return !content.includes('.claude/') || content.includes('!.claude/');
|
|
71
|
+
},
|
|
72
|
+
impact: 'high',
|
|
73
|
+
rating: 4,
|
|
74
|
+
category: 'git',
|
|
75
|
+
fix: 'Remove .claude/ from .gitignore (keep .claude/settings.local.json ignored).',
|
|
76
|
+
template: null
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
mermaidArchitecture: {
|
|
80
|
+
id: 51,
|
|
81
|
+
name: 'Mermaid architecture diagram',
|
|
82
|
+
check: (ctx) => {
|
|
83
|
+
const md = ctx.fileContent('CLAUDE.md') || '';
|
|
84
|
+
return md.includes('mermaid') || md.includes('graph ') || md.includes('flowchart ');
|
|
85
|
+
},
|
|
86
|
+
impact: 'high',
|
|
87
|
+
rating: 5,
|
|
88
|
+
category: 'memory',
|
|
89
|
+
fix: 'Add a Mermaid diagram to CLAUDE.md showing project architecture. Saves 73% tokens vs prose.',
|
|
90
|
+
template: 'mermaid'
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
verificationLoop: {
|
|
94
|
+
id: 93,
|
|
95
|
+
name: 'Verification criteria in CLAUDE.md',
|
|
96
|
+
check: (ctx) => {
|
|
97
|
+
const md = ctx.fileContent('CLAUDE.md') || '';
|
|
98
|
+
return md.includes('test') || md.includes('verify') || md.includes('lint') || md.includes('check');
|
|
99
|
+
},
|
|
100
|
+
impact: 'critical',
|
|
101
|
+
rating: 5,
|
|
102
|
+
category: 'quality',
|
|
103
|
+
fix: 'Add test/lint/build commands to CLAUDE.md so Claude can verify its own work.',
|
|
104
|
+
template: null
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
agents: {
|
|
108
|
+
id: 22,
|
|
109
|
+
name: 'Custom agents',
|
|
110
|
+
check: (ctx) => ctx.hasDir('.claude/agents') && ctx.dirFiles('.claude/agents').length > 0,
|
|
111
|
+
impact: 'medium',
|
|
112
|
+
rating: 4,
|
|
113
|
+
category: 'workflow',
|
|
114
|
+
fix: 'Create specialized agents (security-reviewer, test-writer) in .claude/agents/.',
|
|
115
|
+
template: 'agents'
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
mcpServers: {
|
|
119
|
+
id: 18,
|
|
120
|
+
name: 'MCP servers configured',
|
|
121
|
+
check: (ctx) => {
|
|
122
|
+
const settings = ctx.jsonFile('.claude/settings.local.json') || ctx.jsonFile('.claude/settings.json');
|
|
123
|
+
return settings && settings.mcpServers && Object.keys(settings.mcpServers).length > 0;
|
|
124
|
+
},
|
|
125
|
+
impact: 'medium',
|
|
126
|
+
rating: 3,
|
|
127
|
+
category: 'tools',
|
|
128
|
+
fix: 'Configure MCP servers for external tool integration (database, APIs, etc).',
|
|
129
|
+
template: null
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
settingsPermissions: {
|
|
133
|
+
id: 24,
|
|
134
|
+
name: 'Permission configuration',
|
|
135
|
+
check: (ctx) => {
|
|
136
|
+
const settings = ctx.jsonFile('.claude/settings.local.json') || ctx.jsonFile('.claude/settings.json');
|
|
137
|
+
return settings && settings.permissions;
|
|
138
|
+
},
|
|
139
|
+
impact: 'medium',
|
|
140
|
+
rating: 4,
|
|
141
|
+
category: 'security',
|
|
142
|
+
fix: 'Configure allow/deny permission lists for safe tool usage.',
|
|
143
|
+
template: null
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
xmlTags: {
|
|
147
|
+
id: 96,
|
|
148
|
+
name: 'XML tags for structured prompts',
|
|
149
|
+
check: (ctx) => {
|
|
150
|
+
const md = ctx.fileContent('CLAUDE.md') || '';
|
|
151
|
+
return md.includes('<') && md.includes('>') && (
|
|
152
|
+
md.includes('<constraints') || md.includes('<rules') ||
|
|
153
|
+
md.includes('<validation') || md.includes('<instructions')
|
|
154
|
+
);
|
|
155
|
+
},
|
|
156
|
+
impact: 'high',
|
|
157
|
+
rating: 5,
|
|
158
|
+
category: 'prompting',
|
|
159
|
+
fix: 'Use XML tags (<constraints>, <validation>) in CLAUDE.md for unambiguous instructions.',
|
|
160
|
+
template: null
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Stack detection
|
|
165
|
+
const STACKS = {
|
|
166
|
+
react: { files: ['package.json'], content: { 'package.json': 'react' }, label: 'React' },
|
|
167
|
+
vue: { files: ['package.json'], content: { 'package.json': 'vue' }, label: 'Vue' },
|
|
168
|
+
angular: { files: ['angular.json'], content: {}, label: 'Angular' },
|
|
169
|
+
nextjs: { files: ['next.config'], content: {}, label: 'Next.js' },
|
|
170
|
+
python: { files: ['requirements.txt', 'setup.py', 'pyproject.toml', 'Pipfile'], content: {}, label: 'Python' },
|
|
171
|
+
django: { files: ['manage.py'], content: {}, label: 'Django' },
|
|
172
|
+
fastapi: { files: ['requirements.txt'], content: { 'requirements.txt': 'fastapi' }, label: 'FastAPI' },
|
|
173
|
+
node: { files: ['package.json'], content: {}, label: 'Node.js' },
|
|
174
|
+
typescript: { files: ['tsconfig.json'], content: {}, label: 'TypeScript' },
|
|
175
|
+
rust: { files: ['Cargo.toml'], content: {}, label: 'Rust' },
|
|
176
|
+
go: { files: ['go.mod'], content: {}, label: 'Go' },
|
|
177
|
+
docker: { files: ['Dockerfile', 'docker-compose.yml', 'docker-compose.yaml'], content: {}, label: 'Docker' },
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
module.exports = { TECHNIQUES, STACKS };
|