@claude-code-mastery/starter-kit 1.0.0 → 1.2.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/.claude/.starter-kit/profiles/clean.md +7 -1
- package/.claude/.starter-kit/profiles/go.md +1 -1
- package/.claude/.starter-kit/profiles/node.md +13 -4
- package/.claude/.starter-kit/profiles/python.md +1 -1
- package/.claude/commands/show-user-guide.md +22 -20
- package/.dockerignore +39 -0
- package/.env.example +74 -0
- package/.gitignore +70 -0
- package/CLAUDE.md +838 -0
- package/README.md +111 -2073
- package/README.npm.md +190 -0
- package/bin/cli.js +22 -0
- package/package.json +14 -4
- package/playwright.config.ts +79 -0
- package/scripts/.gitkeep +0 -0
- package/scripts/build-content.ts +108 -0
- package/scripts/content/html-template.ts +144 -0
- package/scripts/content/markdown-processor.ts +261 -0
- package/scripts/content/seo-generator.ts +42 -0
- package/scripts/content/sidebar-generator.ts +71 -0
- package/scripts/content/types.ts +72 -0
- package/scripts/content.config.json +49 -0
- package/scripts/db-query.ts +143 -0
- package/scripts/queries/example-count-docs.ts +25 -0
- package/scripts/queries/example-find-user.ts +32 -0
- package/scripts/scaffold-clean.sh +591 -0
- package/scripts/scaffold-default.sh +1251 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +15 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
# CLAUDE.md — Project Instructions
|
|
2
|
+
|
|
3
|
+
> Based on Claude Code Mastery Guides V1-V5 by TheDecipherist
|
|
4
|
+
> https://github.com/TheDecipherist/claude-code-mastery
|
|
5
|
+
|
|
6
|
+
> **New here?** When starting a fresh session in this project, greet the user:
|
|
7
|
+
> "Welcome to the Claude Code Mastery Project Starter Kit! Use `/help` to see all 27 commands or `/show-user-guide` for the full interactive guide."
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Quick Reference — Scripts
|
|
12
|
+
|
|
13
|
+
| Command | What it does |
|
|
14
|
+
|---------|-------------|
|
|
15
|
+
| `pnpm dev` | Start dev server with hot reload |
|
|
16
|
+
| `pnpm dev:website` | Dev server on port 3000 |
|
|
17
|
+
| `pnpm dev:api` | Dev server on port 3001 |
|
|
18
|
+
| `pnpm dev:dashboard` | Dev server on port 3002 |
|
|
19
|
+
| `pnpm build` | Type-check + compile TypeScript |
|
|
20
|
+
| `pnpm start` | Run compiled production build |
|
|
21
|
+
| `pnpm typecheck` | TypeScript type-check only (no emit) |
|
|
22
|
+
| **Testing** | |
|
|
23
|
+
| `pnpm test` | Run ALL tests (unit + E2E) |
|
|
24
|
+
| `pnpm test:unit` | Run unit/integration tests (Vitest) |
|
|
25
|
+
| `pnpm test:unit:watch` | Unit tests in watch mode |
|
|
26
|
+
| `pnpm test:coverage` | Unit tests with coverage report |
|
|
27
|
+
| `pnpm test:e2e` | Run E2E tests (kills test ports first, spawns servers on 4000/4010) |
|
|
28
|
+
| `pnpm test:e2e:ui` | E2E with Playwright UI mode |
|
|
29
|
+
| `pnpm test:e2e:headed` | E2E with visible browser |
|
|
30
|
+
| `pnpm test:e2e:chromium` | E2E on Chromium only (fast) |
|
|
31
|
+
| `pnpm test:e2e:report` | Open last E2E test report |
|
|
32
|
+
| `pnpm test:kill-ports` | Kill anything on test ports (4000, 4010, 4020) |
|
|
33
|
+
| **Database** | |
|
|
34
|
+
| `pnpm db:query <name>` | Run a dev/test database query |
|
|
35
|
+
| `pnpm db:query:list` | List all registered database queries |
|
|
36
|
+
| **Content** | |
|
|
37
|
+
| `pnpm content:build` | Build all published markdown → HTML |
|
|
38
|
+
| `pnpm content:build:id <id>` | Build a single article by ID |
|
|
39
|
+
| `pnpm content:list` | List all articles and their status |
|
|
40
|
+
| **CSS Optimization** | |
|
|
41
|
+
| `pnpm build:optimize` | Post-build CSS class consolidation via Classpresso (runs automatically after `pnpm build`) |
|
|
42
|
+
| **Docker** | |
|
|
43
|
+
| `pnpm docker:optimize` | Audit Dockerfile against 12 best practices (use `/optimize-docker` in Claude) |
|
|
44
|
+
| **Getting Started** | |
|
|
45
|
+
| `/help` | List all commands, skills, and agents |
|
|
46
|
+
| `/quickstart` | Interactive first-run walkthrough for new users |
|
|
47
|
+
| `/show-user-guide` | Open the comprehensive User Guide in your browser |
|
|
48
|
+
| **Setup** | |
|
|
49
|
+
| `/install-global` | Install/merge global Claude config into `~/.claude/` (one-time, never overwrites) |
|
|
50
|
+
| `/install-global mdd` | Install or update the MDD npm package globally (`npm install -g @thedecipherist/mdd && mdd install`) |
|
|
51
|
+
| `/install-mdd [path]` | Install MDD workflow into any existing project — scaffolds `.mdd/` directory structure (requires `@thedecipherist/mdd` npm package) |
|
|
52
|
+
| `/setup` | Interactive .env configuration — GitHub, database, Docker, analytics, RuleCatch |
|
|
53
|
+
| `/setup --reset` | Re-configure everything from scratch |
|
|
54
|
+
| `/set-project-profile-default` | Set the default profile for `/new-project` (any profile: clean, go, vue, python-api, etc.) |
|
|
55
|
+
| `/add-project-setup` | Interactive wizard to create a named profile in `claude-mastery-project.conf` |
|
|
56
|
+
| `/projects-created` | List all projects created by the starter kit with creation dates |
|
|
57
|
+
| `/remove-project <name>` | Remove a project from registry and optionally delete from disk |
|
|
58
|
+
| `/convert-project-to-starter-kit` | Merge starter kit into an existing project (non-destructive) |
|
|
59
|
+
| `/update-project` | Update a starter-kit project with the latest commands, hooks, and rules |
|
|
60
|
+
| `/update-project --clean` | Remove starter-kit-scoped commands from a project (cleanup for older scaffolds) |
|
|
61
|
+
| `/add-feature <name>` | Add a capability (MongoDB, Docker, testing, etc.) to an existing project |
|
|
62
|
+
| **RuleCatch** | |
|
|
63
|
+
| `pnpm ai:monitor` | Free monitor mode — live AI activity in a separate terminal (no API key needed) |
|
|
64
|
+
| `/what-is-my-ai-doing` | Same as above — launches AI-Pooler free monitor |
|
|
65
|
+
| **Git** | |
|
|
66
|
+
| `/worktree <name>` | Create isolated branch + worktree for a task (never touch main) |
|
|
67
|
+
| **Code Quality** | |
|
|
68
|
+
| `/refactor <file>` | Audit + refactor a file against all CLAUDE.md rules (split, type, extract, clean) |
|
|
69
|
+
| **API** | |
|
|
70
|
+
| `/create-api <resource>` | Scaffold a full API endpoint — route, handler, types, tests — wired into the server |
|
|
71
|
+
| **Documentation** | |
|
|
72
|
+
| `/diagram <type>` | Generate diagrams from actual code: `architecture`, `api`, `database`, `infrastructure`, `all` |
|
|
73
|
+
| **Utility** | |
|
|
74
|
+
| `pnpm clean` | Remove dist/, coverage/, test-results/, playwright-report/ |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Critical Rules
|
|
79
|
+
|
|
80
|
+
### 0. NEVER Publish Sensitive Data
|
|
81
|
+
|
|
82
|
+
- NEVER commit passwords, API keys, tokens, or secrets to git/npm/docker
|
|
83
|
+
- NEVER commit `.env` files — ALWAYS verify `.env` is in `.gitignore`
|
|
84
|
+
- Before ANY commit: verify no secrets are included
|
|
85
|
+
- NEVER output secrets in suggestions, logs, or responses
|
|
86
|
+
|
|
87
|
+
### 1. TypeScript Always
|
|
88
|
+
|
|
89
|
+
- ALWAYS use TypeScript for new files (strict mode)
|
|
90
|
+
- NEVER use `any` unless absolutely necessary and documented why
|
|
91
|
+
- When editing JavaScript files, convert to TypeScript first
|
|
92
|
+
- Types are specs — they tell you what functions accept and return
|
|
93
|
+
|
|
94
|
+
### 2. API Versioning
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
CORRECT: /api/v1/users
|
|
98
|
+
WRONG: /api/users
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Every API endpoint MUST use `/api/v1/` prefix. No exceptions.
|
|
102
|
+
|
|
103
|
+
### 3. Database Access — StrictDB
|
|
104
|
+
|
|
105
|
+
StrictDB started as this starter kit's custom database wrapper and evolved into a standalone npm package. Install `strictdb` + your database driver. Use `StrictDB.create()` directly. NEVER import native drivers (`mongodb`, `pg`, `mysql2`, `mssql`, `better-sqlite3`) — StrictDB handles everything.
|
|
106
|
+
|
|
107
|
+
- NEVER create database connections anywhere except your app's startup/entry point
|
|
108
|
+
- NEVER use `mongoose` or any ODM
|
|
109
|
+
- StrictDB has built-in sanitization, guardrails, and AI-first discovery
|
|
110
|
+
- Backend auto-detected from `STRICTDB_URI` scheme — one API for all databases
|
|
111
|
+
|
|
112
|
+
| URI Scheme | Backend |
|
|
113
|
+
|---|---|
|
|
114
|
+
| `mongodb://` `mongodb+srv://` | MongoDB |
|
|
115
|
+
| `postgresql://` `postgres://` | PostgreSQL |
|
|
116
|
+
| `mysql://` | MySQL |
|
|
117
|
+
| `mssql://` | MSSQL |
|
|
118
|
+
| `file:` `sqlite:` | SQLite |
|
|
119
|
+
| `http://` `https://` | Elasticsearch |
|
|
120
|
+
|
|
121
|
+
#### Setup
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { StrictDB } from 'strictdb';
|
|
125
|
+
|
|
126
|
+
// Create once at app startup, share the instance
|
|
127
|
+
const db = await StrictDB.create({ uri: process.env.STRICTDB_URI! });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// CORRECT — use the StrictDB instance
|
|
132
|
+
const user = await db.queryOne<User>('users', { email });
|
|
133
|
+
|
|
134
|
+
// WRONG — NEVER import native drivers
|
|
135
|
+
import { MongoClient } from 'mongodb'; // FORBIDDEN
|
|
136
|
+
import { Pool } from 'pg'; // FORBIDDEN
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### Reading data
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Single document/row lookup
|
|
143
|
+
const user = await db.queryOne<User>('users', { email });
|
|
144
|
+
|
|
145
|
+
// Multiple documents/rows with options
|
|
146
|
+
const recentOrders = await db.queryMany<Order>('orders',
|
|
147
|
+
{ userId, status: 'active' },
|
|
148
|
+
{ sort: { createdAt: -1 }, limit: 20 },
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
// Lookup/join
|
|
152
|
+
const userWithOrders = await db.queryWithLookup<UserWithOrders>('users', {
|
|
153
|
+
match: { _id: userId },
|
|
154
|
+
lookup: { from: 'orders', localField: '_id', foreignField: 'userId', as: 'orders' },
|
|
155
|
+
unwind: 'orders',
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Count
|
|
159
|
+
const total = await db.count('users', { role: 'admin' });
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### Writing data
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Insert
|
|
166
|
+
await db.insertOne('users', { email, name, createdAt: new Date() });
|
|
167
|
+
await db.insertMany('events', batchOfEvents);
|
|
168
|
+
|
|
169
|
+
// Update — use $inc for counters, $set for fields (NEVER read-modify-write)
|
|
170
|
+
await db.updateOne('users', { _id: userId }, { $set: { name: 'New Name' } });
|
|
171
|
+
await db.updateOne('stats', { date }, { $inc: { pageViews: 1, visitors: 1 } }, true); // upsert
|
|
172
|
+
|
|
173
|
+
// Batch operations
|
|
174
|
+
await db.batch([
|
|
175
|
+
{ operation: 'insertOne', collection: 'orders', doc: { item: 'widget', qty: 5 } },
|
|
176
|
+
{ operation: 'updateOne', collection: 'inventory', filter: { sku: 'W1' }, update: { $inc: { stock: -5 } } },
|
|
177
|
+
]);
|
|
178
|
+
|
|
179
|
+
// Delete
|
|
180
|
+
await db.deleteOne('tokens', { token: expiredToken });
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### AI-first discovery
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// Discover collection schema — call before querying unfamiliar collections
|
|
187
|
+
const schema = await db.describe('users');
|
|
188
|
+
|
|
189
|
+
// Dry-run validation — catches errors before execution
|
|
190
|
+
const check = await db.validate('users', { filter: { role: 'admin' }, doc: { email: 'test@test.com' } });
|
|
191
|
+
|
|
192
|
+
// See the native query under the hood
|
|
193
|
+
const plan = await db.explain('users', { filter: { role: 'admin' }, limit: 50 });
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### StrictDB-MCP — AI agents should use the `strictdb-mcp` MCP server for database operations. It exposes 14 tools with all guardrails enforced automatically:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
claude mcp add strictdb -- npx -y strictdb-mcp@latest
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Requires `STRICTDB_URI` in your environment.
|
|
203
|
+
|
|
204
|
+
#### Schema registration with Zod
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { z } from 'zod';
|
|
208
|
+
|
|
209
|
+
db.registerCollection({
|
|
210
|
+
name: 'users',
|
|
211
|
+
schema: z.object({
|
|
212
|
+
email: z.string().max(255),
|
|
213
|
+
name: z.string(),
|
|
214
|
+
role: z.enum(['admin', 'user', 'mod']),
|
|
215
|
+
}),
|
|
216
|
+
indexes: [{ collection: 'users', fields: { email: 1 }, unique: true }],
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Call once at app startup
|
|
220
|
+
await db.ensureIndexes();
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
#### Graceful shutdown — MANDATORY for every Node.js entry point
|
|
224
|
+
|
|
225
|
+
ANY crash or termination signal MUST close database connections before exiting.
|
|
226
|
+
NEVER call `process.exit()` without closing connections first.
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Termination signals — clean exit
|
|
230
|
+
process.on('SIGTERM', () => db.gracefulShutdown(0));
|
|
231
|
+
process.on('SIGINT', () => db.gracefulShutdown(0));
|
|
232
|
+
|
|
233
|
+
// Crashes — close connections, then exit with error code
|
|
234
|
+
process.on('uncaughtException', (err) => {
|
|
235
|
+
console.error('Uncaught Exception:', err);
|
|
236
|
+
db.gracefulShutdown(1);
|
|
237
|
+
});
|
|
238
|
+
process.on('unhandledRejection', (reason) => {
|
|
239
|
+
console.error('Unhandled Rejection:', reason);
|
|
240
|
+
db.gracefulShutdown(1);
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
`db.gracefulShutdown()` is idempotent — safe to call from multiple signals.
|
|
245
|
+
|
|
246
|
+
#### Test queries — `scripts/db-query.ts` (MANDATORY pattern)
|
|
247
|
+
|
|
248
|
+
**ABSOLUTE RULE: ALL ad-hoc / test / dev database queries go through the db-query system. No exceptions.**
|
|
249
|
+
|
|
250
|
+
When a developer asks to "look something up in the database", "check a collection", "find a user", or any exploratory query:
|
|
251
|
+
|
|
252
|
+
1. **Create a query file** in `scripts/queries/<descriptive-name>.ts`
|
|
253
|
+
2. **Register it** in `scripts/db-query.ts` query registry
|
|
254
|
+
3. **NEVER** create standalone scripts, one-off files, or inline queries in `src/`
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
// scripts/queries/find-expired-sessions.ts
|
|
258
|
+
import type { StrictDB } from 'strictdb';
|
|
259
|
+
|
|
260
|
+
export default {
|
|
261
|
+
name: 'find-expired-sessions',
|
|
262
|
+
description: 'Find sessions that expired in the last 24 hours',
|
|
263
|
+
async run(db: StrictDB, args: string[]): Promise<void> {
|
|
264
|
+
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
265
|
+
const sessions = await db.queryMany('sessions',
|
|
266
|
+
{ expiresAt: { $lt: cutoff } },
|
|
267
|
+
{ sort: { expiresAt: -1 }, limit: 50 },
|
|
268
|
+
);
|
|
269
|
+
console.log(`Found ${sessions.length} expired sessions:`);
|
|
270
|
+
console.log(JSON.stringify(sessions, null, 2));
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Then register in `scripts/db-query.ts`:
|
|
276
|
+
```typescript
|
|
277
|
+
const queryRegistry = {
|
|
278
|
+
'find-expired-sessions': () => import('./queries/find-expired-sessions.js'),
|
|
279
|
+
};
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Run: `npx tsx scripts/db-query.ts find-expired-sessions`
|
|
283
|
+
|
|
284
|
+
**Why this matters:**
|
|
285
|
+
- **One instance** — prevents connection exhaustion (the #1 Claude Code database failure)
|
|
286
|
+
- **One place to change** — swap databases without touching business logic
|
|
287
|
+
- **One place to mock** — testing becomes trivial
|
|
288
|
+
- **One place for test queries** — no scripts scattered across the project
|
|
289
|
+
- **Discoverable** — `npx tsx scripts/db-query.ts --list` shows all available queries
|
|
290
|
+
|
|
291
|
+
**FORBIDDEN patterns:**
|
|
292
|
+
```typescript
|
|
293
|
+
// NEVER do this — creates rogue query files outside the system
|
|
294
|
+
// scripts/check-users.ts ← WRONG
|
|
295
|
+
// src/utils/debug-query.ts ← WRONG
|
|
296
|
+
// src/handlers/temp-lookup.ts ← WRONG
|
|
297
|
+
|
|
298
|
+
// ALWAYS do this — use the db-query system
|
|
299
|
+
// scripts/queries/check-users.ts + register in db-query.ts ← CORRECT
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 4. Testing — Explicit Success Criteria
|
|
303
|
+
|
|
304
|
+
- ALWAYS define explicit success criteria for E2E tests
|
|
305
|
+
- "Page loads" is NOT a success criterion
|
|
306
|
+
- Every test MUST verify: URL, visible elements, data displayed
|
|
307
|
+
- NEVER write tests without assertions
|
|
308
|
+
- Use `/create-e2e <feature>` to create E2E tests with proper structure
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
// CORRECT — explicit success criteria (MINIMUM 3 assertions per test)
|
|
312
|
+
await expect(page).toHaveURL('/dashboard'); // 1. URL
|
|
313
|
+
await expect(page.locator('h1')).toContainText('Welcome'); // 2. Element visible
|
|
314
|
+
await expect(page.locator('[data-testid="user"]')).toContainText('test@example.com'); // 3. Data correct
|
|
315
|
+
|
|
316
|
+
// WRONG — passes even if broken
|
|
317
|
+
await page.goto('/dashboard');
|
|
318
|
+
// no assertion!
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**A test is NOT finished until it has:**
|
|
322
|
+
- At least one URL assertion (`toHaveURL`)
|
|
323
|
+
- At least one element visibility assertion (`toBeVisible`)
|
|
324
|
+
- At least one content/data assertion (`toContainText`, `toHaveValue`)
|
|
325
|
+
- Error case coverage (what happens when it fails?)
|
|
326
|
+
|
|
327
|
+
**E2E test execution — ALWAYS kills test ports first:**
|
|
328
|
+
```bash
|
|
329
|
+
pnpm test:e2e # kills ports 4000/4010/4020 → spawns servers → runs Playwright
|
|
330
|
+
pnpm test:e2e:headed # same but with visible browser
|
|
331
|
+
pnpm test:e2e:ui # same but with Playwright UI mode
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
E2E tests run on TEST ports (4000, 4010, 4020) — never dev ports.
|
|
335
|
+
`playwright.config.ts` spawns servers automatically via `webServer`.
|
|
336
|
+
|
|
337
|
+
### 5. NEVER Hardcode Credentials
|
|
338
|
+
|
|
339
|
+
- ALWAYS use environment variables for secrets
|
|
340
|
+
- NEVER put API keys, passwords, or tokens directly in code
|
|
341
|
+
- NEVER hardcode connection strings — use STRICTDB_URI from .env
|
|
342
|
+
|
|
343
|
+
### 6. ALWAYS Ask Before Deploying
|
|
344
|
+
|
|
345
|
+
- NEVER auto-deploy, even if the fix seems simple
|
|
346
|
+
- NEVER assume approval — wait for explicit "yes, deploy"
|
|
347
|
+
- ALWAYS ask before deploying to production
|
|
348
|
+
|
|
349
|
+
### 7. Quality Gates
|
|
350
|
+
|
|
351
|
+
- No file > 300 lines (split if larger)
|
|
352
|
+
- No function > 50 lines (extract helper functions)
|
|
353
|
+
- All tests must pass before committing
|
|
354
|
+
- TypeScript must compile with no errors (`tsc --noEmit`)
|
|
355
|
+
|
|
356
|
+
### 8. Parallelize Independent Awaits
|
|
357
|
+
|
|
358
|
+
- When multiple `await` calls are independent (none depends on another's result), ALWAYS use `Promise.all`
|
|
359
|
+
- NEVER await independent operations sequentially — it wastes time
|
|
360
|
+
- Before writing sequential awaits, evaluate: does the second call need the first call's result?
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
// CORRECT — independent operations run in parallel
|
|
364
|
+
const [users, products, orders] = await Promise.all([
|
|
365
|
+
getUsers(),
|
|
366
|
+
getProducts(),
|
|
367
|
+
getOrders(),
|
|
368
|
+
]);
|
|
369
|
+
|
|
370
|
+
// WRONG — sequential when they don't depend on each other
|
|
371
|
+
const users = await getUsers();
|
|
372
|
+
const products = await getProducts(); // waits for users unnecessarily
|
|
373
|
+
const orders = await getOrders(); // waits for products unnecessarily
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
// CORRECT — sequential when there IS a dependency
|
|
378
|
+
const user = await getUserById(id);
|
|
379
|
+
const orders = await getOrdersByUserId(user.id); // needs user.id
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### 9. MDD — Standalone Package
|
|
383
|
+
|
|
384
|
+
MDD is no longer part of the starter kit. It lives in its own npm package at `https://github.com/TheDecipherist/mdd`.
|
|
385
|
+
|
|
386
|
+
The MDD terminal dashboard (mdd-tui) is a separate package at `https://github.com/TheDecipherist/mdd-tui`.
|
|
387
|
+
|
|
388
|
+
To update MDD: edit files in `~/projects/mdd/commands/`, bump `mdd_version` in `commands/mdd.md` frontmatter AND `version` in `package.json`, build (`pnpm build`), then `npm publish --access public`.
|
|
389
|
+
|
|
390
|
+
To install or update MDD globally: `npm install -g @thedecipherist/mdd && mdd install` (or run `/install-global mdd` in Claude Code — same thing).
|
|
391
|
+
|
|
392
|
+
### 10. Git Workflow — NEVER Work Directly on Main
|
|
393
|
+
|
|
394
|
+
**Auto-branch is ON by default.** A hook blocks commits to `main`. To avoid wasted work, **ALWAYS check and branch BEFORE editing any files:**
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
# MANDATORY first step — do this BEFORE writing or editing anything:
|
|
398
|
+
git branch --show-current
|
|
399
|
+
# If on main → create a feature branch IMMEDIATELY:
|
|
400
|
+
git checkout -b feat/<task-name>
|
|
401
|
+
# NOW start working.
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**Branch naming conventions:**
|
|
405
|
+
- `feat/<name>` — new features
|
|
406
|
+
- `fix/<name>` — bug fixes
|
|
407
|
+
- `docs/<name>` — documentation changes
|
|
408
|
+
- `refactor/<name>` — code refactors
|
|
409
|
+
- `chore/<name>` — maintenance tasks
|
|
410
|
+
- `test/<name>` — test additions
|
|
411
|
+
|
|
412
|
+
**Why branch FIRST, not at commit time:**
|
|
413
|
+
- The `check-branch.sh` hook blocks `git commit` on `main`
|
|
414
|
+
- If you edit 10 files on `main` then try to commit, you'll be blocked and have to branch retroactively
|
|
415
|
+
- Branching first costs 1 second. Branching after being blocked wastes time and creates messy history.
|
|
416
|
+
|
|
417
|
+
- Use `/worktree <branch-name>` when you want a separate directory (parallel sessions)
|
|
418
|
+
- If Claude screws up on a feature branch, delete it — main is untouched
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
# For parallel sessions (separate directories):
|
|
422
|
+
/worktree add-auth # creates branch + separate working directory
|
|
423
|
+
|
|
424
|
+
# To disable auto-branching:
|
|
425
|
+
# Set auto_branch = false in claude-mastery-project.conf
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Before merging any branch back to main:**
|
|
429
|
+
1. Review the full diff: `git diff main...HEAD`
|
|
430
|
+
2. Ask the user: "Do you want RuleCatch to check for violations on this branch?"
|
|
431
|
+
3. Only merge after the user confirms
|
|
432
|
+
|
|
433
|
+
**Why this matters:**
|
|
434
|
+
- Main should always be deployable
|
|
435
|
+
- Feature branches are disposable — delete and start over if needed
|
|
436
|
+
- `git diff main...HEAD` shows exactly what changed, making review easy
|
|
437
|
+
- Auto-branching means zero friction — you don't have to remember
|
|
438
|
+
- Worktrees let you run multiple Claude sessions in parallel without conflicts
|
|
439
|
+
- RuleCatch catches violations Claude missed — last line of defense before merge
|
|
440
|
+
|
|
441
|
+
### 11. Docker Push Gate — Local Test Before Push
|
|
442
|
+
|
|
443
|
+
**Disabled by default.** When enabled (`docker_test_before_push = true` in `claude-mastery-project.conf`), ANY `docker push` is BLOCKED until the image passes local verification:
|
|
444
|
+
|
|
445
|
+
1. Build the image
|
|
446
|
+
2. Run the container locally
|
|
447
|
+
3. Wait 5 seconds for startup
|
|
448
|
+
4. Verify container is still running (didn't crash/exit)
|
|
449
|
+
5. Hit the health endpoint (must return 200)
|
|
450
|
+
6. Check logs for fatal errors
|
|
451
|
+
7. Clean up test container
|
|
452
|
+
8. **Only then** allow `docker push`
|
|
453
|
+
|
|
454
|
+
If any step fails: STOP, show what failed, and do NOT push.
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
# Enable in claude-mastery-project.conf:
|
|
458
|
+
docker_test_before_push = true
|
|
459
|
+
|
|
460
|
+
# Disable (default):
|
|
461
|
+
docker_test_before_push = false
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
This gate applies globally — every command or workflow that pushes to Docker Hub must respect it.
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Featured Packages
|
|
469
|
+
|
|
470
|
+
Open-source packages by [TheDecipherist](https://github.com/TheDecipherist) (the developer of this starter kit) are integrated into project profiles. All are MIT-licensed.
|
|
471
|
+
|
|
472
|
+
### ClassMCP (MCP Server) — Semantic CSS for AI
|
|
473
|
+
|
|
474
|
+
Provides semantic CSS class patterns to Claude via MCP, reducing token usage when working with styles. Auto-included in CSS-enabled profiles (`mcp` field in `claude-mastery-project.conf`).
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
claude mcp add classmcp -- npx -y classmcp@latest
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
npm: [classmcp](https://www.npmjs.com/package/classmcp)
|
|
481
|
+
|
|
482
|
+
### Classpresso — Post-Build CSS Optimization
|
|
483
|
+
|
|
484
|
+
Consolidates CSS classes after build for 50% faster style recalculation with zero runtime overhead. Auto-included as a devDependency in CSS-enabled profiles; runs via `pnpm build:optimize` (also auto-runs as `postbuild`).
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
pnpm add -D classpresso
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
npm: [classpresso](https://www.npmjs.com/package/classpresso)
|
|
491
|
+
|
|
492
|
+
### StrictDB-MCP (MCP Server) — Database Access for AI
|
|
493
|
+
|
|
494
|
+
Gives AI agents direct database access through 14 MCP tools with full guardrails, sanitization, and error handling. Auto-included in database-enabled profiles (`mcp` field in `claude-mastery-project.conf`).
|
|
495
|
+
|
|
496
|
+
```bash
|
|
497
|
+
claude mcp add strictdb -- npx -y strictdb-mcp@latest
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
npm: [strictdb-mcp](https://www.npmjs.com/package/strictdb-mcp)
|
|
501
|
+
|
|
502
|
+
### TerseJSON (Optional) — Memory-Efficient JSON
|
|
503
|
+
|
|
504
|
+
Proxy-based lazy JSON expansion achieving ~70% memory reduction. **Not auto-included** — install only if your project handles large JSON payloads.
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
pnpm add tersejson
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
npm: [tersejson](https://www.npmjs.com/package/tersejson)
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## When Something Seems Wrong
|
|
515
|
+
|
|
516
|
+
Before jumping to conclusions:
|
|
517
|
+
|
|
518
|
+
- Missing UI element? → Check feature gates BEFORE assuming bug
|
|
519
|
+
- Empty data? → Check if services are running BEFORE assuming broken
|
|
520
|
+
- 404 error? → Check service separation BEFORE adding endpoint
|
|
521
|
+
- Auth failing? → Check which auth system BEFORE debugging
|
|
522
|
+
- Test failing? → Read the error message fully BEFORE changing code
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## Windows Users — Use VS Code in WSL Mode
|
|
527
|
+
|
|
528
|
+
If you're on Windows, you should be running VS Code in **WSL 2 mode**. Most people don't know this exists and it dramatically changes everything:
|
|
529
|
+
|
|
530
|
+
- **HMR is 5-10x faster** — file changes don't cross the Windows/Linux boundary
|
|
531
|
+
- **Playwright tests run significantly faster** — native Linux browser processes
|
|
532
|
+
- **File watching actually works** — `tsx watch`, `next dev`, `nodemon` are all reliable
|
|
533
|
+
- **Node.js filesystem operations** avoid the slow NTFS translation layer
|
|
534
|
+
- **Claude Code runs faster** — native Linux tools (`grep`, `find`, `git`)
|
|
535
|
+
|
|
536
|
+
**CRITICAL:** Your project must be on the **WSL filesystem** (`~/projects/`), NOT on `/mnt/c/`. Having WSL but keeping your project on the Windows filesystem gives you the worst of both worlds.
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
# Check if you're set up correctly:
|
|
540
|
+
pwd
|
|
541
|
+
# GOOD: /home/you/projects/my-app
|
|
542
|
+
# BAD: /mnt/c/Users/you/projects/my-app ← still hitting Windows filesystem
|
|
543
|
+
|
|
544
|
+
# VS Code: click green "><" icon bottom-left → "Connect to WSL"
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
Run `/setup` to auto-detect your environment and get specific instructions.
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
## Service Ports (FIXED — NEVER CHANGE)
|
|
552
|
+
|
|
553
|
+
| Service | Dev Port | Test Port | URL |
|
|
554
|
+
|---------|----------|-----------|-----|
|
|
555
|
+
| Website | 3000 | 4000 | http://localhost:{port} |
|
|
556
|
+
| API | 3001 | 4010 | http://localhost:{port} |
|
|
557
|
+
| Dashboard | 3002 | 4020 | http://localhost:{port} |
|
|
558
|
+
|
|
559
|
+
When starting any service, ALWAYS use its assigned port:
|
|
560
|
+
|
|
561
|
+
```bash
|
|
562
|
+
# CORRECT
|
|
563
|
+
npx next dev -p 3002
|
|
564
|
+
|
|
565
|
+
# WRONG — never let it default
|
|
566
|
+
npx next dev
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
Before starting services, ALWAYS kill existing processes on those ports:
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
lsof -ti:3000,3001,3002 | xargs kill -9 2>/dev/null
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## Project Structure
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
project/
|
|
581
|
+
├── CLAUDE.md # You are here
|
|
582
|
+
├── CLAUDE.local.md # Personal overrides (gitignored)
|
|
583
|
+
├── .claude/
|
|
584
|
+
│ ├── commands/ # Slash commands (/review, /refactor, /worktree, /new-project, etc.)
|
|
585
|
+
│ ├── skills/ # Triggered expertise & scaffolding templates
|
|
586
|
+
│ ├── agents/ # Custom subagents
|
|
587
|
+
│ └── hooks/ # Enforcement scripts (9 hooks: secrets, branch, ports, rybbit, e2e, lint, env-sync, rulecatch)
|
|
588
|
+
├── project-docs/
|
|
589
|
+
│ ├── ARCHITECTURE.md # System overview & data flow
|
|
590
|
+
│ ├── INFRASTRUCTURE.md # Deployment & environment details
|
|
591
|
+
│ └── DECISIONS.md # Why we chose X over Y
|
|
592
|
+
├── docs/ # GitHub Pages site
|
|
593
|
+
│ └── user-guide.html # Interactive User Guide (HTML)
|
|
594
|
+
├── src/
|
|
595
|
+
│ ├── handlers/ # Business logic
|
|
596
|
+
│ ├── adapters/ # External service wrappers
|
|
597
|
+
│ └── types/ # Shared TypeScript types
|
|
598
|
+
├── tests/
|
|
599
|
+
│ ├── unit/
|
|
600
|
+
│ ├── integration/
|
|
601
|
+
│ └── e2e/
|
|
602
|
+
├── scripts/
|
|
603
|
+
│ ├── db-query.ts # Test Query Master — index of all dev/test queries
|
|
604
|
+
│ ├── queries/ # Individual query files (dev/test only, NOT production)
|
|
605
|
+
│ ├── build-content.ts # Markdown → HTML article builder
|
|
606
|
+
│ └── content.config.json # Article registry (source, output, SEO metadata)
|
|
607
|
+
├── content/ # Markdown source files for articles/posts
|
|
608
|
+
├── USER_GUIDE.md # Comprehensive User Guide (Markdown)
|
|
609
|
+
├── .env.example # Template with placeholders (committed)
|
|
610
|
+
├── .env # Actual secrets (NEVER committed)
|
|
611
|
+
├── .gitignore
|
|
612
|
+
├── .dockerignore
|
|
613
|
+
├── package.json # All scripts: dev, test, db:query, content:build, ai:monitor
|
|
614
|
+
├── claude-mastery-project.conf # Profile presets for /new-project (clean, default, api, go, etc.)
|
|
615
|
+
├── playwright.config.ts # E2E test config (test ports 4000/4010/4020, webServer)
|
|
616
|
+
├── vitest.config.ts # Unit/integration test config
|
|
617
|
+
└── tsconfig.json
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
## Project Documentation
|
|
623
|
+
|
|
624
|
+
| Document | Purpose | When to Read |
|
|
625
|
+
|----------|---------|--------------|
|
|
626
|
+
| `project-docs/ARCHITECTURE.md` | System overview & data flow | Before architectural changes |
|
|
627
|
+
| `project-docs/INFRASTRUCTURE.md` | Deployment details | Before environment changes |
|
|
628
|
+
| `project-docs/DECISIONS.md` | Architectural decisions | Before proposing alternatives |
|
|
629
|
+
|
|
630
|
+
**ALWAYS read relevant docs before making cross-service changes.**
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
## Coding Standards
|
|
635
|
+
|
|
636
|
+
### Imports
|
|
637
|
+
|
|
638
|
+
```typescript
|
|
639
|
+
// CORRECT — explicit, typed
|
|
640
|
+
import { getUserById } from './handlers/users.js';
|
|
641
|
+
import type { User } from './types/index.js';
|
|
642
|
+
|
|
643
|
+
// WRONG — barrel imports that pull everything
|
|
644
|
+
import * as everything from './index.js';
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### Error Handling
|
|
648
|
+
|
|
649
|
+
```typescript
|
|
650
|
+
// CORRECT — handle errors explicitly
|
|
651
|
+
try {
|
|
652
|
+
const user = await getUserById(id);
|
|
653
|
+
if (!user) throw new NotFoundError('User not found');
|
|
654
|
+
return user;
|
|
655
|
+
} catch (err) {
|
|
656
|
+
logger.error('Failed to get user', { id, error: err });
|
|
657
|
+
throw err;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// WRONG — swallow errors silently
|
|
661
|
+
try {
|
|
662
|
+
return await getUserById(id);
|
|
663
|
+
} catch {
|
|
664
|
+
return null; // silent failure
|
|
665
|
+
}
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
### Go (Gin / Chi / Echo / Fiber / stdlib)
|
|
669
|
+
|
|
670
|
+
When working on a Go project (detected by `go.mod` in root or `language = go` in profile):
|
|
671
|
+
|
|
672
|
+
- **Standard layout:** `cmd/` for entry points, `internal/` for private packages — follow Go conventions
|
|
673
|
+
- **Go modules:** Always use `go.mod` / `go.sum` — NEVER use `GOPATH` mode or `dep`
|
|
674
|
+
- **golangci-lint:** Run `golangci-lint run` before committing — config in `.golangci.yml`
|
|
675
|
+
- **Table-driven tests:** Use `[]struct{ name string; ... }` pattern for multiple test cases
|
|
676
|
+
- **context.Context:** Every I/O function accepts `ctx context.Context` as first parameter
|
|
677
|
+
- **Interfaces:** Accept interfaces, return structs — define interfaces at the consumer
|
|
678
|
+
- **Error handling:** NEVER ignore errors with `_` — always check and wrap with `fmt.Errorf("context: %w", err)`
|
|
679
|
+
- **No global mutable state:** Pass dependencies via struct fields, not package-level vars
|
|
680
|
+
- **Graceful shutdown:** Handle SIGINT/SIGTERM, close DB connections with `context.WithTimeout`
|
|
681
|
+
- **API versioning:** Same rule — all endpoints under `/api/v1/` prefix
|
|
682
|
+
- **Quality gates:** Same limits — no file > 300 lines, no function > 50 lines
|
|
683
|
+
- **Makefile:** Use `make build`, `make test`, `make lint` — NOT raw `go` commands in scripts
|
|
684
|
+
|
|
685
|
+
### Python (FastAPI / Django / Flask)
|
|
686
|
+
|
|
687
|
+
When working on a Python project (detected by `pyproject.toml` in root or `language = python` in profile):
|
|
688
|
+
|
|
689
|
+
- **Type hints ALWAYS:** Every function MUST have type hints for all parameters AND return type
|
|
690
|
+
- **Modern syntax:** Use `str | None` (not `Optional[str]`), `list[str]` (not `List[str]`)
|
|
691
|
+
- **Async consistently:** FastAPI handlers must be `async def` for I/O operations
|
|
692
|
+
- **pytest only:** NEVER use unittest — use pytest with `@pytest.mark.parametrize` for table-driven tests
|
|
693
|
+
- **Virtual environment:** ALWAYS use `.venv/` — NEVER install packages globally
|
|
694
|
+
- **Pydantic models:** Use Pydantic `BaseModel` for all request/response schemas
|
|
695
|
+
- **Pydantic settings:** Use `pydantic-settings` `BaseSettings` for environment config
|
|
696
|
+
- **ruff:** Run `ruff check` before committing — config in `ruff.toml` or `pyproject.toml`
|
|
697
|
+
- **API versioning:** Same rule — all endpoints under `/api/v1/` prefix
|
|
698
|
+
- **Quality gates:** Same limits — no file > 300 lines, no function > 50 lines
|
|
699
|
+
- **Makefile:** Use `make dev`, `make test`, `make lint` — NOT raw Python commands in scripts
|
|
700
|
+
- **Graceful shutdown:** Handle SIGINT/SIGTERM, close database connections before exiting
|
|
701
|
+
|
|
702
|
+
---
|
|
703
|
+
|
|
704
|
+
## Naming — NEVER Rename Mid-Project
|
|
705
|
+
|
|
706
|
+
Renaming packages, modules, or key variables mid-project causes cascading failures that are extremely hard to catch. If you must rename:
|
|
707
|
+
|
|
708
|
+
1. Create a checklist of ALL files and references first
|
|
709
|
+
2. Use IDE semantic rename (not search-and-replace)
|
|
710
|
+
3. Full project search for old name after renaming
|
|
711
|
+
4. Check: .md files, .txt files, .env files, comments, strings, paths
|
|
712
|
+
5. Start a FRESH Claude session after renaming
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
716
|
+
## Plan Mode — Plan First, Code Second
|
|
717
|
+
|
|
718
|
+
**For any non-trivial task, start in plan mode.** Don't let Claude write code until you've agreed on the plan. Bad plan = bad code. Always.
|
|
719
|
+
|
|
720
|
+
- Use plan mode for: new features, refactors, architectural changes, multi-file edits
|
|
721
|
+
- Skip plan mode for: typo fixes, single-line changes, obvious bugs
|
|
722
|
+
- One Claude writes the plan. You review it as the engineer. THEN code.
|
|
723
|
+
|
|
724
|
+
### Step Naming — MANDATORY
|
|
725
|
+
|
|
726
|
+
Every step in a plan MUST have a consistent, unique name. This is how the user references steps when requesting changes. Claude forgets to update plans — named steps make it unambiguous.
|
|
727
|
+
|
|
728
|
+
```
|
|
729
|
+
CORRECT — named steps the user can reference:
|
|
730
|
+
Step 1 (Project Setup): Initialize repo with TypeScript
|
|
731
|
+
Step 2 (Database Layer): Set up StrictDB
|
|
732
|
+
Step 3 (Auth System): Implement JWT authentication
|
|
733
|
+
Step 4 (API Routes): Create user endpoints
|
|
734
|
+
Step 5 (Testing): Write E2E tests for auth flow
|
|
735
|
+
|
|
736
|
+
WRONG — generic steps nobody can reference:
|
|
737
|
+
Step 1: Set things up
|
|
738
|
+
Step 2: Build the backend
|
|
739
|
+
Step 3: Add tests
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### Modifying a Plan — REPLACE, Don't Append
|
|
743
|
+
|
|
744
|
+
When the user asks to change something in the plan:
|
|
745
|
+
|
|
746
|
+
1. **FIND** the exact named step being changed
|
|
747
|
+
2. **REPLACE** that step's content entirely with the new approach
|
|
748
|
+
3. **Review ALL other steps** for contradictions with the change
|
|
749
|
+
4. **Rewrite the full updated plan** so the user can see the complete picture
|
|
750
|
+
|
|
751
|
+
```
|
|
752
|
+
CORRECT:
|
|
753
|
+
User: "Change Step 3 (Auth System) to use session cookies instead of JWT"
|
|
754
|
+
Claude: Replaces Step 3 content, checks Steps 4-5 for JWT references,
|
|
755
|
+
outputs the FULL updated plan with Step 3 rewritten
|
|
756
|
+
|
|
757
|
+
WRONG:
|
|
758
|
+
User: "Actually use session cookies instead"
|
|
759
|
+
Claude: Appends "Also, use session cookies" at the bottom
|
|
760
|
+
← Step 3 still says JWT. Now the plan contradicts itself.
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
**Claude will forget to do this.** If you notice the plan has contradictions, tell Claude: "Rewrite the full plan — Step 3 and Step 7 contradict each other."
|
|
764
|
+
|
|
765
|
+
- If fundamentally changing direction: `/clear` → state requirements fresh
|
|
766
|
+
|
|
767
|
+
---
|
|
768
|
+
|
|
769
|
+
## Documentation Sync
|
|
770
|
+
|
|
771
|
+
When updating any feature, keep these locations in sync:
|
|
772
|
+
|
|
773
|
+
1. `README.md` (repository root)
|
|
774
|
+
2. `docs/index.html` (GitHub Pages site)
|
|
775
|
+
3. `project-docs/` (relevant documentation)
|
|
776
|
+
4. `CLAUDE.md` quick reference table (if adding commands/scripts)
|
|
777
|
+
5. `tests/STARTER-KIT-VERIFICATION.md` (if adding hooks/files)
|
|
778
|
+
6. Inline code comments
|
|
779
|
+
7. Test descriptions
|
|
780
|
+
|
|
781
|
+
If you update one, update ALL.
|
|
782
|
+
|
|
783
|
+
### Adding a New Command or Hook — MANDATORY Checklist
|
|
784
|
+
|
|
785
|
+
When creating a new `.claude/commands/*.md` or `.claude/hooks/*.sh`:
|
|
786
|
+
|
|
787
|
+
1. **README.md** — Update the command count, project structure tree, and add a description section
|
|
788
|
+
2. **docs/index.html** — Update the command count, project structure tree, and add a command card
|
|
789
|
+
3. **CLAUDE.md** — Add to the quick reference table (if user-facing)
|
|
790
|
+
4. **tests/STARTER-KIT-VERIFICATION.md** — Add verification checklist entry
|
|
791
|
+
5. **.claude/settings.json** — Wire up hooks (if adding a hook)
|
|
792
|
+
|
|
793
|
+
**This is NOT optional.** Every command/hook must appear in all five locations before the commit.
|
|
794
|
+
|
|
795
|
+
### Command Scope Classification
|
|
796
|
+
|
|
797
|
+
Every command has a `scope:` field in its YAML frontmatter:
|
|
798
|
+
|
|
799
|
+
- **`scope: project`** (16 commands) — Work inside any project. Copied to scaffolded projects by `/new-project`, `/convert-project-to-starter-kit`, and `/update-project`.
|
|
800
|
+
- **`scope: starter-kit`** (10 commands) — Kit management only. Never copied to scaffolded projects.
|
|
801
|
+
|
|
802
|
+
**Project commands:** `help`, `review`, `commit`, `progress`, `test-plan`, `architecture`, `security-check`, `optimize-docker`, `create-e2e`, `create-api`, `worktree`, `refactor`, `diagram`, `setup`, `what-is-my-ai-doing`, `show-user-guide`
|
|
803
|
+
|
|
804
|
+
**Starter-kit commands:** `new-project`, `update-project`, `convert-project-to-starter-kit`, `install-global`, `install-mdd`, `projects-created`, `remove-project`, `set-project-profile-default`, `add-project-setup`, `quickstart`, `add-feature`
|
|
805
|
+
|
|
806
|
+
When distributing commands (new-project, convert, update), **always filter by `scope: project`** in the source command's frontmatter. Skills, agents, hooks, and settings.json are copied in full regardless of scope.
|
|
807
|
+
|
|
808
|
+
---
|
|
809
|
+
|
|
810
|
+
## CLAUDE.md Is Team Memory — The Feedback Loop
|
|
811
|
+
|
|
812
|
+
Every time Claude makes a mistake, **add a rule to prevent it from happening again.**
|
|
813
|
+
|
|
814
|
+
This is the single most powerful pattern for improving Claude's behavior over time:
|
|
815
|
+
|
|
816
|
+
1. Claude makes a mistake (wrong pattern, bad assumption, missed edge case)
|
|
817
|
+
2. You fix the mistake
|
|
818
|
+
3. You tell Claude: "Update CLAUDE.md so you don't make that mistake again"
|
|
819
|
+
4. Claude adds a rule to this file
|
|
820
|
+
5. Mistake rates actually drop over time
|
|
821
|
+
|
|
822
|
+
**This file is checked into git. The whole team benefits from every lesson learned.**
|
|
823
|
+
|
|
824
|
+
Don't just fix bugs — fix the rules that allowed the bug. Every mistake is a missing rule.
|
|
825
|
+
|
|
826
|
+
**If RuleCatch is installed:** also add the rule as a custom RuleCatch rule so it's monitored automatically across all future sessions. CLAUDE.md rules are suggestions — RuleCatch enforces them.
|
|
827
|
+
|
|
828
|
+
---
|
|
829
|
+
|
|
830
|
+
## Workflow Preferences
|
|
831
|
+
|
|
832
|
+
- Quality over speed — if unsure, ask before executing
|
|
833
|
+
- Plan first, code second — use plan mode for non-trivial tasks
|
|
834
|
+
- One task, one chat — `/clear` between unrelated tasks
|
|
835
|
+
- One task, one branch — use `/worktree` to isolate work from main
|
|
836
|
+
- Use `/context` to check token usage when working on large tasks
|
|
837
|
+
- When testing: queue observations, fix in batch (not one at a time)
|
|
838
|
+
- Research shows 2% misalignment early in a conversation can cause 40% failure rate by end — start fresh when changing direction
|