soulsync 1.0.11 → 1.0.12
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/index.js +6 -0
- package/package.json +1 -1
- package/src/client.py +0 -2
- package/src/main.py +54 -38
package/index.js
CHANGED
|
@@ -49,6 +49,12 @@ function startPythonService(mode = '--start') {
|
|
|
49
49
|
pythonProcess.on('close', (code) => {
|
|
50
50
|
console.log(`[SoulSync] Python process exited with code ${code}`);
|
|
51
51
|
pythonProcess = null;
|
|
52
|
+
|
|
53
|
+
// If setup succeeded (code 0), auto-start sync
|
|
54
|
+
if (mode === '--setup' && code === 0) {
|
|
55
|
+
console.log('[SoulSync] Setup completed, starting sync service...');
|
|
56
|
+
startPythonService('--start');
|
|
57
|
+
}
|
|
52
58
|
});
|
|
53
59
|
|
|
54
60
|
pythonProcess.on('error', (err) => {
|
package/package.json
CHANGED
package/src/client.py
CHANGED
package/src/main.py
CHANGED
|
@@ -92,9 +92,16 @@ class SoulSyncPlugin:
|
|
|
92
92
|
except:
|
|
93
93
|
config = {}
|
|
94
94
|
|
|
95
|
-
# 保存 email
|
|
96
|
-
if 'user' in auth_result:
|
|
95
|
+
# 保存 email(支持两种返回格式:authenticate 有 user 对象,register 只有一个字段)
|
|
96
|
+
if 'user' in auth_result and isinstance(auth_result.get('user'), dict):
|
|
97
97
|
config['email'] = auth_result['user'].get('email', '')
|
|
98
|
+
elif 'email' in auth_result:
|
|
99
|
+
config['email'] = auth_result.get('email', '')
|
|
100
|
+
|
|
101
|
+
# 保存 password(注册时输入的密码,需要保存以便自动登录)
|
|
102
|
+
# 注意:登录时我们只有从 config 读取的 password
|
|
103
|
+
if 'password' in auth_result:
|
|
104
|
+
config['password'] = auth_result.get('password', '')
|
|
98
105
|
|
|
99
106
|
# 保存 token
|
|
100
107
|
if 'token' in auth_result:
|
|
@@ -132,7 +139,7 @@ class SoulSyncPlugin:
|
|
|
132
139
|
return result
|
|
133
140
|
elif choice == '0':
|
|
134
141
|
print("[SoulSync] Goodbye! / 再见!")
|
|
135
|
-
sys.exit(
|
|
142
|
+
sys.exit(2)
|
|
136
143
|
else:
|
|
137
144
|
print("[SoulSync] Invalid choice / 无效选择")
|
|
138
145
|
|
|
@@ -164,6 +171,8 @@ class SoulSyncPlugin:
|
|
|
164
171
|
temp_client = OpenClawClient(self.config)
|
|
165
172
|
result = temp_client.authenticate(email, password)
|
|
166
173
|
if result:
|
|
174
|
+
result['email'] = email
|
|
175
|
+
result['password'] = password
|
|
167
176
|
print("\n[SoulSync] ✓ Login successful! / 登录成功!")
|
|
168
177
|
self._save_auth_to_config(result)
|
|
169
178
|
return True
|
|
@@ -176,7 +185,7 @@ class SoulSyncPlugin:
|
|
|
176
185
|
print("[SoulSync] Exiting... / 退出...")
|
|
177
186
|
sys.exit(0)
|
|
178
187
|
|
|
179
|
-
print(f"\n[SoulSync] ❌
|
|
188
|
+
print(f"\n[SoulSync] ❌ {e}")
|
|
180
189
|
print("[SoulSync] Returning to menu... / 返回菜单...")
|
|
181
190
|
return None
|
|
182
191
|
|
|
@@ -292,22 +301,23 @@ class SoulSyncPlugin:
|
|
|
292
301
|
try:
|
|
293
302
|
result = self.client.authenticate(email, password)
|
|
294
303
|
if result:
|
|
304
|
+
result['email'] = email
|
|
305
|
+
result['password'] = password
|
|
295
306
|
print("[SoulSync] Login successful! / 登录成功!")
|
|
296
307
|
self._save_auth_to_config(result)
|
|
297
308
|
token = self.client.token
|
|
298
309
|
except Exception as e:
|
|
299
310
|
error_msg = str(e)
|
|
300
|
-
print(f"[SoulSync] Login failed: {e}")
|
|
301
311
|
|
|
302
312
|
if "429" in error_msg or "too many" in error_msg.lower():
|
|
303
313
|
print("\n[SoulSync] ========================================")
|
|
314
|
+
print(f"[SoulSync] ❌ {e}")
|
|
304
315
|
print("[SoulSync] Too many failed attempts. Please try again later / 登录失败次数过多,请稍后再试")
|
|
305
316
|
print("[SoulSync] ========================================\n")
|
|
306
317
|
else:
|
|
307
318
|
print("\n[SoulSync] ========================================")
|
|
308
|
-
print("[SoulSync]
|
|
309
|
-
print("[SoulSync] Please
|
|
310
|
-
print(f" {os.path.normpath(os.path.join(PLUGIN_DIR, 'config.json'))}")
|
|
319
|
+
print(f"[SoulSync] ❌ {e}")
|
|
320
|
+
print("[SoulSync] Please run 'openclaw soulsync:setup' to reconfigure / 请运行 'openclaw soulsync:setup' 重新配置")
|
|
311
321
|
print("[SoulSync] ========================================\n")
|
|
312
322
|
|
|
313
323
|
sys.exit(0)
|
|
@@ -338,13 +348,13 @@ class SoulSyncPlugin:
|
|
|
338
348
|
self.config.get('workspace')
|
|
339
349
|
)
|
|
340
350
|
|
|
341
|
-
print("Pulling all profiles from cloud...")
|
|
351
|
+
print("[SoulSync] Pulling all profiles from cloud...")
|
|
342
352
|
try:
|
|
343
353
|
self.profile_sync.pull_all()
|
|
344
354
|
except Exception as e:
|
|
345
|
-
print(f"Warning: Could not pull profiles: {e}")
|
|
355
|
+
print(f"[SoulSync] Warning: Could not pull profiles: {e}")
|
|
346
356
|
|
|
347
|
-
print("\
|
|
357
|
+
print("\n[SoulSync] Starting file watcher...")
|
|
348
358
|
watch_files = self.config.get('watch_files', [])
|
|
349
359
|
self.watcher = OpenClawMultiWatcher(
|
|
350
360
|
self.config.get('workspace'),
|
|
@@ -353,29 +363,29 @@ class SoulSyncPlugin:
|
|
|
353
363
|
)
|
|
354
364
|
self.watcher.start()
|
|
355
365
|
|
|
356
|
-
print("\
|
|
366
|
+
print("\n[SoulSync] Connecting to WebSocket...")
|
|
357
367
|
try:
|
|
358
368
|
self.client.connect_websocket(self.on_websocket_message)
|
|
359
369
|
except Exception as e:
|
|
360
|
-
print(f"Warning: Could not connect WebSocket: {e}")
|
|
370
|
+
print(f"[SoulSync] Warning: Could not connect WebSocket: {e}")
|
|
361
371
|
|
|
362
372
|
self.running = True
|
|
363
373
|
|
|
364
374
|
def on_file_change(self, event_type: str, relative_path: str, absolute_path: str = None):
|
|
365
375
|
"""文件变化回调"""
|
|
366
|
-
print(f"\n[File {event_type}] {relative_path}")
|
|
376
|
+
print(f"\n[SoulSync] [File {event_type}] {relative_path}")
|
|
367
377
|
|
|
368
378
|
if event_type in ['modified', 'created']:
|
|
369
379
|
time.sleep(0.5)
|
|
370
380
|
|
|
371
381
|
try:
|
|
372
382
|
self.profile_sync.push_file(relative_path)
|
|
373
|
-
print(f"Upload completed: {relative_path}")
|
|
383
|
+
print(f"[SoulSync] Upload completed: {relative_path}")
|
|
374
384
|
except Exception as e:
|
|
375
|
-
print(f"Upload error: {e}")
|
|
385
|
+
print(f"[SoulSync] Upload error: {e}")
|
|
376
386
|
|
|
377
387
|
elif event_type == 'deleted':
|
|
378
|
-
print(f"File deleted (not synced to cloud): {relative_path}")
|
|
388
|
+
print(f"[SoulSync] File deleted (not synced to cloud): {relative_path}")
|
|
379
389
|
|
|
380
390
|
def on_websocket_message(self, data: dict):
|
|
381
391
|
"""WebSocket 消息回调"""
|
|
@@ -384,24 +394,24 @@ class SoulSyncPlugin:
|
|
|
384
394
|
if event == 'file_updated':
|
|
385
395
|
file_path = data.get('file_path')
|
|
386
396
|
version = data.get('version')
|
|
387
|
-
print(f"\n[WebSocket] File updated: {file_path} (v{version})")
|
|
397
|
+
print(f"\n[SoulSync] [WebSocket] File updated: {file_path} (v{version})")
|
|
388
398
|
try:
|
|
389
399
|
self.profile_sync.on_remote_change(file_path, version)
|
|
390
400
|
except Exception as e:
|
|
391
|
-
print(f"Sync error: {e}")
|
|
401
|
+
print(f"[SoulSync] Sync error: {e}")
|
|
392
402
|
|
|
393
403
|
elif event == 'new_memory':
|
|
394
|
-
print(f"\n[WebSocket] New memory available!")
|
|
404
|
+
print(f"\n[SoulSync] [WebSocket] New memory available!")
|
|
395
405
|
try:
|
|
396
406
|
self.profile_sync.pull_all()
|
|
397
|
-
print("Memory synced from remote")
|
|
407
|
+
print("[SoulSync] Memory synced from remote")
|
|
398
408
|
except Exception as e:
|
|
399
|
-
print(f"Sync error: {e}")
|
|
409
|
+
print(f"[SoulSync] Sync error: {e}")
|
|
400
410
|
|
|
401
411
|
elif data.get('type') == 'authenticated':
|
|
402
|
-
print(f"[WebSocket] Authenticated, socket_id: {data.get('socket_id')}")
|
|
412
|
+
print(f"[SoulSync] [WebSocket] Authenticated, socket_id: {data.get('socket_id')}")
|
|
403
413
|
elif data.get('type') == 'error':
|
|
404
|
-
print(f"[WebSocket] Error: {data.get('message')}")
|
|
414
|
+
print(f"[SoulSync] [WebSocket] Error: {data.get('message')}")
|
|
405
415
|
|
|
406
416
|
def run(self):
|
|
407
417
|
"""运行插件"""
|
|
@@ -413,17 +423,17 @@ class SoulSyncPlugin:
|
|
|
413
423
|
self.load_config()
|
|
414
424
|
self.initialize()
|
|
415
425
|
|
|
416
|
-
print("\n=== Plugin Running ===")
|
|
417
|
-
print("Press Ctrl+C to stop\n")
|
|
426
|
+
print("\n[SoulSync] === Plugin Running ===")
|
|
427
|
+
print("[SoulSync] Press Ctrl+C to stop\n")
|
|
418
428
|
|
|
419
429
|
while self.running:
|
|
420
430
|
time.sleep(1)
|
|
421
431
|
|
|
422
432
|
except KeyboardInterrupt:
|
|
423
|
-
print("\n
|
|
433
|
+
print("\n[SoulSync] Shutting down...")
|
|
424
434
|
self.shutdown()
|
|
425
435
|
except Exception as e:
|
|
426
|
-
print(f"\
|
|
436
|
+
print(f"\n[SoulSync] Error: {e}")
|
|
427
437
|
import traceback
|
|
428
438
|
traceback.print_exc()
|
|
429
439
|
self.shutdown()
|
|
@@ -431,24 +441,24 @@ class SoulSyncPlugin:
|
|
|
431
441
|
|
|
432
442
|
def shutdown(self):
|
|
433
443
|
"""关闭插件"""
|
|
434
|
-
print("Shutting down SoulSync plugin...")
|
|
444
|
+
print("[SoulSync] Shutting down SoulSync plugin...")
|
|
435
445
|
self.running = False
|
|
436
446
|
|
|
437
447
|
if self.watcher:
|
|
438
448
|
try:
|
|
439
449
|
self.watcher.stop()
|
|
440
|
-
print("File watcher stopped")
|
|
450
|
+
print("[SoulSync] File watcher stopped")
|
|
441
451
|
except Exception as e:
|
|
442
|
-
print(f"Error stopping watcher: {e}")
|
|
452
|
+
print(f"[SoulSync] Error stopping watcher: {e}")
|
|
443
453
|
|
|
444
454
|
if self.client:
|
|
445
455
|
try:
|
|
446
456
|
self.client.close()
|
|
447
|
-
print("Client connection closed")
|
|
457
|
+
print("[SoulSync] Client connection closed")
|
|
448
458
|
except Exception as e:
|
|
449
|
-
print(f"Error closing client: {e}")
|
|
459
|
+
print(f"[SoulSync] Error closing client: {e}")
|
|
450
460
|
|
|
451
|
-
print("Plugin shutdown complete")
|
|
461
|
+
print("[SoulSync] Plugin shutdown complete")
|
|
452
462
|
def main():
|
|
453
463
|
"""主函数"""
|
|
454
464
|
try:
|
|
@@ -463,12 +473,18 @@ def main():
|
|
|
463
473
|
if args.setup:
|
|
464
474
|
try:
|
|
465
475
|
plugin.load_config()
|
|
466
|
-
plugin.run_setup()
|
|
467
|
-
|
|
468
|
-
|
|
476
|
+
result = plugin.run_setup()
|
|
477
|
+
if result:
|
|
478
|
+
print("\n[SoulSync] ✓ Setup complete! Starting sync... / 设置完成!正在启动同步...")
|
|
479
|
+
print("\n[SoulSync] ========================================")
|
|
480
|
+
print("[SoulSync] Starting SoulSync sync service...")
|
|
481
|
+
print("[SoulSync] ========================================\n")
|
|
482
|
+
plugin.initialize()
|
|
483
|
+
plugin.run()
|
|
484
|
+
return
|
|
469
485
|
except KeyboardInterrupt:
|
|
470
486
|
print("\n[SoulSync] Cancelled by user. Goodbye! / 已取消,再见!")
|
|
471
|
-
sys.exit(
|
|
487
|
+
sys.exit(2)
|
|
472
488
|
|
|
473
489
|
plugin.load_config()
|
|
474
490
|
|