Receber por email
← Voltar para o catálogo

migrate-from-v1

Finaliza a migração de uma instalação NanoClaw v1 para v2, executando tarefas pós-`bash migrate-v2.sh` como configurar o proprietário, limpar arquivos CLAUDE.local.md, reconciliar configurações de contêiner e auxiliar na portabilidade de código v1 personalizado.

29.9kestrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add nanocoai/nanoclaw

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/migrate-from-v1/svg)](https://www.skillteca.com.br/skills/migrate-from-v1)
#ai

Skills relacionadas

Ver todas de DevOps e Infra →

Alerta por categoria

Receba novas skills de DevOps e Infra toda segunda

1 email curto, só com as skills novas de DevOps e Infra. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Finish v1 → v2 migration

bash migrate-v2.sh already ran the deterministic migration. It handled:

  • .env keys merged
  • v2 DB seeded (agent_groups, messaging_groups, wiring)
  • Group folders copied (v1 CLAUDE.md → v2 CLAUDE.local.md)
  • Session data copied with conversation continuity (incl. Claude Code memory + JSONL transcripts)
  • Scheduled tasks ported
  • Channel code installed and auth state copied (incl. WhatsApp Baileys keystore)
  • WhatsApp LIDs resolved from store/auth and aliased into messaging_groups
  • Container skills copied
  • Container image built

Your job is the parts that need human judgment: triage any failed steps, seed the owner, clean up CLAUDE.local.md files, reconcile configs, and port any fork customizations.

Read logs/setup-migration/handoff.json first — it has overall_status, per-step results in steps, and a followups list.

Preflight: was the script run?

Before anything else, check that logs/setup-migration/handoff.json exists. If it doesn't, the user is invoking this skill before migrate-v2.sh ran. Stop and tell them, verbatim:

This skill finishes a migration that migrate-v2.sh started. Run that first, in your terminal — not from inside Claude:
```bash
bash migrate-v2.sh
```
It needs interactive prompts (channel selection, service switchover) and runs Node/pnpm bootstrap, Docker, OneCLI setup, and a container build that don't fit inside a Claude session. When it finishes, it'll hand control back to Claude automatically — at which point this skill picks up.

Do not attempt to run the script yourself, simulate its effects, or pick up the migration mid-stream. The deterministic side has dependencies on a real interactive shell.

Once handoff.json exists, proceed to Phase 0.

Phase 0: Get v2 routing real messages

Before any deeper migration work, prove v2 actually answers messages on the user's real channels. v1 is paused, not touched — flipping back is a service restart.

0a — Fix blockers only

Walk handoff.steps. Fix only the failures that would stop the bot from routing one message; defer the rest to its later phase.

0b — Smoke test, then continue

Tell the user the switch is non-destructive (v1 is paused, not modified; reverting is one command). Help them stop v1's service unit and start v2's, tail the host log for a clean boot, and have them send a real test message. Use AskUserQuestion to confirm the bot responded.

If yes, continue to Phase 1. If no, diagnose from logs/nanoclaw.log and re-test — don't proceed to deeper work on a broken router.

Deferred failures

Re-visit anything you skipped in 0a before declaring the migration done. Most surface naturally in later phases (1c-groups ↔ Phase 2, 1e-tasks ↔ task verification).

Phase 1: Owner and access

v2 auto-creates a users row for every sender it sees (via extractAndUpsertUser in src/modules/permissions/index.ts). By the time this skill runs, the owner's row likely already exists — it just needs the owner role granted.

User ID format: always <channel_type>:<platform_handle>. Each channel populates this differently:

  • Telegram: telegram:<numeric_user_id> (e.g. telegram:6037840640)
  • Discord: discord:<snowflake_user_id> (e.g. discord:123456789012345678)
  • WhatsApp: whatsapp:<phone>@s.whatsapp.net (e.g. whatsapp:14155551234@s.whatsapp.net)
  • Slack: slack:<user_id> (e.g. slack:U04ABCDEF)
  • Others: <channel_type>:<platform_id>

Steps:

  1. Query users table: SELECT id, kind, display_name FROM users.
  2. If exactly one user exists, confirm: AskUserQuestion: "Is <display_name> (<id>) you?" — Yes / No, let me type it.
  3. If multiple users exist, present them as options in AskUserQuestion.
  4. If no users exist yet (service hasn't received a message), ask the user to send a test message first, then re-query.
  5. Once confirmed, check user_roles — if the owner role already exists, skip. Otherwise insert:

``sql INSERT INTO user_roles (user_id, role, agent_group_id, granted_by, granted_at) VALUES ('<user_id>', 'owner', NULL, NULL, datetime('now')) ``

Use the DB helpers in src/db/user-roles.ts — they keep indexes correct. Init the DB first:

import { initDb } from '../src/db/connection.js';
import { runMigrations } from '../src/db/migrations/index.js';
import { DATA_DIR } from '../src/config.js';
import path from 'path';
const db = initDb(path.join(DATA_DIR, 'v2.db'));
runMigrations(db);

Access policy

After seeding the owner, discuss the access policy. v2's messaging_groups.unknown_sender_policy controls who can interact with the bot. migrate-v2.sh set it to public so the bot would respond during the switchover test, but the user may want to tighten it.

Present the options via AskUserQuestion:

  1. Public (current) — anyone can message the bot. Good for personal DM bots.
  2. Known users only — only users in agent_group_members can trigger the bot. Others are silently dropped.
  3. Approval required — unknown senders trigger an approval request to the owner. Good for group chats where you want to vet new members.

If the user picks option 2 or 3, seed the known users from v1's message history. The v1 database is at <handoff.v1_path>/store/messages.db. It has a messages table with sender and sender_name columns. For each group:

-- v1: unique senders per chat (excluding bot messages)
SELECT DISTINCT sender, sender_name
FROM messages
WHERE chat_jid = '<v1_jid>' AND is_from_me = 0 AND sender IS NOT NULL

The sender value is a platform handle (e.g. 6037840640 for Telegram). Build the v2 user ID by inferring the channel type from the chat JID prefix (use parseJid from setup/migrate-v2/shared.ts) and combining: <channel_type>:<sender>.

For each sender:

  1. Upsert into users(id, kind, display_name) if not already present.
  2. Insert into agent_group_members(user_id, agent_group_id) for each agent group wired to that messaging group.

Show the user the list of senders being imported and let them deselect any they don't want.

Then update the messaging groups:

UPDATE messaging_groups SET unknown_sender_policy = '<chosen_policy>'
WHERE id IN (SELECT id FROM messaging_groups WHERE channel_type IN (<migrated_channels>))

Phase 2: Clean up CLAUDE.local.md

The migration copied v1's entire CLAUDE.md into CLAUDE.local.md for each group. This file now contains v1 boilerplate that v2 handles through its own composed fragments (container/CLAUDE.md + .claude-fragments/module-*.md). The user's customizations are buried inside.

For each group that has a CLAUDE.local.md:

  1. Read the file.
  2. Read the v1 template it was based on. Determine which template by checking the v1 install:
  3. If the group had is_main=1 in v1's registered_groups, the template was groups/main/CLAUDE.md
  4. Otherwise, the template was groups/global/CLAUDE.md
  5. The v1 path is in handoff.json → v1_path
  6. Diff the file against the template. Identify sections that are:
  7. Stock boilerplate (identical to template) — remove. v2's fragments cover this.
  8. User customizations (added sections, modified sections) — keep.
  9. The following v1 sections are now handled by v2 fragments and should be removed even if slightly modified:
  10. "What You Can Do" → v2 runtime system prompt
  11. "Communication" / "Internal thoughts" / "Sub-agents" → container/CLAUDE.md + module-core.md
  12. "Your Workspace" / workspace path references → container/CLAUDE.md
  13. "Memory" (the stock version) → container/CLAUDE.md
  14. "Message Formatting" → container/CLAUDE.md
  15. "Admin Context" → v2 uses user_roles, not is_main
  16. "Authentication" → v2 uses OneCLI
  17. "Container Mounts" → v2 mounts are different
  18. "Managing Groups" / "Finding Available Groups" / "Registered Groups Config" → v2 entity model, no IPC
  19. "Global Memory" → v2 has .claude-shared.md symlink
  20. "Sche
Compartilhar X LinkedIn