#!/usr/bin/env python3 """Serve a sitrep-panel report directory on a free localhost port. Usage: python3 serve.py [preferred_port] Prints exactly one line to stdout on success: `SERVING http://localhost:/` then blocks, running the HTTP server — launch this with the caller's background/detached mechanism (e.g. Claude Code's Bash tool with run_in_background: true). Stdlib only, no dependencies. """ from __future__ import annotations import functools import http.server import sys class QuietHandler(http.server.SimpleHTTPRequestHandler): """SimpleHTTPRequestHandler that suppresses per-request access logging, so stdout stays to the one clean SERVING line callers parse.""" def log_message(self, format: str, *args: object) -> None: # noqa: A002 pass def main() -> None: if len(sys.argv) < 2: print("usage: serve.py [preferred_port]", file=sys.stderr) sys.exit(1) directory = sys.argv[1] preferred_port = int(sys.argv[2]) if len(sys.argv) > 2 else 8934 handler = functools.partial(QuietHandler, directory=directory) try: httpd = http.server.ThreadingHTTPServer(("127.0.0.1", preferred_port), handler) except OSError: # Preferred port is taken — let the OS assign a free one rather than # guessing and racing another process for it. httpd = http.server.ThreadingHTTPServer(("127.0.0.1", 0), handler) port = httpd.server_address[1] print(f"SERVING http://localhost:{port}/", flush=True) httpd.serve_forever() if __name__ == "__main__": main()