name: refactor description: Safely restructure code in an isolated git worktree with test-preserved, incremental transformations disable-model-invocation: true effort: max
Safely refactor code while preserving all existing behavior.
Refactoring goal: $ARGUMENTS
Instructions
Follow these phases in order. Each phase has a gate — do not proceed until the gate is satisfied. Apply all project rules and conventions that are in your context.
If the refactor touches browser UI, Playwright, dev-server ports, screenshots, or interactive Browser/Chrome inspection, apply ../_shared/ui-automation.md at scoping, environment setup, baseline, verification, delegation, and cleanup points.
Phase 1: Setup
Derive a short kebab-case name from the refactoring goal.
Derive the app name from the git repo:
basename $(git rev-parse --show-toplevel)Switch to main:
git checkout mainPull latest:
git pull origin mainCreate branch
refactor/<name>and worktree../worktrees/<app>/<name>from main. Run two separateexec_commandtool calls — do not chain them with&&. The dashboard's PostToolUse hook only stampsworktree_cwd+branchwhen the command starts withgit worktree add; a compoundmkdir … && git worktree add …slips past the regex and leaves the dashboard unable to detect dir or branch.First, ensure the parent directory exists:
mkdir -p ../worktrees/<app>Then run
git worktree add -b refactor/<name> ../worktrees/<app>/<name> mainas its ownexec_commandtool call:git worktree add -b refactor/<name> ../worktrees/<app>/<name> main- If the branch already exists, ask the user whether to resume it or choose a new name.
From the source repo root (before cd'ing), copy environment files into the worktree preserving their exact relative path from the project root:
- Find all env files recursively:
find . -name '.env*' -not -path './.git/*' -not -path './node_modules/*' - For each file found, recreate its directory structure in the worktree and copy it. For example:
./.env→../worktrees/<app>/<name>/.env./services/api/.env.local→../worktrees/<app>/<name>/services/api/.env.local
- Use:
for f in $(find . -name '.env*' -not -path './.git/*' -not -path './node_modules/*'); do mkdir -p "../worktrees/<app>/<name>/$(dirname "$f")" && cp "$f" "../worktrees/<app>/<name>/$f"; done - If
.claude/settings.local.jsonexists:mkdir -p ../worktrees/<app>/<name>/.claude && cp .claude/settings.local.json ../worktrees/<app>/<name>/.claude/ - Important: Commands in this step write outside the project root. Use Codex escalation (
sandbox_permissions: "require_escalated") with a concise justification; do not try to route around approvals.
- Find all env files recursively:
cd into the worktree, run
node "$HOME/.codex/hooks/agent-dashboard/claim-worktree.js", and confirm withpwdandgit branch --show-currentVerify: compare env files between source and worktree. Run the same
findcommand in both directories and diff the file lists. If any files are missing in the worktree, halt and report failure. If the source repo had no.env*files, note that explicitly.
Gate: Working directory is the new worktree on the correct branch, based on latest main. If .env* files existed in the source repo, they are all present in the worktree.
Phase 2: Scope
Start two tracks in parallel:
Background — Environment setup: Launch a background exec_command to set up the dev environment. It must:
Auto-detect project type from project files (highest match wins):
Priority Signal Type 1 react-nativein package.json dependenciesMobile 2 next,vite, orwebpackin package.jsonWeb 3 requirements.txt,pyproject.toml, orsetup.pyPython 4 go.modGo 5 Dockerfileordocker-compose.ymlContainerized Ask the user only if no signal matches.
Install dependencies appropriate for the project type (e.g.
pip install,npm install,go mod download). Configure ports, create emulators/simulators as needed. For browser UI refactors, allocate worktree-local Playwright/server/profile/output resources per../_shared/ui-automation.md.Symlink large source-content directories (
data/,datasets/,evals/,models/,artifacts/) from the source repo rather than copying. NEVER symlink build outputs or per-project caches (.next/,dist/,build/,out/,target/,.turbo/,.cache/,.parcel-cache/,.vite/,__pycache__/,.pytest_cache/,.gradle/,.venv/,node_modules/) — they bake absolute paths and corrupt across worktrees, and must be regenerated per-worktree.On success, write a sentinel file:
touch .env-setup-doneOn failure, write the error:echo "<error message>" > .env-setup-failed
Foreground — Scoping:
- Parse the refactoring goal — what is being restructured and why?
- Identify all affected files by searching the codebase for the code to be changed and its dependents.
- Check test coverage for the affected code — what tests exist? What is untested?
- If test coverage is insufficient for safe refactoring, tell the user and suggest writing tests first before refactoring.
Gate: The scope is clear. Affected files and their test coverage are identified.
Phase 3: Baseline
Pre-gate: Check for .env-setup-done in the worktree root.
- If present: verify dependencies are installed (e.g.
node_modules/exists,pip listsucceeds,go env GOPATHworks) and data symlinks resolve correctly. - If
.env-setup-failedexists: surface the error and halt. - If neither file exists: the background agent is still running — wait for it to finish before proceeding.
- Run
make testto establish a passing baseline. - If tests fail, stop and report. Do not refactor on a broken codebase. Suggest using
$agent-dashboard:fixfirst. - Record the test output as the regression baseline.
For UI baselines, prefer headless Playwright with worktree-local resources. Use interactive Browser/Chrome inspection only when the shared policy says it is warranted.
Gate: All tests pass. The baseline is established.
Phase 4: Transform
Effort note: When launched via the agent-dashboard's New Agent flow, this skill starts at implementation effort. Use Codex Plan Mode for high-reasoning scoping when the refactor needs it, then return to proportional implementation effort for the mechanical transformation.
Delegation gate: Use Codex spawn_agent only if the user explicitly requested subagents OR the refactor touches 10+ files / ~3,000+ lines of implementation. Below that threshold, the orchestration overhead costs more tokens than implementing directly. If delegating, pass the scope (Phase 2), baseline (Phase 3), exact file paths, and a bounded write scope to a worker; then call wait_agent, review the result, and verify locally. Otherwise, proceed below.
Apply the refactoring in small, atomic steps. For each step:
- Make a single, focused change (e.g., extract a function, rename a variable, move a file).
- Run
make testimmediately after the change. - If tests fail:
- Revert only the changed files (
git checkout -- <file1> <file2> ...) - Analyze why it failed
- Try a different approach
- Revert only the changed files (
- If tests pass, proceed to the next step.
Do not batch multiple changes between test runs. One change, one test run.
Gate: All transformations applied. All tests pass after each step.
Phase 5: Cleanup
- Remove dead code — unused imports, functions, variables, files.
- Update any affected documentation or comments.
- Run
make testone final time.
Gate: No dead code remains. All tests pass.
Phase 6: Review, Commit, and Open PR
- Review all changes for correctness, security, and convention adherence.
- Verify that behavior is preserved — no new features, no bug fixes, only structural changes.
- Commit with a
refactor:conventional commit message that describes what was restructured and why. - Open the PR by invoking
$agent-dashboard:pr. That skill owns cleanup,make fmt,make test, push, andgh pr create. Do not callgh pr createdirectly — apr-skill-gatehook will block it.
Gate: Clean commit with conventional message. Behavior is unchanged. No critical or high-severity review issues. PR opened via $agent-dashboard:pr.
Phase 7: Cleanup (on merge)
Triggered when the user indicates the refactor has been merged upstream.
- Verify the branch is merged (warn if unmerged commits remain)
- Tear down environment resources: remove symlinks, stop dev servers or emulators, release any browser lease, remove worktree-local UI scratch state, delete
.env-setup-done/.env-setup-failedsentinel files - Remove worktree and delete branch
- Confirm cleanup is complete