Help us improve
Share bugs, ideas, or general feedback.
From Claude Setup
Orchestrates a multi-step refactoring pipeline: analyzes code quality, plans improvements, optionally writes tests, implements changes, and reviews results. Routes simple refactors to a lighter workflow.
npx claudepluginhub nickmaglowsch/claude-setup --plugin claude-setupHow this skill is triggered — by the user, by Claude, or both
Slash command
/claude-setup:refactor <file, directory, or description of what to refactor><file, directory, or description of what to refactor>The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are orchestrating the full refactoring pipeline. Follow these steps strictly in order.
Autonomous comprehensive refactoring through a three-phase pipeline: tactical cleanup, architectural restructuring, then final tactical pass.
Orchestrates behavior-preserving refactors: confirm tests green, restructure in small steps, keep tests green, review, and gated commit. Use when structure should improve but behavior must not change.
Safely restructure code in an isolated git worktree with test-preserved, incremental transformations
Share bugs, ideas, or general feedback.
You are orchestrating the full refactoring pipeline. Follow these steps strictly in order.
The refactoring target (file path, directory, or description of what to improve):
$ARGUMENTS
/claude-setup:refactor-lite?Before asking auto-commit, worktree, or orchestration questions, spend at most 2-3 minutes on a bounded read-only check:
Glob/Grep/bounded Read only where needed to estimate scope, callers, and whether independent parallel work exists.Route to /claude-setup:refactor-lite and stop this workflow if the refactor appears to be any of:
Proceed with full /claude-setup:refactor only when the work likely needs 3+ independent refactor tasks that can run in parallel, or when the target is broad enough to exceed a single warm context.
If routing to lite, tell the user: "This looks cheaper and equally safe as /claude-setup:refactor-lite because . Switching to the lite workflow." Then immediately follow skills/refactor-lite/SKILL.md from Step 1 using the same $ARGUMENTS, skipping all remaining full /claude-setup:refactor steps.
Ask: "Enable auto-commit and PR?" (Yes / No) → AUTO_COMMIT.
If AUTO_COMMIT=true:
git rev-parse --abbrev-ref HEAD to get CURRENT_BRANCH. If CURRENT_BRANCH is main or master: BRANCH_ACTION=new. Else ask: "Branch <name> exists — create new or commit here?" → BRANCH_ACTION=new/current.COMMIT_MODE=squash/per-wave/per-task-at-endrefactor/<3-5-word-slug> from $ARGUMENTS → AUTO_COMMIT_BRANCH.BRANCH_ACTION=new:
git fetch origin to get latest remote state.git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||'. If empty or error, default to main. Store as DEFAULT_BRANCH.<AUTO_COMMIT_BRANCH> be based on?"
<DEFAULT_BRANCH> (remote default)<CURRENT_BRANCH> (current branch)BASE_BRANCH.git checkout -b or git worktree add -b based on the worktree choice.If AUTO_COMMIT=false: BRANCH_ACTION=none, COMMIT_MODE=none.
Ask: "Run workflow in a new git worktree? (enables running multiple pipelines in parallel in the same project)" (Yes / No) → USE_WORKTREE.
Store WORKTREE_PATH="" as the default. It is set to the new worktree's relative path only if one is created.
USE_WORKTREE=false:AUTO_COMMIT=true AND BRANCH_ACTION=new: run git checkout -b <AUTO_COMMIT_BRANCH> <BASE_BRANCH>. On failure append -2 to AUTO_COMMIT_BRANCH, retry once.USE_WORKTREE=true:If AUTO_COMMIT=true AND BRANCH_ACTION=current: worktrees require a fresh branch (git disallows two worktrees on the same branch). Ask: "Worktree needs a new branch. Switch to a new branch, or skip the worktree and commit on the current branch?"
BRANCH_ACTION=new. Generate AUTO_COMMIT_BRANCH=refactor/<3-5-word-slug> from $ARGUMENTS if not already generated. Run the same base-branch Q&A as Step 0.1 step 4 to pick BASE_BRANCH.USE_WORKTREE=false and fall through to the USE_WORKTREE=false branch above.Resolve the worktree branch and base:
AUTO_COMMIT=true: WT_BRANCH=$AUTO_COMMIT_BRANCH, WT_BASE=$BASE_BRANCH (both set in Step 0.1).AUTO_COMMIT=false:
refactor/<3-5-word-slug> derived from $ARGUMENTS. Store as WT_BRANCH.git fetch origin and detect DEFAULT_BRANCH (same as Step 0.1 step 4).CURRENT_BRANCH if not already set.<WT_BRANCH> be based on?" with the same three options (default / current / other). Store as WT_BASE.Sanitize $WT_BRANCH into a filesystem-safe path segment (same rules as Step 0a's SANITIZED): replace / with -, strip non-[A-Za-z0-9._-], trim leading/trailing dashes. Store as WT_PATH_SEG.
Create the worktree and branch atomically:
git worktree add -b "$WT_BRANCH" ".claude-worktrees/$WT_PATH_SEG" "$WT_BASE"
On failure (branch or path already exists), append -2 to both $WT_BRANCH and $WT_PATH_SEG and retry once. If it still fails, abort with a clear error to the user. If the retry succeeds and AUTO_COMMIT=true, set AUTO_COMMIT_BRANCH=$WT_BRANCH so downstream commit/push/PR/report steps target the renamed branch.
cd ".claude-worktrees/$WT_PATH_SEG". All subsequent steps run inside the worktree.
Set WORKTREE_PATH=".claude-worktrees/$WT_PATH_SEG" for the final report.
Check for a saved orchestration mode preference:
cat ~/.claude/user-preferences.json 2>/dev/null"orchestrationMode" is parallel or agent-teams:
<value>"ORCHESTRATION_MODE to the saved value"orchestrationMode" exists but has any other value, warn that the saved value is invalid and continue to the prompt below.If no saved preference, ask the user which orchestration mode to use:
Use AskUserQuestion with:
parallel-task-orchestrator — proven sub-agent approach with wave-based parallel executionStore the result as ORCHESTRATION_MODE (parallel or agent-teams).
Then ask: "Save this as your default orchestration mode?" (Yes / No).
If Yes: run this command, replacing <ORCHESTRATION_MODE> with the actual value (parallel or agent-teams):
MODE=<ORCHESTRATION_MODE> python3 -c "
import json, os
path = os.path.expanduser('~/.claude/user-preferences.json')
prefs = json.load(open(path)) if os.path.exists(path) else {}
prefs['orchestrationMode'] = os.environ['MODE']
json.dump(prefs, open(path, 'w'), indent=2)
"
Run the following in Bash to determine the branch-scoped task directory:
RAW_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
if [ -z "$RAW_BRANCH" ] || [ "$RAW_BRANCH" = "HEAD" ]; then
SHORT_SHA=$(git rev-parse --short HEAD 2>/dev/null || echo "")
RAW_BRANCH=${SHORT_SHA:+detached-$SHORT_SHA}
fi
if [ -z "$RAW_BRANCH" ]; then
echo "Warning: not a git repo — using tasks/ as task directory" >&2
TASKS_DIR="tasks"
else
SANITIZED=$(echo "$RAW_BRANCH" | tr '/' '-' | tr -cs 'A-Za-z0-9._-' '-' | sed 's/^-*//; s/-*$//')
[ -z "$SANITIZED" ] && SANITIZED="unknown-branch"
TASKS_DIR="tasks/$SANITIZED"
fi
Store TASKS_DIR as a session variable — use it everywhere below.
Use Bash to run rm -rf "$TASKS_DIR" to clear only this branch's task directory.
Launch the refactor-planner agent using the Task tool with:
subagent_type: "refactor-planner"MODE: DISCOVERY\n\nTarget: <target from $ARGUMENTS>\nTASKS_DIR=$TASKS_DIR$TASKS_DIR/refactor-questions.mdWait for it to complete. Save the returned agent ID — you will resume this agent in Step 1c.
$TASKS_DIR/refactor-questions.mdAskUserQuestionResume the same refactor-planner agent (using the agent ID from Step 1a) with:
resume: "<agent-id-from-step-1a>"MODE: GENERATE to the prompt$TASKS_DIR/refactor-plan.md in $TASKS_DIR/TASKS_DIR=$TASKS_DIR in the resume promptWait for it to complete. Confirm that task files were created in $TASKS_DIR/.
This step always runs. Do not skip it.
Read all task-*.md files from $TASKS_DIR/. For each, extract:
Present the full refactoring plan to the user:
## Refactoring Plan (N tasks)
1. task-01-name — [Objective]
Dependencies: None
2. task-02-name — [Objective]
Dependencies: task-01
...
Then add: "You can also open and edit any file in $TASKS_DIR/ directly before proceeding."
Use AskUserQuestion with a single question: "How would you like to proceed?"
If user approves: proceed to Step 1.5.
If user requests regeneration: resume the same refactor-planner agent (from Step 1a) with:
resume: "<agent-id-from-step-1a>"MODE: GENERATE\n\nTASKS_DIR=$TASKS_DIR\n\nUser feedback on the refactoring plan:\n<feedback>\n\nPlease regenerate the task files incorporating this feedback.Skip this step if the user did not ask for tests to be written first.
If the user answered yes to writing tests before refactoring:
Launch the test-writer agent using the Task tool with:
subagent_type: "test-writer"Write tests for <target> to create a safety net before refactoring. Focus on covering the behavior that the refactoring tasks will touch.Wait for it to complete, then read the test-writer's final output. It reports whether the tests it wrote pass. If all tests pass, proceed to Step 1.6. If any test fails, do NOT proceed — surface the failures to the user and ask whether to abort or to fix the failing tests first.
Read all $TASKS_DIR/task-*.md files and classify FAST_PATH=true if ANY of:
Otherwise FAST_PATH=false.
Refactoring task files often have linear dependency chains (rename → extract → simplify → decompose) and tend toward fast-path more than feature builds.
FAST_PATH=true) — Direct implementationIf ORCHESTRATION_MODE=agent-teams: inform the user "Fast-path detected — using direct implementation instead of Agent Teams; orchestration overhead is not justified for simple refactors." Skip the env-var setup from Step 0.2.
Implement tasks yourself, sequentially, in the current session. For each task file in order: (1) read the task file fully, (2) read any referenced tests, (3) apply the refactor, (4) run the project test command (the same one Step 1.5 used to write the safety net, or whichever command the task file specifies) to verify behavior is preserved — refactor tasks rarely have their own per-task test commands; the safety net is the verification surface, (5) write $TASKS_DIR/notes/task-NN.md with notes on what was changed and why, plus anything risky for review (Decisions / Deviations / Trade-offs / Risks). After all tasks: concatenate $TASKS_DIR/notes/task-*.md (sorted) into $TASKS_DIR/implementation-notes.md with a # Implementation Notes header.
Commit handling: if COMMIT_MODE=per-wave, after each task run git add -A && git diff --staged --quiet || git commit -m "refactor: <task-objective>". If COMMIT_MODE=per-task-at-end, skip — commits happen in Step 2.5b.
Fast-path keeps continuous session context across tasks (no cold reads) and avoids the orchestrator overhead, which is rarely justified for refactors with sequential dependencies.
FAST_PATH=false) — Run orchestratorIf ORCHESTRATION_MODE=parallel (default):
Launch the parallel-task-orchestrator agent using the Task tool with:
subagent_type: "parallel-task-orchestrator"$TASKS_DIR/TASKS_DIR=$TASKS_DIR in the launch prompt$TASKS_DIR/notes/.COMMIT_MODE=per-wave: Include COMMIT_MODE=per-wave in the launch prompt so the orchestrator commits after each wave.COMMIT_MODE=squash, per-task-at-end, or AUTO_COMMIT=false: Launch normally with no additional commit instructions.Wait for it to complete. Note any issues reported.
If ORCHESTRATION_MODE=agent-teams (Beta):
First, enable the required env var by finding the user's settings file (check .claude/settings.local.json, then .claude/settings.json, then ~/.claude/settings.json) and adding CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 to the env object, preserving all existing settings. If no settings file exists, create .claude/settings.local.json with the env var.
Do NOT spawn a sub-agent. Instead, execute Agent Teams orchestration directly in this session:
agents/agent-teams-orchestrator.mdTASKS_DIR=$TASKS_DIR as session context$TASKS_DIR/implementation-notes.md and $TASKS_DIR/execution-metrics.mdNote: Per-wave commits in Agent Teams mode are handled by the agent-teams-orchestrator when COMMIT_MODE=per-wave is passed in the session context. Per-task-at-end commits are handled by the skill layer in Step 2.5b (runs after Agent Teams execution completes).
After Agent Teams execution completes (whether successful or not), clean up the env var: read the settings file that was modified above, remove CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS from the env object, and write it back. If the env object is now empty, remove it entirely. This prevents the beta env var from persisting across future sessions.
Run a quick build/lint check to catch obvious breakage:
package.json, Makefile, Cargo.toml, or similar build confignpm run build, pnpm build, make, cargo check)This step is especially critical for refactoring — the primary success criterion is that all existing tests still pass.
npm test, pnpm test, pytest, go test ./..., cargo test)The refactor tasks already did the structural work (rename/extract/decompose). A /simplify pass is an optional final polish that catches local cleanups the tasks introduced. It mutates code, so behavior preservation must be re-verified — the same primary success criterion as the refactor itself.
Guard: Only offer this step if Step 2c passed with no regressions. If tests failed or there is no test suite to verify against, skip this step entirely — never apply unverifiable cleanups on top of a refactor. Set SIMPLIFY_RAN=false.
Use AskUserQuestion: "Run a /simplify polish pass on the refactored code before review?"
SIMPLIFY_RAN=false and proceed to Step 2.5If "Yes": invoke the simplify skill via the Skill tool. Tell it to scope to the full branch diff against the base branch, so changes already committed in per-wave/per-task-at-end modes are covered — not just uncommitted edits. Wait for it to finish.
Re-verify behavior preservation: re-run the Step 2b build check and the full test suite from Step 2c.
git checkout -- <files> / git restore) and continue, or (c) stop. Do not silently proceed — behavior preservation is the contract.SIMPLIFY_RAN=true.Simplify's edits are left uncommitted and flow into the existing Step 2.5b commit logic.
Skip if AUTO_COMMIT=false.
2.5a Safety: Run git rev-parse --abbrev-ref HEAD. If main/master: abort ("Auto-commit aborted: on main/master. Commit manually.") → proceed to Step 3.
2.5b Commit:
COMMIT_MODE=squash: Read all $TASKS_DIR/task-*.md files. Extract the ## Objective line from each. Run:
git add -A
git commit -m "refactor: <$ARGUMENTS summary>" -m "$(cat <<'EOF'
- <objective from task-01>
- <objective from task-02>
- <objective from task-03>
... (one bullet per task, no cap)
EOF
)"
Subject line: 72-char max. Body: one bullet per task objective, all listed (no 3-bullet cap).
COMMIT_MODE=per-wave: Commits were made by the orchestrator during execution. Run git add -A to catch any unstaged changes left after the final wave, then commit any remainder:
git add -A
git diff --staged --quiet || git commit -m "refactor: post-run cleanup"
If nothing is staged after git add -A, skip the final commit.
COMMIT_MODE=per-task-at-end: Full parallel run is complete. Now create one commit per task in task-file order:
git add -A to stage all changes.$TASKS_DIR/task-NN-*.md file in numerical order.## Objective line and the list of files it touched (from the ## Target Files section).git restore --staged . to unstage everything, then selectively stage only the files for this task using git add <file1> <file2> ..., then commit:
git restore --staged .
git add <files for this task>
git commit -m "refactor: <task objective>"
git add -A && git diff --staged --quiet || git commit -m "refactor: miscellaneous changes" to catch any files not covered by the task-file manifests.2.5d Push: git push -u origin <branch-name>. On failure, show manual command and continue.
2.5e PR: Run gh auth status 2>/dev/null && echo GH_OK || echo GH_UNAVAILABLE.
GH_OK: Create PR body (1-2 sentence summary + "## Changes" task bullets + "## Behavior Preservation" noting test results). Run gh pr create --title "refactor: <desc>" --body "<body>" --base main. Display URL.GH_UNAVAILABLE: Display ready-to-copy gh pr create command.2.5f Report: Branch: <name> | Commits: <N> | Push: ok/failed | PR: <url or manual>
Check if $TASKS_DIR/implementation-notes.md and $TASKS_DIR/execution-metrics.md exist (produced by the orchestrator).
Before launching the reviewer, gather a compact review packet:
DEFAULT_BRANCH is not set, resolve it: DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||') (fallback main if empty or error).git diff --stat "$DEFAULT_BRANCH"...HEAD, git diff --name-only "$DEFAULT_BRANCH"...HEAD, and git log --oneline "$DEFAULT_BRANCH"..HEAD.Launch the code-reviewer agent using the Task tool with:
subagent_type: "code-reviewer"$TASKS_DIR/refactor-plan.md$TASKS_DIR/implementation-notes.md exists, tell it to read this file for implementer decision context$TASKS_DIR/refactor-review-report.mdTASKS_DIR=$TASKS_DIR in the launch promptSIMPLIFY_RAN=true: append A /simplify polish pass already ran on these changes — do NOT re-flag reuse, simplification, efficiency, or altitude items as Minor issues. Focus on behavior preservation, correctness, and whether the code is measurably cleaner. so the report stays signal-dense.Wait for it to complete.
Summarize the full refactoring run to the user:
Check if $TASKS_DIR/execution-metrics.md exists (produced by the orchestrator in full-path mode). If not (fast-path mode), generate equivalent metrics inline from your own execution.
## Refactor Complete
### Target
- [What was refactored]
### Changes Made
- [N tasks completed]
- [Key improvements: what's better now]
### Build Check
- [passed / failed / skipped]
### Tests
- [all passed / N regressions / no test suite]
### Simplify
- [ran — behavior preserved / ran — broke X, user chose Y / skipped / not offered (no green baseline)]
### Execution Metrics
- Tasks: [completed/total] | Waves: [N] | Retries: [N]
- Implementation notes: [see $TASKS_DIR/implementation-notes.md]
### Review
- [compliance score]
- [behavior preserved: yes/no]
- [critical issues if any]
### Auto-Commit
- [skipped — not enabled]
OR
- Branch: <branch-name>
- PR: <url or "manual command displayed">
### Worktree
- [omit this section entirely if `WORKTREE_PATH` is empty]
OR
- Path: <WORKTREE_PATH>
- Cleanup: `git worktree remove <WORKTREE_PATH>` (run from the original repo root)
### Next Steps
- [e.g., review the changes, run manual tests, address any regressions]