/migrate
Inventory an existing spec-driven project and apply bounded migrations to jig defaults: `report`, `adopt-layout`, `rename-decisions`, `split-slices`, slice-to-spec, `seed-decisions`, and `copy-machinery`. Use when the user says migrate this project to jig, adopt jig here, this
Claude Code
$ npx -y skills add ramboz/jig --skill migrate --agent claude-code
Codex
$ npx skills add ramboz/jig --skill migrate -a codex -y
Cursor
$ npx skills add ramboz/jig --skill migrate -a cursor -y
Gemini CLI
$ npx skills add ramboz/jig --skill migrate -a gemini-cli -y
GitHub Copilot
$ npx skills add ramboz/jig --skill migrate -a github-copilot -y
OpenCode
$ npx skills add ramboz/jig --skill migrate -a opencode -y
Windsurf
$ npx skills add ramboz/jig --skill migrate -a windsurf -y
SKILL.md
migrate.SKILL.mdname: migrate
description: >
Inventory an existing spec-driven project and apply bounded migrations to
jig defaults: `report`, `adopt-layout`, `rename-decisions`, `split-slices`,
slice-to-spec, `seed-decisions`, and `copy-machinery`. Use when the user says migrate this project to jig,
adopt jig here, this repo already has specs — set up jig,
scaffold-init refused — what now; introduce jig to an existing codebase;
apply ADR-0004 to
my project; migrate flat slices into nested specs; seed the
lightweight-decisions home; or copy jig's machinery
into my project. Reports are read-only; mutations support dry runs where
available, refuse conflicts before writing, and preserve originals in the
agentic slice-to-spec workflow.
user-invocable: true
> Spec 008 created this skill from scratch. The deterministic filesystem > walk + verdict logic + report rendering live in `migrate.py`; this > SKILL.md drives the judgment layer (when to invoke, how to interpret > ambiguities, what operations to suggest in what order).
What this skill does
Closes the "already spec-driven" gap that `scaffold-init` doesn't handle: projects that organically grew the same workflow jig codifies but landed on different conventions (folder names, filename prefixes, slice topology). Direct example: a project with `docs/slices/` (flat) and `docs/decisions/` (validator-style) — `scaffold-init` would not detect it as scaffolded and would either refuse confusingly or pollute the tree.
`migrate` flips that around: detect existing shape first, then propose a migration plan, then (in later slices) apply the rename / restructure operations.
`migrate.py` exposes six subcommands:
- `report` — strictly read-only inventory + plan.
- `adopt-layout` — validates an existing custom-root corpus and writes only
its `scaffold.json` sentinel/config; supports `--dry-run`.
- `rename-decisions` — applies ADR-0004's rename. Idempotent; refuses
on conflict; has a `--dry-run` mode; `--host claude|codex` selects whether cross-reference rewrites scan `CLAUDE.md`/`.claude/` or `AGENTS.md`/`.codex/`.
- `split-slices` — extracts embedded slice sections into sibling
slice files.
- `seed-decisions` — seeds `docs/decisions/lightweight-decisions.md` from
jig's template. Idempotent; supports `--dry-run` and `--docs-root`; never overwrites an existing file.
- `copy-machinery` — copies jig runtime machinery into the target's
host-local scaffold runtime; `--host claude` writes `.claude/`, and `--host codex` writes `.codex/`.
How to use
Run the migration report
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" report \
<project-dir> [--docs-root <relative-root>]- `<project-dir>` — path to the project root (e.g. `/path/to/repo`,
`.` for cwd).
- `--docs-root .` — inventory a track-local corpus whose `specs/`,
`decisions/`, `workflow.md`, and `architecture.md` live directly under the selected subproject instead of under `docs/`.
Adopt an existing custom-root corpus
Preview first, then apply:
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
adopt-layout <subproject-dir> --docs-root . --dry-run
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
adopt-layout <subproject-dir> --docs-root .The operation refuses incomplete/ambiguous corpora and existing or malformed sentinels before mutation. Apply writes only `<subproject-dir>/scaffold.json` using scaffold-init's canonical manifest builder; it does not move or rewrite the existing artifacts. Afterward, `workflow.py transition`, status-board, and ADR helpers discover the subproject through that sentinel.
Run the rename-decisions migration
Once `report` has been reviewed and the verdict is `adoptable`, the recommended sequence is:
# 1. Preview the plan (no writes).
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
rename-decisions <project-dir> --dry-run
# 2. After reviewing the planned operations, apply them.
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
rename-decisions <project-dir>What it does, in display order:
1. `docs/adrs/` → `docs/decisions/` (directory rename, atomic). 2. Per-file renames: `NNN-<slug>.md` → `adr-NNNN-<slug>.md` (pad 3-digit to 4-digit; add `adr-` prefix where missing). 3. Cross-reference rewrites in text files under `docs/`, `CLAUDE.md`, and `.claude/` by default. With `--host codex`, rewrites scan `docs/`, `AGENTS.md`, and `.codex/` instead. The helper itself (`migrate.py` and its fixtures) is never rewritten.
Refusal cases (exit 2, no mutations):
- Both `docs/adrs/` and `docs/decisions/` present (manual merge first).
- Two source files normalize to the same target name (collision).
- `<project-dir>` missing, not a directory, or unreadable.
No-op cases (exit 0):
- Neither dir present, OR all files already on the canonical shape —
emits "already aligned: nothing to do" and returns.
Run the seed-decisions operation
`seed-decisions` backfills `docs/decisions/lightweight-decisions.md` — the home `/jig:memory-sync`'s `decisions.py add-lightweight` records into, and the one the Stop-hook decision nudge points at.
Reach for it when `report` flags the gap, or when a project's `add-lightweight` fails because the file is missing. Every project that adopted jig **before** the lightweight-decisions feature landed needs it: `scaffold-init` seeds the file only at init and cannot be re-run on an already-scaffolded project, so there was previously no supported way to obtain it (bug 012 / [#109](https://github.com/ramboz/jig/issues/109)).
# preview
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
seed-decisions <project-dir> --dry-run
# apply
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
seed-decisions <project-dir>Idempotent — a second run reports "already present" and exits 0.
**It never overwrites.** If the file exists but is not in jig's format (no `## E
Read more
name: migrate description: > Inventory an existing spec-driven project and apply bounded migrations to jig defaults: `report`, `adopt-layout`, `rename-decisions`, `split-slices`, slice-to-spec, `seed-decisions`, and `copy-machinery`. Use when the user says migrate this project to jig, adopt jig here, this repo already has specs — set up jig, scaffold-init refused — what now; introduce jig to an existing codebase; apply ADR-0004 to my project; migrate flat slices into nested specs; seed the lightweight-decisions home; or copy jig's machinery into my project. Reports are read-only; mutations support dry runs where available, refuse conflicts before writing, and preserve originals in the agentic slice-to-spec workflow. user-invocable: true
> Spec 008 created this skill from scratch. The deterministic filesystem > walk + verdict logic + report rendering live in `migrate.py`; this > SKILL.md drives the judgment layer (when to invoke, how to interpret > ambiguities, what operations to suggest in what order).
What this skill does
Closes the "already spec-driven" gap that `scaffold-init` doesn't handle: projects that organically grew the same workflow jig codifies but landed on different conventions (folder names, filename prefixes, slice topology). Direct example: a project with `docs/slices/` (flat) and `docs/decisions/` (validator-style) — `scaffold-init` would not detect it as scaffolded and would either refuse confusingly or pollute the tree.
`migrate` flips that around: detect existing shape first, then propose a migration plan, then (in later slices) apply the rename / restructure operations.
`migrate.py` exposes six subcommands:
- `report` — strictly read-only inventory + plan.
- `adopt-layout` — validates an existing custom-root corpus and writes only
its `scaffold.json` sentinel/config; supports `--dry-run`.
- `rename-decisions` — applies ADR-0004's rename. Idempotent; refuses
on conflict; has a `--dry-run` mode; `--host claude|codex` selects whether cross-reference rewrites scan `CLAUDE.md`/`.claude/` or `AGENTS.md`/`.codex/`.
- `split-slices` — extracts embedded slice sections into sibling
slice files.
- `seed-decisions` — seeds `docs/decisions/lightweight-decisions.md` from
jig's template. Idempotent; supports `--dry-run` and `--docs-root`; never overwrites an existing file.
- `copy-machinery` — copies jig runtime machinery into the target's
host-local scaffold runtime; `--host claude` writes `.claude/`, and `--host codex` writes `.codex/`.
How to use
Run the migration report
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" report \
<project-dir> [--docs-root <relative-root>]- `<project-dir>` — path to the project root (e.g. `/path/to/repo`,
`.` for cwd).
- `--docs-root .` — inventory a track-local corpus whose `specs/`,
`decisions/`, `workflow.md`, and `architecture.md` live directly under the selected subproject instead of under `docs/`.
Adopt an existing custom-root corpus
Preview first, then apply:
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
adopt-layout <subproject-dir> --docs-root . --dry-run
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
adopt-layout <subproject-dir> --docs-root .The operation refuses incomplete/ambiguous corpora and existing or malformed sentinels before mutation. Apply writes only `<subproject-dir>/scaffold.json` using scaffold-init's canonical manifest builder; it does not move or rewrite the existing artifacts. Afterward, `workflow.py transition`, status-board, and ADR helpers discover the subproject through that sentinel.
Run the rename-decisions migration
Once `report` has been reviewed and the verdict is `adoptable`, the recommended sequence is:
# 1. Preview the plan (no writes).
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
rename-decisions <project-dir> --dry-run
# 2. After reviewing the planned operations, apply them.
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
rename-decisions <project-dir>What it does, in display order:
1. `docs/adrs/` → `docs/decisions/` (directory rename, atomic). 2. Per-file renames: `NNN-<slug>.md` → `adr-NNNN-<slug>.md` (pad 3-digit to 4-digit; add `adr-` prefix where missing). 3. Cross-reference rewrites in text files under `docs/`, `CLAUDE.md`, and `.claude/` by default. With `--host codex`, rewrites scan `docs/`, `AGENTS.md`, and `.codex/` instead. The helper itself (`migrate.py` and its fixtures) is never rewritten.
Refusal cases (exit 2, no mutations):
- Both `docs/adrs/` and `docs/decisions/` present (manual merge first).
- Two source files normalize to the same target name (collision).
- `<project-dir>` missing, not a directory, or unreadable.
No-op cases (exit 0):
- Neither dir present, OR all files already on the canonical shape —
emits "already aligned: nothing to do" and returns.
Run the seed-decisions operation
`seed-decisions` backfills `docs/decisions/lightweight-decisions.md` — the home `/jig:memory-sync`'s `decisions.py add-lightweight` records into, and the one the Stop-hook decision nudge points at.
Reach for it when `report` flags the gap, or when a project's `add-lightweight` fails because the file is missing. Every project that adopted jig **before** the lightweight-decisions feature landed needs it: `scaffold-init` seeds the file only at init and cannot be re-run on an already-scaffolded project, so there was previously no supported way to obtain it (bug 012 / [#109](https://github.com/ramboz/jig/issues/109)).
# preview
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
seed-decisions <project-dir> --dry-run
# apply
python3 "${CLAUDE_PLUGIN_ROOT}/skills/migrate/migrate.py" \
seed-decisions <project-dir>Idempotent — a second run reports "already present" and exits 0.
**It never overwrites.** If the file exists but is not in jig's format (no `## E
A Claude Code and Codex plugin that scaffolds AI-native development practices into new projects. jig adds a repeatable spec, implementation, review, and memory workflow to AI-assisted software projects.
Other skills on jig.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about migrate.
- Which coding agents can use migrate?
- migrate installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

