soulsync 1.0.0 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.md +120 -0
- package/DEPLOY_CHECKLIST.md +151 -0
- package/INSTALL.md +103 -0
- package/SPEC.md +170 -0
- package/TROUBLESHOOTING.md +199 -0
- package/{config.json → config.json.example} +3 -3
- package/debug.py +221 -0
- package/index.js +54 -0
- package/openclaw.plugin.json +18 -0
- package/package.json +7 -21
- package/setup.sh +91 -0
- package/src/__init__.py +1 -0
- package/src/client.py +81 -11
- package/src/interactive_auth.py +283 -0
- package/src/main.py +130 -83
- package/src/main_fixed.py +434 -0
- package/src/register.py +131 -0
- package/src/sync.py +172 -109
- package/workspace/MEMORY.md +0 -5
package/CHANGES.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
\# SoulSync 插件修改记录
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
\## 版本 1.0.2 → 1.0.3
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
\### 修复问题
|
|
10
|
+
|
|
11
|
+
1\. \*\*Python 模块导入问题\*\*
|
|
12
|
+
|
|
13
|
+
- 修复 `src/main.py`、`src/sync.py` 中的 `from src.xxx` 导入错误
|
|
14
|
+
|
|
15
|
+
- 改为相对导入 `from xxx` 或绝对导入 `from profiles import xxx`
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
2\. \*\*OpenClaw 插件格式问题\*\*
|
|
20
|
+
|
|
21
|
+
- 添加 `index.js` 作为 JavaScript 入口文件
|
|
22
|
+
|
|
23
|
+
- 修改 `package.json` 的 `openclaw.extensions` 格式
|
|
24
|
+
|
|
25
|
+
- 添加 `openclaw.plugin.json` 文件
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
3\. \*\*配置文件路径问题\*\*
|
|
30
|
+
|
|
31
|
+
- 修复 `main\_fixed.py` 中的路径处理
|
|
32
|
+
|
|
33
|
+
- 支持跨平台路径(Windows/Linux)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
\### 新增文件
|
|
38
|
+
|
|
39
|
+
\- `index.js` - OpenClaw JavaScript 入口
|
|
40
|
+
|
|
41
|
+
\- `src/main\_fixed.py` - 修复版主程序
|
|
42
|
+
|
|
43
|
+
\- `src/\_\_init\_\_.py` - Python 包标识
|
|
44
|
+
|
|
45
|
+
\- `debug.py` - 调试诊断工具
|
|
46
|
+
|
|
47
|
+
\- `setup.sh` - Linux 自动安装脚本
|
|
48
|
+
|
|
49
|
+
\- `INSTALL.md` - 安装文档
|
|
50
|
+
|
|
51
|
+
\- `TROUBLESHOOTING.md` - 故障排除指南
|
|
52
|
+
|
|
53
|
+
\- `DEPLOY\_CHECKLIST.md` - 部署检查清单
|
|
54
|
+
|
|
55
|
+
\- `.gitignore` - Git 忽略文件
|
|
56
|
+
|
|
57
|
+
\- `CHANGES.md` - 本文件
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
\### 修改的文件
|
|
62
|
+
|
|
63
|
+
\- `package.json` - 更新版本号、main 入口、openclaw.extensions 格式
|
|
64
|
+
|
|
65
|
+
\- `openclaw.plugin.json` - 更新版本号和配置
|
|
66
|
+
|
|
67
|
+
\- `src/main.py` - 修复导入语句
|
|
68
|
+
|
|
69
|
+
\- `src/sync.py` - 修复导入语句
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
\### 待实现功能
|
|
74
|
+
|
|
75
|
+
\- \[ ] 首次启动交互式登录(输入邮箱密码)
|
|
76
|
+
|
|
77
|
+
\- \[ ] 自动检测 Python 环境
|
|
78
|
+
|
|
79
|
+
\- \[ ] 自动安装 Python 依赖
|
|
80
|
+
|
|
81
|
+
\- \[ ] Windows 安装脚本(setup.bat)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
\## 测试记录
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
\### Ubuntu 测试环境
|
|
90
|
+
|
|
91
|
+
\- OpenClaw 版本: 2026.2.15
|
|
92
|
+
|
|
93
|
+
\- Python 版本: 3.12.3
|
|
94
|
+
|
|
95
|
+
\- 安装方式: 本地路径安装
|
|
96
|
+
|
|
97
|
+
\- 测试结果: ✅ 插件注册成功、启动成功、文件同步成功
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
\### 测试命令
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
|
|
105
|
+
\# 安装
|
|
106
|
+
|
|
107
|
+
openclaw plugins install ~/.openclaw/extensions/soulsync
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
\# 启动
|
|
112
|
+
|
|
113
|
+
openclaw soulsync:start
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
\# 查看日志
|
|
118
|
+
|
|
119
|
+
openclaw plugins logs soulsync
|
|
120
|
+
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# SoulSync OpenClaw 插件部署检查清单
|
|
2
|
+
|
|
3
|
+
## 本地 Ubuntu 部署步骤
|
|
4
|
+
|
|
5
|
+
### ✅ 第1步:准备环境
|
|
6
|
+
- [ ] Ubuntu 系统已更新: `sudo apt-get update`
|
|
7
|
+
- [ ] Python 3.7+ 已安装: `python3 --version`
|
|
8
|
+
- [ ] pip3 已安装: `pip3 --version`
|
|
9
|
+
|
|
10
|
+
### ✅ 第2步:复制插件文件
|
|
11
|
+
```bash
|
|
12
|
+
# 创建插件目录
|
|
13
|
+
mkdir -p ~/.openclaw/plugins/soulsync
|
|
14
|
+
|
|
15
|
+
# 复制文件(根据你的实际路径调整)
|
|
16
|
+
cp -r /path/to/soulsync/plugins/openclaw/* ~/.openclaw/plugins/soulsync/
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### ✅ 第3步:安装依赖
|
|
20
|
+
```bash
|
|
21
|
+
cd ~/.openclaw/plugins/soulsync
|
|
22
|
+
pip3 install -r requirements.txt --user
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### ✅ 第4步:配置插件
|
|
26
|
+
```bash
|
|
27
|
+
# 编辑配置文件
|
|
28
|
+
nano ~/.openclaw/plugins/soulsync/config.json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
填写以下信息:
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"cloud_url": "http://你的服务器IP:3000",
|
|
35
|
+
"email": "你的邮箱",
|
|
36
|
+
"password": "你的密码",
|
|
37
|
+
"workspace": "./workspace",
|
|
38
|
+
"watch_files": ["MEMORY.md", "memory/"]
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### ✅ 第5步:运行诊断
|
|
43
|
+
```bash
|
|
44
|
+
cd ~/.openclaw/plugins/soulsync
|
|
45
|
+
python3 debug.py
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**期望结果**: 所有检查项显示 ✅
|
|
49
|
+
|
|
50
|
+
### ✅ 第6步:测试运行
|
|
51
|
+
```bash
|
|
52
|
+
python3 src/main_fixed.py
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**期望结果**:
|
|
56
|
+
- 成功加载配置
|
|
57
|
+
- 成功连接服务器(如果配置了账号)
|
|
58
|
+
- 文件监听器启动
|
|
59
|
+
- 显示 "Plugin Running"
|
|
60
|
+
|
|
61
|
+
### ✅ 第7步:集成到 OpenClaw
|
|
62
|
+
1. 确保 `openclaw.plugin.json` 格式正确
|
|
63
|
+
2. 重启 OpenClaw
|
|
64
|
+
3. 在 OpenClaw 中启用 SoulSync 插件
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 常见问题速查
|
|
69
|
+
|
|
70
|
+
| 问题 | 快速解决 |
|
|
71
|
+
|------|---------|
|
|
72
|
+
| ModuleNotFoundError | `export PYTHONPATH="${PYTHONPATH}:$(pwd)/src"` |
|
|
73
|
+
| Permission Denied | `chmod -R 755 ~/.openclaw/plugins/soulsync` |
|
|
74
|
+
| 依赖安装失败 | `sudo apt-get install python3-dev` |
|
|
75
|
+
| WebSocket 失败 | 检查 config.json 中的 cloud_url |
|
|
76
|
+
| 文件监听失败 | `echo fs.inotify.max_user_watches=524288 \| sudo tee -a /etc/sysctl.conf && sudo sysctl -p` |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 验证部署成功
|
|
81
|
+
|
|
82
|
+
运行以下命令验证:
|
|
83
|
+
```bash
|
|
84
|
+
cd ~/.openclaw/plugins/soulsync
|
|
85
|
+
|
|
86
|
+
# 1. 检查文件结构
|
|
87
|
+
ls -la
|
|
88
|
+
|
|
89
|
+
# 2. 检查依赖
|
|
90
|
+
pip3 list | grep -E "requests|watchdog|websocket"
|
|
91
|
+
|
|
92
|
+
# 3. 运行诊断
|
|
93
|
+
python3 debug.py
|
|
94
|
+
|
|
95
|
+
# 4. 测试启动(按 Ctrl+C 退出)
|
|
96
|
+
python3 src/main_fixed.py
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 同步到 GitHub
|
|
102
|
+
|
|
103
|
+
调试完成后,提交到 GitHub:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cd /path/to/soulsync
|
|
107
|
+
|
|
108
|
+
# 查看修改的文件
|
|
109
|
+
git status
|
|
110
|
+
|
|
111
|
+
# 添加新文件
|
|
112
|
+
git add plugins/openclaw/debug.py
|
|
113
|
+
git add plugins/openclaw/setup.sh
|
|
114
|
+
git add plugins/openclaw/INSTALL.md
|
|
115
|
+
git add plugins/openclaw/TROUBLESHOOTING.md
|
|
116
|
+
git add plugins/openclaw/src/__init__.py
|
|
117
|
+
git add plugins/openclaw/src/main_fixed.py
|
|
118
|
+
git add plugins/openclaw/DEPLOY_CHECKLIST.md
|
|
119
|
+
|
|
120
|
+
# 提交修改
|
|
121
|
+
git commit -m "fix: 修复 Ubuntu 安装问题
|
|
122
|
+
|
|
123
|
+
- 添加 __init__.py 解决 Python 模块导入问题
|
|
124
|
+
- 创建 main_fixed.py 修复跨平台路径问题
|
|
125
|
+
- 添加 debug.py 诊断工具
|
|
126
|
+
- 添加 setup.sh 自动安装脚本
|
|
127
|
+
- 添加完整文档(INSTALL, TROUBLESHOOTING, DEPLOY_CHECKLIST)
|
|
128
|
+
- 更新版本号到 1.0.2"
|
|
129
|
+
|
|
130
|
+
# 推送到 GitHub
|
|
131
|
+
git push origin main
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## NPM 发布(如果适用)
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
cd plugins/openclaw
|
|
140
|
+
|
|
141
|
+
# 更新版本号
|
|
142
|
+
npm version patch # 或 minor/major
|
|
143
|
+
|
|
144
|
+
# 发布到 NPM
|
|
145
|
+
npm publish
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
**最后更新**: 2026-02-26
|
|
151
|
+
**版本**: 1.0.2
|
package/INSTALL.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# SoulSync OpenClaw 插件安装指南
|
|
2
|
+
|
|
3
|
+
## Ubuntu/Linux 安装步骤
|
|
4
|
+
|
|
5
|
+
### 1. 安装系统依赖
|
|
6
|
+
```bash
|
|
7
|
+
sudo apt-get update
|
|
8
|
+
sudo apt-get install -y python3-pip python3-venv
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### 2. 安装 Python 依赖
|
|
12
|
+
```bash
|
|
13
|
+
cd /path/to/openclaw/plugins/soulsync
|
|
14
|
+
pip3 install -r requirements.txt
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 3. 配置文件
|
|
18
|
+
复制配置模板并修改:
|
|
19
|
+
```bash
|
|
20
|
+
cp config.json config.json.backup
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
编辑 `config.json`:
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"cloud_url": "http://你的服务器IP:3000",
|
|
27
|
+
"email": "你的邮箱",
|
|
28
|
+
"password": "你的密码",
|
|
29
|
+
"workspace": "./workspace",
|
|
30
|
+
"memory_file": "MEMORY.md",
|
|
31
|
+
"watch_files": [
|
|
32
|
+
"SOUL.md",
|
|
33
|
+
"IDENTITY.md",
|
|
34
|
+
"USER.md",
|
|
35
|
+
"AGENTS.md",
|
|
36
|
+
"TOOLS.md",
|
|
37
|
+
"skills.json",
|
|
38
|
+
"memory/",
|
|
39
|
+
"MEMORY.md"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 4. 创建工作目录
|
|
45
|
+
```bash
|
|
46
|
+
mkdir -p workspace/memory
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 5. 测试运行
|
|
50
|
+
```bash
|
|
51
|
+
python3 src/main.py
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 常见问题排查
|
|
55
|
+
|
|
56
|
+
### 问题1:ModuleNotFoundError
|
|
57
|
+
**错误**:`No module named 'src'`
|
|
58
|
+
|
|
59
|
+
**解决**:
|
|
60
|
+
```bash
|
|
61
|
+
export PYTHONPATH="${PYTHONPATH}:$(pwd)"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 问题2:Permission Denied
|
|
65
|
+
**错误**:无法写入文件
|
|
66
|
+
|
|
67
|
+
**解决**:
|
|
68
|
+
```bash
|
|
69
|
+
chmod -R 755 /path/to/plugin
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 问题3:Watchdog 错误
|
|
73
|
+
**错误**:`inotify` 限制
|
|
74
|
+
|
|
75
|
+
**解决**:
|
|
76
|
+
```bash
|
|
77
|
+
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
|
|
78
|
+
sudo sysctl -p
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 调试模式
|
|
82
|
+
|
|
83
|
+
启用详细日志:
|
|
84
|
+
```bash
|
|
85
|
+
DEBUG=1 python3 src/main.py
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 手动安装到 OpenClaw
|
|
89
|
+
|
|
90
|
+
1. 找到 OpenClaw 插件目录:
|
|
91
|
+
```bash
|
|
92
|
+
# 通常在用户目录下
|
|
93
|
+
~/.openclaw/plugins/
|
|
94
|
+
# 或
|
|
95
|
+
/usr/share/openclaw/plugins/
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
2. 复制插件:
|
|
99
|
+
```bash
|
|
100
|
+
cp -r /path/to/soulsync/plugins/openclaw ~/.openclaw/plugins/
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. 重启 OpenClaw
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# SoulSync 插件端同步逻辑开发规范
|
|
2
|
+
|
|
3
|
+
## 目标
|
|
4
|
+
|
|
5
|
+
补全 `plugins/openclaw/src/sync.py`,实现完整的文件同步逻辑,使插件能与云端服务器双向同步文件。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 现有代码概览
|
|
10
|
+
|
|
11
|
+
以下模块已完成,sync.py 需要调用它们:
|
|
12
|
+
|
|
13
|
+
### 1. ProfilesClient (profiles.py) - 已完成
|
|
14
|
+
```python
|
|
15
|
+
# 可用方法:
|
|
16
|
+
profiles_client.get_profiles(path=None) # 获取云端文件列表
|
|
17
|
+
profiles_client.upload_profile(file_path, content, version) # 上传文件
|
|
18
|
+
profiles_client.download_profile(file_path) # 下载单个文件(如有)
|
|
19
|
+
```
|
|
20
|
+
- upload_profile 冲突时抛出 ConflictError(server_version, server_content)
|
|
21
|
+
|
|
22
|
+
### 2. VersionManager (version_manager.py) - 已完成
|
|
23
|
+
```python
|
|
24
|
+
# 可用方法:
|
|
25
|
+
version_manager.get_version(file_path) # 获取本地版本号
|
|
26
|
+
version_manager.set_version(file_path, ver) # 设置版本号
|
|
27
|
+
version_manager.get_all_versions() # 获取所有版本
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 3. OpenClawMultiWatcher (watcher.py) - 已完成
|
|
31
|
+
- 监听 workspace 目录下的文件变化
|
|
32
|
+
- 变化时调用 callback(file_path)
|
|
33
|
+
|
|
34
|
+
### 4. OpenClawClient (client.py) - 已完成
|
|
35
|
+
- WebSocket 连接已实现
|
|
36
|
+
- 收到 ws 消息时调用 on_message_callback
|
|
37
|
+
|
|
38
|
+
### 5. 服务端 API (soulsync-server)
|
|
39
|
+
- `GET /api/profiles` → 返回 `{files: [{file_path, content, version, updated_at}]}`
|
|
40
|
+
- `GET /api/profiles?path=xxx` → 返回单个文件
|
|
41
|
+
- `POST /api/profiles` → 上传文件,body: `{file_path, content, version}`
|
|
42
|
+
- 成功返回 `{file_path, version, updated_at}`
|
|
43
|
+
- 冲突返回 409: `{error, server_version, server_content}`
|
|
44
|
+
- WebSocket 事件 `file_updated`: `{file_path, version, updated_at}`
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 开发任务
|
|
49
|
+
|
|
50
|
+
### 任务 1:实现 sync.py 的 pull_all 方法
|
|
51
|
+
|
|
52
|
+
启动时从云端拉取所有文件到本地:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
流程:
|
|
56
|
+
1. 调用 profiles_client.get_profiles() 获取云端所有文件
|
|
57
|
+
2. 遍历每个文件:
|
|
58
|
+
a. 读取本地文件内容(如果存在)
|
|
59
|
+
b. 比较云端 version 和本地 version_manager 中的版本
|
|
60
|
+
c. 如果云端版本更新 → 写入本地文件,更新 version_manager
|
|
61
|
+
d. 如果本地版本更新(本地有修改但未推送)→ 调用 push_file
|
|
62
|
+
e. 如果版本相同 → 跳过
|
|
63
|
+
3. 打印同步结果摘要
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**注意**:写入本地文件时,watcher 会触发 callback,需要有机制避免"写入触发再次上传"的死循环。建议在 sync 中维护一个 `_syncing_files` 集合,watcher callback 中检查该集合来跳过。
|
|
67
|
+
|
|
68
|
+
### 任务 2:实现 sync.py 的 push_file 方法
|
|
69
|
+
|
|
70
|
+
本地文件变更时推送到云端:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
流程:
|
|
74
|
+
1. 检查 file_path 是否在 _syncing_files 中,如果是则跳过(避免死循环)
|
|
75
|
+
2. 读取本地文件内容
|
|
76
|
+
3. 获取本地版本号 version_manager.get_version(file_path)
|
|
77
|
+
4. 调用 profiles_client.upload_profile(file_path, content, version)
|
|
78
|
+
5. 成功 → 更新 version_manager 为返回的新版本号
|
|
79
|
+
6. 冲突 → 处理冲突(见任务 4)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 任务 3:实现 sync.py 的 on_remote_change 方法
|
|
83
|
+
|
|
84
|
+
收到 WebSocket 通知时拉取远程变更:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
流程:
|
|
88
|
+
1. 收到 {file_path, version} 事件
|
|
89
|
+
2. 比较 version 和本地 version_manager 中的版本
|
|
90
|
+
3. 如果远程版本更新 → 下载文件内容,写入本地,更新 version_manager
|
|
91
|
+
4. 写入本地时加入 _syncing_files 避免触发 push
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 任务 4:冲突处理
|
|
95
|
+
|
|
96
|
+
当 push_file 遇到 ConflictError 时:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
策略(第一阶段简单处理):
|
|
100
|
+
1. 打印冲突警告信息
|
|
101
|
+
2. 保存本地版本为 .conflict 备份文件
|
|
102
|
+
3. 用云端版本覆盖本地文件
|
|
103
|
+
4. 更新 version_manager
|
|
104
|
+
5. 提示用户手动合并
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 任务 5:在 main.py 中连接 sync 与 watcher/websocket
|
|
108
|
+
|
|
109
|
+
确保以下联动正常:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
# watcher 的 callback 应调用 sync.push_file
|
|
113
|
+
def on_file_changed(file_path):
|
|
114
|
+
sync.push_file(file_path)
|
|
115
|
+
|
|
116
|
+
# websocket 的 on_message 应调用 sync.on_remote_change
|
|
117
|
+
def on_ws_message(data):
|
|
118
|
+
if data.get('event') == 'file_updated':
|
|
119
|
+
sync.on_remote_change(data['file_path'], data['version'])
|
|
120
|
+
|
|
121
|
+
# 启动时应调用 sync.pull_all
|
|
122
|
+
sync.pull_all()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 防死循环机制(关键)
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
class ProfileSync:
|
|
131
|
+
def __init__(self, ...):
|
|
132
|
+
self._syncing_files = set() # 正在同步的文件
|
|
133
|
+
self._sync_lock = threading.Lock()
|
|
134
|
+
|
|
135
|
+
def _is_syncing(self, file_path):
|
|
136
|
+
return file_path in self._syncing_files
|
|
137
|
+
|
|
138
|
+
def _mark_syncing(self, file_path):
|
|
139
|
+
self._syncing_files.add(file_path)
|
|
140
|
+
|
|
141
|
+
def _unmark_syncing(self, file_path):
|
|
142
|
+
# 延迟移除,给 watcher 时间忽略事件
|
|
143
|
+
import threading
|
|
144
|
+
def remove():
|
|
145
|
+
time.sleep(2)
|
|
146
|
+
self._syncing_files.discard(file_path)
|
|
147
|
+
threading.Thread(target=remove, daemon=True).start()
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 测试验证
|
|
153
|
+
|
|
154
|
+
完成后需要通过以下测试:
|
|
155
|
+
|
|
156
|
+
1. **启动同步**:插件启动 → pull_all 拉取云端文件到本地
|
|
157
|
+
2. **本地推送**:修改本地 MEMORY.md → 自动推送到云端
|
|
158
|
+
3. **远程拉取**:另一设备修改文件 → WebSocket 通知 → 本地自动更新
|
|
159
|
+
4. **冲突处理**:两端同时修改 → 生成 .conflict 文件 + 提示用户
|
|
160
|
+
5. **防死循环**:拉取写入本地时不触发再次推送
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 技术约束
|
|
165
|
+
|
|
166
|
+
1. 使用现有的 ProfilesClient、VersionManager,不要重写
|
|
167
|
+
2. 文件路径使用相对于 workspace 的路径(如 "MEMORY.md"、"memory/xxx.md")
|
|
168
|
+
3. 所有文件读写使用 UTF-8 编码
|
|
169
|
+
4. 打印日志格式统一为 `[Sync] 操作描述`
|
|
170
|
+
5. 异常要捕获并打印,不能让插件崩溃
|