worclaude 2.2.6 → 2.4.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/README.md +114 -37
  3. package/package.json +7 -2
  4. package/src/commands/doctor.js +507 -104
  5. package/src/commands/init.js +103 -19
  6. package/src/core/detector.js +34 -10
  7. package/src/core/merger.js +48 -3
  8. package/src/core/scaffolder.js +58 -1
  9. package/src/data/agent-registry.js +17 -2
  10. package/src/data/agents.js +7 -0
  11. package/src/index.js +2 -1
  12. package/src/prompts/claude-md-merge.js +5 -0
  13. package/templates/agents/universal/build-validator.md +23 -0
  14. package/templates/agents/universal/code-simplifier.md +11 -0
  15. package/templates/agents/universal/plan-reviewer.md +39 -0
  16. package/templates/agents/universal/test-writer.md +25 -0
  17. package/templates/agents/universal/upstream-watcher.md +120 -0
  18. package/templates/agents/universal/verify-app.md +12 -0
  19. package/templates/commands/build-fix.md +5 -0
  20. package/templates/commands/commit-push-pr.md +6 -0
  21. package/templates/commands/compact-safe.md +5 -0
  22. package/templates/commands/conflict-resolver.md +5 -0
  23. package/templates/commands/end.md +10 -0
  24. package/templates/commands/learn.md +33 -0
  25. package/templates/commands/refactor-clean.md +10 -0
  26. package/templates/commands/review-changes.md +5 -0
  27. package/templates/commands/review-plan.md +5 -0
  28. package/templates/commands/setup.md +5 -0
  29. package/templates/commands/start.md +10 -0
  30. package/templates/commands/status.md +5 -0
  31. package/templates/commands/sync.md +5 -0
  32. package/templates/commands/techdebt.md +5 -0
  33. package/templates/commands/test-coverage.md +5 -0
  34. package/templates/commands/update-claude-md.md +5 -0
  35. package/templates/commands/upstream-check.md +85 -0
  36. package/templates/commands/verify.md +11 -0
  37. package/templates/core/agents-md.md +25 -0
  38. package/templates/core/claude-md.md +17 -0
  39. package/templates/hooks/README.md +106 -0
  40. package/templates/hooks/correction-detect.cjs +48 -0
  41. package/templates/hooks/examples/prompt-hook-commit-validator.json +16 -0
  42. package/templates/hooks/learn-capture.cjs +179 -0
  43. package/templates/hooks/pre-compact-save.cjs +60 -0
  44. package/templates/hooks/skill-hint.cjs +66 -0
  45. package/templates/memory/decisions.md +11 -0
  46. package/templates/memory/preferences.md +17 -0
  47. package/templates/settings/base.json +56 -8
  48. package/templates/skills/templates/backend-conventions.md +1 -0
  49. package/templates/skills/templates/frontend-design-system.md +1 -0
  50. package/templates/skills/templates/project-patterns.md +1 -0
  51. package/templates/skills/universal/coding-principles.md +60 -0
  52. package/templates/skills/universal/context-management.md +21 -0
  53. package/templates/skills/universal/planning-with-files.md +11 -0
  54. package/templates/skills/universal/verification.md +18 -0
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // UserPromptSubmit hook: detects correction and learn patterns in user prompts.
5
+ // Outputs a hint to stdout if a pattern matches; empty output otherwise.
6
+ // No file I/O, no network. Always exits 0.
7
+
8
+ const { readFileSync } = require('fs');
9
+
10
+ const correctionPatterns = [
11
+ /no,?\s*(that's|thats)?\s*(wrong|incorrect|not right)/i,
12
+ /you\s*(should|shouldn't|need to|forgot)/i,
13
+ /that's not what I (meant|asked|wanted)/i,
14
+ /wrong file/i,
15
+ /undo that/i,
16
+ /don't do that/i,
17
+ /actually,?\s/i,
18
+ /I said /i,
19
+ ];
20
+
21
+ const learnPatterns = [
22
+ /remember (this|that)/i,
23
+ /add (this|that) to (your )?rules/i,
24
+ /don't (do|make) that (again|mistake)/i,
25
+ /learn from this/i,
26
+ /\[LEARN\]/i,
27
+ ];
28
+
29
+ try {
30
+ const data = JSON.parse(readFileSync(0, 'utf8'));
31
+ const prompt = data.input?.prompt || '';
32
+
33
+ if (prompt) {
34
+ if (learnPatterns.some((p) => p.test(prompt))) {
35
+ process.stdout.write(
36
+ '[Learn trigger detected] Capture this as a [LEARN] block with category, rule, and optional mistake/correction.\n'
37
+ );
38
+ } else if (correctionPatterns.some((p) => p.test(prompt))) {
39
+ process.stdout.write(
40
+ '[Correction detected] Consider proposing a [LEARN] block if this is a generalizable rule.\n'
41
+ );
42
+ }
43
+ }
44
+ } catch {
45
+ // Never block user input
46
+ }
47
+
48
+ process.exit(0);
@@ -0,0 +1,16 @@
1
+ {
2
+ "PreToolUse": [
3
+ {
4
+ "matcher": "Bash",
5
+ "hooks": [
6
+ {
7
+ "type": "prompt",
8
+ "prompt": "Check if this git commit message follows Conventional Commits (feat/fix/refactor/docs/test/chore/ci/build/perf/style/revert). Message: $ARGUMENTS. Reply with JSON only: {\"ok\": true} or {\"ok\": false, \"reason\": \"...\"}.",
9
+ "model": "haiku",
10
+ "timeout": 30,
11
+ "statusMessage": "Validating commit message format"
12
+ }
13
+ ]
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Stop hook: scans the transcript for [LEARN] blocks and persists them
5
+ // to .claude/learnings/ as markdown files with YAML frontmatter.
6
+ // Always exits 0 — never blocks session stop.
7
+
8
+ const { readFileSync, writeFileSync, mkdirSync, existsSync, statSync, unlinkSync } = require('fs');
9
+ const { join, basename } = require('path');
10
+
11
+ const LEARN_REGEX =
12
+ /\[LEARN\]\s*([\w][\w\s-]*?)\s*:\s*(.+?)(?:\r?\nMistake:\s*(.+?))?(?:\r?\nCorrection:\s*(.+?))?(?=\r?\n\[LEARN\]|\r?\n\r?\n|$)/gim;
13
+
14
+ const STALE_THRESHOLD_MS = 30000; // 30 seconds
15
+
16
+ function slugify(text) {
17
+ return text
18
+ .toLowerCase()
19
+ .replace(/\s+/g, '-')
20
+ .replace(/[^a-z0-9-]/g, '');
21
+ }
22
+
23
+ function checkStopHookActive(cwd) {
24
+ const flagPath = join(cwd, '.claude', '.stop-hook-active');
25
+ if (existsSync(flagPath)) {
26
+ try {
27
+ const stat = statSync(flagPath);
28
+ if (Date.now() - stat.mtimeMs < STALE_THRESHOLD_MS) {
29
+ return true; // Another stop hook is active
30
+ }
31
+ } catch {
32
+ // Flag file unreadable — proceed
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+
38
+ function setStopHookActive(cwd) {
39
+ const flagPath = join(cwd, '.claude', '.stop-hook-active');
40
+ try {
41
+ writeFileSync(flagPath, String(Date.now()));
42
+ } catch {
43
+ // Non-critical
44
+ }
45
+ }
46
+
47
+ function clearStopHookActive(cwd) {
48
+ const flagPath = join(cwd, '.claude', '.stop-hook-active');
49
+ try {
50
+ unlinkSync(flagPath);
51
+ } catch {
52
+ // Non-critical
53
+ }
54
+ }
55
+
56
+ function readIndex(learningsDir) {
57
+ const indexPath = join(learningsDir, 'index.json');
58
+ if (existsSync(indexPath)) {
59
+ try {
60
+ return JSON.parse(readFileSync(indexPath, 'utf8'));
61
+ } catch {
62
+ return { learnings: [] };
63
+ }
64
+ }
65
+ return { learnings: [] };
66
+ }
67
+
68
+ function writeIndex(learningsDir, index) {
69
+ writeFileSync(join(learningsDir, 'index.json'), JSON.stringify(index, null, 2) + '\n');
70
+ }
71
+
72
+ function extractLearnings(transcriptPath) {
73
+ if (!existsSync(transcriptPath)) return [];
74
+
75
+ const lines = readFileSync(transcriptPath, 'utf8').split(/\r?\n/).filter(Boolean);
76
+ const learnings = [];
77
+
78
+ // Scan last 20 lines for assistant messages containing [LEARN] blocks
79
+ const recent = lines.slice(-20);
80
+ for (const line of recent) {
81
+ try {
82
+ const entry = JSON.parse(line);
83
+ if (entry.type !== 'assistant') continue;
84
+
85
+ const content = entry.message?.content;
86
+ if (!Array.isArray(content)) continue;
87
+
88
+ for (const block of content) {
89
+ if (block.type !== 'text' || !block.text) continue;
90
+
91
+ let match;
92
+ LEARN_REGEX.lastIndex = 0;
93
+ while ((match = LEARN_REGEX.exec(block.text)) !== null) {
94
+ learnings.push({
95
+ category: match[1].trim(),
96
+ rule: match[2].trim(),
97
+ mistake: match[3] ? match[3].trim() : null,
98
+ correction: match[4] ? match[4].trim() : null,
99
+ });
100
+ }
101
+ }
102
+ } catch {
103
+ // Skip malformed JSONL lines
104
+ }
105
+ }
106
+
107
+ return learnings;
108
+ }
109
+
110
+ try {
111
+ const input = readFileSync(0, 'utf8');
112
+ const data = JSON.parse(input);
113
+ const cwd = data.cwd || process.cwd();
114
+ const transcriptPath = data.transcript_path;
115
+
116
+ if (checkStopHookActive(cwd)) process.exit(0);
117
+ setStopHookActive(cwd);
118
+
119
+ try {
120
+ if (!transcriptPath) process.exit(0);
121
+
122
+ const learnings = extractLearnings(transcriptPath);
123
+ if (learnings.length === 0) process.exit(0);
124
+
125
+ const learningsDir = join(cwd, '.claude', 'learnings');
126
+ mkdirSync(learningsDir, { recursive: true });
127
+
128
+ const index = readIndex(learningsDir);
129
+ const today = new Date().toISOString().split('T')[0];
130
+ const projectName = basename(cwd);
131
+
132
+ for (const learning of learnings) {
133
+ const slug = slugify(learning.category);
134
+ const filename = `${slug}.md`;
135
+ const filePath = join(learningsDir, filename);
136
+
137
+ const entry = [
138
+ '---',
139
+ `created: ${today}`,
140
+ `category: ${learning.category}`,
141
+ `project: ${projectName}`,
142
+ 'times_applied: 0',
143
+ '---',
144
+ '',
145
+ `**Rule:** ${learning.rule}`,
146
+ ];
147
+ if (learning.mistake) entry.push(`**Mistake:** ${learning.mistake}`);
148
+ if (learning.correction) entry.push(`**Correction:** ${learning.correction}`);
149
+ entry.push('');
150
+
151
+ if (existsSync(filePath)) {
152
+ const existing = readFileSync(filePath, 'utf8');
153
+ writeFileSync(filePath, existing + '\n' + entry.join('\n'));
154
+ } else {
155
+ writeFileSync(filePath, entry.join('\n'));
156
+ }
157
+
158
+ const existingEntry = index.learnings.find((l) => l.file === filename);
159
+ if (existingEntry) {
160
+ existingEntry.created = today;
161
+ } else {
162
+ index.learnings.push({
163
+ file: filename,
164
+ category: learning.category,
165
+ created: today,
166
+ times_applied: 0,
167
+ });
168
+ }
169
+ }
170
+
171
+ writeIndex(learningsDir, index);
172
+ } finally {
173
+ clearStopHookActive(cwd);
174
+ }
175
+ } catch {
176
+ // Never block session stop
177
+ }
178
+
179
+ process.exit(0);
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // PreCompact hook: saves context snapshot before compaction.
5
+ // Reads JSON from stdin per Claude Code hook contract.
6
+ // Writes snapshot to .claude/sessions/pre-compact-{timestamp}.md.
7
+ // Always exits 0 — never blocks compaction.
8
+
9
+ const { readFileSync, writeFileSync, mkdirSync } = require('fs');
10
+ const { join } = require('path');
11
+ const { execSync } = require('child_process');
12
+
13
+ function run(cmd, cwd) {
14
+ try {
15
+ return execSync(cmd, {
16
+ cwd,
17
+ encoding: 'utf8',
18
+ timeout: 5000,
19
+ stdio: ['ignore', 'pipe', 'ignore'],
20
+ }).trim();
21
+ } catch {
22
+ return '';
23
+ }
24
+ }
25
+
26
+ try {
27
+ const input = readFileSync(0, 'utf8');
28
+ const data = JSON.parse(input);
29
+
30
+ const trigger = data.trigger || 'unknown';
31
+ const cwd = data.cwd || process.cwd();
32
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
33
+
34
+ const sessionsDir = join(cwd, '.claude', 'sessions');
35
+ mkdirSync(sessionsDir, { recursive: true });
36
+
37
+ const branch = run('git rev-parse --abbrev-ref HEAD', cwd) || 'unknown';
38
+ const modifiedFiles = run('git status --porcelain', cwd) || '_No uncommitted changes_';
39
+ const recentCommits = run('git log --oneline -3', cwd) || '_No commits_';
40
+
41
+ const snapshot = [
42
+ '# Pre-Compact Snapshot',
43
+ `**Trigger:** ${trigger}`,
44
+ `**Time:** ${new Date().toISOString()}`,
45
+ `**Branch:** ${branch}`,
46
+ '',
47
+ '## Modified Files',
48
+ modifiedFiles,
49
+ '',
50
+ '## Recent Commits',
51
+ recentCommits,
52
+ '',
53
+ ].join('\n');
54
+
55
+ writeFileSync(join(sessionsDir, `pre-compact-${timestamp}.md`), snapshot);
56
+ } catch {
57
+ // Never block compaction
58
+ }
59
+
60
+ process.exit(0);
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // UserPromptSubmit hook: hints at relevant skills based on user prompt keywords.
5
+ // Reads .claude/skills/ directory, matches skill-name tokens against prompt tokens.
6
+ // Outputs at most one hint to stdout if a match is found; empty output otherwise.
7
+ // Always exits 0.
8
+
9
+ const { readFileSync, readdirSync, statSync } = require('fs');
10
+ const path = require('path');
11
+
12
+ const STOPWORDS = new Set([
13
+ 'the', 'and', 'for', 'with', 'that', 'this', 'have', 'from', 'your',
14
+ 'will', 'would', 'could', 'should', 'about', 'when', 'what', 'which',
15
+ 'there', 'here', 'than', 'then', 'them', 'they', 'their', 'been',
16
+ 'being', 'does', 'doing', 'just', 'some', 'like', 'want', 'need',
17
+ 'make', 'made', 'take', 'into', 'also', 'only', 'because',
18
+ ]);
19
+
20
+ function tokenize(text) {
21
+ return (text || '')
22
+ .toLowerCase()
23
+ .split(/[^a-z0-9]+/)
24
+ .filter((w) => w.length >= 4 && !STOPWORDS.has(w));
25
+ }
26
+
27
+ try {
28
+ const data = JSON.parse(readFileSync(0, 'utf8'));
29
+ const prompt = data.input?.prompt || '';
30
+ const cwd = data.cwd || process.cwd();
31
+ const skillsDir = path.join(cwd, '.claude', 'skills');
32
+
33
+ if (prompt) {
34
+ const promptTokens = new Set(tokenize(prompt));
35
+
36
+ let skills = [];
37
+ try {
38
+ skills = readdirSync(skillsDir)
39
+ .filter((name) => {
40
+ try {
41
+ return statSync(path.join(skillsDir, name)).isDirectory();
42
+ } catch {
43
+ return false;
44
+ }
45
+ })
46
+ .sort();
47
+ } catch {
48
+ // .claude/skills/ missing — nothing to hint at
49
+ }
50
+
51
+ for (const slug of skills) {
52
+ const slugTokens = tokenize(slug);
53
+ const hit = slugTokens.some((t) => promptTokens.has(t));
54
+ if (hit) {
55
+ process.stdout.write(
56
+ `[Skill hint] Consider loading skill: ${slug}/SKILL.md\n`
57
+ );
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ } catch {
63
+ // Never block user input
64
+ }
65
+
66
+ process.exit(0);
@@ -0,0 +1,11 @@
1
+ # Decisions Log
2
+
3
+ Record significant design and architectural decisions here.
4
+ Format: date, decision, rationale, alternatives considered.
5
+
6
+ <!-- Example:
7
+ ## 2026-04-14: Use PostgreSQL over SQLite
8
+ **Rationale:** Need concurrent write support and dataset will exceed 10GB.
9
+ **Alternatives:** SQLite (too limited for concurrency), MongoDB (team unfamiliar).
10
+ **Status:** Active
11
+ -->
@@ -0,0 +1,17 @@
1
+ # Project Preferences
2
+
3
+ Conventions and preferences learned during development.
4
+ Claude's native memory captures some of these automatically.
5
+ Use this file for team-shared preferences that should be in git.
6
+
7
+ ## Code Style
8
+
9
+ <!-- Add project-specific preferences here -->
10
+
11
+ ## Tooling
12
+
13
+ <!-- Add tooling preferences here -->
14
+
15
+ ## Workflow
16
+
17
+ <!-- Add workflow preferences here -->
@@ -46,13 +46,6 @@
46
46
  "command": "p=${WORCLAUDE_HOOK_PROFILE:-standard}; case \"$p\" in minimal) exit 0;; esac; {formatter_command}"
47
47
  }]
48
48
  },
49
- {
50
- "matcher": "Stop",
51
- "hooks": [{
52
- "type": "command",
53
- "command": "p=${WORCLAUDE_HOOK_PROFILE:-standard}; case \"$p\" in minimal) exit 0;; esac; {notification_command}"
54
- }]
55
- },
56
49
  {
57
50
  "matcher": "Write|Edit",
58
51
  "hooks": [{
@@ -70,12 +63,67 @@
70
63
  }]
71
64
  }
72
65
  ],
66
+ "PreCompact": [
67
+ {
68
+ "matcher": "",
69
+ "hooks": [{
70
+ "type": "command",
71
+ "command": "test -f .claude/hooks/pre-compact-save.cjs && node .claude/hooks/pre-compact-save.cjs || true",
72
+ "async": true
73
+ }]
74
+ }
75
+ ],
73
76
  "SessionStart": [
74
77
  {
75
78
  "matcher": "",
76
79
  "hooks": [{
77
80
  "type": "command",
78
- "command": "echo '=== CLAUDE.md ==='; cat CLAUDE.md 2>/dev/null; echo; echo '=== PROGRESS ==='; cat docs/spec/PROGRESS.md 2>/dev/null; echo; echo '=== LAST SESSION ==='; f=$(ls -t .claude/sessions/*.md 2>/dev/null | head -1); if [ -n \"$f\" ]; then cat \"$f\"; else echo 'No previous session found'; fi; echo; echo '=== BRANCH ==='; git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'not a git repo'"
81
+ "command": "echo '=== CLAUDE.md ==='; cat CLAUDE.md 2>/dev/null; echo; echo '=== PROGRESS ==='; cat docs/spec/PROGRESS.md 2>/dev/null; echo; echo '=== LAST SESSION ==='; f=$(ls -t .claude/sessions/*.md 2>/dev/null | head -1); if [ -n \"$f\" ]; then cat \"$f\"; else echo 'No previous session found'; fi; echo; echo '=== BRANCH ==='; git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'not a git repo'; echo; echo '=== RECENT LEARNINGS ==='; if [ -f .claude/learnings/index.json ]; then node -e \"const idx=JSON.parse(require('fs').readFileSync('.claude/learnings/index.json','utf8'));idx.learnings.sort((a,b)=>b.created.localeCompare(a.created)).slice(0,5).forEach(l=>console.log('- ['+l.category+'] '+l.file));\" 2>/dev/null; else echo 'No learnings captured yet. Use [LEARN] blocks to capture corrections.'; fi"
82
+ }]
83
+ }
84
+ ],
85
+ "SessionEnd": [
86
+ {
87
+ "matcher": "",
88
+ "hooks": [{
89
+ "type": "command",
90
+ "command": "p=${WORCLAUDE_HOOK_PROFILE:-standard}; case \"$p\" in minimal) exit 0;; esac; {notification_command}",
91
+ "async": true
92
+ }]
93
+ }
94
+ ],
95
+ "Stop": [
96
+ {
97
+ "matcher": "",
98
+ "hooks": [{
99
+ "type": "command",
100
+ "command": "p=${WORCLAUDE_HOOK_PROFILE:-standard}; case \"$p\" in minimal) exit 0;; esac; test -f .claude/hooks/learn-capture.cjs && node .claude/hooks/learn-capture.cjs || true"
101
+ }]
102
+ }
103
+ ],
104
+ "UserPromptSubmit": [
105
+ {
106
+ "matcher": "",
107
+ "hooks": [{
108
+ "type": "command",
109
+ "command": "p=${WORCLAUDE_HOOK_PROFILE:-standard}; case \"$p\" in minimal) exit 0;; esac; test -f .claude/hooks/correction-detect.cjs && node .claude/hooks/correction-detect.cjs || true"
110
+ }]
111
+ },
112
+ {
113
+ "matcher": "",
114
+ "hooks": [{
115
+ "type": "command",
116
+ "command": "p=${WORCLAUDE_HOOK_PROFILE:-standard}; case \"$p\" in minimal) exit 0;; esac; test -f .claude/hooks/skill-hint.cjs && node .claude/hooks/skill-hint.cjs || true"
117
+ }]
118
+ }
119
+ ],
120
+ "Notification": [
121
+ {
122
+ "matcher": "",
123
+ "hooks": [{
124
+ "type": "command",
125
+ "command": "p=${WORCLAUDE_HOOK_PROFILE:-standard}; case \"$p\" in minimal) exit 0;; esac; {notification_command}",
126
+ "async": true
79
127
  }]
80
128
  }
81
129
  ]
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: "Stack-specific backend patterns, API design, database access, error handling conventions"
3
3
  when_to_use: "When working on backend logic, data access patterns, configuration management, or filesystem operations"
4
+ version: "1.0.0"
4
5
  paths:
5
6
  - "src/**"
6
7
  - "lib/**"
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: "Design system, component library, styling approach, accessibility and responsive design standards"
3
3
  when_to_use: "When building, modifying, or reviewing UI components, styling, layouts, or frontend architecture"
4
+ version: "1.0.0"
4
5
  paths:
5
6
  - "src/components/**"
6
7
  - "src/pages/**"
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: "Architectural patterns, naming conventions, file organization, and error handling philosophy for this project"
3
3
  when_to_use: "When writing new code that should follow established project patterns, or when reviewing code for consistency"
4
+ version: "1.0.0"
4
5
  paths:
5
6
  - "src/**"
6
7
  - "lib/**"
@@ -0,0 +1,60 @@
1
+ ---
2
+ description: "Core behavioral principles: when to ask, when to push back, when to simplify, how to make surgical changes"
3
+ when_to_use: "Always relevant. Load when starting substantive coding tasks, reviewing code, or when output feels overcomplicated or off-target."
4
+ version: "1.0.0"
5
+ ---
6
+
7
+ # Coding Principles
8
+
9
+ Reference card. Depth and examples live in the linked skills — this file consolidates the rules, not the rationale.
10
+
11
+ ## 1. Think Before Coding
12
+
13
+ Don't assume. Don't hide confusion. Surface tradeoffs.
14
+
15
+ - State assumptions explicitly. If uncertain, ask.
16
+ - If multiple interpretations exist, present them — don't pick silently.
17
+ - If a simpler approach exists, say so. Push back when warranted.
18
+ - If something is unclear, stop. Name what's confusing. Ask.
19
+
20
+ See `prompt-engineering/SKILL.md` for eliciting quality and writing specs.
21
+
22
+ ## 2. Simplicity First
23
+
24
+ Minimum code that solves the problem. Nothing speculative.
25
+
26
+ - No features beyond what was asked. No abstractions for single-use code.
27
+ - No "flexibility" or "configurability" that wasn't requested.
28
+ - No error handling for impossible scenarios.
29
+ - If you wrote 200 lines and it could be 50, rewrite it.
30
+
31
+ When NOT to simplify: hot paths, stable legacy, framework boilerplate, security-critical code, code you don't fully understand. When in doubt, leave it — a working system is more valuable than a clean one. See the `code-simplifier` agent and `/refactor-clean` command.
32
+
33
+ ## 3. Surgical Changes
34
+
35
+ Touch only what you must. Every changed line must trace to the request.
36
+
37
+ - Don't "improve" adjacent code, comments, or formatting.
38
+ - Don't refactor things that aren't broken.
39
+ - Match existing style, even if you'd do it differently.
40
+ - Remove imports/variables YOUR changes made unused. Leave pre-existing dead code unless asked.
41
+ - Never combine cleanup with feature work.
42
+
43
+ See `git-conventions/SKILL.md` for style matching and the `/refactor-clean` command for scope.
44
+
45
+ ## 4. Goal-Driven Execution
46
+
47
+ Define success criteria up front. Loop until verified.
48
+
49
+ Transform tasks into verifiable goals:
50
+ - "Add validation" → "Write tests for invalid inputs, then make them pass"
51
+ - "Fix the bug" → "Write a failing test that reproduces it, then make it pass"
52
+ - "Refactor X" → "Ensure tests pass before and after"
53
+
54
+ Close the feedback loop BEFORE committing: change → verify → commit. Not: commit → discover it's broken.
55
+
56
+ See `verification/SKILL.md`, `testing/SKILL.md`, and `planning-with-files/SKILL.md`.
57
+
58
+ ---
59
+
60
+ **These principles are working if:** fewer unnecessary diff lines, fewer rewrites from overcomplication, clarifying questions come before implementation rather than after mistakes.
@@ -6,6 +6,11 @@ version: "1.0.0"
6
6
 
7
7
  # Context Management
8
8
 
9
+ > **Note:** The bash examples below are reference snippets. If you enable
10
+ > `disableSkillShellExecution` in Claude Code settings (v2.1.101+), any inline
11
+ > shell execution from skills is blocked. These fenced examples are safe to read;
12
+ > copy-paste them into your terminal to run.
13
+
9
14
  ## The 70% Rule
10
15
 
11
16
  Context windows are finite. When you estimate you've used roughly 70% of available
@@ -141,6 +146,22 @@ Practical takeaways:
141
146
  - Skills over 5k tokens get truncated after compaction. Keep skills focused.
142
147
  - The 70% rule still applies — these numbers help you estimate when you'll hit it.
143
148
 
149
+ ## Context Budget Tiers
150
+
151
+ Monitor your context usage and adjust behavior accordingly:
152
+
153
+ | Tier | Context Free | Behavior |
154
+ |------|-------------|----------|
155
+ | PEAK | >75% | Normal operation — read files freely, keep full context |
156
+ | GOOD | 50-75% | Be selective about file reads — summarize large files |
157
+ | DEGRADING | 25-50% | Summarize before reading new files, consider /compact |
158
+ | CRITICAL | <25% | Save state immediately, /compact, reload only essentials |
159
+
160
+ Heuristics (you cannot measure exact tokens):
161
+ - Many large file reads in this session = likely DEGRADING
162
+ - Long conversation with multiple tasks = likely DEGRADING
163
+ - Just started or just compacted = likely PEAK
164
+
144
165
  ## Gotchas
145
166
 
146
167
  - Compacting doesn't free as much context as you think. If you've read 20 large files,
@@ -103,6 +103,17 @@ Just do it:
103
103
  - Documentation updates
104
104
  - Config changes
105
105
 
106
+ ## Must-Haves Contract
107
+
108
+ Every plan should define must-haves that carry through from planning to verification:
109
+
110
+ - **Truths**: Observable behaviors that must be true when done (e.g., "POST /api/users returns 201 with a user object")
111
+ - **Artifacts**: Files that must exist with real implementation (e.g., "src/routes/users.js with createUser function")
112
+ - **Key Links**: Connections between artifacts (e.g., "users route imported in src/app.js and registered at /api/users")
113
+
114
+ These must-haves become the verification checklist. If the plan-reviewer doesn't see them,
115
+ it should request them. If the verify-app agent can't confirm them, the feature isn't done.
116
+
106
117
  ## Gotchas
107
118
 
108
119
  - Plans rot fast. If a plan is more than 2 sessions old and hasn't been started,
@@ -11,6 +11,11 @@ paths:
11
11
 
12
12
  # Verification
13
13
 
14
+ > **Note:** The bash examples below are reference snippets. If you enable
15
+ > `disableSkillShellExecution` in Claude Code settings (v2.1.101+), any inline
16
+ > shell execution from skills is blocked. These fenced examples are safe to read;
17
+ > copy-paste them into your terminal to run.
18
+
14
19
  ## Beyond Unit Tests
15
20
 
16
21
  Unit tests verify code logic. Verification confirms the feature actually works in
@@ -114,6 +119,19 @@ If verification fails:
114
119
  3. If you introduced it, fix it before committing.
115
120
  4. If it's pre-existing, document it and decide whether to fix now or file it.
116
121
 
122
+ ## Verification Gate Types
123
+
124
+ Different situations call for different gate behaviors:
125
+
126
+ - **Pre-flight**: Validate preconditions before starting. Deterministic checks only (file exists, env var set, branch clean). Fail fast if not met.
127
+ - **Revision**: Evaluate output quality, loop back with feedback. Maximum 3 iterations before escalating to user.
128
+ - **Escalation**: Surface unresolvable issues to the user. Pause work, present options clearly, wait for input.
129
+ - **Abort**: Terminate to prevent damage. Preserve current state, report what happened and why, suggest recovery steps.
130
+
131
+ Use pre-flight for anything that can be checked cheaply up front. Use revision for quality
132
+ gates that may need iteration. Escalate when you've exhausted your ability to resolve.
133
+ Abort only when continuing would make things worse.
134
+
117
135
  ## Gotchas
118
136
 
119
137
  - "Tests pass" is not the same as "it works." A test suite can have 100% coverage