Skip to content

Commit f4fbe6b

Browse files
feat: add /update-project command (25th command)
Smart merge that updates registered starter-kit projects with the latest commands, hooks, skills, agents, and rules while preserving custom files. Doc sync across all 5 mandatory locations + USER_GUIDE.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e40c348 commit f4fbe6b

9 files changed

Lines changed: 318 additions & 24 deletions

File tree

.claude/commands/convert-project-to-starter-kit.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ Registered in project registry. View with /projects-created.
450450
451451
Next steps:
452452
1. Run /setup to configure environment variables
453-
2. Run /help to see all 24 available commands
453+
2. Run /help to see all 25 available commands
454454
3. Review CLAUDE.md and customize rules for your project
455455
```
456456

.claude/commands/help.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Display the complete list of commands, skills, and agents available in this star
1010
**Print this exactly:**
1111

1212
```
13-
=== Claude Code Starter Kit — Command Reference (24 commands) ===
13+
=== Claude Code Starter Kit — Command Reference (25 commands) ===
1414
1515
GETTING STARTED
1616
/help List all commands, skills, and agents (this screen)
@@ -27,6 +27,7 @@ PROJECT SCAFFOLD
2727
/projects-created List all projects created by the starter kit with creation dates
2828
/remove-project Remove a project from the registry and optionally delete it from disk
2929
/convert-project-to-starter-kit Merge starter kit into an existing project (non-destructive)
30+
/update-project Update a starter-kit project with the latest commands, hooks, and rules
3031
3132
CODE QUALITY
3233
/review Systematic code review against 7-point checklist

.claude/commands/update-project.md

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
---
2+
description: Update a starter-kit project with the latest commands, hooks, skills, and rules
3+
argument-hint: [--force]
4+
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, AskUserQuestion
5+
---
6+
7+
# Update Starter Kit Project
8+
9+
Update an existing starter-kit project with the latest commands, hooks, skills, agents, and rules from the current starter kit source. Smart merge — replaces starter kit files with newer versions while preserving any custom files the user created themselves.
10+
11+
**Arguments:** $ARGUMENTS
12+
13+
---
14+
15+
## Step 0 — Resolve Source (Starter Kit)
16+
17+
Find the starter kit source directory:
18+
19+
1. If CWD has BOTH `claude-mastery-project.conf` AND `.claude/commands/new-project.md` → use CWD as `$SOURCE`
20+
2. Else read `~/.claude/starter-kit-source-path` → verify it still has both files
21+
3. Else ask via AskUserQuestion: "Where is the starter kit cloned?" with a text input
22+
23+
Store as `$SOURCE`.
24+
25+
---
26+
27+
## Step 1 — Registry Picker (Select Target)
28+
29+
1. Read `~/.claude/starter-kit-projects.json`
30+
- If file doesn't exist or empty → error: "No projects found. Use `/new-project` to create one first."
31+
- If file is invalid JSON → error: "Project registry is corrupted. Check `~/.claude/starter-kit-projects.json`."
32+
33+
2. Filter to projects whose `path` directory still exists on disk
34+
35+
3. If no valid projects remain → error: "No registered projects found on disk. Use `/new-project` to create one."
36+
37+
4. Display list with AskUserQuestion:
38+
- "Which project do you want to update?"
39+
- Options: up to 4 most recent projects (by `createdAt`), each showing: `name — language/framework — path`
40+
- If more than 4: the 4th option should be "Other (type a path)"
41+
42+
5. Store selected path as `$TARGET`
43+
44+
### Validations (all must pass — stop with clear error if any fail)
45+
46+
1. `$TARGET` directory exists → if not: "Directory not found: $TARGET"
47+
2. `$TARGET` is a git repo → run: `git -C "$TARGET" rev-parse --is-inside-work-tree 2>/dev/null`
48+
- If not a git repo: "This project must be a git repo. Run `git init && git commit --allow-empty -m 'init'` first."
49+
3. `$TARGET` is NOT the starter kit itself (compare resolved paths of `$SOURCE` and `$TARGET`)
50+
- If same: "Cannot update the starter kit itself."
51+
4. `$TARGET` is registered in `~/.claude/starter-kit-projects.json`
52+
- If not registered: "This project isn't in the registry. Use `/convert-project-to-starter-kit` instead."
53+
54+
Parse `--force` from `$ARGUMENTS` — if present, set `$FORCE=true` (skips confirmation prompts).
55+
56+
---
57+
58+
## Step 2 — Safety Commit
59+
60+
```bash
61+
cd "$TARGET"
62+
git status --porcelain
63+
```
64+
65+
- **If uncommitted changes exist** (git status --porcelain has output):
66+
```bash
67+
cd "$TARGET" && git add -A && git commit -m "chore: pre-update snapshot (before starter kit update)"
68+
```
69+
70+
- **If clean** (no uncommitted changes):
71+
```bash
72+
cd "$TARGET" && git commit --allow-empty -m "chore: pre-update marker (before starter kit update)"
73+
```
74+
75+
Store the hash: `PRE_UPDATE_HASH=$(git -C "$TARGET" rev-parse HEAD)`
76+
77+
**STOP if git fails** (except "nothing to commit" which is fine — treat as clean).
78+
79+
---
80+
81+
## Step 3 — Inventory & Diff
82+
83+
Build a manifest of what the starter kit currently has vs what the target has.
84+
85+
### Categories to compare
86+
87+
| Category | Source Location | Target Location |
88+
|----------|----------------|-----------------|
89+
| Commands | `$SOURCE/.claude/commands/*.md` | `$TARGET/.claude/commands/*.md` |
90+
| Hooks | `$SOURCE/.claude/hooks/*.{sh,py}` | `$TARGET/.claude/hooks/*.{sh,py}` |
91+
| Skills | `$SOURCE/.claude/skills/*/SKILL.md` | `$TARGET/.claude/skills/*/SKILL.md` |
92+
| Agents | `$SOURCE/.claude/agents/*.md` | `$TARGET/.claude/agents/*.md` |
93+
94+
### For each file, classify as:
95+
96+
- **NEW** — exists in source, not in target → will be added
97+
- **UPDATED** — exists in both, content differs (compare with `diff -q`) → will be replaced
98+
- **UNCHANGED** — exists in both, content is identical → skip
99+
- **CUSTOM** — exists in target only, not in source → never touched (user-created)
100+
101+
### Display the diff report
102+
103+
```
104+
=== Starter Kit Update Report ===
105+
106+
Target: $TARGET
107+
Source: $SOURCE
108+
109+
Commands:
110+
+ NEW: update-project.md, show-user-guide.md
111+
↻ UPDATED: commit.md, review.md (starter kit versions changed)
112+
= UNCHANGED: help.md, progress.md, ... (12 files)
113+
○ CUSTOM: my-custom-command.md (yours, not touched)
114+
115+
Hooks:
116+
+ NEW: (none)
117+
↻ UPDATED: check-branch.sh
118+
= UNCHANGED: block-secrets.py, lint-on-save.sh, ...
119+
○ CUSTOM: (none)
120+
121+
Skills: (all unchanged)
122+
Agents: (all unchanged)
123+
124+
settings.json: hooks will be deep-merged
125+
CLAUDE.md: 3 new sections will be appended
126+
Infrastructure: .gitignore (2 lines to add), .env.example (1 key to add)
127+
128+
Total: N files to add, N files to update, N unchanged, N custom (untouched)
129+
```
130+
131+
---
132+
133+
## Step 4 — Confirm (unless --force)
134+
135+
If not `$FORCE`, ask via AskUserQuestion:
136+
137+
"Apply these updates? N new files, N updated files. Your custom files won't be touched."
138+
- **Yes, update** (Recommended)
139+
- **Show me the diffs first** — for each UPDATED file, show `diff` output between source and target, then ask again
140+
- **No, cancel**
141+
142+
If user selects "No, cancel" → stop immediately with: "Update cancelled. No changes made."
143+
144+
---
145+
146+
## Step 5 — Apply Updates
147+
148+
### 5a. Commands, Hooks, Skills, Agents
149+
150+
For each **NEW** file: copy from source to target.
151+
For each **UPDATED** file: overwrite target with source version.
152+
For **CUSTOM** and **UNCHANGED**: skip entirely.
153+
154+
For skills: copy the entire skill directory (e.g., `$SOURCE/.claude/skills/code-review/``$TARGET/.claude/skills/code-review/`).
155+
156+
Make hooks executable:
157+
```bash
158+
chmod +x "$TARGET/.claude/hooks/"*.sh 2>/dev/null
159+
chmod +x "$TARGET/.claude/hooks/"*.py 2>/dev/null
160+
```
161+
162+
### 5b. settings.json — Deep Merge
163+
164+
Same merge logic as `/convert-project-to-starter-kit`:
165+
166+
1. Read both `$SOURCE/.claude/settings.json` and `$TARGET/.claude/settings.json` as JSON
167+
2. `permissions.deny`: merge arrays, deduplicate by value
168+
3. For each hook event type (`PreToolUse`, `PostToolUse`, `Stop`):
169+
- For each matcher entry in source: check if target already has same matcher string
170+
- Same matcher → merge the `hooks` arrays (deduplicate by `command` string)
171+
- New matcher → add entire entry to target
172+
4. NEVER remove existing entries from target
173+
5. Write merged result to `$TARGET/.claude/settings.json`
174+
175+
If target has no `.claude/settings.json`: copy from source directly.
176+
177+
### 5c. CLAUDE.md — Section Merge
178+
179+
Same as `/convert-project-to-starter-kit`:
180+
181+
1. Parse both by `## ` (h2) headers
182+
2. For each section in source not in target → append at end of target CLAUDE.md
183+
3. For Critical Rules: sub-merge by `### ` (h3) numbered rules — add missing rules, keep existing
184+
4. NEVER remove or replace existing sections
185+
186+
If target has no `CLAUDE.md`: skip (don't create — the project should already have one from initial creation).
187+
188+
### 5d. Infrastructure Files
189+
190+
| File | If Missing in Target | If Exists in Target |
191+
|------|---------------------|---------------------|
192+
| `CLAUDE.local.md` | Copy from source | Skip |
193+
| `claude-mastery-project.conf` | Copy from source | Skip |
194+
| `project-docs/ARCHITECTURE.md` | Create `project-docs/` dir, copy | Skip |
195+
| `project-docs/INFRASTRUCTURE.md` | Copy | Skip |
196+
| `project-docs/DECISIONS.md` | Copy | Skip |
197+
| `.env.example` | Copy from source | Merge: read both, add lines from source whose key name (before `=`) doesn't exist in target. Append missing lines at end. |
198+
| `.gitignore` | Copy from source | Merge: add lines from source that don't exist in target. Ensure `.env`, `CLAUDE.local.md`, `_ai_temp/` are present. |
199+
| `.dockerignore` | Copy from source | Merge: add lines from source that don't exist in target. |
200+
201+
---
202+
203+
## Step 6 — Update Registry
204+
205+
1. Read `~/.claude/starter-kit-projects.json`
206+
2. Find the project entry by `path` matching `$TARGET`
207+
3. Add or update `updatedAt` field with current ISO timestamp
208+
4. Increment `updateCount` field (start at 1 if missing, increment if exists)
209+
5. Write updated registry back to `~/.claude/starter-kit-projects.json`
210+
211+
---
212+
213+
## Step 7 — Commit + Summary
214+
215+
```bash
216+
cd "$TARGET"
217+
git add -A
218+
git commit -m "chore: update Claude Code Starter Kit infrastructure"
219+
```
220+
221+
Store: `UPDATE_HASH=$(git -C "$TARGET" rev-parse HEAD)`
222+
223+
**If nothing to commit** (all files unchanged): skip the commit, note "Already up to date."
224+
225+
### Display summary
226+
227+
```
228+
=== Starter Kit Update Complete ===
229+
230+
Target: $TARGET
231+
232+
Commands: N added, N updated, N unchanged, N custom
233+
Hooks: N added, N updated, N unchanged, N custom
234+
Skills: N added, N updated, N unchanged, N custom
235+
Agents: N added, N updated, N unchanged, N custom
236+
settings.json: deep merged (N new hooks added) / unchanged / copied
237+
CLAUDE.md: N sections added, N skipped (exists)
238+
Infrastructure: N files added, N merged, N skipped
239+
240+
Pre-update commit: $PRE_UPDATE_HASH
241+
Update commit: $UPDATE_HASH
242+
243+
To undo: git revert HEAD
244+
To review: git diff $PRE_UPDATE_HASH..HEAD
245+
246+
Next: Run /help to see any new commands.
247+
```
248+
249+
---
250+
251+
## Edge Cases
252+
253+
1. **Already up to date** — If all files are UNCHANGED and no infrastructure changes needed, report "Already up to date — no changes needed." and skip the update commit.
254+
255+
2. **Target has no .claude/ directory** — This shouldn't happen for registered projects, but if it does, create the directories and treat all files as NEW.
256+
257+
3. **Git fails** — If any git operation fails (commit, add), stop with a clear error. Never leave the project in a half-updated state.
258+
259+
4. **Custom files with same name as starter kit** — If a user happened to create a file with the same name as a starter kit file (e.g., `help.md`), it will show as UPDATED (content differs). The diff report makes this visible before applying.

CLAUDE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
> https://github.com/TheDecipherist/claude-code-mastery
55
66
> **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 24 commands or `/show-user-guide` for the full interactive guide."
7+
> "Welcome to the Claude Code Mastery Project Starter Kit! Use `/help` to see all 25 commands or `/show-user-guide` for the full interactive guide."
88
99
---
1010

@@ -54,6 +54,7 @@
5454
| `/projects-created` | List all projects created by the starter kit with creation dates |
5555
| `/remove-project <name>` | Remove a project from registry and optionally delete from disk |
5656
| `/convert-project-to-starter-kit` | Merge starter kit into an existing project (non-destructive) |
57+
| `/update-project` | Update a starter-kit project with the latest commands, hooks, and rules |
5758
| **RuleCatch** | |
5859
| `pnpm ai:monitor` | Free monitor mode — live AI activity in a separate terminal (no API key needed) |
5960
| `/what-is-my-ai-doing` | Same as above — launches AI-Pooler free monitor |

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ cd ~/projects/my-app # Enter your new project
6161
pnpm install && pnpm dev # Start building
6262
```
6363

64-
Use `/help` to see all 24 commands at any time.
64+
Use `/help` to see all 25 commands at any time.
6565

6666
## See It In Action
6767

6868
| | |
6969
|---|---|
7070
| ![/help command](docs/screenshots/help-command.png) | ![/review violations](docs/screenshots/review-violations.png) |
71-
| **`/help`** &mdash; All 24 commands | **`/review`** &mdash; Catching violations with severity ratings |
71+
| **`/help`** &mdash; All 25 commands | **`/review`** &mdash; Catching violations with severity ratings |
7272
| ![Auto-branch hook](docs/screenshots/auto-branch.png) | ![Lint-on-save hook](docs/screenshots/hooks-lint-on-save.png) |
7373
| **Auto-Branching** &mdash; Hook blocks commits to main | **Lint-on-Save** &mdash; TypeScript errors caught instantly |
7474
| ![/diagram architecture](docs/screenshots/diagram-architecture.png) | ![/setup flow](docs/screenshots/setup-flow.png) |
@@ -82,7 +82,7 @@ Everything you need to start a Claude Code project the right way — security, a
8282

8383
- **CLAUDE.md** — Battle-tested project instructions with 11 numbered critical rules for security, TypeScript, database wrappers, testing, and deployment
8484
- **Global CLAUDE.md** — Security gatekeeper for all projects. Never publish secrets, never commit .env files, standardized scaffolding rules
85-
- **24 Slash Commands**`/help`, `/quickstart`, `/install-global`, `/setup`, `/show-user-guide`, `/diagram`, `/review`, `/commit`, `/progress`, `/test-plan`, `/architecture`, `/new-project`, `/security-check`, `/optimize-docker`, `/create-e2e`, `/create-api`, `/worktree`, `/what-is-my-ai-doing`, `/refactor`, `/set-project-profile-default`, `/add-project-setup`, `/projects-created`, `/remove-project`, `/convert-project-to-starter-kit`
85+
- **25 Slash Commands**`/help`, `/quickstart`, `/install-global`, `/setup`, `/show-user-guide`, `/diagram`, `/review`, `/commit`, `/progress`, `/test-plan`, `/architecture`, `/new-project`, `/security-check`, `/optimize-docker`, `/create-e2e`, `/create-api`, `/worktree`, `/what-is-my-ai-doing`, `/refactor`, `/set-project-profile-default`, `/add-project-setup`, `/projects-created`, `/remove-project`, `/convert-project-to-starter-kit`, `/update-project`
8686
- **9 Hooks** — Deterministic enforcement that always runs. Block secrets, lint on save, verify no credentials, branch protection, port conflicts, Rybbit pre-deploy gate, E2E test gate, env sync warnings, and RuleCatch monitoring (optional — skips silently if not installed)
8787
- **Skills** — Context-aware templates: systematic code review checklist and full microservice scaffolding
8888
- **Custom Agents** — Read-only code reviewer for security audits. Test writer that creates tests with explicit assertions
@@ -304,6 +304,7 @@ project/
304304
│ │ ├── projects-created.md # /projects-created — list all created projects
305305
│ │ ├── remove-project.md # /remove-project — remove a project from registry
306306
│ │ ├── convert-project-to-starter-kit.md # /convert-project-to-starter-kit — merge into existing project
307+
│ │ ├── update-project.md # /update-project — update a project with latest starter kit
307308
│ │ └── show-user-guide.md # /show-user-guide — open the User Guide in browser
308309
│ ├── skills/
309310
│ │ ├── code-review/SKILL.md # Triggered code review checklist
@@ -792,6 +793,15 @@ Merges all starter kit infrastructure into an existing project without destroyin
792793
/convert-project-to-starter-kit ~/projects/my-app --force
793794
```
794795

796+
### `/update-project`
797+
798+
Updates an existing starter-kit project with the latest commands, hooks, skills, agents, and rules from the current starter kit source. Smart merge — replaces starter kit files with newer versions while preserving any custom files the user created. Shows a diff report before applying. Creates a safety commit first so you can `git revert HEAD` to undo.
799+
800+
```bash
801+
/update-project # Pick from registered projects
802+
/update-project --force # Skip confirmation prompts
803+
```
804+
795805
### `/create-e2e`
796806

797807
Generates a properly structured Playwright E2E test for a feature. Reads the source code, identifies URLs/elements/data to verify, creates the test at `tests/e2e/[name].spec.ts` with happy path, error cases, and edge cases. Verifies the test meets the "done" checklist before finishing.

0 commit comments

Comments
 (0)