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 ADDED
@@ -0,0 +1,126 @@
1
+ # Claude Power Stack
2
+
3
+ A power-user `~/.claude` configuration for Claude Code — with GSD workflow, safety hooks, modular rules, and a fleet of specialized agents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ # npm create (recommended — zero global install)
9
+ npm create claude-stack@latest
10
+
11
+ # or npx
12
+ npx create-claude-stack@latest
13
+
14
+ # or curl (macOS / Linux / WSL)
15
+ curl -fsSL https://raw.githubusercontent.com/nattechan/claude-power-stack/main/install.sh | bash
16
+ ```
17
+
18
+ The installer is interactive: it asks where your projects live, whether you use Obsidian, and whether you want Discord notifications. **Existing files are never silently overwritten** — conflicts are shown with a diff and you choose what to do.
19
+
20
+ ## What's included
21
+
22
+ ### `CLAUDE.md`
23
+ Global instructions that load in every Claude Code session. Establishes the GSD workflow, tool hierarchy, confidence protocol, and session state pattern. Edit it to describe your stack.
24
+
25
+ ### `rules/`
26
+ Modular rule files loaded alongside `CLAUDE.md`:
27
+
28
+ | File | What it governs |
29
+ |------|----------------|
30
+ | `cognitive.md` | Think flags, PDCA loop, confidence protocol |
31
+ | `git-workflow.md` | Branch model (`nc{N}`), commit format, PR flow |
32
+ | `code-standards.md` | Language standards, TDD, file size limits |
33
+ | `agents.md` | Which agent to reach for which task |
34
+ | `new-project.md` | New project checklist, GSD customization |
35
+
36
+ ### `hooks/`
37
+ Lifecycle hooks that run automatically:
38
+
39
+ | Hook | When it runs | What it does |
40
+ |------|-------------|--------------|
41
+ | `safety-guard.js` | Before every Bash tool call | Blocks `rm -rf /`, fork bombs, DROP DATABASE, force push to main, etc. |
42
+ | `gsd-context-monitor.js` | After every tool call | Warns the agent at 35% / 25% context remaining so it can wrap up before hitting limits |
43
+ | `discord-notify.sh` | On session stop + notification | Posts a message to a Discord channel (optional — needs `DISCORD_WEBHOOK_URL` in `.env`) |
44
+
45
+ ### `agents/`
46
+ Specialized subagents dispatched with the Agent tool:
47
+
48
+ | Agent | Use for |
49
+ |-------|---------|
50
+ | `engineer` | Code implementation, debugging, TDD, PR review |
51
+ | `pm` | GSD phase planning, roadmap, milestone management |
52
+ | `researcher` | Web research, docs, library comparisons |
53
+ | `obsidian` | Save findings to vault, query knowledge, daily logs |
54
+
55
+ ### `mcp.json`
56
+ Global MCP server configuration: `filesystem`, `brave-search`, `firecrawl`, `repomix`.
57
+
58
+ ### `settings.json`
59
+ Permissions (allow/ask/deny), hooks wiring, enabled plugins, and autoApprove list.
60
+
61
+ ## Prerequisites
62
+
63
+ - **Claude Code CLI** — [install guide](https://docs.anthropic.com/en/docs/claude-code)
64
+ - **Node.js 18+** — required for hooks and the installer
65
+ - **GSD plugin** — install inside Claude Code: `/install get-shit-done`
66
+
67
+ ## Recommended plugins
68
+
69
+ Install these in Claude Code after setup:
70
+
71
+ ```
72
+ superpowers — writing plans, executing plans, brainstorming, debugging
73
+ everything-claude-code — 100+ skills: TDD, security review, code review, etc.
74
+ commit-commands — /commit, /push, /pr in one shot
75
+ feature-dev — feature planning and implementation workflow
76
+ frontend-design — UI/UX implementation workflow
77
+ ```
78
+
79
+ ## Optional integrations
80
+
81
+ ### Discord notifications
82
+
83
+ Add your webhook to `~/.claude/.env`:
84
+
85
+ ```bash
86
+ DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your/webhook
87
+ ```
88
+
89
+ Session-complete and attention-needed events post to your channel.
90
+
91
+ ### Obsidian vault
92
+
93
+ If you chose Obsidian during install, the `obsidian` agent knows your vault path.
94
+ Install the `obsidian` plugin in Claude Code for `/obsidian-daily-note`, `/obsidian-compress`, etc.
95
+
96
+ ### Brave Search
97
+
98
+ Free tier at [brave.com/search/api](https://brave.com/search/api) — 2 000 queries/month.
99
+ Add `BRAVE_API_KEY` to `~/.claude/.env`.
100
+
101
+ ## Customizing
102
+
103
+ - **CLAUDE.md** — edit to describe your tech stack, preferred tools, and project domains
104
+ - **rules/** — each file is ≤ 100 lines; add or remove rule files as needed
105
+ - **agents/** — copy an existing agent as a template for domain-specific agents
106
+ - **hooks/** — edit `safety-guard.js` to add your own blocked command patterns
107
+ - **mcp.json** — add project-specific MCP servers (n8n, Supabase, Sentry, etc.)
108
+
109
+ ## Project layout after install
110
+
111
+ ```text
112
+ ~/.claude/
113
+ ├── CLAUDE.md ← Global instructions
114
+ ├── mcp.json ← MCP servers
115
+ ├── settings.json ← Permissions + hooks
116
+ ├── .env.example ← API key template (copy to .env)
117
+ ├── rules/ ← Modular rule files
118
+ ├── hooks/ ← Lifecycle hooks
119
+ ├── agents/ ← Subagent definitions
120
+ └── tasks/
121
+ └── lessons.md ← Self-learning log
122
+ ```
123
+
124
+ ## License
125
+
126
+ MIT
package/bin/create.js ADDED
@@ -0,0 +1,353 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const os = require('os');
7
+ const rl_ = require('readline');
8
+ const { execSync } = require('child_process');
9
+
10
+ const HOME = os.homedir();
11
+ const CLAUDE_DIR = path.join(HOME, '.claude');
12
+ const TMPL_DIR = path.join(__dirname, '..', 'template');
13
+
14
+ // ── ANSI helpers ──────────────────────────────────────────────────────────────
15
+ const C = {
16
+ green: s => `\x1b[32m${s}\x1b[0m`,
17
+ yellow: s => `\x1b[33m${s}\x1b[0m`,
18
+ cyan: s => `\x1b[36m${s}\x1b[0m`,
19
+ red: s => `\x1b[31m${s}\x1b[0m`,
20
+ bold: s => `\x1b[1m${s}\x1b[0m`,
21
+ dim: s => `\x1b[2m${s}\x1b[0m`,
22
+ };
23
+
24
+ const ok = msg => console.log(` ${C.green('✓')} ${msg}`);
25
+ const skip = msg => console.log(` ${C.dim('–')} ${msg} ${C.dim('(skipped)')}`);
26
+ const warn = msg => console.log(` ${C.yellow('⚠')} ${msg}`);
27
+ const err = msg => console.log(` ${C.red('✗')} ${msg}`);
28
+ const hdr = msg => console.log(`\n${C.bold(msg)}`);
29
+
30
+ const DRY_RUN = process.argv.includes('--dry-run');
31
+
32
+ // ── Readline helpers ──────────────────────────────────────────────────────────
33
+ let rl;
34
+
35
+ function openRL() {
36
+ rl = rl_.createInterface({ input: process.stdin, output: process.stdout });
37
+ }
38
+ function closeRL() {
39
+ rl.close();
40
+ }
41
+ function ask(question, defaultVal) {
42
+ return new Promise(resolve => {
43
+ const hint = defaultVal ? ` ${C.dim(`[${defaultVal}]`)}` : '';
44
+ rl.question(` ${question}${hint} `, ans => {
45
+ resolve(ans.trim() || defaultVal || '');
46
+ });
47
+ });
48
+ }
49
+ function askYN(question, defaultYes = true) {
50
+ return new Promise(resolve => {
51
+ const hint = defaultYes ? C.dim('[Y/n]') : C.dim('[y/N]');
52
+ rl.question(` ${question} ${hint} `, ans => {
53
+ const a = ans.trim().toLowerCase();
54
+ resolve(!a ? defaultYes : a === 'y' || a === 'yes');
55
+ });
56
+ });
57
+ }
58
+ async function askChoice(question, choices) {
59
+ // choices: [{key, label}]
60
+ console.log(` ${question}`);
61
+ choices.forEach(({ key, label }) => console.log(` ${C.cyan(key)}) ${label}`));
62
+ return new Promise(resolve => {
63
+ rl.question(' Choice: ', ans => resolve(ans.trim().toLowerCase()));
64
+ });
65
+ }
66
+
67
+ // ── File helpers ──────────────────────────────────────────────────────────────
68
+ function readTemplate(relPath) {
69
+ return fs.readFileSync(path.join(TMPL_DIR, relPath), 'utf8');
70
+ }
71
+
72
+ function substitute(content, vars) {
73
+ let result = content;
74
+ for (const [k, v] of Object.entries(vars)) {
75
+ result = result.split(k).join(v);
76
+ }
77
+ return result;
78
+ }
79
+
80
+ function fileExists(relPath) {
81
+ return fs.existsSync(path.join(CLAUDE_DIR, relPath));
82
+ }
83
+
84
+ function destContent(relPath) {
85
+ const p = path.join(CLAUDE_DIR, relPath);
86
+ return fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : null;
87
+ }
88
+
89
+ // ── Conflict resolution ───────────────────────────────────────────────────────
90
+ // Returns true if the file should be written.
91
+ async function resolveConflict(relPath, newContent) {
92
+ const existing = destContent(relPath);
93
+
94
+ // File doesn't exist → always write
95
+ if (existing === null) return true;
96
+
97
+ // File is identical → nothing to do
98
+ if (existing === newContent) { skip(relPath); return false; }
99
+
100
+ // File differs → ask
101
+ console.log(`\n ${C.yellow('conflict')} ${relPath}`);
102
+ const choice = await askChoice(
103
+ 'This file already exists and differs from the template. What would you like to do?',
104
+ [
105
+ { key: 'o', label: 'Overwrite with template version' },
106
+ { key: 'k', label: 'Keep existing (skip this file)' },
107
+ { key: 'm', label: 'Merge: keep existing, append template as a comment block at the end' },
108
+ { key: 'd', label: 'Show diff then decide' },
109
+ ]
110
+ );
111
+
112
+ if (choice === 'd') {
113
+ // Show a simple line diff summary
114
+ const existingLines = existing.split('\n');
115
+ const newLines = newContent.split('\n');
116
+ console.log(C.dim(` --- existing (${existingLines.length} lines) +++ template (${newLines.length} lines)`));
117
+ // Print first differing lines for context
118
+ let shown = 0;
119
+ for (let i = 0; i < Math.max(existingLines.length, newLines.length) && shown < 8; i++) {
120
+ const eL = existingLines[i] ?? '';
121
+ const nL = newLines[i] ?? '';
122
+ if (eL !== nL) {
123
+ if (eL) console.log(C.red(` - ${eL.slice(0, 80)}`));
124
+ if (nL) console.log(C.green(` + ${nL.slice(0, 80)}`));
125
+ shown++;
126
+ }
127
+ }
128
+ if (shown === 8) console.log(C.dim(' ... (truncated)'));
129
+ return resolveConflict(relPath, newContent); // re-ask after showing diff
130
+ }
131
+
132
+ if (choice === 'o') return true;
133
+ if (choice === 'k') { skip(relPath); return false; }
134
+ if (choice === 'm') {
135
+ const merged = existing + '\n\n# ─── Template version (appended by claude-power-stack installer) ───\n# ' +
136
+ newContent.split('\n').join('\n# ');
137
+ if (!DRY_RUN) {
138
+ fs.mkdirSync(path.dirname(path.join(CLAUDE_DIR, relPath)), { recursive: true });
139
+ fs.writeFileSync(path.join(CLAUDE_DIR, relPath), merged);
140
+ }
141
+ ok(`${relPath} ${C.dim('(merged)')}`);
142
+ return false; // already written
143
+ }
144
+ // unrecognised → keep
145
+ skip(relPath);
146
+ return false;
147
+ }
148
+
149
+ // ── Backup ────────────────────────────────────────────────────────────────────
150
+ function backupExisting() {
151
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
152
+ const backup = `${CLAUDE_DIR}.bak-${stamp}`;
153
+ if (!DRY_RUN) fs.cpSync(CLAUDE_DIR, backup, { recursive: true });
154
+ warn(`Full backup written to ${backup}`);
155
+ return backup;
156
+ }
157
+
158
+ // ── Install one file ──────────────────────────────────────────────────────────
159
+ async function installFile(relPath, vars) {
160
+ let content;
161
+ try {
162
+ content = readTemplate(relPath);
163
+ } catch {
164
+ warn(`Template not found: ${relPath}`);
165
+ return;
166
+ }
167
+
168
+ const final = substitute(content, vars);
169
+ const write = await resolveConflict(relPath, final);
170
+
171
+ if (write) {
172
+ if (!DRY_RUN) {
173
+ fs.mkdirSync(path.dirname(path.join(CLAUDE_DIR, relPath)), { recursive: true });
174
+ fs.writeFileSync(path.join(CLAUDE_DIR, relPath), final);
175
+ }
176
+ ok(relPath);
177
+ }
178
+ }
179
+
180
+ // ── Preview what will change ──────────────────────────────────────────────────
181
+ function previewChanges(files, vars) {
182
+ const statuses = files.map(f => {
183
+ const tmplPath = path.join(TMPL_DIR, f);
184
+ if (!fs.existsSync(tmplPath)) return { f, status: 'missing-template' };
185
+ const existing = destContent(f);
186
+ if (existing === null) return { f, status: 'new' };
187
+ const newContent = substitute(fs.readFileSync(tmplPath, 'utf8'), vars);
188
+ if (existing === newContent) return { f, status: 'unchanged' };
189
+ return { f, status: 'conflict' };
190
+ });
191
+
192
+ const newFiles = statuses.filter(s => s.status === 'new');
193
+ const conflicts = statuses.filter(s => s.status === 'conflict');
194
+ const unchanged = statuses.filter(s => s.status === 'unchanged');
195
+
196
+ hdr('Preview of changes:');
197
+ if (newFiles.length) {
198
+ console.log(`\n ${C.green('New files')} (${newFiles.length}):`);
199
+ newFiles.forEach(s => console.log(` ${C.green('+')} ${s.f}`));
200
+ }
201
+ if (conflicts.length) {
202
+ console.log(`\n ${C.yellow('Conflicts')} (${conflicts.length}) — you will be asked what to do:`);
203
+ conflicts.forEach(s => console.log(` ${C.yellow('~')} ${s.f}`));
204
+ }
205
+ if (unchanged.length) {
206
+ console.log(`\n ${C.dim('Unchanged')} (${unchanged.length}) — will be skipped automatically`);
207
+ }
208
+
209
+ return { newFiles, conflicts, unchanged };
210
+ }
211
+
212
+ // ── Main ──────────────────────────────────────────────────────────────────────
213
+ async function main() {
214
+ console.log(`\n${C.bold('━━━ Claude Power Stack Installer ━━━')}`);
215
+ console.log(' Power-user ~/.claude configuration with GSD, safety hooks, and modular rules.\n');
216
+
217
+ if (DRY_RUN) warn('Dry-run mode — no files will be written.\n');
218
+
219
+ openRL();
220
+
221
+ // 1. Gather config
222
+ hdr('Configuration:');
223
+ const srcDir = await ask('Where do you store your projects?', path.join(HOME, 'src'));
224
+ const useObsidian = await askYN('Do you use Obsidian?', false);
225
+ let obsidianPath = path.join(HOME, 'obsidian_vault');
226
+ if (useObsidian) {
227
+ const defaultVault = path.join(HOME, 'Library', 'Mobile Documents',
228
+ 'iCloud~md~obsidian', 'Documents', 'obsidian_vault');
229
+ obsidianPath = await ask('Obsidian vault path?', defaultVault);
230
+ }
231
+ const useDiscord = await askYN('Enable Discord notifications? (add webhook to .env later)', false);
232
+
233
+ closeRL();
234
+
235
+ const vars = {
236
+ '__SRC_DIR__': srcDir,
237
+ '__OBSIDIAN_PATH__': obsidianPath,
238
+ };
239
+
240
+ const ALL_FILES = [
241
+ 'CLAUDE.md',
242
+ 'mcp.json',
243
+ 'settings.json',
244
+ 'rules/cognitive.md',
245
+ 'rules/git-workflow.md',
246
+ 'rules/code-standards.md',
247
+ 'rules/agents.md',
248
+ 'rules/new-project.md',
249
+ 'hooks/safety-guard.js',
250
+ 'hooks/gsd-context-monitor.js',
251
+ 'hooks/discord-notify.sh',
252
+ 'agents/engineer.md',
253
+ 'agents/pm.md',
254
+ 'agents/researcher.md',
255
+ 'agents/obsidian.md',
256
+ ];
257
+
258
+ // 2. Preview
259
+ const existingClaude = fs.existsSync(CLAUDE_DIR);
260
+ const preview = previewChanges(ALL_FILES, vars);
261
+
262
+ // 3. Backup offer
263
+ if (existingClaude) {
264
+ openRL();
265
+ console.log('');
266
+ const doBackup = await askYN(
267
+ `~/.claude already exists. Create a full backup before installing?`,
268
+ true
269
+ );
270
+ if (doBackup) backupExisting();
271
+ closeRL();
272
+ }
273
+
274
+ // 4. Final confirm
275
+ openRL();
276
+ console.log('');
277
+ console.log(` Will install to: ${C.cyan(CLAUDE_DIR)}`);
278
+ if (preview.conflicts.length) {
279
+ console.log(` ${C.yellow(preview.conflicts.length + ' conflicts')} will be resolved interactively.`);
280
+ }
281
+ const go = await askYN('Proceed with installation?', true);
282
+ closeRL();
283
+
284
+ if (!go) { console.log('\n Aborted.'); process.exit(0); }
285
+
286
+ // 5. Install files
287
+ hdr('Installing:');
288
+ if (!DRY_RUN) fs.mkdirSync(CLAUDE_DIR, { recursive: true });
289
+
290
+ openRL(); // keep open for conflict resolution prompts
291
+ for (const f of ALL_FILES) {
292
+ await installFile(f, vars);
293
+ }
294
+
295
+ // Make discord hook executable
296
+ const discordHookDest = path.join(CLAUDE_DIR, 'hooks', 'discord-notify.sh');
297
+ if (!DRY_RUN && fs.existsSync(discordHookDest)) {
298
+ fs.chmodSync(discordHookDest, 0o755);
299
+ }
300
+
301
+ // .env.example
302
+ const envLines = [
303
+ '# Claude Power Stack — API Keys',
304
+ '# Copy this file to .env and fill in your keys.',
305
+ '',
306
+ '# Web search (free tier: https://brave.com/search/api/)',
307
+ 'BRAVE_API_KEY=',
308
+ '',
309
+ '# Web scraping (https://firecrawl.dev)',
310
+ 'FIRECRAWL_API_KEY=',
311
+ ];
312
+ if (useDiscord) {
313
+ envLines.push('', '# Discord notifications (create webhook in Server Settings → Integrations)');
314
+ envLines.push('DISCORD_WEBHOOK_URL=');
315
+ }
316
+ const envContent = envLines.join('\n') + '\n';
317
+ const envWrite = await resolveConflict('.env.example', envContent);
318
+ if (envWrite && !DRY_RUN) {
319
+ fs.writeFileSync(path.join(CLAUDE_DIR, '.env.example'), envContent);
320
+ ok('.env.example');
321
+ }
322
+
323
+ // tasks/ scaffold (only create if doesn't exist)
324
+ const lessonsPath = path.join(CLAUDE_DIR, 'tasks', 'lessons.md');
325
+ if (!fs.existsSync(lessonsPath)) {
326
+ if (!DRY_RUN) {
327
+ fs.mkdirSync(path.join(CLAUDE_DIR, 'tasks'), { recursive: true });
328
+ fs.writeFileSync(lessonsPath, '# Lessons\n\n| Date | What went wrong | Rule to follow |\n|------|----------------|----------------|\n');
329
+ }
330
+ ok('tasks/lessons.md');
331
+ } else {
332
+ skip('tasks/lessons.md (already exists — your notes are safe)');
333
+ }
334
+
335
+ closeRL();
336
+
337
+ // 6. Next steps
338
+ hdr('Done! Next steps:\n');
339
+ console.log(` 1. ${C.bold('Add API keys')}`);
340
+ console.log(` cp ~/.claude/.env.example ~/.claude/.env`);
341
+ console.log(` # Edit .env — add BRAVE_API_KEY at minimum\n`);
342
+ console.log(` 2. ${C.bold('Install GSD workflow plugin')} (primary workflow engine)`);
343
+ console.log(` Open Claude Code and run: /install get-shit-done\n`);
344
+ console.log(` 3. ${C.bold('Install recommended plugins')} in Claude Code:`);
345
+ console.log(` superpowers · everything-claude-code · commit-commands\n`);
346
+ if (useDiscord) {
347
+ console.log(` 4. ${C.bold('Set up Discord notifications')}`);
348
+ console.log(` Add your webhook URL to ~/.claude/.env as DISCORD_WEBHOOK_URL\n`);
349
+ }
350
+ console.log(` Full docs: https://github.com/nattechan/claude-power-stack\n`);
351
+ }
352
+
353
+ main().catch(e => { console.error(C.red('\nFatal: ' + e.message)); process.exit(1); });
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "create-claude-stack",
3
+ "version": "1.0.0",
4
+ "description": "Scaffold a power-user Claude Code configuration with GSD workflow, safety hooks, and modular rules",
5
+ "bin": {
6
+ "create-claude-stack": "bin/create.js"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/nattechan/claude-power-stack.git"
11
+ },
12
+ "homepage": "https://github.com/nattechan/claude-power-stack#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/nattechan/claude-power-stack/issues"
15
+ },
16
+ "author": "",
17
+ "files": [
18
+ "bin/",
19
+ "template/"
20
+ ],
21
+ "scripts": {
22
+ "test": "node bin/create.js --dry-run"
23
+ },
24
+ "keywords": [
25
+ "claude",
26
+ "claude-code",
27
+ "anthropic",
28
+ "ai",
29
+ "developer-tools",
30
+ "configuration"
31
+ ],
32
+ "license": "MIT",
33
+ "engines": {
34
+ "node": ">=18.0.0"
35
+ }
36
+ }
@@ -0,0 +1,88 @@
1
+ # CLAUDE.md — Global Protocol
2
+
3
+ ## Context Budget
4
+
5
+ `CLAUDE.md` ≤ 150 lines. Each `rules/` file ≤ 100 lines. Prefer a file path reference over inlining content. If adding content would exceed the budget, trim something first.
6
+
7
+ ## Role
8
+
9
+ Generalist engineer and technical PM. Delegates to specialized agents.
10
+ GSD is the primary workflow for all project work.
11
+
12
+ ## Primary Workflow — GSD
13
+
14
+ ```text
15
+ /gsd:discuss-phase → /gsd:plan-phase → /gsd:execute-phase → /gsd:verify-work → /gsd:ship
16
+ ...repeat per phase... → /gsd:complete-milestone → /gsd:new-milestone
17
+ ```
18
+
19
+ Quick access: `/gsd:new-project` | `/gsd:progress` | `/gsd:plan-phase` | `/gsd:execute-phase` | `/gsd:quick` | `/gsd:do`
20
+
21
+ ## Available Tools
22
+
23
+ **Hierarchy: CLI > MCP > Plugin.**
24
+
25
+ ### CLIs
26
+
27
+ | CLI | Purpose |
28
+ |-----|---------|
29
+ | `gh` | GitHub: PRs, issues, Actions, releases |
30
+ | `git` | version control |
31
+ | `supabase` | local dev, migrations, functions |
32
+ | `vercel` | deploy and manage Vercel projects |
33
+ | `docker` | build images, compose stacks |
34
+ | `npx playwright` / `playwright-cli` | browser automation |
35
+ | `repomix` | pack repo into LLM file (`--style markdown`, `--remote <url>`) |
36
+ | `gemini` | Gemini CLI: research, code review, multi-modal |
37
+ | `firecrawl` | web scraping: scrape, crawl, map, search |
38
+ | `tsc` / `ts-node` | TypeScript compiler and runner |
39
+ | `markdownlint-cli2` | lint/fix markdown |
40
+
41
+ ### MCPs
42
+
43
+ - `filesystem` — direct access to `__SRC_DIR__`
44
+ - `context7` — up-to-date library docs
45
+ - `brave-search` — web search (requires `BRAVE_API_KEY` in `~/.claude/.env`)
46
+ - `firecrawl` — web scraping (requires `FIRECRAWL_API_KEY`)
47
+
48
+ ### Plugins (invoke via Skill tool)
49
+
50
+ `superpowers` · `GSD` · `commit-commands` · `everything-claude-code` · `feature-dev` · `frontend-design` · `app-security` · `cost-reducer`
51
+
52
+ ## Universal Rules
53
+
54
+ 1. Check for relevant skill before acting — use Skill tool
55
+ 2. GSD for any multi-step project — never plan inline in chat
56
+ 3. Tool hierarchy: CLI > MCP > Plugin
57
+ 4. Use `gh` CLI for all GitHub operations — no GitHub MCP
58
+ 5. Browser automation: `playwright-cli` / `npx playwright` only
59
+ 6. Verification: never mark complete without proving it works (run tests, check logs, diff behavior)
60
+ 7. Self-learning: after any correction → append to `~/.claude/tasks/lessons.md`: `[date] | what went wrong | rule to follow`
61
+ 8. Confidence: ≥90% → proceed; 70-89% → surface alternatives; <70% → ask first
62
+ 9. Plan-first: 3+ step tasks → write plan before implementing; stop and re-plan if blocked mid-task
63
+
64
+ ## Session State
65
+
66
+ `~/.claude/primer.md` — rewritten each session end, re-injected after `/compact`.
67
+ Before closing: *"Rewrite `~/.claude/primer.md` with: active project, completed, exact next step, blockers. Under 100 lines."*
68
+ At session start: scan `~/.claude/tasks/lessons.md` for patterns relevant to the current task before acting.
69
+
70
+ ## Key Patterns
71
+
72
+ | Situation | Action |
73
+ |-----------|--------|
74
+ | Context long | `/gsd:pause-work` → new session → `/gsd:resume-work` |
75
+ | Recurring task | Ralph Loop or CronCreate |
76
+ | Unsure next step | `/gsd:progress` |
77
+ | New skill | `/skill-create` (everything-claude-code) |
78
+ | Security review | `/app-security` |
79
+
80
+ ## Autocompact
81
+
82
+ At 35% remaining: wrap up current task. At 25%: run `/compact` immediately, then resume.
83
+
84
+ ## Usage Limit Handling
85
+
86
+ 1. GSD active (`.planning/STATE.md` exists): `/gsd:pause-work` immediately
87
+ 2. No GSD: write to `~/.claude/primer.md`
88
+ 3. Tell user: "Usage limit reached. State saved. Run `/gsd:resume-work` in new session."
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: engineer
3
+ description: Software engineer agent. Use for code implementation, debugging, TDD, PR reviews, GitHub Actions. Invokes superpowers skills for structured workflows.
4
+ tools: Read, Write, Edit, Bash, Glob, Grep, Agent
5
+ ---
6
+
7
+ You are a senior software engineer. You write clean, tested, production-ready code.
8
+
9
+ ## Approach
10
+
11
+ - Always read existing code before modifying
12
+ - Use TDD: write failing test first (`superpowers:test-driven-development`)
13
+ - Commit frequently with descriptive messages
14
+ - Use `gh` CLI for all GitHub operations
15
+ - Use `agent-browser` for any browser automation
16
+
17
+ ## GitHub Operations
18
+
19
+ ```bash
20
+ gh pr create --title "..." --body "..."
21
+ gh pr merge 123 --squash --delete-branch
22
+ gh workflow run deploy.yml
23
+ gh run watch
24
+ gh issue create
25
+ ```
26
+
27
+ ## Debugging
28
+
29
+ Use `superpowers:systematic-debugging` — never guess, always diagnose root cause.
30
+
31
+ ## Code Review
32
+
33
+ Use `superpowers:requesting-code-review` before marking work complete.
34
+
35
+ ## Languages
36
+
37
+ Python (uv pip, type hints), TypeScript/React, SQL (DuckDB), Bash
38
+
39
+ Project-specific conventions: see project CLAUDE.md
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: obsidian
3
+ description: Obsidian vault agent. Use for saving session findings, capturing notes, querying existing knowledge, managing daily logs, and syncing project context to vault.
4
+ tools: Read, Write, Bash
5
+ ---
6
+
7
+ You manage the Obsidian knowledge vault.
8
+
9
+ ## Vault Location
10
+
11
+ `__OBSIDIAN_PATH__`
12
+
13
+ ## Available MCP Tools
14
+
15
+ - `mcp__obsidian__read_note` — read a note
16
+ - `mcp__obsidian__write_note` — create/overwrite a note
17
+ - `mcp__obsidian__patch_note` — append to a note
18
+ - `mcp__obsidian__search_notes` — full-text search
19
+ - `mcp__obsidian__list_directory` — browse vault structure
20
+ - `mcp__obsidian__get_notes_info` — note metadata
21
+ - `mcp__obsidian__manage_tags` — add/remove tags
22
+ - `mcp__obsidian__move_note` — reorganize notes
23
+
24
+ ## Common Operations
25
+
26
+ ### Save research findings
27
+
28
+ Path: `Research/YYYY-MM-DD-topic.md`
29
+
30
+ ### Log GSD phase completion
31
+
32
+ Path: `Projects/project-name/phases/phase-N-complete.md`
33
+
34
+ ### Daily log
35
+
36
+ Path: `Daily/YYYY-MM-DD.md`
37
+
38
+ ### Capture a quick note
39
+
40
+ Path: `Inbox/YYYY-MM-DD-HH-MM-topic.md`
41
+
42
+ ## Vault Structure Convention
43
+
44
+ ```text
45
+ obsidian_vault/
46
+ ├── Daily/ — daily logs
47
+ ├── Projects/ — per-project notes
48
+ ├── Research/ — research findings
49
+ ├── Inbox/ — quick captures
50
+ └── Reference/ — permanent reference notes
51
+ ```