Add Wormhole auto-kill so Interface 5 can be claimed

Cable autorun holds IF5; kill on launch/connect and via GUI button/CLI.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
joyharam
2026-07-15 10:58:35 +09:00
parent 2035c0b4fe
commit d9c0b8078c
9 changed files with 398 additions and 6 deletions
+27
View File
@@ -17,6 +17,7 @@ from typing import Any, Optional
from .protocol import Session
from .usb_link import Juc500Link, list_devices, doctor
from .wormhole_kill import kill_wormhole_processes, wormhole_status
DEFAULT_GUI_PORT = 8765
@@ -68,6 +69,7 @@ class GuiState:
self.last_progress = {"done": 0, "total": 0, "label": "", "error": None, "busy": False}
self.connecting = False
self.log_lines: list[str] = []
self.auto_kill_wormhole = True
def log(self, msg: str) -> None:
self.log_lines.append(msg)
@@ -141,6 +143,13 @@ def connect_usb(timeout: float = 45.0) -> dict[str, Any]:
STATE.auto_status = "USB 링크 여는 중…"
try:
if STATE.auto_kill_wormhole:
STATE.auto_status = "공식 Wormhole 종료 중…"
STATE.log("공식 Wormhole 프로세스 종료 시도")
result = kill_wormhole_processes(force=True)
STATE.log(result.get("message") or "")
if result.get("killed"):
time.sleep(0.4)
devices = list_devices()
if not devices:
raise RuntimeError("JUC500(Smart Data Link) 장치가 없습니다. 케이블을 연결하세요.")
@@ -442,6 +451,7 @@ class Handler(BaseHTTPRequestHandler):
"pid": f"{cable.pid:04x}" if cable else None,
},
"usb_error": list_err,
"wormhole": wormhole_status(),
"inputshare": {
"supported": False,
"enabled": False,
@@ -456,6 +466,10 @@ class Handler(BaseHTTPRequestHandler):
self._json(200, doctor().to_dict())
return
if path == "/api/wormhole":
self._json(200, wormhole_status())
return
if path == "/api/settings/ports":
# Reuse settings modal: expose local_root / serial as "ports"-like rows
self._json(
@@ -548,6 +562,12 @@ class Handler(BaseHTTPRequestHandler):
self._json(200, {"ok": True})
return
if path in ("/api/wormhole/kill", "/api/wormhole/stop"):
result = kill_wormhole_processes(force=True)
STATE.log(result.get("message") or "wormhole kill")
self._json(200, result)
return
if path == "/api/auto/start":
self._json(200, {"ok": True})
return
@@ -644,6 +664,13 @@ def run_gui(open_browser: bool = True, port: int | None = None, host: str = "127
preferred = port or STATE.gui_port or DEFAULT_GUI_PORT
listen_port = _pick_port(host, preferred)
STATE.gui_port = listen_port
# Cable autorun Wormhole often starts with the volume — clear it on launch.
try:
result = kill_wormhole_processes(force=True)
if result.get("killed"):
print(result.get("message"))
except Exception as exc: # noqa: BLE001
print(f"Wormhole 자동 종료 건너뜀: {exc}")
server = ThreadingHTTPServer((host, listen_port), Handler)
url = f"http://{host}:{listen_port}/"
print(f"JUC500 GUI: {url}")