claude-base-setup 1.0.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/README.md +63 -0
- package/bin/cli.js +99 -0
- package/index.js +5 -0
- package/package.json +37 -0
- package/templates/agents/context-loader.md +114 -0
- package/templates/agents/package-checker.md +45 -0
- package/templates/agents/pre-code-check.md +48 -0
- package/templates/agents/structure-validator.md +56 -0
- package/templates/hooks/session-start.sh +79 -0
- package/templates/hooks/smart-inject-llm.sh +156 -0
- package/templates/hooks/smart-inject-rules.sh +148 -0
- package/templates/hooks/triggers.json +68 -0
- package/templates/rules/announce-actions.md +57 -0
- package/templates/rules/code-standards.md +74 -0
- package/templates/rules/rule-format.md +72 -0
- package/templates/rules/subagent-format.md +63 -0
- package/templates/settings.local.json +45 -0
- package/templates/skills/.gitkeep +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# claude-base-setup
|
|
2
|
+
|
|
3
|
+
A reusable `.claude` configuration for Claude Code projects with smart context injection, rules, and agents.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx claude-base-setup
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This creates a `.claude/` directory in your project with:
|
|
12
|
+
|
|
13
|
+
- **hooks/** - Smart context injection on every prompt
|
|
14
|
+
- **rules/** - Behavioral guidelines injected into context
|
|
15
|
+
- **agents/** - Task workers (pre-code-check, package-checker, etc.)
|
|
16
|
+
- **skills/** - Custom slash commands (empty by default)
|
|
17
|
+
- **settings.local.json** - Hook configuration
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Re-initialize (overwrite existing)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx claude-base-setup --force
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### What it does
|
|
28
|
+
|
|
29
|
+
1. **On every prompt**: Analyzes your input and injects relevant rules
|
|
30
|
+
2. **On session start**: Checks if project context is fresh, suggests refresh if stale
|
|
31
|
+
3. **Before creating code**: Suggests running `pre-code-check` agent to avoid duplicates
|
|
32
|
+
4. **Before installing packages**: Suggests running `package-checker` for version compatibility
|
|
33
|
+
|
|
34
|
+
## Included Rules
|
|
35
|
+
|
|
36
|
+
| Rule | Trigger | Description |
|
|
37
|
+
|------|---------|-------------|
|
|
38
|
+
| code-standards | code keywords | No hardcoding, dynamic discovery |
|
|
39
|
+
| announce-actions | always | Announce actions, track agent usage |
|
|
40
|
+
| rule-format | "rule" keywords | How to create rules |
|
|
41
|
+
| subagent-format | "agent" keywords | How to create agents |
|
|
42
|
+
|
|
43
|
+
## Included Agents
|
|
44
|
+
|
|
45
|
+
| Agent | Purpose |
|
|
46
|
+
|-------|---------|
|
|
47
|
+
| pre-code-check | Search for existing code before creating new |
|
|
48
|
+
| package-checker | Check package versions and compatibility |
|
|
49
|
+
| context-loader | Scan codebase and generate CONTEXT.md |
|
|
50
|
+
| structure-validator | Validate project structure after file ops |
|
|
51
|
+
|
|
52
|
+
## Customization
|
|
53
|
+
|
|
54
|
+
After installation, modify files in `.claude/` to fit your project:
|
|
55
|
+
|
|
56
|
+
- Add project-specific rules in `rules/`
|
|
57
|
+
- Customize keyword triggers in `hooks/triggers.json`
|
|
58
|
+
- Add custom agents in `agents/`
|
|
59
|
+
- Update `settings.local.json` for permissions
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const TEMPLATES_DIR = path.join(__dirname, '..', 'templates');
|
|
7
|
+
const TARGET_DIR = path.join(process.cwd(), '.claude');
|
|
8
|
+
|
|
9
|
+
function copyDir(src, dest) {
|
|
10
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
11
|
+
|
|
12
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
13
|
+
|
|
14
|
+
for (const entry of entries) {
|
|
15
|
+
const srcPath = path.join(src, entry.name);
|
|
16
|
+
const destPath = path.join(dest, entry.name);
|
|
17
|
+
|
|
18
|
+
if (entry.isDirectory()) {
|
|
19
|
+
copyDir(srcPath, destPath);
|
|
20
|
+
} else {
|
|
21
|
+
fs.copyFileSync(srcPath, destPath);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function makeExecutable(dir) {
|
|
27
|
+
const hooksDir = path.join(dir, 'hooks');
|
|
28
|
+
if (fs.existsSync(hooksDir)) {
|
|
29
|
+
const files = fs.readdirSync(hooksDir);
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
if (file.endsWith('.sh')) {
|
|
32
|
+
const filePath = path.join(hooksDir, file);
|
|
33
|
+
fs.chmodSync(filePath, 0o755);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function init() {
|
|
40
|
+
console.log('🔧 Initializing Claude Code base setup...\n');
|
|
41
|
+
|
|
42
|
+
if (fs.existsSync(TARGET_DIR)) {
|
|
43
|
+
console.log('⚠️ .claude directory already exists.');
|
|
44
|
+
console.log(' Use --force to overwrite.\n');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!fs.existsSync(TEMPLATES_DIR)) {
|
|
49
|
+
console.error('❌ Templates directory not found. Package may be corrupted.');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
copyDir(TEMPLATES_DIR, TARGET_DIR);
|
|
54
|
+
makeExecutable(TARGET_DIR);
|
|
55
|
+
|
|
56
|
+
console.log('✅ Created .claude/ directory with:');
|
|
57
|
+
console.log(' 📁 hooks/ - Smart context injection');
|
|
58
|
+
console.log(' 📁 rules/ - Behavioral guidelines');
|
|
59
|
+
console.log(' 📁 agents/ - Task workers');
|
|
60
|
+
console.log(' 📁 skills/ - Custom commands (empty)');
|
|
61
|
+
console.log(' 📄 settings.local.json\n');
|
|
62
|
+
console.log('🚀 Ready! Claude Code will now use these rules and agents.\n');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function forceInit() {
|
|
66
|
+
if (fs.existsSync(TARGET_DIR)) {
|
|
67
|
+
fs.rmSync(TARGET_DIR, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
init();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function showHelp() {
|
|
73
|
+
console.log(`
|
|
74
|
+
claude-base-setup - Initialize .claude configuration for Claude Code
|
|
75
|
+
|
|
76
|
+
Usage:
|
|
77
|
+
npx claude-base-setup Initialize .claude in current directory
|
|
78
|
+
npx claude-base-setup --force Overwrite existing .claude directory
|
|
79
|
+
npx claude-base-setup --help Show this help message
|
|
80
|
+
|
|
81
|
+
What's included:
|
|
82
|
+
• hooks/ Smart context injection on every prompt
|
|
83
|
+
• rules/ Behavioral guidelines (code standards, etc.)
|
|
84
|
+
• agents/ Task workers (pre-code-check, package-checker, etc.)
|
|
85
|
+
• skills/ Custom slash commands (empty by default)
|
|
86
|
+
|
|
87
|
+
Learn more: https://github.com/fr0mpy/claude-base-setup
|
|
88
|
+
`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const args = process.argv.slice(2);
|
|
92
|
+
|
|
93
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
94
|
+
showHelp();
|
|
95
|
+
} else if (args.includes('--force') || args.includes('-f')) {
|
|
96
|
+
forceInit();
|
|
97
|
+
} else {
|
|
98
|
+
init();
|
|
99
|
+
}
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claude-base-setup",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A reusable .claude configuration for Claude Code projects with smart context injection, rules, and agents",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"claude-base-setup": "./bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"No tests yet\" && exit 0"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"claude",
|
|
14
|
+
"claude-code",
|
|
15
|
+
"ai",
|
|
16
|
+
"llm",
|
|
17
|
+
"development",
|
|
18
|
+
"automation",
|
|
19
|
+
"rules",
|
|
20
|
+
"agents",
|
|
21
|
+
"hooks"
|
|
22
|
+
],
|
|
23
|
+
"author": "",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/fr0mpy/claude-base-setup.git"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bin/",
|
|
31
|
+
"templates/",
|
|
32
|
+
"index.js"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=16.0.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-loader
|
|
3
|
+
description: Loads project context at session start. Scans codebase and generates/updates CONTEXT.md if stale (>1h).
|
|
4
|
+
tools: Glob, Grep, Read, Write, Bash
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a context loader that works with ANY project structure.
|
|
9
|
+
|
|
10
|
+
## Your Task
|
|
11
|
+
|
|
12
|
+
1. Check if `.claude/CONTEXT.md` exists
|
|
13
|
+
2. If exists, check modification time with `stat`
|
|
14
|
+
3. If missing OR older than 1 hour → regenerate by scanning
|
|
15
|
+
4. Output a brief context summary
|
|
16
|
+
|
|
17
|
+
## Scan Process (if regenerating)
|
|
18
|
+
|
|
19
|
+
### Step 1: Discover Project Structure
|
|
20
|
+
|
|
21
|
+
Use Glob to find the project root patterns:
|
|
22
|
+
- `**/package.json` → Node/JS project
|
|
23
|
+
- `**/app.json` → Expo/React Native
|
|
24
|
+
- `**/Cargo.toml` → Rust
|
|
25
|
+
- `**/go.mod` → Go
|
|
26
|
+
- `**/pyproject.toml` or `**/setup.py` → Python
|
|
27
|
+
|
|
28
|
+
### Step 2: Discover Source Directories
|
|
29
|
+
|
|
30
|
+
Use Glob with broad patterns to find where code lives:
|
|
31
|
+
- `**/*.tsx` → React components
|
|
32
|
+
- `**/*.ts` → TypeScript files
|
|
33
|
+
- `**/*.py` → Python files
|
|
34
|
+
- `**/*.go` → Go files
|
|
35
|
+
|
|
36
|
+
Group by directory to understand the structure.
|
|
37
|
+
|
|
38
|
+
### Step 3: Categorize What You Find
|
|
39
|
+
|
|
40
|
+
Look at directory names to infer purpose:
|
|
41
|
+
- `components`, `ui`, `views` → UI layer
|
|
42
|
+
- `screens`, `pages`, `routes` → Page/Screen layer
|
|
43
|
+
- `hooks`, `composables` → Reusable logic
|
|
44
|
+
- `services`, `api`, `clients` → External integrations
|
|
45
|
+
- `store`, `stores`, `state` → State management
|
|
46
|
+
- `utils`, `helpers`, `lib` → Utilities
|
|
47
|
+
- `types`, `interfaces`, `models` → Type definitions
|
|
48
|
+
- `config`, `constants` → Configuration
|
|
49
|
+
|
|
50
|
+
### Step 4: Identify Key Patterns
|
|
51
|
+
|
|
52
|
+
Grep for common patterns to assess status:
|
|
53
|
+
- `// TODO` or `# TODO` → Incomplete work
|
|
54
|
+
- `throw new Error('not implemented')` → Stubs
|
|
55
|
+
- Empty function bodies
|
|
56
|
+
- `console.log` debugging
|
|
57
|
+
|
|
58
|
+
### Step 5: Write `.claude/CONTEXT.md`
|
|
59
|
+
|
|
60
|
+
```markdown
|
|
61
|
+
# [Project Name] Context
|
|
62
|
+
> Auto-generated: [timestamp]
|
|
63
|
+
|
|
64
|
+
## Quick Stats
|
|
65
|
+
[Dynamic based on what was found]
|
|
66
|
+
|
|
67
|
+
## Stack
|
|
68
|
+
[Detected from package.json, Cargo.toml, etc.]
|
|
69
|
+
|
|
70
|
+
## Project Structure
|
|
71
|
+
```
|
|
72
|
+
[Actual directory tree, 2 levels deep]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Key Directories
|
|
76
|
+
[For each discovered category:]
|
|
77
|
+
### [Category Name] ([count] files)
|
|
78
|
+
[List of files]
|
|
79
|
+
|
|
80
|
+
## Needs Work
|
|
81
|
+
[Files with TODOs or stubs]
|
|
82
|
+
|
|
83
|
+
## Detected Patterns
|
|
84
|
+
[Coding patterns observed - state management, styling approach, etc.]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Output Format
|
|
88
|
+
|
|
89
|
+
**If context is fresh (<1h old):**
|
|
90
|
+
```
|
|
91
|
+
📊 Context loaded (fresh)
|
|
92
|
+
[1-line summary of key stats]
|
|
93
|
+
📁 .claude/CONTEXT.md
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**If regenerated:**
|
|
97
|
+
```
|
|
98
|
+
📊 Context regenerated
|
|
99
|
+
[1-line summary of key stats]
|
|
100
|
+
📁 .claude/CONTEXT.md updated
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**If empty project:**
|
|
104
|
+
```
|
|
105
|
+
⚠️ No source files found - project appears empty
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Rules
|
|
109
|
+
|
|
110
|
+
- DISCOVER structure dynamically - never assume paths
|
|
111
|
+
- Use Glob to scan, Grep to find patterns
|
|
112
|
+
- Only Read specific files if needed (package.json, config)
|
|
113
|
+
- Keep output to 3-5 lines
|
|
114
|
+
- Be fast - don't read every source file
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: package-checker
|
|
3
|
+
description: Checks latest package versions before installation. Use proactively when user asks to install, add packages, or mentions npm/yarn/pnpm.
|
|
4
|
+
tools: WebSearch, Read
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a package version checker for a React Native/Expo project.
|
|
9
|
+
|
|
10
|
+
## Project Stack
|
|
11
|
+
|
|
12
|
+
- React Native: 0.81
|
|
13
|
+
- Expo SDK: 54
|
|
14
|
+
- React: 19.x
|
|
15
|
+
- TypeScript: 5.x
|
|
16
|
+
|
|
17
|
+
## Your Task
|
|
18
|
+
|
|
19
|
+
Before any package is installed:
|
|
20
|
+
|
|
21
|
+
1. **Search for latest version** - Web search "[package] npm latest version 2026"
|
|
22
|
+
2. **Check compatibility** - Verify works with RN 0.81 / Expo SDK 54
|
|
23
|
+
3. **Check peer deps** - Note any required peer dependencies
|
|
24
|
+
4. **Report findings** - Give exact version to install
|
|
25
|
+
|
|
26
|
+
## Output Format
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
📦 Package version check:
|
|
30
|
+
|
|
31
|
+
@react-navigation/native
|
|
32
|
+
├─ Latest: 7.3.1 (stable)
|
|
33
|
+
├─ Compatible: ✅ RN 0.81, Expo 54
|
|
34
|
+
├─ Peer deps: react-native-screens, react-native-safe-area-context
|
|
35
|
+
└─ Install: npm install @react-navigation/native@7.3.1
|
|
36
|
+
|
|
37
|
+
Recommendation: Install version 7.3.1
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Rules
|
|
41
|
+
|
|
42
|
+
- Always check compatibility before recommending
|
|
43
|
+
- If latest is <1 week old, recommend previous stable
|
|
44
|
+
- Warn about breaking changes between major versions
|
|
45
|
+
- Note if package is deprecated and suggest alternatives
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pre-code-check
|
|
3
|
+
description: Searches for existing code before creating new components, hooks, utils, or services. Use proactively when user asks to create, build, make, add, or implement code.
|
|
4
|
+
tools: Grep, Glob, Read
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a code duplication checker for a React Native/Expo project.
|
|
9
|
+
|
|
10
|
+
## Your Task
|
|
11
|
+
|
|
12
|
+
Before any code is created, search for existing implementations:
|
|
13
|
+
|
|
14
|
+
1. **Search by name** - Look for files with similar names
|
|
15
|
+
2. **Search by function** - Look for similar functionality
|
|
16
|
+
3. **Report findings** - List what exists with file paths
|
|
17
|
+
4. **Recommend action** - REUSE > EXTEND > CREATE
|
|
18
|
+
|
|
19
|
+
## Search Locations
|
|
20
|
+
|
|
21
|
+
- `src/components/` - UI components
|
|
22
|
+
- `src/hooks/` - Custom hooks
|
|
23
|
+
- `src/utils/` - Utility functions
|
|
24
|
+
- `src/services/` - API/service functions
|
|
25
|
+
- `src/screens/` - Screen components
|
|
26
|
+
|
|
27
|
+
## Output Format
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
🔍 Existing code check for: [requested item]
|
|
31
|
+
|
|
32
|
+
Found:
|
|
33
|
+
- src/components/Button.tsx - Generic button with variants
|
|
34
|
+
- src/components/IconButton.tsx - Button with icon support
|
|
35
|
+
|
|
36
|
+
Recommendation: EXTEND src/components/Button.tsx by adding [specific feature]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or if nothing found:
|
|
40
|
+
```
|
|
41
|
+
✅ No existing [item] found. Safe to create new.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Rules
|
|
45
|
+
|
|
46
|
+
- Be thorough but fast
|
|
47
|
+
- Only report relevant matches (>50% similar purpose)
|
|
48
|
+
- Always give a clear recommendation
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: structure-validator
|
|
3
|
+
description: Validates project structure after file/directory operations. Use after creating files, directories, or reorganizing code.
|
|
4
|
+
tools: Glob, Bash, Read
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a project structure validator for a React Native/Expo project.
|
|
9
|
+
|
|
10
|
+
## Your Task
|
|
11
|
+
|
|
12
|
+
After file/directory operations, check for:
|
|
13
|
+
|
|
14
|
+
1. **Nested duplicates** - e.g., `app/app/`, `src/src/`
|
|
15
|
+
2. **Multiple src dirs** - Should usually be one
|
|
16
|
+
3. **Empty directories** - Potential cleanup needed
|
|
17
|
+
4. **Correct placement** - Files in right locations
|
|
18
|
+
|
|
19
|
+
## Expected Structure
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
fast96/
|
|
23
|
+
├── fast96-app/
|
|
24
|
+
│ ├── src/
|
|
25
|
+
│ │ ├── components/
|
|
26
|
+
│ │ ├── screens/
|
|
27
|
+
│ │ ├── hooks/
|
|
28
|
+
│ │ ├── services/
|
|
29
|
+
│ │ ├── utils/
|
|
30
|
+
│ │ ├── config/
|
|
31
|
+
│ │ ├── constants/
|
|
32
|
+
│ │ ├── theme/
|
|
33
|
+
│ │ └── types/
|
|
34
|
+
│ ├── App.tsx
|
|
35
|
+
│ └── package.json
|
|
36
|
+
└── .claude/
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Output Format
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
🔍 Structure validation:
|
|
43
|
+
|
|
44
|
+
✅ No nested duplicates
|
|
45
|
+
✅ Single src/ directory
|
|
46
|
+
⚠️ Empty directories found:
|
|
47
|
+
- src/hooks/ (empty)
|
|
48
|
+
|
|
49
|
+
Recommendation: Remove empty dirs or add placeholder
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Rules
|
|
53
|
+
|
|
54
|
+
- Run after any file creation
|
|
55
|
+
- Flag nested duplicates immediately
|
|
56
|
+
- Suggest fixes for issues found
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Session Start Hook
|
|
3
|
+
# - Checks if context is stale
|
|
4
|
+
# - Outputs instruction for Claude to use context-loader agent
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
CLAUDE_DIR=""
|
|
9
|
+
CURRENT_DIR="$(pwd)"
|
|
10
|
+
while [[ "$CURRENT_DIR" != "/" ]]; do
|
|
11
|
+
if [[ -d "$CURRENT_DIR/.claude" ]]; then
|
|
12
|
+
CLAUDE_DIR="$CURRENT_DIR/.claude"
|
|
13
|
+
break
|
|
14
|
+
fi
|
|
15
|
+
CURRENT_DIR="$(dirname "$CURRENT_DIR")"
|
|
16
|
+
done
|
|
17
|
+
|
|
18
|
+
[[ -z "$CLAUDE_DIR" ]] && exit 0
|
|
19
|
+
|
|
20
|
+
CONTEXT_FILE="$CLAUDE_DIR/CONTEXT.md"
|
|
21
|
+
FRESHNESS_THRESHOLD=3600 # 1 hour in seconds
|
|
22
|
+
|
|
23
|
+
# ============================================================================
|
|
24
|
+
# FUNCTIONS
|
|
25
|
+
# ============================================================================
|
|
26
|
+
|
|
27
|
+
is_fresh() {
|
|
28
|
+
[[ ! -f "$CONTEXT_FILE" ]] && return 1
|
|
29
|
+
|
|
30
|
+
local file_age
|
|
31
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
32
|
+
file_age=$(( $(date +%s) - $(stat -f %m "$CONTEXT_FILE") ))
|
|
33
|
+
else
|
|
34
|
+
file_age=$(( $(date +%s) - $(stat -c %Y "$CONTEXT_FILE") ))
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
[[ $file_age -lt $FRESHNESS_THRESHOLD ]]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get_context_summary() {
|
|
41
|
+
if [[ -f "$CONTEXT_FILE" ]]; then
|
|
42
|
+
# Extract quick stats section
|
|
43
|
+
grep -A5 "## Quick Stats" "$CONTEXT_FILE" 2>/dev/null | tail -4 | sed 's/^/ /'
|
|
44
|
+
fi
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# ============================================================================
|
|
48
|
+
# MAIN
|
|
49
|
+
# ============================================================================
|
|
50
|
+
|
|
51
|
+
echo "<session_context>"
|
|
52
|
+
|
|
53
|
+
if [[ ! -f "$CONTEXT_FILE" ]]; then
|
|
54
|
+
cat << 'EOF'
|
|
55
|
+
📋 No project context found.
|
|
56
|
+
|
|
57
|
+
⚠️ ACTION REQUIRED: Use the `context-loader` agent to scan the codebase and generate .claude/CONTEXT.md
|
|
58
|
+
|
|
59
|
+
This will help you understand the project structure and current implementation status.
|
|
60
|
+
EOF
|
|
61
|
+
|
|
62
|
+
elif ! is_fresh; then
|
|
63
|
+
echo "📋 Project context is STALE (>1h old)"
|
|
64
|
+
echo ""
|
|
65
|
+
get_context_summary
|
|
66
|
+
echo ""
|
|
67
|
+
cat << 'EOF'
|
|
68
|
+
⚠️ ACTION REQUIRED: Use the `context-loader` agent to refresh .claude/CONTEXT.md
|
|
69
|
+
EOF
|
|
70
|
+
|
|
71
|
+
else
|
|
72
|
+
echo "📋 Project context loaded (fresh)"
|
|
73
|
+
echo ""
|
|
74
|
+
get_context_summary
|
|
75
|
+
echo ""
|
|
76
|
+
echo "📁 Full details: .claude/CONTEXT.md"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
echo "</session_context>"
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# LLM-powered smart rule/agent injection using Claude Haiku
|
|
5
|
+
# Replaces static keyword matching with semantic understanding
|
|
6
|
+
|
|
7
|
+
# Read prompt from stdin
|
|
8
|
+
PROMPT=$(cat)
|
|
9
|
+
|
|
10
|
+
# Find .claude directory
|
|
11
|
+
find_claude_dir() {
|
|
12
|
+
local dir="$PWD"
|
|
13
|
+
while [[ "$dir" != "/" ]]; do
|
|
14
|
+
if [[ -d "$dir/.claude" ]]; then
|
|
15
|
+
echo "$dir/.claude"
|
|
16
|
+
return 0
|
|
17
|
+
fi
|
|
18
|
+
dir="$(dirname "$dir")"
|
|
19
|
+
done
|
|
20
|
+
return 1
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
CLAUDE_DIR=$(find_claude_dir) || exit 0
|
|
24
|
+
|
|
25
|
+
RULES_DIR="$CLAUDE_DIR/rules"
|
|
26
|
+
AGENTS_DIR="$CLAUDE_DIR/agents"
|
|
27
|
+
|
|
28
|
+
# Check directories exist
|
|
29
|
+
[[ -d "$RULES_DIR" ]] || exit 0
|
|
30
|
+
|
|
31
|
+
# Get API key from environment
|
|
32
|
+
API_KEY="${ANTHROPIC_API_KEY:-}"
|
|
33
|
+
[[ -n "$API_KEY" ]] || { echo "⚠️ ANTHROPIC_API_KEY not set - using static fallback" >&2; exec "$CLAUDE_DIR/hooks/smart-inject-rules.sh" <<< "$PROMPT"; }
|
|
34
|
+
|
|
35
|
+
# Build rules summary (name + description from YAML frontmatter)
|
|
36
|
+
RULES_SUMMARY=""
|
|
37
|
+
for rule_file in "$RULES_DIR"/*.md; do
|
|
38
|
+
[[ -f "$rule_file" ]] || continue
|
|
39
|
+
RULE_NAME=$(basename "$rule_file" .md)
|
|
40
|
+
# Try YAML frontmatter first, fall back to SUMMARY comment
|
|
41
|
+
RULE_DESC=$(sed -n '/^---$/,/^---$/p' "$rule_file" 2>/dev/null | grep -m1 "^description:" | sed 's/description: *//' | tr -d '\n')
|
|
42
|
+
if [[ -z "$RULE_DESC" ]]; then
|
|
43
|
+
RULE_DESC=$(grep -m1 "<!-- SUMMARY:" "$rule_file" 2>/dev/null | sed 's/.*SUMMARY: *\([^-]*\) *-->.*/\1/' | tr -d '\n')
|
|
44
|
+
fi
|
|
45
|
+
[[ -n "$RULE_DESC" ]] && RULES_SUMMARY+="- $RULE_NAME: $RULE_DESC\n"
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
# Build agents summary
|
|
49
|
+
AGENTS_SUMMARY=""
|
|
50
|
+
if [[ -d "$AGENTS_DIR" ]]; then
|
|
51
|
+
for agent_file in "$AGENTS_DIR"/*.md; do
|
|
52
|
+
[[ -f "$agent_file" ]] || continue
|
|
53
|
+
AGENT_NAME=$(basename "$agent_file" .md)
|
|
54
|
+
AGENT_DESC=$(grep -m1 "^description:" "$agent_file" 2>/dev/null | sed 's/description: *//' | tr -d '\n')
|
|
55
|
+
AGENTS_SUMMARY+="- $AGENT_NAME: $AGENT_DESC\n"
|
|
56
|
+
done
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Escape prompt for JSON
|
|
60
|
+
ESCAPED_PROMPT=$(echo "$PROMPT" | jq -Rs '.')
|
|
61
|
+
ESCAPED_RULES=$(echo -e "$RULES_SUMMARY" | jq -Rs '.')
|
|
62
|
+
ESCAPED_AGENTS=$(echo -e "$AGENTS_SUMMARY" | jq -Rs '.')
|
|
63
|
+
|
|
64
|
+
# Build dynamic system prompt from actual files
|
|
65
|
+
SYSTEM_PROMPT="You analyze user prompts and select relevant rules/agents. Respond ONLY with valid JSON.
|
|
66
|
+
|
|
67
|
+
Output format:
|
|
68
|
+
{
|
|
69
|
+
\"active_rules\": [\"rule-name\"],
|
|
70
|
+
\"suggested_agents\": [\"agent-name\"],
|
|
71
|
+
\"enforcement\": \"Brief instruction Claude MUST follow\"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Available rules (select based on their descriptions):
|
|
75
|
+
$(echo -e "$RULES_SUMMARY")
|
|
76
|
+
|
|
77
|
+
Available agents (select based on their descriptions):
|
|
78
|
+
$(echo -e "$AGENTS_SUMMARY")
|
|
79
|
+
|
|
80
|
+
Selection guidelines:
|
|
81
|
+
- Read each rule/agent description to understand when it applies
|
|
82
|
+
- Select rules that match the user's intent, not just keywords
|
|
83
|
+
- Select agents that should run BEFORE or AFTER the task
|
|
84
|
+
- If no rules/agents apply, return empty arrays
|
|
85
|
+
|
|
86
|
+
Enforcement rules:
|
|
87
|
+
- If you select ANY agent, enforcement MUST say \"YOU MUST run [agent-name] FIRST\" or \"YOU MUST run [agent-name] AFTER\"
|
|
88
|
+
- If you select rules, include their key requirement in enforcement
|
|
89
|
+
- Enforcement should be SHORT (<100 chars) but MANDATORY language
|
|
90
|
+
|
|
91
|
+
Good enforcement examples:
|
|
92
|
+
- \"YOU MUST run pre-code-check BEFORE writing code\"
|
|
93
|
+
- \"YOU MUST run package-checker BEFORE installing\"
|
|
94
|
+
- \"Prefix actions with 🔧. YOU MUST run pre-code-check FIRST\"
|
|
95
|
+
|
|
96
|
+
Bad enforcement examples:
|
|
97
|
+
- \"Consider running pre-code-check\" (too weak)
|
|
98
|
+
- \"pre-code-check suggested\" (not mandatory)
|
|
99
|
+
"
|
|
100
|
+
|
|
101
|
+
USER_MSG="User prompt: $PROMPT
|
|
102
|
+
|
|
103
|
+
Based on the prompt, select relevant rules and agents. Return JSON only."
|
|
104
|
+
|
|
105
|
+
ESCAPED_SYSTEM=$(printf '%s' "$SYSTEM_PROMPT" | jq -Rs '.')
|
|
106
|
+
ESCAPED_USER=$(printf '%s' "$USER_MSG" | jq -Rs '.')
|
|
107
|
+
|
|
108
|
+
# Call Haiku API
|
|
109
|
+
RESPONSE=$(curl -s --max-time 5 "https://api.anthropic.com/v1/messages" \
|
|
110
|
+
-H "Content-Type: application/json" \
|
|
111
|
+
-H "x-api-key: $API_KEY" \
|
|
112
|
+
-H "anthropic-version: 2023-06-01" \
|
|
113
|
+
-d "{
|
|
114
|
+
\"model\": \"claude-3-5-haiku-latest\",
|
|
115
|
+
\"max_tokens\": 256,
|
|
116
|
+
\"messages\": [{
|
|
117
|
+
\"role\": \"user\",
|
|
118
|
+
\"content\": $ESCAPED_USER
|
|
119
|
+
}],
|
|
120
|
+
\"system\": $ESCAPED_SYSTEM
|
|
121
|
+
}" 2>/dev/null) || { exec "$CLAUDE_DIR/hooks/smart-inject-rules.sh" <<< "$PROMPT"; }
|
|
122
|
+
|
|
123
|
+
# Extract JSON from response
|
|
124
|
+
LLM_OUTPUT=$(echo "$RESPONSE" | jq -r '.content[0].text // empty' 2>/dev/null) || { exec "$CLAUDE_DIR/hooks/smart-inject-rules.sh" <<< "$PROMPT"; }
|
|
125
|
+
|
|
126
|
+
[[ -n "$LLM_OUTPUT" ]] || { exec "$CLAUDE_DIR/hooks/smart-inject-rules.sh" <<< "$PROMPT"; }
|
|
127
|
+
|
|
128
|
+
# Parse LLM response
|
|
129
|
+
ACTIVE_RULES=$(echo "$LLM_OUTPUT" | jq -r '.active_rules[]? // empty' 2>/dev/null)
|
|
130
|
+
SUGGESTED_AGENTS=$(echo "$LLM_OUTPUT" | jq -r '.suggested_agents[]? // empty' 2>/dev/null)
|
|
131
|
+
ENFORCEMENT=$(echo "$LLM_OUTPUT" | jq -r '.enforcement // empty' 2>/dev/null)
|
|
132
|
+
|
|
133
|
+
OUTPUT="<user-prompt-submit-hook>\n"
|
|
134
|
+
|
|
135
|
+
# Add active rules
|
|
136
|
+
if [[ -n "$ACTIVE_RULES" ]]; then
|
|
137
|
+
OUTPUT+="📋 Rules: $(echo "$ACTIVE_RULES" | tr '\n' ', ' | sed 's/,$//')\n"
|
|
138
|
+
else
|
|
139
|
+
OUTPUT+="📋 Rules: none\n"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Add suggested agents
|
|
143
|
+
if [[ -n "$SUGGESTED_AGENTS" ]]; then
|
|
144
|
+
OUTPUT+="🤖 Agents: $(echo "$SUGGESTED_AGENTS" | tr '\n' ', ' | sed 's/,$//')\n"
|
|
145
|
+
else
|
|
146
|
+
OUTPUT+="🤖 Agents: none\n"
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Add enforcement instruction if present
|
|
150
|
+
if [[ -n "$ENFORCEMENT" ]]; then
|
|
151
|
+
OUTPUT+="⚠️ $ENFORCEMENT\n"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
OUTPUT+="</user-prompt-submit-hook>"
|
|
155
|
+
|
|
156
|
+
echo -e "$OUTPUT"
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Smart Context Injection
|
|
3
|
+
# - Injects behavioral rules
|
|
4
|
+
# - Suggests agents for tasks that would bloat context
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
CLAUDE_DIR=""
|
|
9
|
+
CURRENT_DIR="$(pwd)"
|
|
10
|
+
while [[ "$CURRENT_DIR" != "/" ]]; do
|
|
11
|
+
if [[ -d "$CURRENT_DIR/.claude/rules" ]]; then
|
|
12
|
+
CLAUDE_DIR="$CURRENT_DIR/.claude"
|
|
13
|
+
break
|
|
14
|
+
fi
|
|
15
|
+
CURRENT_DIR="$(dirname "$CURRENT_DIR")"
|
|
16
|
+
done
|
|
17
|
+
|
|
18
|
+
[[ -z "$CLAUDE_DIR" ]] && exit 0
|
|
19
|
+
|
|
20
|
+
RULES_DIR="$CLAUDE_DIR/rules"
|
|
21
|
+
AGENTS_DIR="$CLAUDE_DIR/agents"
|
|
22
|
+
TRIGGERS_FILE="$CLAUDE_DIR/hooks/triggers.json"
|
|
23
|
+
|
|
24
|
+
# ============================================================================
|
|
25
|
+
# FUNCTIONS
|
|
26
|
+
# ============================================================================
|
|
27
|
+
|
|
28
|
+
get_summary() {
|
|
29
|
+
head -1 "$1" 2>/dev/null | grep '<!-- SUMMARY:' | sed 's/.*<!-- SUMMARY: //;s/ -->$//' || echo ""
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get_trigger() {
|
|
33
|
+
head -2 "$1" 2>/dev/null | grep '<!-- TRIGGER:' | sed 's/.*<!-- TRIGGER: //;s/ -->$//' || echo "always"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get_rule_name() {
|
|
37
|
+
basename "$1" .md | tr '-' ' ' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get_agent_name() {
|
|
41
|
+
grep '^name:' "$1" 2>/dev/null | sed 's/name: *//' || basename "$1" .md
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get_agent_desc() {
|
|
45
|
+
grep '^description:' "$1" 2>/dev/null | sed 's/description: *//' | head -c 80 || echo ""
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
parse_json_array() {
|
|
49
|
+
local trigger="$1"
|
|
50
|
+
local in_array=0
|
|
51
|
+
local keywords=""
|
|
52
|
+
|
|
53
|
+
while IFS= read -r line; do
|
|
54
|
+
if [[ $in_array -eq 0 ]] && echo "$line" | grep -q "\"$trigger\":"; then
|
|
55
|
+
in_array=1
|
|
56
|
+
continue
|
|
57
|
+
fi
|
|
58
|
+
if [[ $in_array -eq 1 ]]; then
|
|
59
|
+
if echo "$line" | grep -q '\]'; then
|
|
60
|
+
break
|
|
61
|
+
fi
|
|
62
|
+
local kw=$(echo "$line" | tr -d '",[] ' | tr -d '\t')
|
|
63
|
+
[[ -n "$kw" ]] && keywords="$keywords|$kw"
|
|
64
|
+
fi
|
|
65
|
+
done < "$TRIGGERS_FILE"
|
|
66
|
+
|
|
67
|
+
echo "$keywords" | sed 's/^|//'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# ============================================================================
|
|
71
|
+
# MAIN
|
|
72
|
+
# ============================================================================
|
|
73
|
+
|
|
74
|
+
PROMPT=""
|
|
75
|
+
[[ ! -t 0 ]] && PROMPT=$(cat)
|
|
76
|
+
PROMPT_LOWER=$(echo "$PROMPT" | tr '[:upper:]' '[:lower:]')
|
|
77
|
+
|
|
78
|
+
MATCHED_TRIGGERS=""
|
|
79
|
+
|
|
80
|
+
if [[ -f "$TRIGGERS_FILE" ]]; then
|
|
81
|
+
TRIGGER_NAMES=$(grep '": \[' "$TRIGGERS_FILE" | grep -v '_comment' | sed 's/.*"\([^"]*\)".*/\1/')
|
|
82
|
+
|
|
83
|
+
for trigger in $TRIGGER_NAMES; do
|
|
84
|
+
KEYWORDS=$(parse_json_array "$trigger")
|
|
85
|
+
if [[ -n "$KEYWORDS" ]] && echo "$PROMPT_LOWER" | grep -qiE "$KEYWORDS"; then
|
|
86
|
+
MATCHED_TRIGGERS="$MATCHED_TRIGGERS $trigger"
|
|
87
|
+
fi
|
|
88
|
+
done
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
MATCHED_TRIGGERS=$(echo "$MATCHED_TRIGGERS" | sed 's/^ //')
|
|
92
|
+
|
|
93
|
+
# ============================================================================
|
|
94
|
+
# OUTPUT
|
|
95
|
+
# ============================================================================
|
|
96
|
+
|
|
97
|
+
echo "<context_injection>"
|
|
98
|
+
|
|
99
|
+
# Rules status
|
|
100
|
+
echo "RULES:"
|
|
101
|
+
for f in "$RULES_DIR"/*.md; do
|
|
102
|
+
[[ ! -f "$f" ]] && continue
|
|
103
|
+
local_summary=$(get_summary "$f")
|
|
104
|
+
local_trigger=$(get_trigger "$f")
|
|
105
|
+
[[ -z "$local_summary" ]] && continue
|
|
106
|
+
|
|
107
|
+
if echo " $MATCHED_TRIGGERS " | grep -q " $local_trigger "; then
|
|
108
|
+
echo "✅ $(get_rule_name "$f")"
|
|
109
|
+
else
|
|
110
|
+
echo "◽ $(get_rule_name "$f")"
|
|
111
|
+
fi
|
|
112
|
+
done
|
|
113
|
+
|
|
114
|
+
# Agent suggestions based on triggers
|
|
115
|
+
SUGGESTED_AGENTS=""
|
|
116
|
+
for trigger in $MATCHED_TRIGGERS; do
|
|
117
|
+
case "$trigger" in
|
|
118
|
+
code) SUGGESTED_AGENTS="$SUGGESTED_AGENTS pre-code-check" ;;
|
|
119
|
+
package) SUGGESTED_AGENTS="$SUGGESTED_AGENTS package-checker" ;;
|
|
120
|
+
structure) SUGGESTED_AGENTS="$SUGGESTED_AGENTS structure-validator" ;;
|
|
121
|
+
esac
|
|
122
|
+
done
|
|
123
|
+
|
|
124
|
+
if [[ -n "$SUGGESTED_AGENTS" ]]; then
|
|
125
|
+
echo ""
|
|
126
|
+
echo "USE AGENTS:"
|
|
127
|
+
for agent in $SUGGESTED_AGENTS; do
|
|
128
|
+
agent_file="$AGENTS_DIR/${agent}.md"
|
|
129
|
+
if [[ -f "$agent_file" ]]; then
|
|
130
|
+
echo "🤖 $agent: $(get_agent_desc "$agent_file")"
|
|
131
|
+
fi
|
|
132
|
+
done
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
echo "</context_injection>"
|
|
136
|
+
|
|
137
|
+
# Inject full rules only for matched behavioral triggers
|
|
138
|
+
for trigger in $MATCHED_TRIGGERS; do
|
|
139
|
+
for f in "$RULES_DIR"/*.md; do
|
|
140
|
+
[[ ! -f "$f" ]] && continue
|
|
141
|
+
if [[ "$(get_trigger "$f")" == "$trigger" ]]; then
|
|
142
|
+
echo ""
|
|
143
|
+
echo "<${trigger}_rule>"
|
|
144
|
+
grep -v '^<!-- ' "$f" | head -40
|
|
145
|
+
echo "</${trigger}_rule>"
|
|
146
|
+
fi
|
|
147
|
+
done
|
|
148
|
+
done
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"code": [
|
|
3
|
+
"create",
|
|
4
|
+
"build",
|
|
5
|
+
"make",
|
|
6
|
+
"add",
|
|
7
|
+
"implement",
|
|
8
|
+
"write",
|
|
9
|
+
"new",
|
|
10
|
+
"generate",
|
|
11
|
+
"component",
|
|
12
|
+
"hook",
|
|
13
|
+
"util",
|
|
14
|
+
"service",
|
|
15
|
+
"function",
|
|
16
|
+
"screen",
|
|
17
|
+
"class",
|
|
18
|
+
"module",
|
|
19
|
+
"button",
|
|
20
|
+
"card",
|
|
21
|
+
"input",
|
|
22
|
+
"modal",
|
|
23
|
+
"form",
|
|
24
|
+
"api",
|
|
25
|
+
"handler",
|
|
26
|
+
"code"
|
|
27
|
+
],
|
|
28
|
+
"package": [
|
|
29
|
+
"install",
|
|
30
|
+
"package",
|
|
31
|
+
"npm",
|
|
32
|
+
"yarn",
|
|
33
|
+
"pnpm",
|
|
34
|
+
"dependency",
|
|
35
|
+
"dependencies",
|
|
36
|
+
"upgrade",
|
|
37
|
+
"update package"
|
|
38
|
+
],
|
|
39
|
+
"structure": [
|
|
40
|
+
"directory",
|
|
41
|
+
"folder",
|
|
42
|
+
"mkdir",
|
|
43
|
+
"structure",
|
|
44
|
+
"move",
|
|
45
|
+
"rename",
|
|
46
|
+
"reorganize",
|
|
47
|
+
"refactor structure",
|
|
48
|
+
"file structure"
|
|
49
|
+
],
|
|
50
|
+
"rules": [
|
|
51
|
+
"rule",
|
|
52
|
+
"rules",
|
|
53
|
+
"claude rule",
|
|
54
|
+
"add rule",
|
|
55
|
+
"create rule",
|
|
56
|
+
"update rule",
|
|
57
|
+
"modify rule"
|
|
58
|
+
],
|
|
59
|
+
"subagent": [
|
|
60
|
+
"subagent",
|
|
61
|
+
"sub agent",
|
|
62
|
+
"agent",
|
|
63
|
+
"create agent",
|
|
64
|
+
"add agent",
|
|
65
|
+
"new agent"
|
|
66
|
+
],
|
|
67
|
+
"_comment": "Add new triggers here. Keywords are matched case-insensitive against user prompt."
|
|
68
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!-- SUMMARY: Announce actions, track agent usage, prevent duplicates -->
|
|
2
|
+
<!-- TRIGGER: always -->
|
|
3
|
+
# RULE: Announce Actions
|
|
4
|
+
|
|
5
|
+
## Enforcement
|
|
6
|
+
|
|
7
|
+
**For every operation:**
|
|
8
|
+
1. Announce what you're doing
|
|
9
|
+
2. Announce when delegating to an agent
|
|
10
|
+
3. Report results
|
|
11
|
+
4. **NEVER run the same agent twice in one prompt**
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Agent Deduplication
|
|
16
|
+
|
|
17
|
+
⚠️ **CRITICAL**: Each agent runs ONCE per user prompt, max.
|
|
18
|
+
|
|
19
|
+
Before invoking an agent, check if you already used it this turn:
|
|
20
|
+
- If `pre-code-check` already ran → skip, use cached result
|
|
21
|
+
- If `context-loader` already ran → skip, context is loaded
|
|
22
|
+
- If `structure-validator` already ran → skip
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Format
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
🔧 [Action]: [what]
|
|
30
|
+
✅ Done: [result]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**When using agents (use present continuous):**
|
|
34
|
+
```
|
|
35
|
+
🤖 Searching for existing code...
|
|
36
|
+
🤖 Checking package versions...
|
|
37
|
+
🤖 Validating project structure...
|
|
38
|
+
🤖 Loading project context...
|
|
39
|
+
[agent does work]
|
|
40
|
+
✅ Done: [summary]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**When agent already ran:**
|
|
44
|
+
```
|
|
45
|
+
⏭️ Skipping [agent-name] (already ran this prompt)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Quick Reference
|
|
51
|
+
|
|
52
|
+
| Trigger | Action | Max runs |
|
|
53
|
+
|---------|--------|----------|
|
|
54
|
+
| Creating code | `pre-code-check` first | 1 |
|
|
55
|
+
| Installing packages | `package-checker` first | 1 |
|
|
56
|
+
| File operations | `structure-validator` after | 1 |
|
|
57
|
+
| Session start | `context-loader` | 1 |
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<!-- SUMMARY: Dynamic, scalable code - no hardcoding, discover don't assume -->
|
|
2
|
+
<!-- TRIGGER: code -->
|
|
3
|
+
# RULE: Code Standards - Dynamic & Scalable
|
|
4
|
+
|
|
5
|
+
⚠️ **ALWAYS-ACTIVE RULE** - Applies to every code generation.
|
|
6
|
+
|
|
7
|
+
## 🔐 Enforcement
|
|
8
|
+
|
|
9
|
+
**For EVERY piece of code, you MUST:**
|
|
10
|
+
1. No hardcoded values - use constants/config/theme
|
|
11
|
+
2. Discover structure dynamically - never assume paths exist
|
|
12
|
+
3. Single responsibility per file
|
|
13
|
+
4. Code must work regardless of project size
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Dynamic Patterns
|
|
18
|
+
|
|
19
|
+
| ❌ Hardcoded/Assumed | ✅ Dynamic/Discovered |
|
|
20
|
+
|----------------------|----------------------|
|
|
21
|
+
| `src/components/*.tsx` | Glob for `**/*.tsx`, group by directory |
|
|
22
|
+
| `if (items.length === 3)` | `if (items.length === expectedCount)` |
|
|
23
|
+
| `users[0], users[1]` | `users.map()` or `users.forEach()` |
|
|
24
|
+
| `case 'admin': case 'user':` | `ROLES.includes(role)` |
|
|
25
|
+
| Fixed array indices | Iterate or find by property |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Value Mapping
|
|
30
|
+
|
|
31
|
+
| ❌ Hardcoded | ✅ Use Instead |
|
|
32
|
+
|--------------|----------------|
|
|
33
|
+
| `'#007AFF'` | `theme.colors.primary` |
|
|
34
|
+
| `padding: 16` | `theme.spacing.md` |
|
|
35
|
+
| `'https://api...'` | `config.API_BASE_URL` |
|
|
36
|
+
| `'Invalid email'` | `MESSAGES.INVALID_EMAIL` |
|
|
37
|
+
| `if (x > 50)` | `if (x > CONFIG.THRESHOLD)` |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Scalability Principles
|
|
42
|
+
|
|
43
|
+
1. **Discover, don't assume** - Scan for what exists, don't hardcode paths
|
|
44
|
+
2. **Iterate, don't index** - Use `.map()`, `.filter()`, `.find()` not `[0]`, `[1]`
|
|
45
|
+
3. **Configure, don't embed** - Values that might change go in config
|
|
46
|
+
4. **Categorize by pattern** - Group by naming convention, not explicit list
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Quick Examples
|
|
51
|
+
|
|
52
|
+
**File Discovery:**
|
|
53
|
+
```typescript
|
|
54
|
+
// ❌ const screens = ['Home', 'Settings', 'Profile']
|
|
55
|
+
// ✅ const screens = await glob('**/screens/**/*.tsx')
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Iteration:**
|
|
59
|
+
```typescript
|
|
60
|
+
// ❌ processItem(items[0]); processItem(items[1]);
|
|
61
|
+
// ✅ items.forEach(item => processItem(item))
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Role Checks:**
|
|
65
|
+
```typescript
|
|
66
|
+
// ❌ if (role === 'admin' || role === 'superadmin')
|
|
67
|
+
// ✅ if (ELEVATED_ROLES.includes(role))
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Path Building:**
|
|
71
|
+
```typescript
|
|
72
|
+
// ❌ const path = 'src/components/' + name + '.tsx'
|
|
73
|
+
// ✅ const path = join(SRC_DIR, 'components', `${name}.tsx`)
|
|
74
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!-- SUMMARY: Follow standard format when creating or modifying rules -->
|
|
2
|
+
<!-- TRIGGER: rules -->
|
|
3
|
+
# RULE: Rule Format - Standard Structure for All Rules
|
|
4
|
+
|
|
5
|
+
⚠️ **ALWAYS-ACTIVE RULE** - Apply when creating or modifying any rule file.
|
|
6
|
+
|
|
7
|
+
## 🔐 Enforcement
|
|
8
|
+
|
|
9
|
+
**When creating/modifying rules, you MUST:**
|
|
10
|
+
1. Follow the exact template below
|
|
11
|
+
2. Keep content concise - no filler words
|
|
12
|
+
3. Use the metadata comments for hook integration
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Template
|
|
17
|
+
|
|
18
|
+
```markdown
|
|
19
|
+
<!-- SUMMARY: One-line description (max 80 chars) -->
|
|
20
|
+
<!-- TRIGGER: code | package | structure | always -->
|
|
21
|
+
# RULE: Name - Short Description
|
|
22
|
+
|
|
23
|
+
⚠️ **ALWAYS-ACTIVE RULE** - Brief scope statement.
|
|
24
|
+
|
|
25
|
+
## 🔐 Enforcement
|
|
26
|
+
|
|
27
|
+
**[When this triggers], you MUST:**
|
|
28
|
+
1. Step one
|
|
29
|
+
2. Step two
|
|
30
|
+
3. Step three
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## What to Check
|
|
35
|
+
|
|
36
|
+
- Bullet point checks
|
|
37
|
+
- Keep actionable
|
|
38
|
+
|
|
39
|
+
## Quick Reference
|
|
40
|
+
|
|
41
|
+
| Do | Don't |
|
|
42
|
+
|----|-------|
|
|
43
|
+
| Good example | Bad example |
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Metadata Fields
|
|
49
|
+
|
|
50
|
+
| Field | Values | Purpose |
|
|
51
|
+
|-------|--------|---------|
|
|
52
|
+
| `SUMMARY` | Max 80 chars | Displayed in lightweight mode |
|
|
53
|
+
| `TRIGGER` | `code`, `package`, `structure`, `always` | When hook injects this rule |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Principles
|
|
58
|
+
|
|
59
|
+
1. **Concise** - No paragraphs explaining why. Just what to do.
|
|
60
|
+
2. **Actionable** - Every line should be a clear instruction.
|
|
61
|
+
3. **Scannable** - Use tables, bullets, code blocks. No walls of text.
|
|
62
|
+
4. **Self-contained** - Rule should work without reading other docs.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Anti-Patterns
|
|
67
|
+
|
|
68
|
+
❌ Long explanations of "why" this rule exists
|
|
69
|
+
❌ Multiple examples when one suffices
|
|
70
|
+
❌ Repeating the same instruction in different words
|
|
71
|
+
❌ Sections that don't add actionable value
|
|
72
|
+
❌ "Philosophy" or "Background" sections
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<!-- SUMMARY: Follow standard format when creating or modifying subagents -->
|
|
2
|
+
<!-- TRIGGER: subagent -->
|
|
3
|
+
# RULE: Subagent Format
|
|
4
|
+
|
|
5
|
+
⚠️ **ACTIVE RULE** - Apply when creating or modifying subagent files.
|
|
6
|
+
|
|
7
|
+
## 🔐 Enforcement
|
|
8
|
+
|
|
9
|
+
**When creating/modifying subagents, you MUST:**
|
|
10
|
+
1. Use YAML frontmatter with required fields
|
|
11
|
+
2. Keep prompts concise and actionable
|
|
12
|
+
3. Place in `.claude/agents/` directory
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Template
|
|
17
|
+
|
|
18
|
+
```markdown
|
|
19
|
+
---
|
|
20
|
+
name: agent-name
|
|
21
|
+
description: Brief description. When to use this agent proactively.
|
|
22
|
+
tools: Grep, Glob, Read, WebSearch, Bash
|
|
23
|
+
model: haiku
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
You are a [role] for [project type].
|
|
27
|
+
|
|
28
|
+
## Your Task
|
|
29
|
+
|
|
30
|
+
1. Step one
|
|
31
|
+
2. Step two
|
|
32
|
+
3. Step three
|
|
33
|
+
|
|
34
|
+
## Output Format
|
|
35
|
+
|
|
36
|
+
[Expected output structure]
|
|
37
|
+
|
|
38
|
+
## Rules
|
|
39
|
+
|
|
40
|
+
- Rule one
|
|
41
|
+
- Rule two
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Required Fields
|
|
47
|
+
|
|
48
|
+
| Field | Purpose |
|
|
49
|
+
|-------|---------|
|
|
50
|
+
| `name` | Unique identifier (kebab-case) |
|
|
51
|
+
| `description` | When Claude should delegate to this agent |
|
|
52
|
+
| `tools` | Allowed tools (Grep, Glob, Read, WebSearch, Bash, Write, Edit) |
|
|
53
|
+
| `model` | `haiku` for fast/cheap, `sonnet` for complex |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Best Practices
|
|
58
|
+
|
|
59
|
+
- Write clear `description` - Claude uses this to decide when to delegate
|
|
60
|
+
- Limit to 3-4 subagents total per project
|
|
61
|
+
- Use `haiku` model for simple searches
|
|
62
|
+
- Use `sonnet` for complex reasoning
|
|
63
|
+
- Keep prompts focused on one task
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(npx create-expo-app:*)",
|
|
5
|
+
"Bash(npx create-expo-app@latest fast96-app --template blank-typescript)",
|
|
6
|
+
"Bash(npm install:*)",
|
|
7
|
+
"Bash(git init:*)",
|
|
8
|
+
"Bash(git remote add:*)",
|
|
9
|
+
"Bash(git add:*)",
|
|
10
|
+
"Bash(git commit:*)",
|
|
11
|
+
"Bash(git ls-tree:*)",
|
|
12
|
+
"Bash(git rm:*)",
|
|
13
|
+
"Bash(chmod:*)"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"hooks": {
|
|
17
|
+
"SessionStart": [
|
|
18
|
+
{
|
|
19
|
+
"matcher": "startup",
|
|
20
|
+
"hooks": [
|
|
21
|
+
{
|
|
22
|
+
"type": "command",
|
|
23
|
+
"command": ".claude/hooks/session-start.sh",
|
|
24
|
+
"statusMessage": "Loading project context..."
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"UserPromptSubmit": [
|
|
30
|
+
{
|
|
31
|
+
"matcher": ".*",
|
|
32
|
+
"hooks": [
|
|
33
|
+
{
|
|
34
|
+
"type": "command",
|
|
35
|
+
"command": ".claude/hooks/smart-inject-rules.sh",
|
|
36
|
+
"statusMessage": "Analyzing prompt..."
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"sandbox": {
|
|
43
|
+
"enabled": true
|
|
44
|
+
}
|
|
45
|
+
}
|
|
File without changes
|