Migrate from v1
Finish migrating a NanoClaw v1 install into v2 after the migration script runs — seed the owner, clean up carried-over config, and port fork customizations.
What it does
- Picks up where the migrate-v2.sh script leaves off, using its handoff.json
- Proves v2 routes real messages before any deeper work
- Seeds the owner role and sets the access policy for your channels
- Strips v1 boilerplate from CLAUDE.local.md while keeping your customizations
- Reconciles container.json mounts and ports fork code that's portable
- Runs an end-to-end verify step to confirm the migration is healthy
What you'll need
- A NanoClaw v1 install to migrate from
- `bash migrate-v2.sh` already run to completion (it writes logs/setup-migration/handoff.json)
- The v1 checkout still present on disk for reference
Install
/migrate-from-v1 How it works
Migrating from v1 to v2 happens in two stages. First you run bash migrate-v2.sh in your terminal — it does the deterministic, mechanical work: merging .env keys, seeding the v2 database, copying group folders and session data with conversation continuity, porting scheduled tasks, installing channel code and auth state, copying container skills, and building the container image. That script needs interactive prompts and a real shell, so it runs outside Claude.
The /migrate-from-v1 skill picks up the parts that need human judgment. When the script finishes it writes logs/setup-migration/handoff.json — an overall_status, per-step results, and a follow-up list — and hands control back to Claude. The skill reads that file first and works through what’s left. If you invoke the skill before the script has run, it stops and tells you to run bash migrate-v2.sh first rather than trying to simulate the deterministic side.
Throughout, your v1 checkout is treated as read-only. The switchover is non-destructive: v1 is paused, not modified, so reverting is a single service restart.
Setup
The skill moves through the migration in phases:
- Route real messages first. Before any deeper work, it fixes only the blockers that would stop the bot from answering one message, helps you stop v1’s service and start v2’s, tails the host log for a clean boot, and has you send a real test message to confirm v2 responds.
- Owner and access. v2 auto-creates a
usersrow for every sender it sees, so the owner usually already exists and just needs theownerrole granted. User IDs follow<channel_type>:<platform_handle>. The skill confirms which user is you, grants the role idempotently, then discusses the access policy —public,strict, orrequest_approval— and can seed known users from v1’s message history. - Clean up CLAUDE.local.md. The migration copied each group’s entire v1
CLAUDE.mdintoCLAUDE.local.md. The skill diffs it against the original v1 template, removes stock boilerplate that v2 now handles through its composed fragments, keeps your customizations, and fixes stale path references (for example/workspace/group/becomes/workspace/agent/). It shows you the proposed file before writing it. - Container config. It verifies each
container.jsonand checks thatadditionalMountshost paths still exist, or rewrites a proper config from the.v1-container-config.jsonfallback if the v1 config couldn’t be parsed. - Fork customizations. If your v1 install had commits ahead of upstream, it helps you copy portable items (container skills,
.claude/skills, docs) and stashes non-portable source todocs/v1-fork-reference/rather than translating it.
The setup flow at setup/index.ts exposes individual steps you can re-run if something failed:
pnpm exec tsx setup/index.ts --step <name>
Steps include onecli, auth, container, service, mounts, environment, and verify.
Tips
- Read
handoff.jsonbefore anything else. It’s also the recovery point — if context gets compacted, re-read it and checkgit statusto recover state. - Nothing is destroyed on the way over. v1 stays paused and untouched, so you can flip back with one service restart if the test message doesn’t land.
- When done, run the verify step (
pnpm exec tsx setup/index.ts --step verify), then deletehandoff.json— the skill offers to save it as a dated migration doc first. - The v2 service label is install-specific, so restart it by deriving the label from
src/install-slug.tsrather than guessing the name.