Files
hermes-agent/scripts/dump_desktop_slash_registry.py
teknium1 e06efbcff0 fix(ci): desktop slash-registry dump gets --check; apps/ contract JSON edits run the Python lane
scripts/dump_desktop_slash_registry.py --check exits 1 (no write) when the
committed apps/desktop/src/lib/desktop-slash-registry.json differs from
desktop_surface_registry(); the docstring now cites the test that actually
fails (test_desktop_slash_registry.py, not test_commands.py). The pytest
runs --check as a subprocess (green on the committed file) and calls
check() on a hand-edited copy (red).

scripts/ci/classify_changes.py: _PY_SKIP includes apps/, so an apps-only
edit of that JSON (or apps/shared/src/gateway-events.json) skipped the
Python lane and the only equality check never ran in CI. A table of
cross-language contract files now forces python:true; two classifier rows
pin it.
2026-09-13 06:50:57 -07:00

51 lines
1.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""Regenerate apps/desktop/src/lib/desktop-slash-registry.json from COMMAND_REGISTRY.
Run after changing any ``desktop=`` value or alias in ``hermes_cli/commands.py``;
``tests/hermes_cli/test_desktop_slash_registry.py`` fails until the committed
copy matches. ``--check`` writes nothing and exits 1 when the committed JSON
differs from what the registry renders (the same verdict the pytest gives,
usable from any shell or CI step without pytest).
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
OUT = ROOT / "apps" / "desktop" / "src" / "lib" / "desktop-slash-registry.json"
def render() -> str:
sys.path.insert(0, str(ROOT))
from hermes_cli.commands import desktop_surface_registry
return json.dumps(desktop_surface_registry(), indent=2, sort_keys=True) + "\n"
def check(out: Path = OUT) -> int:
"""0 when ``out`` matches the registry byte-for-byte, else 1 with a hint on stderr."""
committed = out.read_text(encoding="utf-8") if out.exists() else ""
if committed == render():
return 0
rel = out.relative_to(ROOT) if out.is_relative_to(ROOT) else out
print(f"{rel} is stale — run scripts/dump_desktop_slash_registry.py", file=sys.stderr)
return 1
def main(argv: list[str]) -> int:
if argv == ["--check"]:
return check()
if argv:
print(f"usage: {Path(__file__).name} [--check]", file=sys.stderr)
return 2
OUT.write_text(render(), encoding="utf-8")
print(f"wrote {OUT.relative_to(ROOT)}")
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))