#!/usr/bin/env python3 import os import sys import platform import stat import json from pathlib import Path def setup(): print(f"[ai-log] Detecting OS: {platform.system()}") is_windows = platform.system() == "Windows" # UNIVERSAL POLYGLOT COMMAND: Works on Linux (Bash), Windows CMD, and PowerShell. # Uses sys.executable to always pick the correct Python binary. # Uses subprocess.run() directly (no os.system shell overhead). # Uses subprocess.DEVNULL for cross-platform stderr suppression # (avoids 2>nul which creates junk files on Linux, and 2>/dev/null which fails on CMD). # Tries python3 first (Linux default), falls back to python (Windows default). def get_universal_cmd(tool): logic = "import sys,subprocess;subprocess.run([sys.executable,'scripts/log_hook.py','--tool','" + tool + "'],stderr=subprocess.DEVNULL)" return 'python3 -c "' + logic + '" || python -c "' + logic + '"' # 1. Setup Git Pre-push Hook if Path(".git").exists(): python_cmd = "python" if is_windows else "python3" hook_path = Path(".git/hooks/pre-push") hook_path.parent.mkdir(parents=True, exist_ok=True) hook_content = f"#!/bin/sh\n{python_cmd} scripts/submit_log.py\nexit 0\n" with open(hook_path, "w", newline="\n") as f: f.write(hook_content) if not is_windows: os.chmod(hook_path, os.stat(hook_path).st_mode | stat.S_IEXEC) print(f"[ai-log] Git pre-push hook installed.") # 2. Update Tool Configs with OS-Specific Command def recursive_fix(obj, tool_name): if isinstance(obj, dict): for k, v in obj.items(): if k == "command" and isinstance(v, str) and ("log_hook.py" in v): obj[k] = get_universal_cmd(tool_name) else: recursive_fix(v, tool_name) elif isinstance(obj, list): for item in obj: recursive_fix(item, tool_name) configs = { ".codex/hooks.json": "codex", ".gemini/settings.json": "gemini", ".cursor/hooks.json": "cursor", ".claude/settings.json": "claude", ".github/hooks/hooks.json": "copilot" } for path_str, tool in configs.items(): path = Path(path_str) if not path.exists(): continue try: with open(path, "r", encoding="utf-8") as f: data = json.load(f) # Special case for Copilot which has bash/powershell keys if tool == "copilot" and "hooks" in data: for k in data["hooks"]: for h in data["hooks"][k]: if h.get("type") == "command": h["bash"] = f"python3 scripts/log_hook.py" h["powershell"] = f"python scripts/log_hook.py" else: recursive_fix(data, tool) with open(path, "w", newline="\n", encoding="utf-8") as f: json.dump(data, f, indent=2) print(f"[ai-log] Synchronized {path} (Universal Command)") except Exception as e: print(f"[ai-log] Failed to update {path}: {e}") # 3. Create .ai-log directory log_dir = Path(".ai-log") log_dir.mkdir(exist_ok=True) (log_dir / ".gitkeep").touch() print("[ai-log] Setup complete. Repository is now cross-platform and git-safe.") if __name__ == "__main__": setup()