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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user