soulsync 1.0.9 → 1.0.11

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/main.py +162 -150
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soulsync",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "SoulSync plugin for OpenClaw - cross-bot memory synchronization",
5
5
  "main": "index.js",
6
6
  "repository": {
package/src/main.py CHANGED
@@ -67,16 +67,6 @@ class SoulSyncPlugin:
67
67
  self.config['cloud_url'] = 'https://soulsync.work'
68
68
  print("[SoulSync] Cloud URL not set, using default: https://soulsync.work")
69
69
 
70
- if not email or not password or email == 'your-email@example.com' or password == 'your-password':
71
- print("\n[SoulSync] ========================================")
72
- print("[SoulSync] Please configure your account first / 请先配置账号")
73
- print("[SoulSync] ========================================")
74
- print("[SoulSync] Edit config file / 编辑配置文件:")
75
- print(f" {config_path}")
76
- print("[SoulSync] Set your email and password, then restart / 填写邮箱和密码后重启")
77
- print("[SoulSync] ========================================\n")
78
- sys.exit(0)
79
-
80
70
  workspace = self.config.get('workspace', './workspace')
81
71
  if workspace.startswith('./'):
82
72
  workspace = workspace[2:]
@@ -116,151 +106,166 @@ class SoulSyncPlugin:
116
106
  print("[SoulSync] Auth info saved to config.json")
117
107
 
118
108
  def run_setup(self):
119
- """交互式设置:注册或登录"""
120
- print("\n[SoulSync] ========================================")
121
- print("[SoulSync] Welcome to SoulSync! / 欢迎使用 SoulSync!")
122
- print("[SoulSync] ========================================")
123
- print("[SoulSync] 1. Register / 注册")
124
- print("[SoulSync] 2. Login / 登录")
125
- print("[SoulSync] ========================================")
126
-
127
- choice = input("[SoulSync] Choose / 选择 (1/2): ").strip()
128
-
129
- if choice == '1':
130
- return self._interactive_register()
131
- elif choice == '2':
132
- return self._interactive_login()
133
- else:
134
- print("[SoulSync] Invalid choice / 无效选择")
135
- sys.exit(0)
109
+ """交互式设置:注册或登录(带循环)"""
110
+ while True:
111
+ print("\n[SoulSync] ========================================")
112
+ print("[SoulSync] Welcome to SoulSync! / 欢迎使用 SoulSync!")
113
+ print("[SoulSync] ========================================")
114
+ print("[SoulSync] 1. Register / 注册")
115
+ print("[SoulSync] 2. Login / 登录")
116
+ print("[SoulSync] 0. Exit / 退出")
117
+ print("[SoulSync] ========================================")
118
+
119
+ try:
120
+ choice = input("[SoulSync] Choose / 选择 (0/1/2): ").strip()
121
+ except KeyboardInterrupt:
122
+ print("\n[SoulSync] Cancelled by user. Goodbye! / 已取消,再见!")
123
+ sys.exit(0)
124
+
125
+ if choice == '1':
126
+ result = self._interactive_register()
127
+ if result:
128
+ return result
129
+ elif choice == '2':
130
+ result = self._interactive_login()
131
+ if result:
132
+ return result
133
+ elif choice == '0':
134
+ print("[SoulSync] Goodbye! / 再见!")
135
+ sys.exit(0)
136
+ else:
137
+ print("[SoulSync] Invalid choice / 无效选择")
136
138
 
137
139
  def _interactive_login(self):
138
- """交互式登录(带重试)"""
140
+ """交互式登录(失败返回 None,由主循环处理)"""
139
141
  from client import OpenClawClient
140
142
 
141
- max_retries = 5
142
- retry_count = 0
143
+ print("\n--- Login / 登录 ---")
143
144
 
144
- while retry_count < max_retries:
145
- print("\n--- Login / 登录 ---")
145
+ try:
146
146
  email = input("[SoulSync] Email / 邮箱: ").strip()
147
147
  if not email:
148
148
  print("[SoulSync] Email cannot be empty / 邮箱不能为空")
149
- continue
150
-
149
+ return None
150
+ except KeyboardInterrupt:
151
+ print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
152
+ return None
153
+
154
+ try:
151
155
  password = getpass.getpass("[SoulSync] Password / 密码: ")
152
156
  if not password:
153
157
  print("[SoulSync] Password cannot be empty / 密码不能为空")
154
- continue
158
+ return None
159
+ except KeyboardInterrupt:
160
+ print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
161
+ return None
162
+
163
+ try:
164
+ temp_client = OpenClawClient(self.config)
165
+ result = temp_client.authenticate(email, password)
166
+ if result:
167
+ print("\n[SoulSync] ✓ Login successful! / 登录成功!")
168
+ self._save_auth_to_config(result)
169
+ return True
170
+ except Exception as e:
171
+ error_msg = str(e)
155
172
 
156
- try:
157
- temp_client = OpenClawClient(self.config)
158
- result = temp_client.authenticate(email, password)
159
- if result:
160
- print("\n[SoulSync] ✓ Login successful! / 登录成功!")
161
- self._save_auth_to_config(result)
162
- return True
163
- except Exception as e:
164
- retry_count += 1
165
- remaining = max_retries - retry_count
166
- error_msg = str(e)
167
-
168
- if "429" in error_msg or "too many" in error_msg.lower():
169
- print(f"\n[SoulSync] ❌ {e}")
170
- print("\n[SoulSync] Too many failed attempts / 登录失败次数过多")
171
- print("[SoulSync] Exiting... / 退出...")
172
- sys.exit(0)
173
-
174
- if remaining > 0:
175
- print(f"\n[SoulSync] ❌ Login failed: {e} / 登录失败: {e}")
176
- print(f"[SoulSync] Remaining attempts / 剩余尝试次数: {remaining}")
177
- else:
178
- print(f"\n[SoulSync] ❌ Login failed: {e} / 登录失败: {e}")
173
+ if "429" in error_msg or "too many" in error_msg.lower():
174
+ print(f"\n[SoulSync] {e}")
175
+ print("\n[SoulSync] Too many failed attempts. Please try again later / 登录失败次数过多,请稍后再试")
176
+ print("[SoulSync] Exiting... / 退出...")
177
+ sys.exit(0)
178
+
179
+ print(f"\n[SoulSync] ❌ Login failed: {e} / 登录失败: {e}")
180
+ print("[SoulSync] Returning to menu... / 返回菜单...")
181
+ return None
179
182
 
180
- print("\n[SoulSync] ❌ Too many failed attempts. Please try again in 15 minutes. / 登录失败次数过多,请15分钟后再试")
181
- print("[SoulSync] Exiting... / 退出...")
182
- sys.exit(0)
183
+ print("[SoulSync] ❌ Login failed / 登录失败")
184
+ print("[SoulSync] Returning to menu... / 返回菜单...")
185
+ return None
183
186
 
184
187
  def _interactive_register(self):
185
- """交互式注册(带重试)"""
188
+ """交互式注册(失败返回 None)"""
186
189
  from client import OpenClawClient
187
190
 
188
- max_retries = 5
189
- retry_count = 0
191
+ print("\n--- Register / 注册 ---")
190
192
 
191
- while retry_count < max_retries:
192
- print("\n--- Register / 注册 ---")
193
+ try:
193
194
  email = input("[SoulSync] Email / 邮箱: ").strip()
194
195
  if not email or '@' not in email:
195
196
  print("[SoulSync] Invalid email / 无效邮箱")
196
- continue
197
+ return None
198
+ except KeyboardInterrupt:
199
+ print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
200
+ return None
201
+
202
+ password = None
203
+ while password is None:
204
+ try:
205
+ password = getpass.getpass("[SoulSync] Password / 密码: ")
206
+ if len(password) < 6:
207
+ print("[SoulSync] Password must be at least 6 characters / 密码至少6位")
208
+ password = None
209
+ continue
210
+ except KeyboardInterrupt:
211
+ print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
212
+ return None
197
213
 
198
- password = getpass.getpass("[SoulSync] Password / 密码: ")
199
- if len(password) < 6:
200
- print("[SoulSync] Password must be at least 6 characters / 密码至少6位")
201
- continue
214
+ try:
215
+ password2 = getpass.getpass("[SoulSync] Confirm password / 确认密码: ")
216
+ except KeyboardInterrupt:
217
+ print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
218
+ return None
202
219
 
203
- password2 = getpass.getpass("[SoulSync] Confirm password / 确认密码: ")
204
220
  if password != password2:
205
221
  print("[SoulSync] Passwords do not match / 两次密码不一致")
222
+ password = None
223
+
224
+ print(f"\n[SoulSync] Sending verification code to {email}...")
225
+ try:
226
+ temp_client = OpenClawClient(self.config)
227
+ temp_client.send_verification_code(email)
228
+ print("[SoulSync] ✓ Verification code sent! / 验证码已发送!")
229
+ except Exception as e:
230
+ print(f"[SoulSync] ❌ Failed to send code: {e}")
231
+ print("[SoulSync] Returning to menu... / 返回菜单...")
232
+ return None
233
+
234
+ code_success = False
235
+ code_retry = 0
236
+ max_code_retries = 3
237
+
238
+ while code_retry < max_code_retries and not code_success:
239
+ try:
240
+ code = input(f"[SoulSync] Enter code / 输入验证码 ({max_code_retries - code_retry} left): ").strip()
241
+ except KeyboardInterrupt:
242
+ print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
243
+ return None
244
+
245
+ if len(code) != 6 or not code.isdigit():
246
+ code_retry += 1
247
+ print("[SoulSync] Invalid code format / 验证码格式错误")
206
248
  continue
207
249
 
208
- print(f"\n[SoulSync] Sending verification code to {email}...")
209
250
  try:
210
- temp_client = OpenClawClient(self.config)
211
- temp_client.send_verification_code(email)
212
- print("[SoulSync] ✓ Verification code sent! / 验证码已发送!")
251
+ result = temp_client.register(email, password, code)
252
+ print("\n[SoulSync] ✓ Registration successful! / 注册成功!")
253
+ self._save_auth_to_config(result)
254
+ return True
213
255
  except Exception as e:
214
- print(f"[SoulSync] Failed to send code: {e}")
215
- continue
216
-
217
- code_retry = 0
218
- while code_retry < max_retries:
219
- code = input(f"[SoulSync] Enter code / 输入验证码 ({max_retries - code_retry} attempts left): ").strip()
220
- if len(code) != 6 or not code.isdigit():
221
- code_retry += 1
222
- print("[SoulSync] Invalid code format / 验证码格式错误")
223
- continue
224
-
225
- try:
226
- result = temp_client.register(email, password, code)
227
- print("\n[SoulSync] ✓ Registration successful! / 注册成功!")
228
- self._save_auth_to_config(result)
229
- return True
230
- except Exception as e:
231
- code_retry += 1
232
- remaining_code = max_retries - code_retry
233
- if "invalid" in str(e).lower() or "expired" in str(e).lower():
234
- if remaining_code > 0:
235
- print(f"[SoulSync] ❌ Invalid or expired code: {e}")
236
- print(f"[SoulSync] Remaining attempts / 剩余尝试: {remaining_code}")
237
- else:
238
- print("[SoulSync] ❌ Too many code attempts / 验证码错误次数过多")
239
- break
256
+ code_retry += 1
257
+ if "invalid" in str(e).lower() or "expired" in str(e).lower():
258
+ if code_retry < max_code_retries:
259
+ print(f"[SoulSync] Invalid or expired code: {e}")
260
+ print(f"[SoulSync] Remaining attempts / 剩余尝试: {max_code_retries - code_retry}")
240
261
  else:
241
- print(f"[SoulSync] ❌ Registration failed: {e}")
242
- break
243
-
244
- if code_retry >= max_retries:
245
- print("\n[SoulSync] Too many code verification failures.")
246
- print("[SoulSync] 1. Resend code / 重新发送验证码")
247
- print("[SoulSync] 2. Start over / 重新开始")
248
- print("[SoulSync] 3. Exit / 退出")
249
-
250
- sub_choice = input("[SoulSync] Choose / 选择 (1/2/3): ").strip()
251
- if sub_choice == '1':
252
- retry_count = 0
253
- continue
254
- elif sub_choice == '2':
255
- retry_count = 0
256
- break
262
+ print("[SoulSync] ❌ Too many code attempts / 验证码错误次数过多")
257
263
  else:
258
- print("[SoulSync] Exiting... / 退出...")
259
- sys.exit(0)
264
+ print(f"[SoulSync] Registration failed: {e}")
260
265
 
261
- print("\n[SoulSync] Too many registration attempts / 注册尝试次数过多")
262
- print("[SoulSync] Exiting... / 退出...")
263
- sys.exit(0)
266
+ print("\n[SoulSync] Too many code verification failures.")
267
+ print("[SoulSync] Returning to menu... / 返回菜单...")
268
+ return None
264
269
 
265
270
  def initialize(self):
266
271
  """初始化组件"""
@@ -446,34 +451,41 @@ class SoulSyncPlugin:
446
451
  print("Plugin shutdown complete")
447
452
  def main():
448
453
  """主函数"""
449
- parser = argparse.ArgumentParser(description='SoulSync Plugin')
450
- parser.add_argument('--setup', action='store_true', help='Run interactive setup (register/login)')
451
- parser.add_argument('--start', action='store_true', help='Start sync service (auto-login from config)')
452
-
453
- args = parser.parse_args()
454
-
455
- plugin = SoulSyncPlugin()
456
-
457
- if args.setup:
454
+ try:
455
+ parser = argparse.ArgumentParser(description='SoulSync Plugin')
456
+ parser.add_argument('--setup', action='store_true', help='Run interactive setup (register/login)')
457
+ parser.add_argument('--start', action='store_true', help='Start sync service (auto-login from config)')
458
+
459
+ args = parser.parse_args()
460
+
461
+ plugin = SoulSyncPlugin()
462
+
463
+ if args.setup:
464
+ try:
465
+ plugin.load_config()
466
+ plugin.run_setup()
467
+ print("\n[SoulSync] ✓ Setup complete! Run 'openclaw soulsync:start' to begin syncing.")
468
+ print("[SoulSync] 设置完成!运行 'openclaw soulsync:start' 开始同步。")
469
+ except KeyboardInterrupt:
470
+ print("\n[SoulSync] Cancelled by user. Goodbye! / 已取消,再见!")
471
+ sys.exit(0)
472
+
458
473
  plugin.load_config()
459
- plugin.run_setup()
460
- print("\n[SoulSync] Setup complete! Run 'openclaw soulsync:start' to begin syncing.")
461
- print("[SoulSync] 设置完成!运行 'openclaw soulsync:start' 开始同步。")
462
- sys.exit(0)
463
-
464
- plugin.load_config()
465
-
466
- email = plugin.config.get('email', '').strip()
467
- password = plugin.config.get('password', '').strip()
468
-
469
- if not email or not password:
470
- print("\n[SoulSync] ========================================")
471
- print("[SoulSync] Not configured. Run 'openclaw soulsync:setup' first.")
472
- print("[SoulSync] 尚未配置,请先运行 'openclaw soulsync:setup'")
473
- print("[SoulSync] ========================================\n")
474
+
475
+ email = plugin.config.get('email', '').strip()
476
+ password = plugin.config.get('password', '').strip()
477
+
478
+ if not email or not password:
479
+ print("\n[SoulSync] ========================================")
480
+ print("[SoulSync] Not configured. Run 'openclaw soulsync:setup' first.")
481
+ print("[SoulSync] 尚未配置,请先运行 'openclaw soulsync:setup'")
482
+ print("[SoulSync] ========================================\n")
483
+ sys.exit(0)
484
+
485
+ plugin.initialize()
486
+ plugin.run()
487
+ except KeyboardInterrupt:
488
+ print("\n[SoulSync] Cancelled by user. Goodbye! / 已取消,再见!")
474
489
  sys.exit(0)
475
-
476
- plugin.initialize()
477
- plugin.run()
478
490
  if __name__ == '__main__':
479
491
  main()