Files
nanoclaw/docs/zh/migration-dev.md
2026-05-12 13:14:17 +00:00

5.7 KiB
Raw Permalink Blame History

v1 → v2 迁移 — 开发指南

如何测试、开发和调试迁移流程。

快速入门

# 完整周期:重置 → 迁移 → Claude 完成
bash migrate-v2-reset.sh && bash migrate-v2.sh

架构

两部分迁移:

  1. migrate-v2.sh——确定性 bash 脚本。处理前提条件、DB 种子、文件拷贝、频道安装、容器构建、服务切换。写入 logs/setup-migration/handoff.json,然后 exec 到 Claude 中。

  2. /migrate-from-v1 技能——由 Claude 驱动。读取交接文件,种子 owner/roles清理 CLAUDE.local.md验证容器配置移植 fork 定制。

文件布局

migrate-v2.sh                        # 入口点
migrate-v2-reset.sh                  # 清除 v2 状态以重新测试
setup/migrate-v2/
  env.ts                             # 阶段 1a合并 .env
  db.ts                              # 阶段 1b种子 v2 DB
  groups.ts                          # 阶段 1c拷贝 group 目录 + container.json
  sessions.ts                        # 阶段 1d拷贝 session 并设置续接
  tasks.ts                           # 阶段 1e移植计划任务
  channel-auth.ts                    # 阶段 2b拷贝频道认证状态
  select-channels.ts                 # 阶段 2aclack 多选
  switchover-prompt.ts               # 服务切换提示
setup/migrate-v2/shared.ts           # 共享辅助函数JID 解析、触发器映射等)
.claude/skills/migrate-from-v1/      # Claude 技能
logs/setup-migration/handoff.json    # 由 migrate-v2.sh 写入,由技能读取
logs/migrate-steps/*.log             # 每个步骤的原始输出

开发循环

# 重置 v2 到干净状态(保留 node_modules
bash migrate-v2-reset.sh

# 以非交互式频道选择运行迁移
NANOCLAW_CHANNELS="telegram" bash migrate-v2.sh

# 或以交互方式运行clack 多选)
bash migrate-v2.sh

migrate-v2-reset.sh 清除:data/logs/.envgroups/(恢复 git 跟踪的)、container/skills/(恢复 git 跟踪的)、src/channels/(恢复 git 跟踪的)。

清除 node_modules/(重新安装成本高昂)。

测试单个步骤

每个步骤是一个独立的 TypeScript 文件:

# 运行单个步骤(在 pnpm install 之后)
pnpm exec tsx setup/migrate-v2/env.ts /path/to/v1
pnpm exec tsx setup/migrate-v2/db.ts /path/to/v1
pnpm exec tsx setup/migrate-v2/groups.ts /path/to/v1
pnpm exec tsx setup/migrate-v2/sessions.ts /path/to/v1
pnpm exec tsx setup/migrate-v2/tasks.ts /path/to/v1
pnpm exec tsx setup/migrate-v2/channel-auth.ts /path/to/v1 telegram discord

每个步骤向 stdout 打印 OK:<details>SKIPPED:<reason> 或错误。成功/跳过时退出 0失败时退出非零值。

调试

检查已迁移的内容

# Agent groups
sqlite3 data/v2.db "SELECT * FROM agent_groups"

# Messaging groups + 连线
sqlite3 data/v2.db "SELECT mg.id, mg.channel_type, mg.platform_id, mg.unknown_sender_policy, mga.engage_mode, mga.engage_pattern FROM messaging_groups mg JOIN messaging_group_agents mga ON mga.messaging_group_id = mg.id"

# Sessions
sqlite3 data/v2.db "SELECT * FROM sessions"

# 用户和角色
sqlite3 data/v2.db "SELECT * FROM users"
sqlite3 data/v2.db "SELECT * FROM user_roles"

# Session 续接(哪个 Claude Code session 将被恢复)
AG_ID=$(sqlite3 data/v2.db "SELECT id FROM agent_groups LIMIT 1")
SESS_ID=$(sqlite3 data/v2.db "SELECT id FROM sessions LIMIT 1")
sqlite3 data/v2-sessions/$AG_ID/$SESS_ID/outbound.db "SELECT * FROM session_state"

# 计划任务
sqlite3 data/v2-sessions/$AG_ID/$SESS_ID/inbound.db "SELECT id, kind, recurrence, status FROM messages_in WHERE kind='task'"

检查交接文件

python3 -m json.tool logs/setup-migration/handoff.json

常见问题

切换后 bot 不响应:

  1. 检查两个服务都没有运行:systemctl --user list-units 'nanoclaw*'
  2. 检查错误日志:tail logs/nanoclaw.error.log
  3. 检查发送者策略:sqlite3 data/v2.db "SELECT unknown_sender_policy FROM messaging_groups"——在 owner 被种子之前必须是 public
  4. 检查触发模式:sqlite3 data/v2.db "SELECT engage_mode, engage_pattern FROM messaging_group_agents"——应为 pattern / . 用于响应所有内容

Session 未从 v1 续接:

  1. 检查是否设置了续接:见上方的"Session 续接"查询
  2. 检查 JSONL 是否在正确路径下:ls data/v2-sessions/<ag_id>/.claude-shared/projects/-workspace-agent/
  3. v1 session JSONL 应从 -workspace-group/ 拷贝到 -workspace-agent/v2 容器 CWD 为 /workspace/agent

服务切换回退不起作用:

  1. v2 服务名称为 nanoclaw-v2-<hash>——找到它:systemctl --user list-units 'nanoclaw*'
  2. 手动停止:systemctl --user stop <unit> && systemctl --user disable <unit>
  3. 重启 v1systemctl --user start nanoclaw

步骤日志

每个步骤将原始输出写入 logs/migrate-steps/<step>.log。当某个步骤失败时读取这些日志:

cat logs/migrate-steps/1b-db.log
cat logs/migrate-steps/1d-sessions.log

关键决策

  • unknown_sender_policy 在迁移期间设置为 public,以便 bot 立即响应。/migrate-from-v1 技能在种子 owner 后收紧此设置。
  • v1 中 requires_trigger=0 优先于非空的 trigger_pattern——它意味着"响应所有内容"。
  • v1 container_config.additionalMounts 直接写入 v2 container.json(相同格式)。
  • v1 Claude Code session 从 -workspace-group/ 拷贝到 -workspace-agent/session ID 以 continuation:claude 写入 outbound.db,以便 agent-runner 恢复同一对话。
  • 结尾的 exec claude "/migrate-from-v1" 替换了 bash 进程——write_handoffexec 之前显式调用,因为 EXIT 陷阱不会在 exec 时触发。