claude-dev-kit 2.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.
Files changed (89) hide show
  1. package/.claude/agents/angelic-workshop-energy-clearing.md +113 -0
  2. package/.claude/agents/angelic-workshop-intake.md +84 -0
  3. package/.claude/agents/angelic-workshop-integration.md +140 -0
  4. package/.claude/agents/angelic-workshop-invocation.md +92 -0
  5. package/.claude/agents/angelic-workshop-lead.md +225 -0
  6. package/.claude/agents/angelic-workshop-transmission.md +108 -0
  7. package/.claude/agents/deep-think-partner.md +41 -0
  8. package/.claude/agents/dev-backend.md +74 -0
  9. package/.claude/agents/dev-e2e.md +101 -0
  10. package/.claude/agents/dev-frontend.md +82 -0
  11. package/.claude/agents/dev-lead.md +144 -0
  12. package/.claude/agents/dev-reviewer.md +122 -0
  13. package/.claude/agents/dev-test.md +88 -0
  14. package/.claude/agents/documentation-manager.md +73 -0
  15. package/.claude/agents/haiku-executor.md +8 -0
  16. package/.claude/agents/pm-groomer.md +98 -0
  17. package/.claude/agents/pm-prp-writer.md +144 -0
  18. package/.claude/agents/pm-sizer.md +84 -0
  19. package/.claude/agents/project-manager.md +91 -0
  20. package/.claude/agents/system-architect.md +98 -0
  21. package/.claude/agents/validation-gates.md +121 -0
  22. package/.claude/agents/workflow-builder.md +416 -0
  23. package/.claude/commands/ai/detect.md +117 -0
  24. package/.claude/commands/ai/route.md +128 -0
  25. package/.claude/commands/ai/switch.md +121 -0
  26. package/.claude/commands/bs/brainstorm_full.md +149 -0
  27. package/.claude/commands/bs/claude.md +37 -0
  28. package/.claude/commands/bs/codex.md +37 -0
  29. package/.claude/commands/bs/gemini.md +37 -0
  30. package/.claude/commands/bs/glm.md +37 -0
  31. package/.claude/commands/bs/grok.md +37 -0
  32. package/.claude/commands/bs/kimi.md +37 -0
  33. package/.claude/commands/bs/minimax.md +37 -0
  34. package/.claude/commands/bs/ollama.md +71 -0
  35. package/.claude/commands/code/build-and-fix.md +80 -0
  36. package/.claude/commands/code/simplify.md +77 -0
  37. package/.claude/commands/dev/backend.md +47 -0
  38. package/.claude/commands/dev/e2e.md +49 -0
  39. package/.claude/commands/dev/frontend.md +45 -0
  40. package/.claude/commands/dev/review.md +48 -0
  41. package/.claude/commands/dev/test.md +54 -0
  42. package/.claude/commands/dev-epic.md +121 -0
  43. package/.claude/commands/dev-issue.md +79 -0
  44. package/.claude/commands/dev.md +134 -0
  45. package/.claude/commands/execute-prp.md +113 -0
  46. package/.claude/commands/fix-github-issue.md +14 -0
  47. package/.claude/commands/generate-prp.md +73 -0
  48. package/.claude/commands/git/status.md +14 -0
  49. package/.claude/commands/haiku.md +13 -0
  50. package/.claude/commands/improve.md +178 -0
  51. package/.claude/commands/init.md +311 -0
  52. package/.claude/commands/pm/groom.md +58 -0
  53. package/.claude/commands/pm/plan-epic.md +74 -0
  54. package/.claude/commands/pm/size.md +46 -0
  55. package/.claude/commands/pm.md +47 -0
  56. package/.claude/commands/primer.md +16 -0
  57. package/.claude/commands/self-improve.md +243 -0
  58. package/.claude/commands/think.md +68 -0
  59. package/.claude/commands/workflow/angelic-workshop.md +89 -0
  60. package/.claude/commands/workflow/build.md +91 -0
  61. package/.claude/hooks/pre-tool-use/block-dangerous-commands.js +196 -0
  62. package/.claude/hooks/skill-activation-prompt/package-lock.json +560 -0
  63. package/.claude/hooks/skill-activation-prompt/package.json +16 -0
  64. package/.claude/hooks/skill-activation-prompt/skill-activation-prompt.ts +135 -0
  65. package/.claude/hooks/skill-activation-prompt/skill-rules.json +50 -0
  66. package/.claude/hooks/stop/context_monitor.py +155 -0
  67. package/.claude/hooks/stop/learning_logger.py +218 -0
  68. package/.claude/skills/ai-router/SKILL.md +119 -0
  69. package/.claude/skills/build-and-fix/SKILL.md +271 -0
  70. package/.claude/skills/build-and-fix/examples/javascript-lint-fix.md +37 -0
  71. package/.claude/skills/build-and-fix/language-configs/javascript.yaml +139 -0
  72. package/.claude/skills/build-and-fix/references/config-schema.md +120 -0
  73. package/.claude/skills/build-and-fix/references/error-patterns.md +273 -0
  74. package/.claude/skills/code-investigator/SKILL.md +299 -0
  75. package/.claude/skills/code-investigator/references/investigation-workflows.md +542 -0
  76. package/.claude/skills/code-investigator/references/language-specific.md +761 -0
  77. package/.claude/skills/code-investigator/references/search-patterns.md +258 -0
  78. package/.claude/skills/code-investigator/references/serena-patterns.md +328 -0
  79. package/.claude/skills/stack-detector/SKILL.md +153 -0
  80. package/.claude/skills/verification-before-completion/SKILL.md +143 -0
  81. package/.claude/templates/claude-md-template.md +56 -0
  82. package/.claude/templates/stacks/express-node.md +134 -0
  83. package/.claude/templates/stacks/fastapi.md +152 -0
  84. package/.claude/templates/stacks/generic.md +101 -0
  85. package/.claude/templates/stacks/nextjs-prisma.md +235 -0
  86. package/README.md +499 -0
  87. package/bin/claude-dev-kit.js +11 -0
  88. package/package.json +31 -0
  89. package/scripts/install.sh +448 -0
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Block Dangerous Commands - PreToolUse Hook for Bash
4
+ * Blocks dangerous patterns before execution. Logs to: ~/.claude/hooks-logs/
5
+ *
6
+ * SAFETY_LEVEL: 'critical' | 'high' | 'strict'
7
+ * critical - Only catastrophic: rm -rf ~, dd to disk, fork bombs
8
+ * high - + risky: force push main, secrets exposure, git reset --hard
9
+ * strict - + cautionary: any force push, sudo rm, docker prune
10
+ *
11
+ * Setup in .claude/settings.json:
12
+ * {
13
+ * "hooks": {
14
+ * "PreToolUse": [{
15
+ * "matcher": "Bash",
16
+ * "hooks": [{ "type": "command", "command": "node /path/to/block-dangerous-commands.js" }]
17
+ * }]
18
+ * }
19
+ * }
20
+ */
21
+
22
+ const fs = require('fs');
23
+ const path = require('path');
24
+
25
+ const SAFETY_LEVEL = 'high';
26
+
27
+ const PATTERNS = [
28
+ // CRITICAL - Catastrophic, unrecoverable
29
+ { level: 'critical', id: 'rm-home', regex: /\brm\s+(-.+\s+)*~(\/|\s|$|[;&|])/, reason: 'rm targeting home directory' },
30
+ { level: 'critical', id: 'rm-home-quoted', regex: /\brm\s+(-.+\s+)*["']~\/?["'](\s|$|[;&|])/, reason: 'rm targeting quoted home directory' },
31
+ { level: 'critical', id: 'rm-home-var', regex: /\brm\s+(-.+\s+)*(\$HOME|\$\{HOME\})(\/|\s|$|[;&|])/, reason: 'rm targeting $HOME' },
32
+ { level: 'critical', id: 'rm-home-trailing', regex: /\brm\s+.+\s+(~\/?|\$HOME|\$\{HOME\})(\s*$|[;&|])/, reason: 'rm with trailing ~/ or $HOME' },
33
+ { level: 'critical', id: 'rm-root', regex: /\brm\s+(-.+\s+)*\/(\*|\s|$|[;&|])/, reason: 'rm targeting root filesystem' },
34
+ { level: 'critical', id: 'rm-system', regex: /\brm\s+(-.+\s+)*\/(etc|usr|var|bin|sbin|lib|boot|dev|proc|sys)(\/|\s|$)/, reason: 'rm targeting system directory' },
35
+ { level: 'critical', id: 'rm-cwd', regex: /\brm\s+(-.+\s+)*(\.\/?|\*|\.\/\*)(\s|$|[;&|])/, reason: 'rm deleting current directory contents' },
36
+ { level: 'critical', id: 'dd-disk', regex: /\bdd\b.+of=\/dev\/(sd[a-z]|nvme|hd[a-z]|vd[a-z]|xvd[a-z])/, reason: 'dd writing to disk device' },
37
+ { level: 'critical', id: 'mkfs', regex: /\bmkfs(\.\w+)?\s+\/dev\/(sd[a-z]|nvme|hd[a-z]|vd[a-z])/, reason: 'mkfs formatting disk' },
38
+ { level: 'critical', id: 'fork-bomb', regex: /:\(\)\s*\{.*:\s*\|\s*:.*&/, reason: 'fork bomb detected' },
39
+
40
+ // HIGH - Significant risk, data loss, security
41
+ { level: 'high', id: 'curl-pipe-sh', regex: /\b(curl|wget)\b.+\|\s*(ba)?sh\b/, reason: 'piping URL to shell (RCE risk)' },
42
+ { level: 'high', id: 'git-force-main', regex: /\bgit\s+push\b(?!.+--force-with-lease).+(--force|-f)\b.+\b(main|master)\b/, reason: 'force push to main/master' },
43
+ { level: 'high', id: 'git-reset-hard', regex: /\bgit\s+reset\s+--hard/, reason: 'git reset --hard loses uncommitted work' },
44
+ { level: 'high', id: 'git-clean-f', regex: /\bgit\s+clean\s+(-\w*f|-f)/, reason: 'git clean -f deletes untracked files' },
45
+ { level: 'high', id: 'chmod-777', regex: /\bchmod\b.+\b777\b/, reason: 'chmod 777 is a security risk' },
46
+ { level: 'high', id: 'cat-env', regex: /\b(cat|less|head|tail|more)\s+\.env\b/, reason: 'reading .env file exposes secrets' },
47
+ { level: 'high', id: 'cat-secrets', regex: /\b(cat|less|head|tail|more)\b.+(credentials|secrets?|\.pem|\.key|id_rsa|id_ed25519)/i, reason: 'reading secrets file' },
48
+ { level: 'high', id: 'env-dump', regex: /\b(printenv|^env)\s*([;&|]|$)/, reason: 'env dump may expose secrets' },
49
+ { level: 'high', id: 'echo-secret', regex: /\becho\b.+\$\w*(SECRET|KEY|TOKEN|PASSWORD|API_|PRIVATE)/i, reason: 'echoing secret variable' },
50
+ { level: 'high', id: 'docker-vol-rm', regex: /\bdocker\s+volume\s+(rm|prune)/, reason: 'docker volume deletion loses data' },
51
+ { level: 'high', id: 'rm-ssh', regex: /\brm\b.+\.ssh\/(id_|authorized_keys|known_hosts)/, reason: 'deleting SSH keys' },
52
+
53
+ // STRICT - Cautionary, context-dependent
54
+ { level: 'strict', id: 'git-force-any', regex: /\bgit\s+push\b(?!.+--force-with-lease).+(--force|-f)\b/, reason: 'force push (use --force-with-lease)' },
55
+ { level: 'strict', id: 'git-checkout-dot', regex: /\bgit\s+checkout\s+\./, reason: 'git checkout . discards changes' },
56
+ { level: 'strict', id: 'sudo-rm', regex: /\bsudo\s+rm\b/, reason: 'sudo rm has elevated privileges' },
57
+ { level: 'strict', id: 'docker-prune', regex: /\bdocker\s+(system|image)\s+prune/, reason: 'docker prune removes images' },
58
+ { level: 'strict', id: 'crontab-r', regex: /\bcrontab\s+-r/, reason: 'removes all cron jobs' },
59
+ ];
60
+
61
+ const LEVELS = { critical: 1, high: 2, strict: 3 };
62
+ const EMOJIS = { critical: '🚨', high: '⛔', strict: '⚠️' };
63
+ const LOG_DIR = path.join(process.env.HOME, '.claude', 'hooks-logs');
64
+
65
+ function log(data) {
66
+ try {
67
+ if (!fs.existsSync(LOG_DIR)) fs.mkdirSync(LOG_DIR, { recursive: true });
68
+ const file = path.join(LOG_DIR, `${new Date().toISOString().slice(0, 10)}.jsonl`);
69
+ fs.appendFileSync(file, JSON.stringify({ ts: new Date().toISOString(), ...data }) + '\n');
70
+ } catch {}
71
+ }
72
+
73
+ /**
74
+ * Normalize a command string before pattern matching to defeat trivial bypasses:
75
+ * - Collapse multiple spaces/tabs into single space
76
+ * - Normalize Unicode whitespace
77
+ * - Remove surrounding quotes from individual tokens (not from the whole string)
78
+ */
79
+ function normalizeSegment(segment) {
80
+ return segment
81
+ .replace(/[\t\r\n\u00a0\u2002-\u200b\u202f\u205f\u3000]+/g, ' ') // normalize whitespace variants
82
+ .replace(/\s{2,}/g, ' ') // collapse multiple spaces
83
+ .trim();
84
+ }
85
+
86
+ /**
87
+ * Split a shell command on chain operators: &&, ||, ;, |, and newlines.
88
+ * This ensures each sub-command in a chain is checked independently.
89
+ * Handles quoted strings to avoid splitting inside them.
90
+ */
91
+ function splitOnChainOperators(cmd) {
92
+ const segments = [];
93
+ let current = '';
94
+ let i = 0;
95
+ let inSingleQuote = false;
96
+ let inDoubleQuote = false;
97
+
98
+ while (i < cmd.length) {
99
+ const ch = cmd[i];
100
+ const ch2 = cmd.slice(i, i + 2);
101
+
102
+ // Track quote state
103
+ if (ch === "'" && !inDoubleQuote) {
104
+ inSingleQuote = !inSingleQuote;
105
+ current += ch;
106
+ i++;
107
+ continue;
108
+ }
109
+ if (ch === '"' && !inSingleQuote) {
110
+ inDoubleQuote = !inDoubleQuote;
111
+ current += ch;
112
+ i++;
113
+ continue;
114
+ }
115
+
116
+ // Split on chain operators when not inside quotes
117
+ if (!inSingleQuote && !inDoubleQuote) {
118
+ if (ch2 === '&&' || ch2 === '||') {
119
+ segments.push(current);
120
+ current = '';
121
+ i += 2;
122
+ continue;
123
+ }
124
+ if (ch === ';' || ch === '|' || ch === '\n') {
125
+ segments.push(current);
126
+ current = '';
127
+ i++;
128
+ continue;
129
+ }
130
+ }
131
+
132
+ current += ch;
133
+ i++;
134
+ }
135
+ if (current.trim()) segments.push(current);
136
+ return segments.map(normalizeSegment).filter(Boolean);
137
+ }
138
+
139
+ function checkCommand(cmd, safetyLevel = SAFETY_LEVEL) {
140
+ const threshold = LEVELS[safetyLevel] || 2;
141
+
142
+ // Check the full command first (catches patterns that span operators)
143
+ for (const p of PATTERNS) {
144
+ if (LEVELS[p.level] <= threshold && p.regex.test(cmd)) {
145
+ return { blocked: true, pattern: p };
146
+ }
147
+ }
148
+
149
+ // Then check each segment independently (catches chained dangerous commands)
150
+ const segments = splitOnChainOperators(cmd);
151
+ for (const segment of segments) {
152
+ for (const p of PATTERNS) {
153
+ if (LEVELS[p.level] <= threshold && p.regex.test(segment)) {
154
+ return { blocked: true, pattern: p };
155
+ }
156
+ }
157
+ }
158
+
159
+ return { blocked: false, pattern: null };
160
+ }
161
+
162
+ async function main() {
163
+ let input = '';
164
+ for await (const chunk of process.stdin) input += chunk;
165
+
166
+ try {
167
+ const data = JSON.parse(input);
168
+ const { tool_name, tool_input, session_id, cwd, permission_mode } = data;
169
+ if (tool_name !== 'Bash') return console.log('{}');
170
+
171
+ const cmd = tool_input?.command || '';
172
+ const result = checkCommand(cmd);
173
+
174
+ if (result.blocked) {
175
+ const p = result.pattern;
176
+ log({ level: 'BLOCKED', id: p.id, priority: p.level, cmd, session_id, cwd, permission_mode });
177
+ return console.log(JSON.stringify({
178
+ hookSpecificOutput: {
179
+ hookEventName: 'PreToolUse',
180
+ permissionDecision: 'deny',
181
+ permissionDecisionReason: `${EMOJIS[p.level]} [${p.id}] ${p.reason}`
182
+ }
183
+ }));
184
+ }
185
+ console.log('{}');
186
+ } catch (e) {
187
+ log({ level: 'ERROR', error: e.message });
188
+ console.log('{}');
189
+ }
190
+ }
191
+
192
+ if (require.main === module) {
193
+ main();
194
+ } else {
195
+ module.exports = { PATTERNS, LEVELS, SAFETY_LEVEL, checkCommand, splitOnChainOperators, normalizeSegment };
196
+ }