#!/usr/bin/env python3 """Install or verify a vendored, harness-neutral coordinator.""" from __future__ import annotations import argparse import json import os from pathlib import Path import re import secrets import shlex import stat import sys from typing import Any HERE = Path(__file__).resolve().parent CORE_FILES = ( ".gitignore", "AGENTS.md", "CLAUDE.md", "DESIGN.md", "README.md", "VERSION", "coord", "hook.py", "install", "session.py", "store.py", "workspace.py", ) EXECUTABLES = {"coord", "install"} SKILL_FILES = ( "SKILL.md", "agents/openai.yaml", ) PROJECT_ID_RE = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]{0,127}") VERSION_RE = re.compile( r"(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)" ) CLAUDE_COMMANDS = { "SessionStart": ('python3 "$CLAUDE_PROJECT_DIR/.coord/session.py"', 10), "SessionEnd": ('python3 "$CLAUDE_PROJECT_DIR/.coord/session.py"', 5), "PreToolUse": ('python3 "$CLAUDE_PROJECT_DIR/.coord/hook.py"', 10), } CODEX_DISCOVERY = ( 'root="$PWD"; while [ "$root" != / ] && [ ! -f ' '"$root/.coord/{name}.py" ]; do root="${{root%/*}}"; ' '[ -n "$root" ] || root=/; done; ' '[ -f "$root/.coord/{name}.py" ] || exit 0; ' 'python3 "$root/.coord/{name}.py"' ) def legacy_wrapper(name: str) -> str: if name == "coord": return """#!/usr/bin/env python3 import os from pathlib import Path import sys target = Path(__file__).resolve().parents[2] / ".coord" / "coord" os.execv(str(target), [str(target), *sys.argv[1:]]) """ if name in {"hook.py", "session.py"}: return f"""#!/usr/bin/env python3 from pathlib import Path import runpy target = Path(__file__).resolve().parents[2] / ".coord" / "{name}" runpy.run_path(str(target), run_name="__main__") """ if name in {"store.py", "workspace.py"}: module = f"_coord_{name.removesuffix('.py')}_compat" return f"""from importlib.util import module_from_spec, spec_from_file_location from pathlib import Path import sys target = Path(__file__).resolve().parents[2] / ".coord" / "{name}" spec = spec_from_file_location("{module}", target) assert spec is not None and spec.loader is not None implementation = module_from_spec(spec) sys.modules[spec.name] = implementation spec.loader.exec_module(implementation) globals().update({{ key: value for key, value in vars(implementation).items() if key not in {{"__name__", "__loader__", "__package__", "__spec__"}} }}) """ raise ValueError(f"unsupported compatibility wrapper: {name}") def read_json(path: Path) -> dict[str, Any]: if not path.exists(): return {} try: value = json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError) as exc: raise ValueError(f"refusing invalid JSON at {path}: {exc}") from exc if not isinstance(value, dict): raise ValueError(f"refusing non-object JSON at {path}") return value def is_coord_hook(item: object) -> bool: if not isinstance(item, dict) or not isinstance(item.get("command"), str): return False command = item["command"] return any( endpoint in command for endpoint in ( ".coord/hook.py", ".coord/session.py", ".claude/coord/hook.py", ".claude/coord/session.py", ) ) def merged_hooks( current: dict[str, Any], desired: dict[str, tuple[str, int]] ) -> dict[str, Any]: result = json.loads(json.dumps(current)) hooks = result.setdefault("hooks", {}) if not isinstance(hooks, dict): raise ValueError("refusing hook configuration whose 'hooks' value is not an object") for event, (command, timeout) in desired.items(): existing = hooks.get(event, []) if not isinstance(existing, list): raise ValueError(f"refusing hook event {event!r} whose value is not a list") retained = [] for group in existing: if not isinstance(group, dict): retained.append(group) continue entries = group.get("hooks") if not isinstance(entries, list): retained.append(group) continue kept_entries = [entry for entry in entries if not is_coord_hook(entry)] if kept_entries: kept_group = dict(group) kept_group["hooks"] = kept_entries retained.append(kept_group) installed: dict[str, Any] = { "hooks": [{"type": "command", "command": command, "timeout": timeout}] } if event == "PreToolUse": installed["matcher"] = ".*" retained.append(installed) hooks[event] = retained return result def codex_hooks(current: dict[str, Any]) -> dict[str, Any]: desired = { event: ( CODEX_DISCOVERY.format( name="hook" if event == "PreToolUse" else "session" ), timeout, ) for event, (_command, timeout) in CLAUDE_COMMANDS.items() } return merged_hooks(current, desired) def write_if_changed( path: Path, content: bytes, *, executable: bool = False, check: bool, drift: list[str], ) -> None: observed = path.read_bytes() if path.is_file() else None expected_mode = 0o755 if executable else 0o644 observed_executable = path.is_file() and bool( stat.S_IMODE(path.stat().st_mode) & stat.S_IXUSR ) mode_ok = path.is_file() and observed_executable == executable if observed == content and mode_ok: return drift.append(str(path)) if check: return path.parent.mkdir(parents=True, exist_ok=True) temporary = path.with_name(f".{path.name}.coord-new-{secrets.token_hex(6)}") fd = os.open(temporary, os.O_WRONLY | os.O_CREAT | os.O_EXCL, expected_mode) try: remaining = memoryview(content) while remaining: written = os.write(fd, remaining) if written <= 0: raise OSError(f"short write while creating {temporary}") remaining = remaining[written:] os.fsync(fd) finally: os.close(fd) os.replace(temporary, path) os.chmod(path, expected_mode) def project_id(target: Path, requested: str, *, check: bool) -> str: canonical = target / ".coord" / "project-id" legacy = target / ".claude" / "coord" / "project-id" existing = [] for path in (canonical, legacy): if path.is_file(): existing.append((path, path.read_text(encoding="utf-8").strip())) values = {value for _path, value in existing} if len(values) > 1: detail = ", ".join(f"{path}={value!r}" for path, value in existing) raise ValueError(f"refusing ambiguous existing project IDs: {detail}") selected = next(iter(values), "") if requested and selected and requested != selected: raise ValueError( f"refusing project ID change from {selected!r} to {requested!r}" ) selected = selected or requested if not selected: if check: raise ValueError("installation has no project ID") raise ValueError("new installation requires --project-id") if not PROJECT_ID_RE.fullmatch(selected) or ".." in selected: raise ValueError("project ID must be one safe immutable slug") return selected def source_version() -> str: try: version = (HERE / "VERSION").read_text(encoding="utf-8").strip() except OSError as exc: raise ValueError(f"cannot read source VERSION: {exc}") from exc if not VERSION_RE.fullmatch(version): raise ValueError(f"refusing invalid source VERSION: {version!r}") return version def installed_version(target: Path) -> str: marker = target / ".coord" / "VERSION" if not marker.is_file(): return "unversioned" try: version = marker.read_text(encoding="utf-8").strip() except OSError: return "unreadable" return version if VERSION_RE.fullmatch(version) else "invalid" def install(target: Path, *, requested_id: str, check: bool) -> list[str]: target = target.expanduser().resolve() if not target.is_dir(): raise ValueError(f"target is not a directory: {target}") source_version() selected_id = project_id(target, requested_id, check=check) destination = target / ".coord" planned: list[tuple[Path, bytes, bool]] = [] for name in CORE_FILES: planned.append( ( destination / name, (HERE / name).read_bytes(), name in EXECUTABLES, ) ) for root in ( ".coord/skills/coord", ".agents/skills/coord", ".claude/skills/coord", ): for name in SKILL_FILES: planned.append( ( target / root / name, (HERE / "skills" / "coord" / name).read_bytes(), False, ) ) planned.append( (destination / "project-id", f"{selected_id}\n".encode(), False) ) legacy = target / ".claude" / "coord" for name in ("coord", "hook.py", "session.py", "store.py", "workspace.py"): planned.append( (legacy / name, legacy_wrapper(name).encode(), name == "coord") ) planned.extend( ( (legacy / "project-id", f"{selected_id}\n".encode(), False), ( legacy / "DESIGN.md", b"Canonical design: [`../../.coord/DESIGN.md`](../../.coord/DESIGN.md).\n", False, ), (legacy / ".gitignore", b"state/\n__pycache__/\n", False), ) ) settings = target / ".claude" / "settings.json" expected_claude = ( json.dumps( merged_hooks(read_json(settings), CLAUDE_COMMANDS), indent=2, sort_keys=True, ) + "\n" ).encode() codex = target / ".codex" / "hooks.json" expected_codex = ( json.dumps(codex_hooks(read_json(codex)), indent=2, sort_keys=True) + "\n" ).encode() planned.extend( ( (settings, expected_claude, False), (codex, expected_codex, False), ) ) # All source reads, identity checks, wrapper generation and hook JSON # validation complete before the first target replacement. drift: list[str] = [] for path, content, executable in planned: write_if_changed( path, content, executable=executable, check=check, drift=drift, ) return drift def main() -> int: try: release = source_version() except ValueError as exc: print(f"coord-install: {exc}", file=sys.stderr) return 2 parser = argparse.ArgumentParser(prog="coord-install") parser.add_argument("target", nargs="?", default=".") parser.add_argument("--project-id", default="") mode = parser.add_mutually_exclusive_group() mode.add_argument("--check", action="store_true", help="check for drift") mode.add_argument( "--doctor", action="store_true", help="diagnose installation version and drift without changing files", ) mode.add_argument( "--repair", action="store_true", help="repair managed files and hooks while preserving unrelated content", ) parser.add_argument( "--version", action="version", version=f"coord-install {release}" ) args = parser.parse_args() target = Path(args.target).expanduser().resolve() observed_version = installed_version(target) try: drift = install( target, requested_id=args.project_id, check=args.check or args.doctor, ) except ValueError as exc: print(f"coord-install: {exc}", file=sys.stderr) return 2 if args.check or args.doctor: if args.doctor: print(f"coord-install: source version {release}") print(f"coord-install: installed version {observed_version}") if drift: print(f"coord-install: drift ({len(drift)} files)") for path in drift: print(f" {path}") if args.doctor: command = " ".join( shlex.quote(value) for value in (str(HERE / "install"), str(target), "--repair") ) print(f"coord-install: repair with: {command}") return 1 print(f"coord-install: installation matches {release}") return 0 if args.repair and drift: action = "repaired" elif drift: action = "updated" else: action = "already current" print(f"coord-install: {action} {release}") print(f"target {target}") return 0 if __name__ == "__main__": raise SystemExit(main())