feat: patch marker verification in updater

- is_patched() checks 3 key markers in cli.js
- --check shows patched status (yes/NO)
- cmd_update auto-re-patches if markers missing (e.g. npm update overwrote cli.js)
This commit is contained in:
delta-cloud-208e
2026-02-21 12:16:51 +00:00
parent c3f7c9ccf8
commit 5a46377d2a

View File

@@ -288,6 +288,27 @@ def ver_tuple(v):
return (int(m.group(1)), int(m.group(2)), int(m.group(3))) if m else (0, 0, 0)
# Markers left by the patcher in cli.js — if any is missing, cli.js is not patched
PATCH_MARKERS = [
"__CLAUDE_SETTINGS__",
"/*bypass_permissions_prompt*/",
"/* root check removed by patcher */",
]
def is_patched(cli_js_path):
"""Check if cli.js has patch markers. Returns (patched: bool, missing: list)."""
if not cli_js_path or not os.path.isfile(cli_js_path):
return False, PATCH_MARKERS[:]
try:
with open(cli_js_path, "r", encoding="utf-8", errors="ignore") as f:
content = f.read()
except Exception:
return False, PATCH_MARKERS[:]
missing = [m for m in PATCH_MARKERS if m not in content]
return len(missing) == 0, missing
# ============================================================
# Git pull
# ============================================================
@@ -664,9 +685,18 @@ def cmd_check():
print(f" {R}Cannot determine latest version. Run 'git pull' first.{D}")
return 1
patched, missing = is_patched(cli_js)
if patched:
print(f" Patched: {G}yes{D}")
else:
print(f" Patched: {R}NO{D} (missing {len(missing)} markers)")
if ver_tuple(latest) > ver_tuple(installed):
print(f" {Y}Update available: {installed}{latest}{D}")
return 0
elif not patched:
print(f" {Y}Version is current but patches are missing. Run without --check to fix.{D}")
return 0
else:
print(f" {G}Up to date.{D}")
return 0
@@ -699,8 +729,20 @@ def cmd_update(force=False, settings_only=False):
eprint(f" {R}Cannot determine latest version.{D}")
return 1
# Check if cli.js is actually patched (markers present)
patched, missing_markers = is_patched(cli_js)
if patched:
print(f" Patch status: {G}patched{D}")
elif cli_js:
print(f" Patch status: {R}NOT patched{D} (missing {len(missing_markers)} markers)")
needs_update = force or not installed or ver_tuple(latest) > ver_tuple(installed)
# Even if version matches, re-patch if markers are missing (e.g. npm update overwrote cli.js)
if not patched and cli_js and not needs_update:
print(f" {Y}Patches missing — cli.js was overwritten. Re-applying...{D}")
needs_update = True
if not needs_update and not settings_only:
print(f"\n {G}Already up to date.{D}")
# Still patch settings in case config changed