remote-claude 1.0.5 → 1.0.6

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.
@@ -15,7 +15,6 @@ import time
15
15
  import urllib.request
16
16
  import urllib.parse
17
17
  import urllib.error
18
- import webbrowser
19
18
  from pathlib import Path
20
19
 
21
20
  # 将项目根目录加入 sys.path
@@ -223,12 +222,9 @@ def create_app_via_scan(brand: str = "feishu") -> tuple[str, str]:
223
222
  print(f"\n {CYAN}请在浏览器中打开以下链接,扫码创建应用:{RESET}")
224
223
  print(f"\n {BOLD}{reg['verification_url']}{RESET}\n")
225
224
 
226
- # 尝试自动打开浏览器
227
- try:
228
- webbrowser.open(reg["verification_url"])
225
+ # 尝试自动打开浏览器(纯命令行环境跳过,避免文字浏览器接管终端)
226
+ if _open_browser(reg["verification_url"]):
229
227
  _info("已尝试自动在浏览器中打开(如未打开请手动复制上方链接)")
230
- except Exception:
231
- pass
232
228
 
233
229
  # 尝试显示终端二维码
234
230
  _try_print_qrcode(reg["verification_url"])
@@ -265,6 +261,43 @@ def create_app_via_scan(brand: str = "feishu") -> tuple[str, str]:
265
261
  return app_id, app_secret
266
262
 
267
263
 
264
+ def _has_gui() -> bool:
265
+ """
266
+ 判断当前环境是否有 GUI 可用(能安全调用系统 open/xdg-open)。
267
+
268
+ - macOS:用 `open` 命令,始终非阻塞,安全。
269
+ - Linux:需要 DISPLAY 或 WAYLAND_DISPLAY 环境变量,否则 webbrowser
270
+ 会找到 lynx/w3m/elinks 等文字浏览器并接管终端。
271
+ - 其他:保守返回 False。
272
+ """
273
+ import platform
274
+ if platform.system() == "Darwin":
275
+ return True
276
+ if platform.system() == "Linux":
277
+ return bool(os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"))
278
+ return False
279
+
280
+
281
+ def _open_browser(url: str) -> bool:
282
+ """
283
+ 安全地打开浏览器。仅在有 GUI 环境时才尝试,避免文字浏览器接管终端。
284
+
285
+ 返回 True 表示已触发打开,False 表示跳过。
286
+ """
287
+ if not _has_gui():
288
+ return False
289
+ try:
290
+ import subprocess
291
+ import platform
292
+ if platform.system() == "Darwin":
293
+ subprocess.Popen(["open", url], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
294
+ else:
295
+ subprocess.Popen(["xdg-open", url], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
296
+ return True
297
+ except Exception:
298
+ return False
299
+
300
+
268
301
  def _try_print_qrcode(url: str):
269
302
  """尝试在终端打印二维码(需要 qrcode 库)。"""
270
303
  try:
@@ -374,11 +407,8 @@ def authorize_tenant_scopes(app_id: str, brand: str = "feishu") -> None:
374
407
  print(f" {DIM}(页面加载后,点击「全选」,再点击「确认开通权限」){RESET}")
375
408
  print(f"\n {BOLD}{url}{RESET}\n")
376
409
 
377
- try:
378
- webbrowser.open(url)
410
+ if _open_browser(url):
379
411
  _info("已尝试自动在浏览器中打开")
380
- except Exception:
381
- pass
382
412
 
383
413
  _try_print_qrcode(url)
384
414
 
@@ -502,11 +532,8 @@ def authorize_app_scopes(app_id: str, app_secret: str,
502
532
  print(f" {DIM}(页面中的权限已自动预选,直接点击确认即可){RESET}")
503
533
  print(f"\n {BOLD}{auth['verification_url']}{RESET}\n")
504
534
 
505
- try:
506
- webbrowser.open(auth["verification_url"])
535
+ if _open_browser(auth["verification_url"]):
507
536
  _info("已尝试自动在浏览器中打开")
508
- except Exception:
509
- pass
510
537
 
511
538
  _try_print_qrcode(auth["verification_url"])
512
539
 
@@ -932,10 +959,7 @@ class SetupWizard:
932
959
  publish_url = f"https://open.feishu.cn/app/{app_id}/version/create"
933
960
  print(f" {DIM}未发布的应用无法被飞书用户搜索和使用。{RESET}")
934
961
  print(f" 正在打开发布页面:{CYAN}{publish_url}{RESET}\n")
935
- try:
936
- webbrowser.open(publish_url)
937
- except Exception:
938
- pass
962
+ _open_browser(publish_url)
939
963
 
940
964
  print(f" 请在浏览器中按以下步骤操作:")
941
965
  print(f" 1. 填写版本号")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remote-claude",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "双端共享 Claude CLI 工具",
5
5
  "bin": {
6
6
  "remote-claude": "bin/remote-claude",