添加中文文档

This commit is contained in:
2026-05-12 13:14:17 +00:00
parent 61d7ca6bba
commit 38bb076ac6
24 changed files with 6876 additions and 0 deletions

139
docs/zh/migration-dev.md Normal file
View File

@@ -0,0 +1,139 @@
# v1 → v2 迁移 — 开发指南
如何测试、开发和调试迁移流程。
## 快速入门
```bash
# 完整周期:重置 → 迁移 → 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 # 每个步骤的原始输出
```
## 开发循环
```bash
# 重置 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/``.env``groups/`(恢复 git 跟踪的)、`container/skills/`(恢复 git 跟踪的)、`src/channels/`(恢复 git 跟踪的)。
它**不**清除 `node_modules/`(重新安装成本高昂)。
## 测试单个步骤
每个步骤是一个独立的 TypeScript 文件:
```bash
# 运行单个步骤(在 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失败时退出非零值。
## 调试
### 检查已迁移的内容
```bash
# 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'"
```
### 检查交接文件
```bash
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. 重启 v1`systemctl --user start nanoclaw`
### 步骤日志
每个步骤将原始输出写入 `logs/migrate-steps/<step>.log`。当某个步骤失败时读取这些日志:
```bash
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_handoff``exec` 之前显式调用,因为 EXIT 陷阱不会在 `exec` 时触发。