create-claude-stack 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 +126 -0
- package/bin/create.js +353 -0
- package/package.json +36 -0
- package/template/CLAUDE.md +88 -0
- package/template/agents/engineer.md +39 -0
- package/template/agents/obsidian.md +51 -0
- package/template/agents/pm.md +45 -0
- package/template/agents/researcher.md +57 -0
- package/template/hooks/discord-notify.sh +46 -0
- package/template/hooks/gsd-context-monitor.js +156 -0
- package/template/hooks/safety-guard.js +81 -0
- package/template/mcp.json +34 -0
- package/template/rules/agents.md +20 -0
- package/template/rules/code-standards.md +30 -0
- package/template/rules/cognitive.md +37 -0
- package/template/rules/git-workflow.md +22 -0
- package/template/rules/new-project.md +13 -0
- package/template/settings.json +145 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pm
|
|
3
|
+
description: Technical PM agent. Use for GSD phase planning, roadmap management, milestone tracking, and task decomposition. Routes all project work through GSD protocol.
|
|
4
|
+
tools: Read, Write, Bash, Glob, Grep, TodoWrite
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a technical project manager operating via the GSD protocol.
|
|
8
|
+
|
|
9
|
+
## GSD Workflow
|
|
10
|
+
|
|
11
|
+
All project work uses GSD. Always check project state first:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
/gsd:progress
|
|
15
|
+
/gsd:plan-phase
|
|
16
|
+
/gsd:execute-phase
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Phase Planning
|
|
20
|
+
|
|
21
|
+
1. `/gsd:discuss-phase` — gather context
|
|
22
|
+
2. `/gsd:plan-phase` — create PLAN.md
|
|
23
|
+
3. Review plan with user before executing
|
|
24
|
+
4. `/gsd:execute-phase` — implement
|
|
25
|
+
|
|
26
|
+
## Milestone Management
|
|
27
|
+
|
|
28
|
+
- `/gsd:new-milestone` — start new milestone
|
|
29
|
+
- `/gsd:audit-milestone` — audit before archiving
|
|
30
|
+
- `/gsd:complete-milestone` — archive and prepare next
|
|
31
|
+
|
|
32
|
+
## Task Decomposition
|
|
33
|
+
|
|
34
|
+
Break work into GSD phases. Each phase:
|
|
35
|
+
|
|
36
|
+
- Has a single clear goal
|
|
37
|
+
- Produces verifiable output
|
|
38
|
+
- Takes 1-4 hours of execution time
|
|
39
|
+
- Has explicit success criteria
|
|
40
|
+
|
|
41
|
+
## Context Preservation
|
|
42
|
+
|
|
43
|
+
At natural stopping points: `/gsd:pause-work`
|
|
44
|
+
|
|
45
|
+
Resuming: `/gsd:resume-work`
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: researcher
|
|
3
|
+
description: Research agent. Use for web research, library documentation, technology comparisons, deep codebase investigations, and finding authoritative information. Captures findings to Obsidian vault.
|
|
4
|
+
tools: WebSearch, WebFetch, Bash, Read, Glob, Grep, Agent
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a technical researcher. Your job is to thoroughly investigate a question and return a concise, well-sourced answer. Use your large context window freely — be deep in research, tight in output.
|
|
8
|
+
|
|
9
|
+
## Principles
|
|
10
|
+
|
|
11
|
+
1. **Be thorough** — Search multiple angles. Don't stop at the first result.
|
|
12
|
+
2. **Be concise in output** — Your final answer should be tight. The parent agent doesn't want a novel.
|
|
13
|
+
3. **Cite sources** — Include URLs, file paths, or line numbers for every claim.
|
|
14
|
+
4. **Distinguish fact from inference** — Clearly mark when you're speculating vs. reporting what you found.
|
|
15
|
+
|
|
16
|
+
## Research Strategy
|
|
17
|
+
|
|
18
|
+
1. Start with context7 for library docs (`mcp__plugin_context7_context7__*`) — most accurate, version-specific
|
|
19
|
+
2. Use WebSearch / Brave Search for current information
|
|
20
|
+
3. Use WebFetch to read specific pages in full
|
|
21
|
+
4. Use Glob/Grep to explore codebases
|
|
22
|
+
5. Synthesize findings — do not dump raw search results
|
|
23
|
+
|
|
24
|
+
## Process
|
|
25
|
+
|
|
26
|
+
1. Break the question into sub-questions if needed
|
|
27
|
+
2. Search the web, read files, grep codebases — whatever it takes
|
|
28
|
+
3. Synthesize findings into a structured answer
|
|
29
|
+
4. Write output to the file path provided in your prompt (if given), otherwise return inline
|
|
30
|
+
|
|
31
|
+
## Output Format
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
## Answer
|
|
35
|
+
Direct answer to the question (1-3 sentences).
|
|
36
|
+
|
|
37
|
+
## Key Findings
|
|
38
|
+
- Finding 1 (source: URL or file:line)
|
|
39
|
+
- Finding 2 (source: URL or file:line)
|
|
40
|
+
|
|
41
|
+
## Details
|
|
42
|
+
Deeper explanation if needed. Keep it under 500 words.
|
|
43
|
+
|
|
44
|
+
## Recommendation
|
|
45
|
+
Recommended path forward with rationale.
|
|
46
|
+
|
|
47
|
+
## Next Steps
|
|
48
|
+
Concrete next actions.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
If you cannot find a definitive answer, say so and explain what you did find.
|
|
52
|
+
|
|
53
|
+
## Capturing Findings
|
|
54
|
+
|
|
55
|
+
After research, offer to save to Obsidian via `mcp__obsidian__write_note`.
|
|
56
|
+
|
|
57
|
+
Path pattern: `Research/YYYY-MM-DD-topic.md`
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Discord notification hook for Claude Code
|
|
3
|
+
# Called by Stop/Notification hooks in settings.json
|
|
4
|
+
# Usage: bash discord-notify.sh <event-type>
|
|
5
|
+
# Receives JSON context via stdin
|
|
6
|
+
|
|
7
|
+
EVENT="${1:-stop}"
|
|
8
|
+
|
|
9
|
+
# Extract DISCORD_WEBHOOK_URL from ~/.claude/.env (handles quoted values)
|
|
10
|
+
ENV_FILE="$HOME/.claude/.env"
|
|
11
|
+
DISCORD_WEBHOOK_URL=""
|
|
12
|
+
if [ -f "$ENV_FILE" ]; then
|
|
13
|
+
RAW=$(grep '^DISCORD_WEBHOOK_URL=' "$ENV_FILE" | head -1)
|
|
14
|
+
DISCORD_WEBHOOK_URL="${RAW#DISCORD_WEBHOOK_URL=}"
|
|
15
|
+
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL#\"}"
|
|
16
|
+
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL%\"}"
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
[ -z "$DISCORD_WEBHOOK_URL" ] && exit 0
|
|
20
|
+
|
|
21
|
+
# Read stdin (Claude Code passes session JSON here)
|
|
22
|
+
INPUT=$(timeout 2 cat 2>/dev/null || echo '{}')
|
|
23
|
+
|
|
24
|
+
# Build message based on event type
|
|
25
|
+
case "$EVENT" in
|
|
26
|
+
stop)
|
|
27
|
+
SESSION_ID=$(echo "$INPUT" | python3 -c \
|
|
28
|
+
"import sys,json; d=json.load(sys.stdin); print(d.get('session_id','')[:8])" \
|
|
29
|
+
2>/dev/null || echo "")
|
|
30
|
+
# Skip --print mode sessions (no session_id = ephemeral CLI call, not a real session)
|
|
31
|
+
[ -z "$SESSION_ID" ] && exit 0
|
|
32
|
+
MSG="\u2705 **Claude Code** | Session \`${SESSION_ID}\` complete"
|
|
33
|
+
;;
|
|
34
|
+
notification)
|
|
35
|
+
MSG="\ud83d\udc4b **Claude Code** | Needs your attention"
|
|
36
|
+
;;
|
|
37
|
+
*)
|
|
38
|
+
MSG="\ud83d\udccc **Claude Code** | ${EVENT}"
|
|
39
|
+
;;
|
|
40
|
+
esac
|
|
41
|
+
|
|
42
|
+
# POST to Discord webhook
|
|
43
|
+
curl -s -X POST "$DISCORD_WEBHOOK_URL" \
|
|
44
|
+
-H "Content-Type: application/json" \
|
|
45
|
+
-d "{\"username\":\"Claude Code\",\"content\":\"${MSG}\"}" \
|
|
46
|
+
> /dev/null 2>&1 || true
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// gsd-hook-version: 1.27.0
|
|
3
|
+
// Context Monitor - PostToolUse/AfterTool hook (Gemini uses AfterTool)
|
|
4
|
+
// Reads context metrics from the statusline bridge file and injects
|
|
5
|
+
// warnings when context usage is high. This makes the AGENT aware of
|
|
6
|
+
// context limits (the statusline only shows the user).
|
|
7
|
+
//
|
|
8
|
+
// How it works:
|
|
9
|
+
// 1. The statusline hook writes metrics to /tmp/claude-ctx-{session_id}.json
|
|
10
|
+
// 2. This hook reads those metrics after each tool use
|
|
11
|
+
// 3. When remaining context drops below thresholds, it injects a warning
|
|
12
|
+
// as additionalContext, which the agent sees in its conversation
|
|
13
|
+
//
|
|
14
|
+
// Thresholds:
|
|
15
|
+
// WARNING (remaining <= 35%): Agent should wrap up current task
|
|
16
|
+
// CRITICAL (remaining <= 25%): Agent should stop immediately and save state
|
|
17
|
+
//
|
|
18
|
+
// Debounce: 5 tool uses between warnings to avoid spam
|
|
19
|
+
// Severity escalation bypasses debounce (WARNING -> CRITICAL fires immediately)
|
|
20
|
+
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const os = require('os');
|
|
23
|
+
const path = require('path');
|
|
24
|
+
|
|
25
|
+
const WARNING_THRESHOLD = 35; // remaining_percentage <= 35%
|
|
26
|
+
const CRITICAL_THRESHOLD = 25; // remaining_percentage <= 25%
|
|
27
|
+
const STALE_SECONDS = 60; // ignore metrics older than 60s
|
|
28
|
+
const DEBOUNCE_CALLS = 5; // min tool uses between warnings
|
|
29
|
+
|
|
30
|
+
let input = '';
|
|
31
|
+
// Timeout guard: if stdin doesn't close within 10s (e.g. pipe issues on
|
|
32
|
+
// Windows/Git Bash, or slow Claude Code piping during large outputs),
|
|
33
|
+
// exit silently instead of hanging until Claude Code kills the process
|
|
34
|
+
// and reports "hook error". See #775, #1162.
|
|
35
|
+
const stdinTimeout = setTimeout(() => process.exit(0), 10000);
|
|
36
|
+
process.stdin.setEncoding('utf8');
|
|
37
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
38
|
+
process.stdin.on('end', () => {
|
|
39
|
+
clearTimeout(stdinTimeout);
|
|
40
|
+
try {
|
|
41
|
+
const data = JSON.parse(input);
|
|
42
|
+
const sessionId = data.session_id;
|
|
43
|
+
|
|
44
|
+
if (!sessionId) {
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Check if context warnings are disabled via config
|
|
49
|
+
const cwd = data.cwd || process.cwd();
|
|
50
|
+
const configPath = path.join(cwd, '.planning', 'config.json');
|
|
51
|
+
if (fs.existsSync(configPath)) {
|
|
52
|
+
try {
|
|
53
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
54
|
+
if (config.hooks?.context_warnings === false) {
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
} catch (e) {
|
|
58
|
+
// Ignore config parse errors
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const tmpDir = os.tmpdir();
|
|
63
|
+
const metricsPath = path.join(tmpDir, `claude-ctx-${sessionId}.json`);
|
|
64
|
+
|
|
65
|
+
// If no metrics file, this is a subagent or fresh session -- exit silently
|
|
66
|
+
if (!fs.existsSync(metricsPath)) {
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const metrics = JSON.parse(fs.readFileSync(metricsPath, 'utf8'));
|
|
71
|
+
const now = Math.floor(Date.now() / 1000);
|
|
72
|
+
|
|
73
|
+
// Ignore stale metrics
|
|
74
|
+
if (metrics.timestamp && (now - metrics.timestamp) > STALE_SECONDS) {
|
|
75
|
+
process.exit(0);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const remaining = metrics.remaining_percentage;
|
|
79
|
+
const usedPct = metrics.used_pct;
|
|
80
|
+
|
|
81
|
+
// No warning needed
|
|
82
|
+
if (remaining > WARNING_THRESHOLD) {
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Debounce: check if we warned recently
|
|
87
|
+
const warnPath = path.join(tmpDir, `claude-ctx-${sessionId}-warned.json`);
|
|
88
|
+
let warnData = { callsSinceWarn: 0, lastLevel: null };
|
|
89
|
+
let firstWarn = true;
|
|
90
|
+
|
|
91
|
+
if (fs.existsSync(warnPath)) {
|
|
92
|
+
try {
|
|
93
|
+
warnData = JSON.parse(fs.readFileSync(warnPath, 'utf8'));
|
|
94
|
+
firstWarn = false;
|
|
95
|
+
} catch (e) {
|
|
96
|
+
// Corrupted file, reset
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
warnData.callsSinceWarn = (warnData.callsSinceWarn || 0) + 1;
|
|
101
|
+
|
|
102
|
+
const isCritical = remaining <= CRITICAL_THRESHOLD;
|
|
103
|
+
const currentLevel = isCritical ? 'critical' : 'warning';
|
|
104
|
+
|
|
105
|
+
// Emit immediately on first warning, then debounce subsequent ones
|
|
106
|
+
// Severity escalation (WARNING -> CRITICAL) bypasses debounce
|
|
107
|
+
const severityEscalated = currentLevel === 'critical' && warnData.lastLevel === 'warning';
|
|
108
|
+
if (!firstWarn && warnData.callsSinceWarn < DEBOUNCE_CALLS && !severityEscalated) {
|
|
109
|
+
// Update counter and exit without warning
|
|
110
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
111
|
+
process.exit(0);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Reset debounce counter
|
|
115
|
+
warnData.callsSinceWarn = 0;
|
|
116
|
+
warnData.lastLevel = currentLevel;
|
|
117
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
118
|
+
|
|
119
|
+
// Detect if GSD is active (has .planning/STATE.md in working directory)
|
|
120
|
+
const isGsdActive = fs.existsSync(path.join(cwd, '.planning', 'STATE.md'));
|
|
121
|
+
|
|
122
|
+
// Build advisory warning message (never use imperative commands that
|
|
123
|
+
// override user preferences — see #884)
|
|
124
|
+
let message;
|
|
125
|
+
if (isCritical) {
|
|
126
|
+
message = isGsdActive
|
|
127
|
+
? `CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
128
|
+
'Context is nearly exhausted. Do NOT start new complex work or write handoff files — ' +
|
|
129
|
+
'GSD state is already tracked in STATE.md. Inform the user so they can run ' +
|
|
130
|
+
'/gsd:pause-work at the next natural stopping point.'
|
|
131
|
+
: `CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
132
|
+
'Context is nearly exhausted. Inform the user that context is low and ask how they ' +
|
|
133
|
+
'want to proceed. Do NOT autonomously save state or write handoff files unless the user asks.';
|
|
134
|
+
} else {
|
|
135
|
+
message = isGsdActive
|
|
136
|
+
? `CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
137
|
+
'Context is getting limited. Avoid starting new complex work. If not between ' +
|
|
138
|
+
'defined plan steps, inform the user so they can prepare to pause.'
|
|
139
|
+
: `CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
140
|
+
'Be aware that context is getting limited. Avoid unnecessary exploration or ' +
|
|
141
|
+
'starting new complex work.';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const output = {
|
|
145
|
+
hookSpecificOutput: {
|
|
146
|
+
hookEventName: process.env.GEMINI_API_KEY ? "AfterTool" : "PostToolUse",
|
|
147
|
+
additionalContext: message
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
process.stdout.write(JSON.stringify(output));
|
|
152
|
+
} catch (e) {
|
|
153
|
+
// Silent fail -- never block tool execution
|
|
154
|
+
process.exit(0);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// gsd-hook-version: 1.26.0
|
|
3
|
+
/**
|
|
4
|
+
* PreToolUse safety guard
|
|
5
|
+
* Checks each subcommand in a pipeline/sequence individually.
|
|
6
|
+
* Only fires a pattern when the subcommand's first word matches.
|
|
7
|
+
* Exit with block decision JSON = blocked.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
let raw = '';
|
|
11
|
+
process.stdin.setEncoding('utf8');
|
|
12
|
+
process.stdin.on('data', chunk => { raw += chunk; });
|
|
13
|
+
process.stdin.on('end', () => {
|
|
14
|
+
let input = {};
|
|
15
|
+
try { input = JSON.parse(raw); } catch (_) { process.exit(0); }
|
|
16
|
+
|
|
17
|
+
const toolName = input.tool_name || '';
|
|
18
|
+
const toolInput = input.tool_input || {};
|
|
19
|
+
if (toolName !== 'Bash') process.exit(0);
|
|
20
|
+
|
|
21
|
+
const cmd = (toolInput.command || '').trim();
|
|
22
|
+
|
|
23
|
+
// Split on shell sequence operators to get individual commands
|
|
24
|
+
const subcommands = cmd.split(/\s*(?:;|&&|\|\|)\s*/).map(s => s.trim()).filter(Boolean);
|
|
25
|
+
|
|
26
|
+
// ─── Rules ────────────────────────────────────────────────────────────────────
|
|
27
|
+
//
|
|
28
|
+
// firstWord: only apply this rule when the subcommand starts with this word
|
|
29
|
+
// (null = apply to any subcommand)
|
|
30
|
+
// re: pattern to test against the full subcommand string
|
|
31
|
+
// level: 'block' (hard stop) or 'warn' (stderr only, allow through)
|
|
32
|
+
|
|
33
|
+
const RULES = [
|
|
34
|
+
// Hard blocks
|
|
35
|
+
{ firstWord: 'rm', level: 'block', re: /rm\s+(-[a-z]*f[a-z]*r[a-z]*|-[a-z]*r[a-z]*f[a-z]*)\s+(\/(\s|$|[;|&*])|~(\s|$|[;|&])|\$HOME(\s|$|[;|&])|\/\*)/, label: 'rm -rf on root/home' },
|
|
36
|
+
{ firstWord: 'chmod', level: 'block', re: /chmod\s+-R\s+777/, label: 'chmod -R 777' },
|
|
37
|
+
{ firstWord: 'kill', level: 'block', re: /kill\s+(-9\s+)?1(\s|$)/, label: 'kill PID 1 (init)' },
|
|
38
|
+
{ firstWord: null, level: 'block', re: /:\(\)\s*\{.*\};\s*:/, label: 'fork bomb' },
|
|
39
|
+
{ firstWord: null, level: 'block', re: />\s*(\/etc\/passwd|\/etc\/sudoers|\/etc\/hosts)/, label: 'overwrite system file' },
|
|
40
|
+
{ firstWords: ['psql', 'mysql', 'sqlite3', 'pgcli', 'mycli', 'duckdb'],
|
|
41
|
+
level: 'block', re: /DROP\s+DATABASE/i, label: 'DROP DATABASE via SQL client' },
|
|
42
|
+
|
|
43
|
+
// Warnings (already gated by permissions.ask, this is belt-and-suspenders)
|
|
44
|
+
{ firstWord: 'rm', level: 'warn', re: /rm\s+(-[a-z]*f[a-z]*r[a-z]*|-[a-z]*r[a-z]*f[a-z]*)/, label: 'recursive force rm' },
|
|
45
|
+
{ firstWord: 'git', level: 'warn', re: /git\s+push\s+.*--force/, label: 'force push' },
|
|
46
|
+
{ firstWord: 'git', level: 'warn', re: /git\s+reset\s+--hard/, label: 'git reset --hard' },
|
|
47
|
+
{ firstWord: 'git', level: 'warn', re: /git\s+(checkout\s+--|restore)\s+\./, label: 'discard all working tree changes' },
|
|
48
|
+
{ firstWord: 'git', level: 'warn', re: /git\s+clean\s+-[a-z]*f/, label: 'git clean -f' },
|
|
49
|
+
{ firstWords: ['psql', 'mysql', 'sqlite3', 'pgcli', 'mycli', 'duckdb'],
|
|
50
|
+
level: 'warn', re: /DROP\s+TABLE/i, label: 'DROP TABLE via SQL client' },
|
|
51
|
+
{ firstWords: ['psql', 'mysql', 'sqlite3', 'pgcli', 'mycli', 'duckdb'],
|
|
52
|
+
level: 'warn', re: /TRUNCATE\s+TABLE/i, label: 'TRUNCATE TABLE via SQL client' },
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
function firstWordOf(s) {
|
|
56
|
+
return s.split(/\s+/)[0].replace(/^.*\//, ''); // strip path prefix (e.g. /usr/bin/rm → rm)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function ruleApplies(rule, subcmd) {
|
|
60
|
+
const fw = firstWordOf(subcmd);
|
|
61
|
+
if (rule.firstWord !== undefined && rule.firstWord !== null && fw !== rule.firstWord) return false;
|
|
62
|
+
if (rule.firstWords && !rule.firstWords.includes(fw)) return false;
|
|
63
|
+
return rule.re.test(subcmd);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const subcmd of subcommands) {
|
|
67
|
+
for (const rule of RULES) {
|
|
68
|
+
if (!ruleApplies(rule, subcmd)) continue;
|
|
69
|
+
if (rule.level === 'block') {
|
|
70
|
+
process.stdout.write(JSON.stringify({ decision: 'block', reason: `safety-guard: ${rule.label}` }));
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
if (rule.level === 'warn') {
|
|
74
|
+
process.stderr.write(`[safety-guard] WARNING: ${rule.label}\n subcmd: ${subcmd}\n`);
|
|
75
|
+
break; // one warning per subcommand is enough
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
process.exit(0);
|
|
81
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"filesystem": {
|
|
4
|
+
"type": "stdio",
|
|
5
|
+
"command": "npx",
|
|
6
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "__SRC_DIR__"],
|
|
7
|
+
"description": "Direct file access to all projects in __SRC_DIR__"
|
|
8
|
+
},
|
|
9
|
+
"brave-search": {
|
|
10
|
+
"type": "stdio",
|
|
11
|
+
"command": "npx",
|
|
12
|
+
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
|
|
13
|
+
"env": {
|
|
14
|
+
"BRAVE_API_KEY": "${BRAVE_API_KEY}"
|
|
15
|
+
},
|
|
16
|
+
"description": "Web search via Brave Search API — BRAVE_API_KEY in ~/.claude/.env"
|
|
17
|
+
},
|
|
18
|
+
"firecrawl": {
|
|
19
|
+
"type": "stdio",
|
|
20
|
+
"command": "npx",
|
|
21
|
+
"args": ["-y", "firecrawl-mcp"],
|
|
22
|
+
"env": {
|
|
23
|
+
"FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}"
|
|
24
|
+
},
|
|
25
|
+
"description": "Web scraping and crawling — FIRECRAWL_API_KEY in ~/.claude/.env"
|
|
26
|
+
},
|
|
27
|
+
"repomix": {
|
|
28
|
+
"type": "stdio",
|
|
29
|
+
"command": "npx",
|
|
30
|
+
"args": ["-y", "repomix@latest", "--mcp"],
|
|
31
|
+
"description": "Pack local/remote repos into LLM-readable format"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: When and how to invoke specialized agents and parallel dispatch patterns
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Agent Usage
|
|
6
|
+
|
|
7
|
+
| Agent | Invoke for |
|
|
8
|
+
|-------|-----------|
|
|
9
|
+
| engineer | code, debugging, TDD, PR review, GitHub Actions |
|
|
10
|
+
| pm | GSD planning, phases, roadmap, milestones |
|
|
11
|
+
| researcher | web research, docs, library comparisons |
|
|
12
|
+
| obsidian | save findings to vault, capture notes, query knowledge |
|
|
13
|
+
| requirements-analyst | clarify ambiguous requirements before implementation |
|
|
14
|
+
| root-cause-analyst | deep bug investigation using 5-Why + stack traces |
|
|
15
|
+
| performance-engineer | profiling, N+1 detection, caching, query optimization |
|
|
16
|
+
|
|
17
|
+
**Parallel dispatch:** For 2+ independent tasks use `superpowers:dispatching-parallel-agents`.
|
|
18
|
+
**Team tools:** `/everything-claude-code:team-builder` (up to 5 agents) · `/everything-claude-code:claude-devfleet` (isolated worktrees)
|
|
19
|
+
|
|
20
|
+
**gsd-pi agents** (researcher · worker · scout): used by `gsd` CLI pipelines only, not Claude Code sessions.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Code quality rules, file organization, testing, and language-specific standards
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Code Standards
|
|
6
|
+
|
|
7
|
+
- No hardcoded secrets. No `console.log`/`print` in production. Input validation at system boundaries only.
|
|
8
|
+
- Parameterized queries only. Error handling with try/catch at API boundaries.
|
|
9
|
+
- Files: 200-400 lines typical, 800 max. Organize by feature/domain, not by type.
|
|
10
|
+
- TDD: write failing test first. Unit tests for utilities. Integration tests for APIs and pipelines.
|
|
11
|
+
- Python: type hints on all functions, prefer `uv pip` over `pip`.
|
|
12
|
+
- TypeScript: preferred over JS, no `any`, conventional commits.
|
|
13
|
+
- Markdown: always specify language in code fences (` ```bash `, ` ```json `, etc.). Never bare ` ``` `.
|
|
14
|
+
|
|
15
|
+
**Before marking done:** runs ✓ | tests pass ✓ | edge cases handled ✓ | no regressions ✓ | logs clean ✓
|
|
16
|
+
|
|
17
|
+
## Gotcha List Convention
|
|
18
|
+
|
|
19
|
+
When Claude makes a mistake during a skill workflow: immediately add a `## Gotchas` entry to that SKILL.md — one line: `[date] what happened | rule`. Also append to `~/.claude/tasks/lessons.md`. Do not batch; log the moment it happens.
|
|
20
|
+
|
|
21
|
+
## Stack Maintenance
|
|
22
|
+
|
|
23
|
+
When any CLI, MCP, plugin, or agent is added/removed/renamed, update **all** of:
|
|
24
|
+
|
|
25
|
+
| Doc | What to update |
|
|
26
|
+
|-----|----------------|
|
|
27
|
+
| `~/.claude/CLAUDE.md` | CLIs table, MCPs list, or Plugins line |
|
|
28
|
+
| `~/.claude/USER_GUIDE.md` | Quick Reference tables |
|
|
29
|
+
| `~/.claude/README.md` | Rules table (if rules/ changed), Agents table (if agents/ changed) |
|
|
30
|
+
| `~/.claude/rules/agents.md` | Agent usage table (if new agent added) |
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Think flags, PDCA loop, confidence protocol, and QA gate
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Cognitive Rules
|
|
6
|
+
|
|
7
|
+
## Think Flags
|
|
8
|
+
|
|
9
|
+
| Flag | When to use |
|
|
10
|
+
|------|-------------|
|
|
11
|
+
| `--think` | Ambiguous requirements, multi-step debugging, non-obvious trade-offs |
|
|
12
|
+
| `--think-hard` | Architecture decisions, security-critical code, performance root cause |
|
|
13
|
+
| `--ultrathink` | System design, complex refactors, decisions with large blast radius |
|
|
14
|
+
|
|
15
|
+
Never upgrade the flag without user permission. Flag applies to current response only.
|
|
16
|
+
|
|
17
|
+
## PDCA Loop
|
|
18
|
+
|
|
19
|
+
Use when stuck or requirements are unclear. Max 3 iterations before surfacing to user.
|
|
20
|
+
|
|
21
|
+
**Plan** (what + success criteria) → **Do** (minimum action) → **Check** (actual vs expected) → **Act** (standardize or retry)
|
|
22
|
+
|
|
23
|
+
Output format: `PDCA — Iteration [N] | PLAN: … | DO: … | CHECK: … | ACT: …`
|
|
24
|
+
|
|
25
|
+
## Confidence Protocol
|
|
26
|
+
|
|
27
|
+
Before implementing any non-trivial solution: ≥90% → proceed · 70-89% → surface alternatives · <70% → ask first.
|
|
28
|
+
|
|
29
|
+
If user says "just do it" after low-confidence disclosure → proceed.
|
|
30
|
+
|
|
31
|
+
## QA Gate
|
|
32
|
+
|
|
33
|
+
Run `/reflect` before marking any implementation complete.
|
|
34
|
+
|
|
35
|
+
## Orchestrator Mode
|
|
36
|
+
|
|
37
|
+
Write **goals + constraints**, not steps. "Add rate limiting to login, match existing patterns, don't break tests, add tests for new paths" — not "open auth.js, find login, add param." Review outputs; intervene on direction, not method.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Git Workflow
|
|
2
|
+
|
|
3
|
+
**Branch model:** `nc{N}-description` per feature. Never commit to `main` directly.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
/git-new-feature "desc" → creates nc{N}-desc, pushes
|
|
7
|
+
commit-commands:commit → commit project changes
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
**Commit format:** `<type>: <description>` (imperative) + `Co-Authored-By: Claude <noreply@anthropic.com>`
|
|
11
|
+
Types: `add`, `fix`, `update`, `refactor`, `test`, `docs`
|
|
12
|
+
|
|
13
|
+
| Task | Command |
|
|
14
|
+
|------|---------|
|
|
15
|
+
| Create branch | `/git-new-feature "desc"` |
|
|
16
|
+
| Commit project | `commit-commands:commit` |
|
|
17
|
+
| Commit + PR | `commit-commands:commit-push-pr` |
|
|
18
|
+
| Squash / sync / reset / changelog | `/git-squash` / `/git-sync` / `/git-reset-hard` / `/git-changelog` |
|
|
19
|
+
|
|
20
|
+
**Returning to existing branch:** `git checkout nc{N}-description` — don't create a new branch.
|
|
21
|
+
|
|
22
|
+
**License heuristic:** Next.js/SaaS → proprietary · CLI/library → MIT · personal → MIT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# New Project Checklist
|
|
2
|
+
|
|
3
|
+
1. Create `.claudeignore`: `node_modules/`, `dist/`, `build/`, `.git/`, `*.log`, `coverage/`, `.env`, `*.lock`
|
|
4
|
+
2. GitHub connected? Offer `/install-github-action` (confirm first, don't run automatically)
|
|
5
|
+
3. Create `tasks/` with `lessons.md`, `todo.md`, `completed.md`
|
|
6
|
+
4. Security gate before production: run a security audit before launch
|
|
7
|
+
|
|
8
|
+
# GSD Customization Protocol
|
|
9
|
+
|
|
10
|
+
`~/.claude/gsd-local/` tracks all local GSD modifications. GSD updates wipe `get-shit-done/`.
|
|
11
|
+
|
|
12
|
+
Before modifying any GSD file: add PENDING entry to `gsd-local/PATCHES.md` → make change → save diff → mark ACTIVE.
|
|
13
|
+
After `/gsd:update`: run `/gsd:reapply-patches`.
|