node/cli.py
node/cli.pyBrowse 18 files
1,073 tokens
4,196 bytes
Token encoding: o200k_base
Snapshot 24fd22b
← Back to SKILL.md
1"""`hermes meet node ...` subcommand tree, wired under the ``hermes meet`` parser."""2 3from __future__ import annotations4 5import argparse6import asyncio7import json8import sys9 10from plugins.google_meet.node.client import NodeClient11from plugins.google_meet.node.registry import NodeRegistry12from plugins.google_meet.node.server import NodeServer13 14 15def register_cli(subparser: argparse.ArgumentParser) -> None:16 """Add ``run / list / approve / remove / status / ping`` subparsers to the ``node`` parser."""17 sp = subparser.add_subparsers(dest="node_cmd", required=True)18 run = sp.add_parser("run", help="Start a node server on this machine.")19 run.add_argument("--host", default="0.0.0.0")20 run.add_argument("--port", type=int, default=18789)21 run.add_argument("--display-name", default="hermes-meet-node")22 sp.add_parser("list", help="List approved remote nodes.")23 app = sp.add_parser("approve", help="Register a remote node on the gateway.")24 for arg in ("name", "url", "token"):25 app.add_argument(arg)26 for name, help_ in (("remove", "Forget a registered node."), ("status", "Ping a registered node."),27 ("ping", "Alias for status.")):28 sp.add_parser(name, help=help_).add_argument("name")29 for p in sp.choices.values():30 p.set_defaults(func=node_command)31 32 33def _cmd_run(args: argparse.Namespace, reg: NodeRegistry) -> int:34 server = NodeServer(host=args.host, port=args.port, display_name=args.display_name)35 token = server.ensure_token()36 print(f"[meet-node] display_name={server.display_name}\n"37 f"[meet-node] listening on ws://{args.host}:{args.port}\n"38 f"[meet-node] token (copy to gateway): {token}\n[meet-node] approve with:\n"39 f" hermes meet node approve <name> ws://<host>:{args.port} {token}")40 try:41 asyncio.run(server.serve())42 except KeyboardInterrupt:43 pass44 except RuntimeError as exc:45 print(f"[meet-node] error: {exc}", file=sys.stderr)46 return 247 return 048 49 50def _cmd_list(args: argparse.Namespace, reg: NodeRegistry) -> int:51 nodes = reg.list_all()52 if not nodes:53 print("no nodes registered")54 for n in nodes:55 print(f"{n['name']}\t{n['url']}\ttoken={n['token'][:6]}…")56 return 057 58 59def _cmd_approve(args: argparse.Namespace, reg: NodeRegistry) -> int:60 reg.add(args.name, args.url, args.token)61 print(f"approved node {args.name!r} at {args.url}")62 return 063 64 65def _cmd_remove(args: argparse.Namespace, reg: NodeRegistry) -> int:66 ok = reg.remove(args.name)67 print(f"removed {args.name!r}" if ok else f"no such node: {args.name!r}")68 return 0 if ok else 169 70 71def _cmd_ping(args: argparse.Namespace, reg: NodeRegistry) -> int:72 entry = reg.get(args.name)73 if entry is None:74 print(f"no such node: {args.name!r}", file=sys.stderr)75 return 176 try:77 result = NodeClient(entry["url"], entry["token"]).ping()78 except Exception as exc: # noqa: BLE001 — surface any connection error79 print(json.dumps({"ok": False, "error": str(exc)}))80 return 181 print(json.dumps({"ok": True, "node": args.name, **result}))82 return 083 84 85_COMMANDS = {86 "run": _cmd_run,87 "list": _cmd_list,88 "approve": _cmd_approve,89 "remove": _cmd_remove,90 "status": _cmd_ping,91 "ping": _cmd_ping}92 93 94def node_command(args: argparse.Namespace) -> int:95 """Dispatch for ``hermes meet node ...``; returns a process exit code."""96 cmd = getattr(args, "node_cmd", None)97 handler = _COMMANDS.get(cmd or "")98 if handler is None:99 print(f"unknown node command: {cmd!r}", file=sys.stderr)100 return 2101 # ``run`` never touches the registry; constructing it is side-effect free.102 return handler(args, NodeRegistry())103 104 105# ---- BEGIN PLUGIN-COMPAT (revert-scheduled; see COMPAT_MANIFEST.md) ----106# Names external plugins imported from this module before the Sep 2026 decomposition.107# Internal code MUST NOT use these (scripts/check_compat_pointers.py fails CI if it does).108# The whole block is removed by reverting the commit that added it.109from typing import Any # noqa: F401,E402110# ---- END PLUGIN-COMPAT ----111