@claude-code-mastery/starter-kit 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.
Files changed (70) hide show
  1. package/.claude/.starter-kit/profiles/clean.md +113 -0
  2. package/.claude/.starter-kit/profiles/go.md +458 -0
  3. package/.claude/.starter-kit/profiles/node.md +429 -0
  4. package/.claude/.starter-kit/profiles/python.md +475 -0
  5. package/.claude/.starter-kit/shared/analytics-rybbit.md +55 -0
  6. package/.claude/.starter-kit/shared/claude-md-base.md +93 -0
  7. package/.claude/.starter-kit/shared/deployment-dokploy.md +158 -0
  8. package/.claude/.starter-kit/shared/feature-manifest.md +43 -0
  9. package/.claude/.starter-kit/shared/mcp-and-pooler.md +38 -0
  10. package/.claude/.starter-kit/shared/mongo-setup.md +20 -0
  11. package/.claude/.starter-kit/shared/profile-config.md +65 -0
  12. package/.claude/.starter-kit/shared/seo.md +113 -0
  13. package/.claude/.starter-kit/shared/sql-setup.md +37 -0
  14. package/.claude/commands/add-feature.md +349 -0
  15. package/.claude/commands/add-project-setup.md +156 -0
  16. package/.claude/commands/architecture.md +27 -0
  17. package/.claude/commands/commit.md +61 -0
  18. package/.claude/commands/convert-project-to-starter-kit.md +508 -0
  19. package/.claude/commands/create-api.md +385 -0
  20. package/.claude/commands/create-e2e.md +230 -0
  21. package/.claude/commands/diagram.md +301 -0
  22. package/.claude/commands/help.md +120 -0
  23. package/.claude/commands/install-global.md +145 -0
  24. package/.claude/commands/new-project.md +244 -0
  25. package/.claude/commands/optimize-docker.md +352 -0
  26. package/.claude/commands/progress.md +61 -0
  27. package/.claude/commands/projects-created.md +79 -0
  28. package/.claude/commands/quickstart.md +105 -0
  29. package/.claude/commands/refactor.md +267 -0
  30. package/.claude/commands/remove-project.md +95 -0
  31. package/.claude/commands/review.md +59 -0
  32. package/.claude/commands/security-check.md +77 -0
  33. package/.claude/commands/set-project-profile-default.md +79 -0
  34. package/.claude/commands/setup.md +337 -0
  35. package/.claude/commands/show-user-guide.md +58 -0
  36. package/.claude/commands/starter-kit.md +90 -0
  37. package/.claude/commands/test-plan.md +118 -0
  38. package/.claude/commands/update-project.md +413 -0
  39. package/.claude/commands/what-is-my-ai-doing.md +42 -0
  40. package/.claude/commands/worktree.md +124 -0
  41. package/.claude/hooks/block-dangerous-bash.py +55 -0
  42. package/.claude/hooks/check-branch.sh +116 -0
  43. package/.claude/hooks/check-e2e.sh +71 -0
  44. package/.claude/hooks/check-env-sync.sh +41 -0
  45. package/.claude/hooks/check-file-length.py +47 -0
  46. package/.claude/hooks/check-ports.sh +59 -0
  47. package/.claude/hooks/check-rulecatch.sh +33 -0
  48. package/.claude/hooks/check-rybbit.sh +63 -0
  49. package/.claude/hooks/lint-on-save.sh +59 -0
  50. package/.claude/hooks/verify-no-secrets.sh +80 -0
  51. package/.claude/settings.json +34 -0
  52. package/.claude/skills/api-conventions/SKILL.md +34 -0
  53. package/.claude/skills/code-review/SKILL.md +87 -0
  54. package/.claude/skills/code-review/references/mongodb-checks.md +25 -0
  55. package/.claude/skills/code-review/references/project-checks.md +38 -0
  56. package/.claude/skills/create-service/SKILL.md +222 -0
  57. package/.claude/skills/debugger/SKILL.md +39 -0
  58. package/.claude/skills/dependency-vetting/SKILL.md +46 -0
  59. package/.claude/skills/design-review/SKILL.md +50 -0
  60. package/.claude/skills/mcp-builder/SKILL.md +57 -0
  61. package/.claude/skills/mongodb-rules/SKILL.md +62 -0
  62. package/.claude/skills/terminal-tui/SKILL.md +106 -0
  63. package/.claude/skills/test-writer/SKILL.md +78 -0
  64. package/LICENSE +21 -0
  65. package/README.md +2152 -0
  66. package/bin/cli.js +205 -0
  67. package/claude-mastery-project.conf +220 -0
  68. package/global-claude-md/CLAUDE.md +212 -0
  69. package/global-claude-md/settings.json +3 -0
  70. package/package.json +81 -0
@@ -0,0 +1,244 @@
1
+ ---
2
+ description: Create a new project with all scaffolding rules applied
3
+ scope: starter-kit
4
+ argument-hint: <path> [profile-or-options...]
5
+ allowed-tools: Bash, Write, Read, AskUserQuestion
6
+ ---
7
+
8
+ # New Project Scaffold
9
+
10
+ Create a new project with all best practices from the Claude Code Mastery Guides.
11
+
12
+ **Arguments:** $ARGUMENTS
13
+
14
+ ## Argument Parsing
15
+
16
+ ### Step 0 — Read the config file
17
+
18
+ Before parsing arguments, read `claude-mastery-project.conf` (in the starter kit root or `~/.claude/claude-mastery-project.conf` as fallback).
19
+
20
+ Extract the `[global]` section for `root_dir` and `default_profile`.
21
+
22
+ - `root_dir` — Default parent directory for new projects
23
+ - `default_profile` — Profile to use when no profile is specified in arguments (e.g., `default_profile = clean`). If not set, ask the user as before.
24
+
25
+ ### Step 0.0 — Global Claude Config (one-time setup)
26
+
27
+ Check if the user already has the global Claude config installed:
28
+
29
+ ```bash
30
+ # Check if global CLAUDE.md exists
31
+ ls ~/.claude/CLAUDE.md 2>/dev/null
32
+ ```
33
+
34
+ **If `~/.claude/CLAUDE.md` does NOT exist:**
35
+ - ASK: "You don't have a global CLAUDE.md yet. Want me to install the Claude Code Mastery global config to `~/.claude/`? This sets up security rules, hooks, and standards that apply to ALL your projects. (This is a one-time setup.)"
36
+ - If yes: copy `global-claude-md/CLAUDE.md` → `~/.claude/CLAUDE.md` and `global-claude-md/settings.json` → `~/.claude/settings.json`
37
+ - Also copy hooks: `mkdir -p ~/.claude/hooks && cp .claude/hooks/verify-no-secrets.sh ~/.claude/hooks/`
38
+
39
+ **If `~/.claude/CLAUDE.md` DOES exist:**
40
+ - ASK: "You already have a global CLAUDE.md. Want me to check if the starter kit version has anything new to merge in?"
41
+ - If yes: diff the two files and show what's different. Let the user decide what to merge.
42
+ - If no: skip and continue.
43
+
44
+ **This step typically only happens once.** After the first install, the global config persists across all projects.
45
+
46
+ ### Step 0.1 — Resolve the project path
47
+
48
+ The **first argument** is the project name or path. Resolve it using `root_dir`:
49
+
50
+ 1. **Explicit path** (starts with `./`, `../`, `~/`, or `/`) → use as-is
51
+ - `/new-project ~/code/my-app` → creates at `~/code/my-app`
52
+ - `/new-project ./my-app` → creates at `./my-app`
53
+
54
+ 2. **Just a name** (no path separators) → prepend `root_dir` from `[global]`
55
+ - Config has `root_dir = ~/projects`
56
+ - `/new-project my-app` → creates at `~/projects/my-app`
57
+ - `/new-project tims-api` → creates at `~/projects/tims-api`
58
+
59
+ 3. **No argument at all** → ASK the user for the project name, then prepend `root_dir`
60
+
61
+ Everything after the project name/path is shorthand options or a profile name.
62
+
63
+ ### Shorthand Arguments (after the path/name)
64
+
65
+ Parse remaining $ARGUMENTS for these keywords:
66
+
67
+ **Profiles:** `clean`, `default`, `api`, `static-site`, `quick`, `enterprise`, `go`, `vue`, `nuxt`, `svelte`, `sveltekit`, `angular`, `python-api`, `django`, `flask` (from `claude-mastery-project.conf`)
68
+ **Special:** `clean` — Claude infrastructure only, zero coding opinions (see Clean Mode below)
69
+ **Languages:** `go`, `golang` (triggers Go scaffolding — see Go Mode below) | `python`, `py` (triggers Python Mode below)
70
+ **Project types:** `webapp`, `api`, `fullstack`, `cli`
71
+ **Frameworks:** `vite`, `react`, `next`, `nextjs`, `astro`, `fastify`, `express`, `hono`, `vue`, `nuxt`, `svelte`, `sveltekit`, `angular`
72
+ **Go Frameworks:** `gin`, `chi`, `echo`, `fiber`, `stdlib`
73
+ **Python Frameworks:** `fastapi`, `django`, `flask`
74
+ **Options:** `seo`, `ssr`, `tailwind`, `prisma`, `docker`, `ci`, `multiregion`
75
+ **Hosting:** `dokploy`, `vercel`, `static`
76
+ **Database:** `mongo`, `postgres`, `mysql`, `mssql`, `sqlite`
77
+ **Analytics:** `rybbit`
78
+ **MCP servers:** `playwright`, `context7`, `rulecatch`
79
+ **NPM extras:** `ai-pooler` (installs @rulecatch/ai-pooler)
80
+ **Package managers:** `pnpm`, `npm`, `bun`
81
+
82
+ Examples:
83
+ - `/new-project my-app` — creates at ~/projects/my-app (from root_dir), asks questions
84
+ - `/new-project my-app clean` — Claude infrastructure only, no coding opinions
85
+ - `/new-project my-app default` — creates at ~/projects/my-app with default profile
86
+ - `/new-project my-app fullstack next seo tailwind pnpm` — ~/projects/my-app, skips all questions
87
+ - `/new-project ./custom-path/my-app api fastify` — explicit path, ignores root_dir
88
+ - `/new-project ~/code/my-app default` — explicit path, uses default profile
89
+ - `/new-project my-app fullstack next mongo playwright context7 rulecatch` — full stack
90
+ - `/new-project my-api go` — Go API with Gin, MongoDB, Docker
91
+ - `/new-project my-api go chi postgres` — Go with Chi, PostgreSQL
92
+ - `/new-project my-cli go cli` — Go CLI with Cobra
93
+ - `/new-project my-app vue` — Vue 3 SPA with Tailwind
94
+ - `/new-project my-app nuxt` — Nuxt full-stack with MongoDB, Docker
95
+ - `/new-project my-app svelte` — Svelte SPA with Tailwind
96
+ - `/new-project my-app sveltekit` — SvelteKit full-stack with MongoDB, Docker
97
+ - `/new-project my-app angular` — Angular SPA with Tailwind
98
+ - `/new-project my-api python-api` — FastAPI with PostgreSQL, Docker
99
+ - `/new-project my-app django` — Django full-stack with PostgreSQL, Docker
100
+ - `/new-project my-api flask` — Flask API with PostgreSQL, Docker
101
+ - `/new-project my-api python fastapi postgres docker` — Python API with overrides
102
+
103
+ Any keyword not provided = check `default_profile` in `[global]` first, then ask the user. If `default_profile` is set (e.g., `default_profile = clean`) and no profile was specified in the arguments, use that profile automatically.
104
+
105
+ ---
106
+
107
+ ## Project Registry — MANDATORY Final Step (ALL modes)
108
+
109
+ **After EVERY successful project scaffold (Clean, Go, Python, or Node.js), register the project in `~/.claude/starter-kit-projects.json`.**
110
+
111
+ This enables `/projects-created` and `/remove-project` to track all projects.
112
+
113
+ ### How to register
114
+
115
+ 1. Read `~/.claude/starter-kit-projects.json` (create if it doesn't exist)
116
+ 2. Append a new entry to the `projects` array:
117
+
118
+ ```json
119
+ {
120
+ "name": "my-app",
121
+ "path": "/home/user/projects/my-app",
122
+ "profile": "default",
123
+ "language": "node",
124
+ "framework": "next",
125
+ "database": "mongo",
126
+ "createdAt": "2025-01-15T10:30:00Z"
127
+ }
128
+ ```
129
+
130
+ 3. Write the updated file back
131
+
132
+ **Field mapping:**
133
+ - `name` — project directory name (last segment of path)
134
+ - `path` — absolute path to the project directory
135
+ - `profile` — profile name used (e.g., `clean`, `default`, `go`, `python-api`), or `custom` if built from shorthand args
136
+ - `language` — `node`, `go`, or `python`
137
+ - `framework` — the chosen framework (e.g., `next`, `gin`, `fastapi`), or `none` for clean mode
138
+ - `database` — `mongo`, `postgres`, `mysql`, `mssql`, `sqlite`, or `none`
139
+ - `createdAt` — ISO 8601 timestamp of creation
140
+
141
+ **If the file doesn't exist yet**, create it with:
142
+
143
+ ```json
144
+ {
145
+ "projects": []
146
+ }
147
+ ```
148
+
149
+ **This step happens AFTER git init and initial commit, as the very last action before displaying the verification checklist.**
150
+
151
+ ---
152
+
153
+
154
+ ---
155
+
156
+ ## Route to the Profile
157
+
158
+ The detailed scaffolding lives in `.claude/.starter-kit/`, split so only the parts a run actually needs are loaded. Based on the resolved mode/language, read the matching profile file and follow it exactly:
159
+
160
+ | Mode / language | Read and follow |
161
+ | --- | --- |
162
+ | `clean` | `.claude/.starter-kit/profiles/clean.md` |
163
+ | `go` / `golang` / `gin`, `chi`, `echo`, `fiber`, `stdlib` | `.claude/.starter-kit/profiles/go.md` |
164
+ | `python` / `py` / `fastapi`, `django`, `flask` | `.claude/.starter-kit/profiles/python.md` |
165
+ | default / `node` / any JS-TS framework | `.claude/.starter-kit/profiles/node.md` |
166
+
167
+ Read exactly one profile, the one the mode/language resolves to. Do NOT read the others.
168
+
169
+ `.claude/.starter-kit/` is kit-internal scaffolding source. It is read while running `/new-project`, but it is **never copied into the scaffolded project** (the new project doesn't have `/new-project`). Copy only `skills/`, `hooks/`, `settings.json`, and `scope: project` commands, as the steps below specify.
170
+
171
+ Every profile except `clean` builds its CLAUDE.md from `.claude/.starter-kit/shared/claude-md-base.md` plus its own rules; read the base first. For `clean`, the base *is* the CLAUDE.md.
172
+
173
+ ## Load Only the Shared Modules the Choices Require
174
+
175
+ After the profile, read only the shared modules the user's selections call for, nothing more:
176
+
177
+ | If the user selected | Also read and apply |
178
+ | --- | --- |
179
+ | a SQL database (`postgres`, `mysql`, `mssql`, `sqlite`) | `.claude/.starter-kit/shared/sql-setup.md` |
180
+ | `mongo` | `.claude/.starter-kit/shared/mongo-setup.md` |
181
+ | a web (HTML-serving) project | `.claude/.starter-kit/shared/seo.md` |
182
+ | Dokploy hosting | `.claude/.starter-kit/shared/deployment-dokploy.md` |
183
+ | Rybbit analytics | `.claude/.starter-kit/shared/analytics-rybbit.md` |
184
+ | MCP servers or AI-Pooler | `.claude/.starter-kit/shared/mcp-and-pooler.md` |
185
+
186
+ Profile presets (the `claude-mastery-project.conf` format) are documented in `.claude/.starter-kit/shared/profile-config.md`; read it only when creating or resolving a profile.
187
+
188
+ **Example:** a `node` + `mongo` run reads `profiles/node.md`, `shared/claude-md-base.md`, `shared/mongo-setup.md`, and `shared/seo.md`. It never loads `go.md` or `python.md`.
189
+
190
+ ## Feature Manifest — MANDATORY Final Step (ALL modes except Clean)
191
+
192
+ Follow `.claude/.starter-kit/shared/feature-manifest.md` to map the scaffolding choices to features and write the project's feature manifest.
193
+
194
+ ## Verification Checklist
195
+
196
+ After creation, verify and report:
197
+
198
+ **Core files:**
199
+ - [ ] .env exists (empty)
200
+ - [ ] .env.example exists (with placeholders)
201
+ - [ ] .gitignore includes all required entries
202
+ - [ ] .dockerignore exists
203
+ - [ ] CLAUDE.md has all required sections (overview, stack, commands, ports)
204
+ - [ ] package.json has ALL required scripts (dev, build, test, test:e2e, test:kill-ports)
205
+ - [ ] Error handlers in entry point (gracefulShutdown for StrictDB projects)
206
+ - [ ] TypeScript strict mode enabled
207
+
208
+ **Testing:**
209
+ - [ ] vitest.config.ts created and configured
210
+ - [ ] playwright.config.ts created with test ports (4000/4010/4020) and webServer
211
+ - [ ] test:kill-ports script kills test ports BEFORE E2E runs
212
+ - [ ] tests/e2e/ directory exists
213
+ - [ ] tests/unit/ directory exists
214
+ - [ ] Example E2E test has minimum 3 assertions (URL, element, data)
215
+ - [ ] `pnpm test` runs unit + E2E in sequence
216
+
217
+ **Web projects:**
218
+ - [ ] SEO meta tags in layout/head
219
+ - [ ] JSON-LD structured data included
220
+ - [ ] robots.txt created
221
+
222
+ **Infrastructure:**
223
+ - [ ] Dockerfile with multi-stage build (Docker projects)
224
+ - [ ] scripts/deploy.sh created (Dokploy projects)
225
+ - [ ] Multi-region deploy script (if multiregion selected)
226
+
227
+ **Database (StrictDB projects):**
228
+ - [ ] StrictDB installed as dependency
229
+ - [ ] scripts/db-query.ts — Test Query Master
230
+ - [ ] scripts/queries/ directory
231
+ - [ ] db-query rules in CLAUDE.md
232
+
233
+ **Content (if web project with articles/posts):**
234
+ - [ ] scripts/build-content.ts
235
+ - [ ] scripts/content.config.json
236
+ - [ ] content/ directory
237
+
238
+ **Extras:**
239
+ - [ ] MCP servers installed (if selected)
240
+ - [ ] claude-mastery-project.conf created (if using profiles)
241
+ - [ ] No file > 300 lines
242
+ - [ ] All independent awaits use Promise.all
243
+
244
+ Report any missing items.
@@ -0,0 +1,352 @@
1
+ ---
2
+ description: Analyze and optimize Docker builds for production
3
+ scope: project
4
+ argument-hint: [dockerfile-path]
5
+ allowed-tools: Read, Write, Edit, Grep, Glob, Bash
6
+ ---
7
+
8
+ # Optimize Docker Build
9
+
10
+ Analyze and optimize the Docker setup for: **$ARGUMENTS**
11
+
12
+ If no Dockerfile path provided, search for Dockerfiles in the project root.
13
+
14
+ ## Step 0 — Auto-Branch (if on main)
15
+
16
+ Before modifying any files, check the current branch:
17
+
18
+ ```bash
19
+ git branch --show-current
20
+ ```
21
+
22
+ **Default behavior** (`auto_branch = true` in `claude-mastery-project.conf`):
23
+ - If on `main` or `master`: automatically create a feature branch and switch to it:
24
+ ```bash
25
+ git checkout -b chore/docker-optimize
26
+ ```
27
+ Report: "Created branch `chore/docker-optimize` — main stays untouched."
28
+ - If already on a feature branch: proceed
29
+ - If not a git repo: skip this check
30
+
31
+ **To disable:** Set `auto_branch = false` in `claude-mastery-project.conf`. When disabled, warn and ask the user before proceeding on main.
32
+
33
+ ## Step 1 — Find and Read All Docker Files
34
+
35
+ Read these files (if they exist):
36
+ - `Dockerfile` (or the path provided in $ARGUMENTS)
37
+ - `docker-compose.yml` / `docker-compose.yaml`
38
+ - `.dockerignore`
39
+ - `package.json` (for build scripts and dependencies)
40
+
41
+ ## Step 2 — Audit Against Best Practices
42
+
43
+ Check every rule below. For each violation, report:
44
+ - What's wrong
45
+ - Why it matters (performance impact or security risk)
46
+ - The fix
47
+
48
+ ### RULE 1: Multi-Stage Builds (MANDATORY)
49
+
50
+ Every production Dockerfile MUST use multi-stage builds. No exceptions.
51
+
52
+ ```dockerfile
53
+ # CORRECT — multi-stage: build artifacts don't ship to production
54
+ FROM node:20-alpine AS builder
55
+ WORKDIR /app
56
+ COPY package.json pnpm-lock.yaml ./
57
+ RUN corepack enable && pnpm install --frozen-lockfile
58
+ COPY . .
59
+ RUN pnpm build
60
+
61
+ FROM node:20-alpine AS runner
62
+ WORKDIR /app
63
+ COPY --from=builder /app/dist ./dist
64
+ COPY --from=builder /app/node_modules ./node_modules
65
+ COPY --from=builder /app/package.json ./
66
+ CMD ["node", "dist/index.js"]
67
+
68
+ # WRONG — single stage ships devDependencies, source code, build tools
69
+ FROM node:20
70
+ WORKDIR /app
71
+ COPY . .
72
+ RUN npm install
73
+ RUN npm run build
74
+ CMD ["node", "dist/index.js"]
75
+ ```
76
+
77
+ **Why:** Single-stage images are 3-10x larger. They ship TypeScript source, devDependencies, build tools — none of which are needed at runtime.
78
+
79
+ ### RULE 2: Layer Caching — COPY package.json FIRST
80
+
81
+ ```dockerfile
82
+ # CORRECT — package.json copied before source (cached unless deps change)
83
+ COPY package.json pnpm-lock.yaml ./
84
+ RUN pnpm install --frozen-lockfile
85
+ COPY . .
86
+
87
+ # WRONG — any source change busts the install cache
88
+ COPY . .
89
+ RUN pnpm install
90
+ ```
91
+
92
+ **Why:** Docker caches layers top-down. If `package.json` hasn't changed, the `install` layer is cached. Copying all files first means every code change re-installs all dependencies.
93
+
94
+ ### RULE 3: Use Alpine Base Images
95
+
96
+ ```dockerfile
97
+ # CORRECT — alpine is ~50MB
98
+ FROM node:20-alpine
99
+
100
+ # WRONG — full image is ~350MB
101
+ FROM node:20
102
+ ```
103
+
104
+ **Why:** Alpine is 7x smaller. Less attack surface, faster pulls, smaller registry storage.
105
+
106
+ ### RULE 4: Non-Root User
107
+
108
+ ```dockerfile
109
+ # CORRECT — run as non-root
110
+ RUN addgroup -S appgroup && adduser -S appuser -G appgroup
111
+ USER appuser
112
+
113
+ # WRONG — running as root
114
+ CMD ["node", "dist/index.js"]
115
+ ```
116
+
117
+ **Why:** Running as root inside a container means a container escape gives root on the host. Always drop privileges.
118
+
119
+ ### RULE 5: .dockerignore Exists and Is Complete
120
+
121
+ Must include at minimum:
122
+ ```
123
+ .env
124
+ .env.*
125
+ .git/
126
+ node_modules/
127
+ dist/
128
+ coverage/
129
+ test-results/
130
+ playwright-report/
131
+ .claude/
132
+ CLAUDE.local.md
133
+ *.log
134
+ ```
135
+
136
+ **Why:** Without `.dockerignore`, `COPY . .` sends `.git/` (huge), `node_modules/` (reinstalled anyway), `.env` (secrets!), and test artifacts into the build context.
137
+
138
+ ### RULE 6: Frozen Lockfile for Installs
139
+
140
+ ```dockerfile
141
+ # CORRECT — deterministic installs
142
+ RUN pnpm install --frozen-lockfile
143
+ RUN npm ci
144
+
145
+ # WRONG — may resolve different versions
146
+ RUN pnpm install
147
+ RUN npm install
148
+ ```
149
+
150
+ **Why:** `install` can resolve newer patch versions than what was tested. `--frozen-lockfile` / `ci` ensures exact versions from the lockfile.
151
+
152
+ ### RULE 7: Explicit EXPOSE
153
+
154
+ ```dockerfile
155
+ # CORRECT — documents the port
156
+ EXPOSE 3001
157
+ CMD ["node", "dist/index.js"]
158
+
159
+ # WRONG — no EXPOSE
160
+ CMD ["node", "dist/index.js"]
161
+ ```
162
+
163
+ **Why:** `EXPOSE` documents which ports the container listens on. Required for Docker networking and orchestrators.
164
+
165
+ ### RULE 8: No Secrets in Build Args (for runtime secrets)
166
+
167
+ ```dockerfile
168
+ # CORRECT — runtime secrets via environment
169
+ ENV DATABASE_URL=""
170
+ # Set at runtime: docker run -e DATABASE_URL=...
171
+
172
+ # WRONG — baked into image layer
173
+ ARG DATABASE_URL
174
+ RUN echo $DATABASE_URL > /app/.env
175
+ ```
176
+
177
+ **Exception:** `NEXT_PUBLIC_*` variables for Next.js MUST be build args (they're baked into the JS bundle at build time). This is expected and safe — they're public values.
178
+
179
+ ### RULE 9: Health Check
180
+
181
+ ```dockerfile
182
+ # CORRECT — Docker knows if the app is healthy
183
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
184
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1
185
+ ```
186
+
187
+ **Why:** Without HEALTHCHECK, Docker considers the container healthy as long as the process is running — even if it's deadlocked or returning 500s.
188
+
189
+ ### RULE 10: Minimize Layers
190
+
191
+ ```dockerfile
192
+ # CORRECT — single RUN for related commands
193
+ RUN corepack enable && \
194
+ corepack prepare pnpm@latest --activate && \
195
+ pnpm install --frozen-lockfile
196
+
197
+ # WRONG — each RUN creates a layer
198
+ RUN corepack enable
199
+ RUN corepack prepare pnpm@latest --activate
200
+ RUN pnpm install --frozen-lockfile
201
+ ```
202
+
203
+ **Why:** Each `RUN` creates a cached layer. Fewer layers = smaller image and faster builds.
204
+
205
+ ### RULE 11: Production-Only Dependencies in Runner
206
+
207
+ ```dockerfile
208
+ # CORRECT — only production deps in final image
209
+ FROM node:20-alpine AS runner
210
+ COPY --from=builder /app/package.json ./
211
+ RUN pnpm install --prod --frozen-lockfile
212
+
213
+ # OR: prune in builder stage
214
+ FROM node:20-alpine AS builder
215
+ RUN pnpm install --frozen-lockfile
216
+ RUN pnpm build
217
+ RUN pnpm prune --prod
218
+ ```
219
+
220
+ **Why:** devDependencies (TypeScript, Vitest, Playwright, tsx) are only needed for building. Shipping them adds 100-500MB to the final image.
221
+
222
+ ### RULE 12: Pin Major Versions
223
+
224
+ ```dockerfile
225
+ # CORRECT — predictable
226
+ FROM node:20-alpine
227
+
228
+ # WRONG — could be 20, 22, 24 tomorrow
229
+ FROM node:alpine
230
+ FROM node:latest
231
+ ```
232
+
233
+ **Why:** `latest` or unversioned tags change without notice. Your build may suddenly break on a Node.js major version bump.
234
+
235
+ ## Step 3 — Generate Optimized Dockerfile
236
+
237
+ If the current Dockerfile violates any rules above, generate a corrected version.
238
+
239
+ Use this template as a starting point:
240
+
241
+ ```dockerfile
242
+ # ============================================
243
+ # Stage 1: Build
244
+ # ============================================
245
+ FROM node:20-alpine AS builder
246
+ WORKDIR /app
247
+
248
+ # Enable pnpm
249
+ RUN corepack enable && corepack prepare pnpm@latest --activate
250
+
251
+ # Install dependencies (cached unless package.json changes)
252
+ COPY package.json pnpm-lock.yaml ./
253
+ RUN pnpm install --frozen-lockfile
254
+
255
+ # Build args for public env vars (Next.js only)
256
+ # ARG NEXT_PUBLIC_RYBBIT_SITE_ID
257
+ # ARG NEXT_PUBLIC_RYBBIT_URL
258
+
259
+ # Copy source and build
260
+ COPY . .
261
+ RUN pnpm build
262
+
263
+ # Prune dev dependencies
264
+ RUN pnpm prune --prod
265
+
266
+ # ============================================
267
+ # Stage 2: Production
268
+ # ============================================
269
+ FROM node:20-alpine AS runner
270
+ WORKDIR /app
271
+
272
+ # Non-root user
273
+ RUN addgroup -S appgroup && adduser -S appuser -G appgroup
274
+
275
+ # Copy only what's needed
276
+ COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
277
+ COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
278
+ COPY --from=builder --chown=appuser:appgroup /app/package.json ./
279
+
280
+ # Runtime config
281
+ ENV NODE_ENV=production
282
+ EXPOSE 3001
283
+
284
+ # Health check
285
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
286
+ CMD wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1
287
+
288
+ USER appuser
289
+ CMD ["node", "dist/index.js"]
290
+ ```
291
+
292
+ ## Step 4 — Verify .dockerignore
293
+
294
+ If `.dockerignore` is missing or incomplete, create/update it with all required entries.
295
+
296
+ ## Step 5 — Docker Local Test Gate (if enabled)
297
+
298
+ Check `claude-mastery-project.conf` for `docker_test_before_push`:
299
+
300
+ **When `docker_test_before_push = true`:**
301
+
302
+ Before ANY `docker push` is allowed, you MUST run this verification sequence. If any step fails, STOP and fix the issue — do NOT push.
303
+
304
+ ```bash
305
+ # 1. Build the image
306
+ docker build -t $IMAGE_NAME .
307
+
308
+ # 2. Run container locally
309
+ docker run -d -p 3001:3001 --name test-container $IMAGE_NAME
310
+
311
+ # 3. Wait for startup
312
+ sleep 5
313
+
314
+ # 4. Verify container is still running (didn't crash)
315
+ docker ps --filter "name=test-container" --filter "status=running" -q
316
+
317
+ # 5. Check health endpoint responds
318
+ curl -sf http://localhost:3001/health || echo "HEALTH CHECK FAILED"
319
+
320
+ # 6. Check container logs for fatal errors
321
+ docker logs test-container 2>&1 | grep -iE "(error|fatal|exception|ENOENT|cannot find)" && echo "ERRORS FOUND IN LOGS"
322
+
323
+ # 7. Clean up test container
324
+ docker stop test-container && docker rm test-container
325
+ ```
326
+
327
+ **Pass criteria — ALL must be true:**
328
+ - Container is still running after 5 seconds (didn't exit with error)
329
+ - Health endpoint returns HTTP 200
330
+ - No fatal errors in container logs
331
+
332
+ **If any check fails:** Report exactly what failed, show the logs, and do NOT push. Fix the issue first.
333
+
334
+ **When `docker_test_before_push = false` (default):** Skip this step. The user manages their own testing.
335
+
336
+ This gate applies to ALL docker push operations, not just `/optimize-docker`. Any command or workflow that pushes to Docker Hub must check this setting first.
337
+
338
+ ## Step 6 — RuleCatch Report
339
+
340
+ After all changes are complete, check RuleCatch:
341
+
342
+ - If the RuleCatch MCP server is available: query for violations in the modified Docker files
343
+ - Report any violations found
344
+ - If no MCP: suggest checking the RuleCatch dashboard
345
+
346
+ ## Step 7 — Report
347
+
348
+ Output a summary:
349
+ - Image size estimate (before vs after)
350
+ - Number of violations found and fixed
351
+ - Layer count (before vs after)
352
+ - Security improvements made
@@ -0,0 +1,61 @@
1
+ ---
2
+ description: Show project progress — what's done, what's pending, what's next
3
+ scope: project
4
+ allowed-tools: Read, Bash(find:*), Bash(ls:*), Bash(wc:*), Bash(git log:*)
5
+ ---
6
+
7
+ # Project Progress
8
+
9
+ Check the actual state of all components and report status.
10
+
11
+ ## Instructions
12
+
13
+ 1. Read `project-docs/ARCHITECTURE.md` for project context (if it exists)
14
+ 2. Check the `src/` directory structure
15
+ 3. Check the `tests/` directory for test coverage
16
+ 4. Check recent git activity
17
+
18
+ ## Shell Commands to Run
19
+
20
+ ```bash
21
+ echo "=== Source Files ==="
22
+ find src/ -name "*.ts" -o -name "*.tsx" | head -30 2>/dev/null || echo "No src/ directory"
23
+
24
+ echo ""
25
+ echo "=== Test Files ==="
26
+ find tests/ -name "*.test.*" -o -name "*.spec.*" | head -30 2>/dev/null || echo "No test files"
27
+
28
+ echo ""
29
+ echo "=== Recent Activity (Last 7 Days) ==="
30
+ git log --oneline --since="7 days ago" 2>/dev/null | head -15 || echo "No recent commits"
31
+
32
+ echo ""
33
+ echo "=== File Count by Type ==="
34
+ find src/ -name "*.ts" 2>/dev/null | wc -l | xargs -I{} echo "TypeScript: {} files"
35
+ find src/ -name "*.js" 2>/dev/null | wc -l | xargs -I{} echo "JavaScript: {} files"
36
+ find tests/ -name "*.test.*" 2>/dev/null | wc -l | xargs -I{} echo "Tests: {} files"
37
+ ```
38
+
39
+ ## Output Format
40
+
41
+ | Area | Files | Status | Notes |
42
+ |------|-------|--------|-------|
43
+ | Source code | N files | ... | ... |
44
+ | Tests | N files | ... | ... |
45
+ | Documentation | ... | ... | ... |
46
+
47
+ ### RuleCatch Report
48
+ | Metric | Value |
49
+ |--------|-------|
50
+ | Violations (this session) | ... |
51
+ | Critical violations | ... |
52
+ | Most violated rule | ... |
53
+ | Files with violations | ... |
54
+
55
+ If the RuleCatch MCP server is available: query for session summary and populate the table above.
56
+ If no MCP available: show "Install RuleCatch for violation tracking — `npx @rulecatch/mcp-server init`"
57
+
58
+ ### Next Actions (Priority Order)
59
+ 1. ...
60
+ 2. ...
61
+ 3. ...