zhuyuan-ice-gl-zy001/ZCODE-DEV-20260830/zcode-zc001-legacy-thread-closeout-20260830/repair-projectless-thread-directory.py

68 lines
3.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import json
import os
import shutil
import stat
import tempfile
from pathlib import Path
THREAD_ID = "01a04eae-6afc-7733-be52-96ddaf6176a1"
STATE = Path("/Users/bingshuolingdianyuanhe/.codex/.codex-global-state.json")
ARTIFACT = Path("/Volumes/JZAO/铸渊-ICE-GL-ZY001/ZCODE-DEV-20260830/zcode-zc001-legacy-thread-closeout-20260830")
BACKUP = ARTIFACT / "codex-global-state.before-projectless-repair.json"
OLD_ROOT = "/Users/bingshuolingdianyuanhe/Documents/Codex"
OLD_OUTPUT = "/Users/bingshuolingdianyuanhe/Documents/Codex/2026-08-30/new-chat/outputs"
NEW_ROOT = "/Volumes/JZAO/冰朔-应用数据/Codex-文稿工作区"
NEW_OUTPUT = "/Volumes/JZAO/冰朔-应用数据/Codex-文稿工作区/2026-08-30/new-chat/outputs"
for path in (NEW_ROOT, NEW_OUTPUT):
if not os.path.isdir(path):
raise SystemExit(f"target is not a directory: {path}")
if os.path.realpath(path) != path:
raise SystemExit(f"target is not a canonical real path: {path} -> {os.path.realpath(path)}")
raw = STATE.read_text()
data = json.loads(raw)
electron = data.get("electron-persisted-atom-state", {})
roots_container = electron if "thread-workspace-root-hints" in electron else data
outputs_container = electron if "thread-projectless-output-directories" in electron else data
roots = roots_container["thread-workspace-root-hints"]
outputs = outputs_container["thread-projectless-output-directories"]
before = {"workspace_root": roots.get(THREAD_ID), "output_directory": outputs.get(THREAD_ID)}
if before == {"workspace_root": NEW_ROOT, "output_directory": NEW_OUTPUT}:
print(json.dumps({"outcome": "ALREADY_REPAIRED", "thread_id": THREAD_ID, "mapping": before}, ensure_ascii=False))
raise SystemExit(0)
if before != {"workspace_root": OLD_ROOT, "output_directory": OLD_OUTPUT}:
raise SystemExit(f"unexpected mapping; refusing overwrite: {before!r}")
ARTIFACT.mkdir(parents=True, exist_ok=True)
if not BACKUP.exists():
shutil.copy2(STATE, BACKUP)
roots[THREAD_ID] = NEW_ROOT
outputs[THREAD_ID] = NEW_OUTPUT
mode = stat.S_IMODE(STATE.stat().st_mode)
fd, temp_name = tempfile.mkstemp(prefix=".codex-global-state.projectless-repair-", dir=STATE.parent)
try:
with os.fdopen(fd, "w") as stream:
json.dump(data, stream, ensure_ascii=False, separators=(",", ":"))
stream.flush()
os.fsync(stream.fileno())
os.chmod(temp_name, mode)
os.replace(temp_name, STATE)
finally:
if os.path.exists(temp_name):
os.unlink(temp_name)
check = json.loads(STATE.read_text())
check_electron = check.get("electron-persisted-atom-state", {})
check_roots = check_electron if "thread-workspace-root-hints" in check_electron else check
check_outputs = check_electron if "thread-projectless-output-directories" in check_electron else check
after = {
"workspace_root": check_roots["thread-workspace-root-hints"].get(THREAD_ID),
"output_directory": check_outputs["thread-projectless-output-directories"].get(THREAD_ID),
}
print(json.dumps({"outcome": "REPAIRED", "thread_id": THREAD_ID, "before": before, "after": after, "backup": str(BACKUP)}, ensure_ascii=False, indent=2))