/sdlc:migrate-runtime-state
Generated from solutions/ontological/skills/migrate-runtime-state/SKILL.md.
Description
Section titled “Description”Move SDLC-plugin runtime state from the legacy .claude/ location
to .sdlc/ in a consuming project (worktrees, pr-cursors,
orchestrator-log). Idempotent — re-running on an already-migrated
project is a no-op. Operates directly on the main repo, since the
things being moved are worktrees.
Allowed tools
Section titled “Allowed tools”Bash
Source
Section titled “Source”Usage:
/sdlc:migrate-runtime-state— move every piece of legacy SDLC-plugin runtime state from.claude/to.sdlc/in the current project. PR cursors are discarded by default (they regenerate on the next/sdlc:pr-checktick)./sdlc:migrate-runtime-state --preserve-cursors— move PR cursors to.sdlc/pr-cursors/instead of discarding them./sdlc:migrate-runtime-state --dry-run— report what would change without moving or deleting anything.
Project context (don’t re-derive every run):
- Three buckets move:
- Worktrees: every subdir under
.claude/worktrees/<basename>/becomes.sdlc/worktrees/<basename>/viagit worktree move. Idempotent — a worktree already at the destination is skipped silently. - PR cursors:
.claude/pr-cursors/<pr>.json. Discarded by default; cursors regenerate on the next/sdlc:pr-checktick. Pass--preserve-cursorsto move them to.sdlc/pr-cursors/instead. - Orchestrator log:
.claude/orchestrator-log.mdmoves to.sdlc/orchestrator-log.md. If a log already exists at the destination (rare — both coexisted somehow), the source is appended with a separator line.
- Worktrees: every subdir under
- Operate on the main repo; do NOT add a worktree. Run the script in the main repo. Do not wrap
it in
git worktree add— a new worktree would land under.claude/worktrees/and itself need migrating. - Do not commit. The migrated state lives in gitignored directories (
.claude/*and.sdlc/*). Just run the script and report the marker line. - Idempotent. Re-running after a successful migration emits
NOTHING-TO-MIGRATEand exits 0.
1. Run the migration script
Section titled “1. Run the migration script”From the project root:
bun run ${CLAUDE_PLUGIN_ROOT}skills/migrate-runtime-state/migrate_runtime_state.tsForward any flags the user passed (--dry-run, --preserve-cursors).
2. Parse the stdout marker
Section titled “2. Parse the stdout marker”The script emits exactly one summary line on stdout:
MIGRATED worktrees=N pr-cursors=M orchestrator-log=<moved|absent|merged>— success; at least one bucket changed.NOTHING-TO-MIGRATE— all three buckets were absent or already migrated. The project is already on the new layout.DRY-RUN worktrees=N pr-cursors=M orchestrator-log=<would-move|absent|would-merge>—--dry-runsummary.ERROR reason="<diagnostic>"— failure. Details on stderr.
3. Report to the user
Section titled “3. Report to the user”Surface the marker plus a one-line interpretation:
- On
MIGRATED: list what moved. Ifpr-cursors=Nand--preserve-cursorswas NOT passed, note that N cursor file(s) were discarded (they regenerate on the next/sdlc:pr-checktick). - On
NOTHING-TO-MIGRATE: tell the user plainly — the project is already on the new layout. - On
DRY-RUN: surface the marker as-is plus a one-line “to apply, re-run without —dry-run.” - On
ERROR: surface the stderr details too so the user can act on the failure.
Failure modes
Section titled “Failure modes”git worktree movefails — most often because the worktree at the source has uncommitted changes git refuses to move, or because the destination basename is already taken. The script captures git’s stderr; surface it to the user. Fix the underlying state (commit/stash, or move/remove the conflicting destination) and re-run.- PR cursor with name collision —
--preserve-cursorswon’t clobber an existing cursor at the destination. The cursor stays at the source and the run errors. Delete the conflicting destination file (or accept the default discard behavior) and re-run. - Orchestrator log merge fails — both source and destination present and the append-with-separator path errored on write. Inspect both files; concatenate manually if needed.
- Discarded cursors. Pass
--preserve-cursorsonly when an active PR mid-cycle has a review-comment offset that must survive; otherwise let the default discard them and/sdlc:pr-checkregenerates them on its next tick. - Run right after a plugin upgrade, before any other worktree-creating SDLC verb, so runtime
state doesn’t split across
.claude/and.sdlc/. The umbrella/sdlc:migrateis the canonical entry point. - Eval suite.
${CLAUDE_PLUGIN_ROOT}skills/migrate-runtime-state/tests/migrate_runtime_state.test.tsvalidates the round-trip against a fixture project. Run it before changingmigrate_runtime_state.ts.