Reset the workspace to a clean state on main with no leftover branches,
uncommitted files, or background agents from previous work. Run this between
tasks to start fresh.
When to use this skill:
- After merging a PR and before starting new work
- When the workspace has accumulated stale branches or uncommitted files
- When background agents from a previous session may still be running
- Any time
git status or git diff is not clean and you want a fresh start
Arguments
--force (optional): Skip interactive prompts — auto-delete safe-to-remove
files and stale branches without asking. Still preserves files that appear to
contain meaningful uncommitted work.
Workflow
Work through each phase in order. Report findings at each phase before
acting. Unless --force is given, ask the user before destructive actions.
Phase 1 — Stop background agents
Check for running background tasks (agents, shells, builds) from previous work.
List running tasks: Use the TaskList tool (or /tasks output) to find
any in-progress background agents or shells.
For each running task:
- Identify what it is doing (build, test, agent work, etc.)
- Determine if it is safe to stop — a task is safe to stop if:
- It belongs to a completed/merged PR
- It is idle or stuck
- It is a stale monitoring or polling loop
- A task is NOT safe to stop if:
- It is actively writing files that haven't been committed
- It is mid-push or mid-merge
Stop safe tasks using TaskStop. Report any tasks you chose not to stop
and why.
If no tasks are running, report "No background tasks found" and proceed.
Phase 2 — Analyze uncommitted changes
Examine the working tree for any modifications or untracked files.
Run diagnostics in parallel:
git status --short
git diff --stat
git diff --cached --stat
git log --oneline -10
git branch -vv
If the working tree is clean (no output from status/diff), skip to
Phase 3.
For each uncommitted or untracked file, classify it:
| Classification |
Action |
Examples |
| Belongs to a merged PR |
Should have been committed — warn user |
Source files matching recent PR topics |
| Build artifact / generated file |
Safe to delete or add to .gitignore |
build/, *.o, *.spv, shaders/compiled/ |
| Editor / OS junk |
Add to .git/info/exclude (local only) |
.DS_Store, *.swp, .vscode/settings.json |
| Meaningful new work |
Stash or warn — do NOT delete |
New lesson files, library changes |
| Unknown |
Ask the user |
Anything ambiguous |
To classify files, check recent context:
# Recent merged PRs
gh pr list --state merged --limit 5
# Recent branches (local and remote)
git branch -a --sort=-committerdate | head -20
# What the current branch was working on
git log --oneline HEAD...origin/main 2>/dev/null
Report findings in a table:
Uncommitted files analysis:
──────────────────────────────────────────────
M lessons/gpu/17-normal-maps/main.c → Belongs to merged PR #42 (stale edit)
?? build/CMakeCache.txt → Build artifact (safe to delete)
?? .DS_Store → OS junk (add to local exclude)
A lessons/gpu/30-new-lesson/main.c → New work (stash? ask user)
Take action per classification:
- Merged-PR leftovers: Warn the user. These may be edits that should
have been in the PR. Offer to discard them (
git checkout -- <file>) or
stash them.
- Build artifacts already in
.gitignore: Delete with git clean -fd
for those paths only (not a blanket clean).
- Build artifacts NOT in
.gitignore: Offer to add them to .gitignore
and then delete.
- Editor/OS junk: Add patterns to
.git/info/exclude (not .gitignore,
since these are personal and shouldn't be committed).
- Meaningful new work:
git stash push -m "dev-reset: uncommitted work".
Report the stash entry so the user can recover it.
- Unknown: Ask the user with AskUserQuestion (options: delete, stash,
gitignore, local exclude, skip).
Phase 3 — Switch to main and pull latest
If not on main:
git checkout main
If checkout fails due to uncommitted changes, go back to Phase 2 — something
was missed.
Pull latest:
git pull origin main
Verify:
git status --short
git diff --stat
Both should produce no output. If not, investigate and resolve.
Phase 4 — Remove stale local branches
Find and delete local branches whose work has been merged into origin/main.
Fetch latest remote state:
git fetch --prune origin
Find merged branches:
git branch --merged origin/main \
| sed 's/^[* ]*//' \
| grep -v '^main$'
Find branches whose remote tracking branch is gone (PR was merged and
remote branch deleted):
git branch -vv | grep ': gone]' | awk '{print $1}'
Combine both lists (deduplicate). For each branch:
Confirm it is not the current branch
Confirm it has been merged or its remote is gone
Delete it:
git branch -d <branch-name>
If -d fails (not fully merged), report it and skip — do NOT use -D
unless the user explicitly confirms or --force was given AND the remote
tracking branch is gone (meaning the PR was merged and the remote branch
was deleted by GitHub).
Report what was removed:
Removed stale branches:
✓ lesson-17-normal-maps (merged, remote deleted)
✓ lesson-18-scene-loading (merged, remote deleted)
⏭ experiment-wip (not merged, kept)
Phase 5 — Clean up worktrees
Check for leftover Claude Code worktrees from previous sessions.
git worktree list
If any worktrees exist under .claude/worktrees/:
- Check if they have uncommitted changes (
git -C <path> status --short)
- If clean:
git worktree remove <path>
- If dirty: warn the user and skip
Phase 6 — Final verification
Run a final check to confirm everything is clean.
git status
git diff
git branch
git log --oneline -3
Expected state:
- On branch
main
- Working tree clean (nothing to commit)
git diff produces no output
- Only
main (and any intentionally kept branches) remain
- HEAD matches
origin/main
Report final state:
Workspace Reset Complete
════════════════════════
Branch: main (up to date with origin/main)
Working tree: clean
Stale branches: 3 removed, 0 kept
Background tasks: 0 running
Stashed work: 1 entry (use `git stash list` to see)
Ready for new work.
Error handling
- Merge conflicts during pull: Report the conflict and exit — user must
resolve manually.
- Protected branches: Never force-delete
main or master.
- Network errors on fetch/pull: Report and continue with local cleanup.
gh CLI not authenticated: Skip PR-related analysis, proceed with
git-only checks.
Safety guarantees
- Never runs
git clean -fdx on the entire repo. Only cleans specific
identified paths.
- Never runs
git reset --hard unless the user explicitly confirms.
- Never deletes branches with
-D without user confirmation (or --force
with remote-gone confirmation).
- Always stashes rather than deletes when in doubt about uncommitted work.
- Never modifies
.gitignore without showing the user what will be added.
- Reports everything before acting — the user sees the plan first.
1---2name: dev-reset-workspace3description: Clean the workspace of finished-work vestiges so new work can start from a fresh main branch4---5
6Reset the workspace to a clean state on `main` with no leftover branches,
7uncommitted files, or background agents from previous work. Run this between
8tasks to start fresh.
9
10**When to use this skill:**
11
12- After merging a PR and before starting new work
13- When the workspace has accumulated stale branches or uncommitted files
14- When background agents from a previous session may still be running
15- Any time `git status` or `git diff` is not clean and you want a fresh start
16
17## Arguments
18
19- `--force` (optional): Skip interactive prompts — auto-delete safe-to-remove
20 files and stale branches without asking. Still preserves files that appear to
21 contain meaningful uncommitted work.
22
23## Workflow
24
25Work through each phase **in order**. Report findings at each phase before
26acting. Unless `--force` is given, ask the user before destructive actions.
27
28---
29
30### Phase 1 — Stop background agents
31
32Check for running background tasks (agents, shells, builds) from previous work.
33
341. **List running tasks:** Use the TaskList tool (or `/tasks` output) to find
35 any in-progress background agents or shells.
36
372. **For each running task:**
38 - Identify what it is doing (build, test, agent work, etc.)
39 - Determine if it is safe to stop — a task is safe to stop if:
40 - It belongs to a completed/merged PR
41 - It is idle or stuck
42 - It is a stale monitoring or polling loop
43 - A task is NOT safe to stop if:
44 - It is actively writing files that haven't been committed
45 - It is mid-push or mid-merge
46
473. **Stop safe tasks** using TaskStop. Report any tasks you chose not to stop
48 and why.
49
504. **If no tasks are running**, report "No background tasks found" and proceed.
51
52---
53
54### Phase 2 — Analyze uncommitted changes
55
56Examine the working tree for any modifications or untracked files.
57
581. **Run diagnostics in parallel:**
59
60 ```bash
61 git status --short
62 git diff --stat
63 git diff --cached --stat
64 git log --oneline -10
65 git branch -vv
66 ```
67
682. **If the working tree is clean** (no output from status/diff), skip to
69 Phase 3.
70
713. **For each uncommitted or untracked file**, classify it:
72
73 | Classification | Action | Examples |
74 |---|---|---|
75 | **Belongs to a merged PR** | Should have been committed — warn user | Source files matching recent PR topics |
76 | **Build artifact / generated file** | Safe to delete or add to `.gitignore` | `build/`, `*.o`, `*.spv`, `shaders/compiled/` |
77 | **Editor / OS junk** | Add to `.git/info/exclude` (local only) | `.DS_Store`, `*.swp`, `.vscode/settings.json` |
78 | **Meaningful new work** | Stash or warn — do NOT delete | New lesson files, library changes |
79 | **Unknown** | Ask the user | Anything ambiguous |
80
814. **To classify files, check recent context:**
82
83 ```bash
84 # Recent merged PRs
85 gh pr list --state merged --limit 5
86
87 # Recent branches (local and remote)
88 git branch -a --sort=-committerdate | head -20
89
90 # What the current branch was working on
91 git log --oneline HEAD...origin/main 2>/dev/null
92 ```
93
945. **Report findings** in a table:
95
96 ```text
97 Uncommitted files analysis:
98 ──────────────────────────────────────────────
99 M lessons/gpu/17-normal-maps/main.c → Belongs to merged PR #42 (stale edit)
100 ?? build/CMakeCache.txt → Build artifact (safe to delete)
101 ?? .DS_Store → OS junk (add to local exclude)
102 A lessons/gpu/30-new-lesson/main.c → New work (stash? ask user)
103 ```
104
1056. **Take action per classification:**
106 - **Merged-PR leftovers:** Warn the user. These may be edits that should
107 have been in the PR. Offer to discard them (`git checkout -- <file>`) or
108 stash them.
109 - **Build artifacts already in `.gitignore`:** Delete with `git clean -fd`
110 for those paths only (not a blanket clean).
111 - **Build artifacts NOT in `.gitignore`:** Offer to add them to `.gitignore`
112 and then delete.
113 - **Editor/OS junk:** Add patterns to `.git/info/exclude` (not `.gitignore`,
114 since these are personal and shouldn't be committed).
115 - **Meaningful new work:** `git stash push -m "dev-reset: uncommitted work"`.
116 Report the stash entry so the user can recover it.
117 - **Unknown:** Ask the user with AskUserQuestion (options: delete, stash,
118 gitignore, local exclude, skip).
119
120---
121
122### Phase 3 — Switch to main and pull latest
123
1241. **If not on `main`:**
125
126 ```bash
127 git checkout main
128 ```
129
130 If checkout fails due to uncommitted changes, go back to Phase 2 — something
131 was missed.
132
1332. **Pull latest:**
134
135 ```bash
136 git pull origin main
137 ```
138
1393. **Verify:**
140
141 ```bash
142 git status --short
143 git diff --stat
144 ```
145
146 Both should produce no output. If not, investigate and resolve.
147
148---
149
150### Phase 4 — Remove stale local branches
151
152Find and delete local branches whose work has been merged into `origin/main`.
153
1541. **Fetch latest remote state:**
155
156 ```bash
157 git fetch --prune origin
158 ```
159
1602. **Find merged branches:**
161
162 ```bash
163 git branch --merged origin/main \
164 | sed 's/^[* ]*//' \
165 | grep -v '^main$'
166 ```
167
1683. **Find branches whose remote tracking branch is gone** (PR was merged and
169 remote branch deleted):
170
171 ```bash
172 git branch -vv | grep ': gone]' | awk '{print $1}'
173 ```
174
1754. **Combine both lists** (deduplicate). For each branch:
176 - Confirm it is not the current branch
177 - Confirm it has been merged or its remote is gone
178 - Delete it:
179
180 ```bash
181 git branch -d <branch-name>
182 ```
183
184 - If `-d` fails (not fully merged), report it and skip — do NOT use `-D`
185 unless the user explicitly confirms or `--force` was given AND the remote
186 tracking branch is gone (meaning the PR was merged and the remote branch
187 was deleted by GitHub).
188
1895. **Report what was removed:**
190
191 ```text
192 Removed stale branches:
193 ✓ lesson-17-normal-maps (merged, remote deleted)
194 ✓ lesson-18-scene-loading (merged, remote deleted)
195 ⏭ experiment-wip (not merged, kept)
196 ```
197
198---
199
200### Phase 5 — Clean up worktrees
201
202Check for leftover Claude Code worktrees from previous sessions.
203
204```bash
205git worktree list
206```
207
208If any worktrees exist under `.claude/worktrees/`:
209
210- Check if they have uncommitted changes (`git -C <path> status --short`)
211- If clean: `git worktree remove <path>`
212- If dirty: warn the user and skip
213
214---
215
216### Phase 6 — Final verification
217
218Run a final check to confirm everything is clean.
219
220```bash
221git status
222git diff
223git branch
224git log --oneline -3
225```
226
227**Expected state:**
228
229- On branch `main`
230- Working tree clean (nothing to commit)
231- `git diff` produces no output
232- Only `main` (and any intentionally kept branches) remain
233- HEAD matches `origin/main`
234
235**Report final state:**
236
237```text
238Workspace Reset Complete
239════════════════════════
240Branch: main (up to date with origin/main)
241Working tree: clean
242Stale branches: 3 removed, 0 kept
243Background tasks: 0 running
244Stashed work: 1 entry (use `git stash list` to see)
245
246Ready for new work.
247```
248
249---
250
251## Error handling
252
253- **Merge conflicts during pull:** Report the conflict and exit — user must
254 resolve manually.
255- **Protected branches:** Never force-delete `main` or `master`.
256- **Network errors on fetch/pull:** Report and continue with local cleanup.
257- **`gh` CLI not authenticated:** Skip PR-related analysis, proceed with
258 git-only checks.
259
260## Safety guarantees
261
262- **Never runs `git clean -fdx` on the entire repo.** Only cleans specific
263 identified paths.
264- **Never runs `git reset --hard`** unless the user explicitly confirms.
265- **Never deletes branches with `-D`** without user confirmation (or `--force`
266 with remote-gone confirmation).
267- **Always stashes rather than deletes** when in doubt about uncommitted work.
268- **Never modifies `.gitignore`** without showing the user what will be added.
269- **Reports everything** before acting — the user sees the plan first.