#!/usr/bin/env python3
"""fed-tools — the MGF Family tools launcher.

Scope: the installable `mgf-*` tools. The Magogi Foundation has TWO families; the
Sooth Family keeps repo-local scripts in sooth-standard/tools/ (entrypoint:
tools/validate.sh) and is deliberately NOT listed here — the MGF -> Sooth edge is
one-directional and by-reference (sooth SEC-06/PKG-01), so MGF owns the mechanism
and Sooth owns its usage. See TOOLS_STARTHERE.md "Sooth Family tools".

  fed-tools list             list every MGF tool (▶ = running, ● = installed)
  fed-tools run <web-tool>   install (if needed) + launch a web console
  fed-tools run <t> --show   print the commands instead of running
  fed-tools show <tool>      print any tool's install + run commands
  fed-tools update [tool]    update installed web console(s) to the latest
  fed-tools update --check   only detect what's outdated (exit 1 if any)
  fed-tools install          put `fed-tools` on your PATH (~/.local/bin)
  fed-tools doctor           check the registry against the fleet (exit 1 on drift)

Installs with uv when present (the MGF venvs are uv-managed and have no pip),
else falls back to `python -m pip`. Stdlib-only — running THIS needs nothing
installed. See TOOLS_STARTHERE.md (same directory) for the full written
reference. Web tools are runnable today; the CLI tools are listed with their
install + example so you can run them too.
"""
from __future__ import annotations

import argparse
import os
import re
import shutil
import socket
import subprocess
import sys
import threading
import urllib.error
import urllib.request
import webbrowser

DEVPI = "https://195.15.203.250.sslip.io/magogi/prod/+simple/"
SRC_DEST = os.path.expanduser("~/.cache/mgf-fed-tools/mgf-cloud-web")


def _color() -> bool:
    return sys.stdout.isatty() and not os.environ.get("NO_COLOR")


_ON = _color()


def _c(code: str) -> str:
    return code if _ON else ""


BOLD, DIM, RED, GRN, YEL, CYN, RST = (
    _c("\033[1m"), _c("\033[2m"), _c("\033[31m"),
    _c("\033[32m"), _c("\033[33m"), _c("\033[36m"), _c("\033[0m"),
)

# --- the tool registry (install/run verified against the repos) -----------------
WEB = {
    "cloud-web": {
        "pkg": "mgf-cloud-web", "console": "mgf-cloud-web", "port": 8787,
        "title": "Cloud console",
        "desc": "Web GUI over mgf-cloud — create + manage Infomaniak/OpenStack VMs, volumes, storage.",
        "source": "https://codeberg.org/magogi-admin/mgf-cloud-web.git",  # off devpi
        "aliases": ("cloud", "cw"),
    },
    "fed-web": {
        "pkg": "mgf-fed-web", "console": "mgf-fed-web", "port": 8788,
        "title": "Federation dashboard (review web)",
        "desc": "Read-mostly cockpit: status, roadmap, in-progress, feedback/review rounds, live activity.",
        "aliases": ("fed", "dashboard", "review", "fw"),
    },
    "test-web": {
        "pkg": "mgf-test-web[web]", "console": "proofwarden", "port": 8789,
        "title": "Test & CI authority console (ProofWarden)",
        "desc": "Single-flight test authority — a test can never run twice at once, whatever the launcher.",
        "aliases": ("proofwarden", "warden", "test", "tw"),
    },
}

# (name, description, example command, pip target)
CLI = [
    ("mgf-fed", "Federation orchestrator (gates, releases, scaffold, registry)", "mgf-fed status", "mgf-fed[cli]"),
    ("mgf-secrets", "Credential plane — registry, doctor, encrypted store, exec", "mgf-secrets list", "mgf-secrets"),
    ("fedres", "fed-resources spine + the freshness gate", "fedres check", "mgf-fedres"),
    ("mtest", "Test supervisor — drives pytest, resumable", "mtest --self-check", "mgf-test-supervisor"),
    ("testctl", "Warden CLI — single-flight test runs", "testctl status", "mgf-test-web"),
    ("mgf-cloud", "Cloud resources — VMs, volumes, object storage", "mgf-cloud vm list", "mgf-cloud[infomaniak]"),
    ("mgf-cloud-provision", "Provision self-hosted infra (devpi, CI, Vault)", "mgf-cloud-provision -h", "mgf-cloud-provision[infomaniak]"),
    ("mgf-apiprobe", "REST API verification — typed probes + findings", "apiprobe --help", "mgf-apiprobe[openapi]"),
    ("mgf-hrb", "Hardware resource broker (PCIe, …)", "mgf-hrb info", "mgf-hrb"),
]

# Console scripts the fleet declares that deliberately do NOT get a front-door row,
# each with the reason. `doctor` pages on anything discovered that is in neither
# CLI, WEB, nor here — so a new tool cannot enter the fleet unlisted and unnoticed.
CLI_EXEMPT = {
    "apiprobe": "short alias of mgf-apiprobe",
    "fedres-validate": "helper entry point of mgf-fedres (fedres is the front door)",
    "mgf-test-supervisor": "long-form alias of mtest",
}


def resolve(name: str) -> str | None:
    name = name.lower()
    if name in WEB:
        return name
    return next((k for k, t in WEB.items() if name in t["aliases"]), None)


def install_steps(t: dict) -> list[tuple[str, str]]:
    if "source" in t:
        # the package is off devpi, but its deps (mgf-cloud, …) resolve from devpi
        return [("clone (this one is off devpi)", f"git clone {t['source']} {SRC_DEST}"),
                ("install", f"uv tool install {SRC_DEST} --default-index {DEVPI}")]
    return [("install", f'uv tool install "{t["pkg"]}" --default-index {DEVPI}')]


def _have(console: str) -> bool:
    return shutil.which(console) is not None


def _running(port: int) -> bool:
    """True if something is listening on 127.0.0.1:<port> — i.e. a launched console."""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.settimeout(0.25)
        return s.connect_ex(("127.0.0.1", port)) == 0


def _dist(t: dict) -> str:
    """The distribution name (pkg without any [extras])."""
    return t["pkg"].split("[")[0]


def _uv_tool(*args: str) -> int:
    """Install/upgrade a console as an isolated `uv tool` — its entry point lands
    on ~/.local/bin (PATH), so it's launchable and never pollutes a project venv.
    (The bug this replaces: `uv pip install` landed the console in whatever .venv
    uv happened to discover, off PATH, and clobbered that venv's deps.)"""
    if not shutil.which("uv"):
        print(f"  {RED}uv not found — install uv (https://docs.astral.sh/uv/) or use pipx.{RST}")
        return 127
    return _run(["uv", "tool", *args])


# --- rendering ------------------------------------------------------------------
def banner() -> None:
    # "MGF Family", not "Magogi Foundation": the Foundation has two families and this
    # launcher covers one. Claiming the wider scope is the terminology guard's exact
    # failure — and it is what let "Sooth has no front door" read as "Sooth has none".
    print(f"\n  {CYN}{BOLD}❖ MGF Family — tools{RST}")
    print(f"  {DIM}{'─' * 48}{RST}")


def cmd_list(_args) -> int:
    banner()
    print(f"\n  {BOLD}{CYN}WEB CONSOLES{RST}  {DIM}— fed-tools run <name>{RST}\n")
    for k, t in WEB.items():
        url = f"http://127.0.0.1:{t['port']}"
        if _running(t["port"]):
            dot, tag = f"{GRN}{BOLD}▶{RST}", f"{GRN}running{RST} {CYN}{url}{RST}"
        elif _have(t["console"]):
            dot, tag = f"{GRN}●{RST}", f"{GRN}{DIM}installed{RST}"
        else:
            dot, tag = f"{DIM}○{RST}", ""
        print(f"    {dot} {GRN}{BOLD}{k:<10}{RST} {t['title']:<42} {DIM}:{t['port']}{RST} {tag}")
        print(f"       {DIM}{t['desc']}{RST}")
    print(f"\n  {BOLD}{CYN}COMMAND-LINE TOOLS{RST}  {DIM}— install + run yourself{RST}\n")
    for name, desc, ex, _pkg in CLI:
        mark = f"{GRN}✓{RST}" if _have(name.split("[")[0]) else f"{DIM}›{RST}"
        print(f"    {mark} {BOLD}{name:<20}{RST} {DIM}{desc}{RST}")
        print(f"       {DIM}e.g.{RST} {YEL}{ex}{RST}")
    print(f"\n  {DIM}Launch a web tool:{RST}  {YEL}fed-tools run fed-web{RST}")
    print(f"  {DIM}See its commands: {RST}  {YEL}fed-tools show fed-web{RST}")
    print(f"  {DIM}Check for updates:{RST}  {YEL}fed-tools update --check{RST}")
    print(f"  {DIM}Full reference:   {RST}  {DIM}fed-tools/TOOLS_STARTHERE.md{RST}")
    print(f"  {DIM}Sooth Family tools:{RST} {DIM}sooth-standard/tools/ "
          f"(entrypoint: tools/validate.sh) — not launchable from here{RST}\n")
    return 0


def cmd_show(args) -> int:
    k = resolve(args.tool)
    if k:  # a web console: install (+ its steps) then launch, then open the URL
        t = WEB[k]
        url = f"http://127.0.0.1:{t['port']}"
        print(f"\n  {GRN}{BOLD}{t['pkg']}{RST} — {t['title']}  {DIM}→ {url}{RST}\n")
        for label, cmd in install_steps(t) + [("launch", t["console"])]:
            print(f"    {DIM}# {label}{RST}")
            print(f"    {YEL}{cmd}{RST}")
        print(f"\n  {DIM}then open{RST} {CYN}{url}{RST}\n")
        return 0
    row = next((r for r in CLI if r[0] == args.tool.lower()), None)
    if row:  # a command-line tool: install + an example invocation
        name, desc, ex, pkg = row
        print(f"\n  {BOLD}{name}{RST} — {DIM}{desc}{RST}\n")
        print(f"    {DIM}# install{RST}\n    {YEL}uv tool install \"{pkg}\" --default-index {DEVPI}{RST}")
        print(f"    {DIM}# run{RST}\n    {YEL}{ex}{RST}\n")
        return 0
    return _unknown(args.tool)


def _run(cmd: list[str]) -> int:
    return subprocess.run(cmd).returncode  # noqa: S603


def install(t: dict) -> bool:
    print(f"  {DIM}{t['console']} not found — installing {t['pkg']} …{RST}")
    if "source" in t:
        if not os.path.isdir(SRC_DEST):
            os.makedirs(os.path.dirname(SRC_DEST), exist_ok=True)
            if _run(["git", "clone", t["source"], SRC_DEST]) != 0:
                return False
        return _uv_tool("install", SRC_DEST, "--default-index", DEVPI) == 0
    return _uv_tool("install", t["pkg"], "--default-index", DEVPI) == 0


# --- update detection + apply ---------------------------------------------------
def _ver_key(v: str) -> tuple:
    return tuple(int(n) for n in re.findall(r"\d+", v)) or (0,)


def _installed_version(dist: str) -> str | None:
    """Installed version of a `uv tool` (None if absent). Consoles live in their
    own uv-tool env — not this process's — so `uv tool list` is the source of
    truth, not importlib.metadata."""
    if not shutil.which("uv"):
        return None
    try:
        out = subprocess.run(["uv", "tool", "list"],  # noqa: S603, S607
                             capture_output=True, text=True).stdout
    except OSError:
        return None
    pat = re.escape(dist).replace(r"\-", "[-_]").replace(r"\_", "[-_]")
    m = re.search(rf"^{pat}\s+v?([0-9][A-Za-z0-9.]*)", out, re.I | re.M)
    return m.group(1) if m else None


def _latest_devpi(dist: str) -> str | None:
    """Highest version on the devpi simple index for `dist` (parsed from filenames)."""
    parts = re.escape(dist).replace(r"\-", "[-_.]").replace(r"\_", "[-_.]").replace(r"\.", "[-_.]")
    rx = re.compile(rf"{parts}-([0-9][A-Za-z0-9.]*?)(?:-py|-cp|\.tar|\.zip|\.whl)", re.I)
    try:
        with urllib.request.urlopen(f"{DEVPI}{dist}/", timeout=15) as r:  # noqa: S310
            html = r.read().decode("utf-8", "replace")
    except (urllib.error.URLError, OSError):
        return None
    vs = set(rx.findall(html))
    return max(vs, key=_ver_key) if vs else None


def _git_out(*args: str) -> str | None:
    r = subprocess.run(["git", *args], capture_output=True, text=True)  # noqa: S603, S607
    return r.stdout.strip() if r.returncode == 0 else None


def update_state(t: dict) -> dict:
    """Whether an installed console is outdated. keys: installed, needs, cur, new."""
    if "source" in t:
        if not os.path.isdir(os.path.join(SRC_DEST, ".git")):
            return {"installed": False, "needs": False, "cur": None, "new": None}
        subprocess.run(["git", "-C", SRC_DEST, "fetch", "--quiet"], capture_output=True)  # noqa: S603, S607
        local = _git_out("-C", SRC_DEST, "rev-parse", "HEAD")
        remote = _git_out("-C", SRC_DEST, "rev-parse", "@{u}") \
            or _git_out("-C", SRC_DEST, "rev-parse", "origin/HEAD")
        needs = bool(local and remote and local != remote)
        return {"installed": True, "needs": needs,
                "cur": local[:7] if local else None,
                "new": remote[:7] if remote else None}
    dist = _dist(t)
    cur, new = _installed_version(dist), _latest_devpi(dist)
    needs = bool(cur and new and _ver_key(new) > _ver_key(cur))
    return {"installed": cur is not None, "needs": needs, "cur": cur, "new": new}


def cli_update_state(pkg: str) -> dict:
    """Whether an installed CLI is outdated — same shape as update_state(), for the
    `CLI` rows. These were invisible to `update` for as long as it existed: it looped
    over WEB only, so "all current" was a verdict about three consoles wearing the
    clothes of a verdict about the whole tools plane. `new` is None when devpi could
    not be reached — that is *unverifiable*, and callers must not read it as current."""
    dist = pkg.split("[")[0]
    cur, new = _installed_version(dist), _latest_devpi(dist)
    return {
        "installed": cur is not None,
        "needs": bool(cur and new and _ver_key(new) > _ver_key(cur)),
        "unverifiable": bool(cur and new is None),
        "cur": cur,
        "new": new,
    }


def apply_update(t: dict) -> bool:
    if "source" in t:
        if _run(["git", "-C", SRC_DEST, "pull", "--ff-only"]) != 0:
            return False
        return _uv_tool("install", "--reinstall", SRC_DEST, "--default-index", DEVPI) == 0
    return _uv_tool("install", "--reinstall", t["pkg"], "--default-index", DEVPI) == 0


def cmd_update(args) -> int:
    banner()
    targets = WEB
    if args.tool:
        k = resolve(args.tool)
        if not k:
            return _unknown(args.tool)
        targets = {k: WEB[k]}
    print(f"\n  {DIM}checking for updates …{RST}\n")
    outdated = False
    for k, t in targets.items():
        st = update_state(t)
        if not st["installed"]:
            print(f"    {DIM}○ {k:<10} not installed{RST}  {DIM}— fed-tools run {k}{RST}")
            continue
        if st["needs"]:
            outdated = True
            change = f"{st['cur']} {DIM}→{RST} {GRN}{st['new']}{RST}"
            print(f"    {YEL}⟳ {k:<10}{RST} update available  {change}")
            if not args.check:
                ok = apply_update(t)
                print(f"      {GRN}✓ updated{RST}" if ok else f"      {RED}✗ update failed{RST}")
        else:
            print(f"    {GRN}● {k:<10}{RST} up to date  {DIM}({st['cur']}){RST}")

    # CLIs, when not filtered to one console. `update` applies only to web consoles
    # (they are the ones fed-tools installs); CLIs are *reported* so the verdict below
    # covers the whole plane instead of three consoles.
    unverifiable = []
    if not args.tool:
        shown = False
        for name, _desc, _ex, pkg in CLI:
            st = cli_update_state(pkg)
            if not st["installed"]:
                continue
            if not shown:
                print()
                shown = True
            if st["unverifiable"]:
                unverifiable.append(name)
                print(f"    {RED}? {name:<20}{RST} devpi unreachable  "
                      f"{DIM}(installed {st['cur']}){RST}")
            elif st["needs"]:
                outdated = True
                print(f"    {YEL}⟳ {name:<20}{RST} update available  "
                      f"{st['cur']} {DIM}→{RST} {GRN}{st['new']}{RST}  "
                      f"{DIM}uv tool upgrade {pkg.split('[')[0]}{RST}")
            else:
                print(f"    {GRN}● {name:<20}{RST} up to date  {DIM}({st['cur']}){RST}")

    if args.check:
        if unverifiable:
            print(f"\n  {RED}could not verify {len(unverifiable)}:{RST} {', '.join(unverifiable)}")
            print(f"  {DIM}unverifiable is not current — devpi was unreachable.{RST}\n")
            return 1
        print(f"\n  {YEL}updates available{RST}\n" if outdated else f"\n  {GRN}all current{RST}\n")
        return 1 if outdated else 0
    print()
    return 0


def cmd_run(args) -> int:
    k = resolve(args.tool)
    if not k:
        if any(r[0] == args.tool.lower() for r in CLI):
            print(f"  {DIM}{args.tool} is a command-line tool (only web consoles are launchable) — "
                  f"run it directly, or {YEL}fed-tools show {args.tool}{RST} {DIM}for its commands.{RST}")
            return 2
        return _unknown(args.tool)
    t = WEB[k]
    if args.show:
        return cmd_show(args)
    console = t["console"]
    if not _have(console):
        if not install(t):
            print(f"  {RED}install failed — run these manually:{RST}")
            return cmd_show(args)
    url = f"http://127.0.0.1:{t['port']}"
    print(f"\n  {GRN}{BOLD}▶ {t['pkg']}{RST}  →  {CYN}{BOLD}{url}{RST}   {DIM}(Ctrl-C to stop){RST}\n")
    try:
        threading.Timer(2.5, lambda: webbrowser.open(url)).start()
    except Exception:
        pass
    try:
        return subprocess.run([console]).returncode  # noqa: S603
    except KeyboardInterrupt:
        print(f"\n  {DIM}stopped.{RST}")
        return 0
    except FileNotFoundError:
        print(f"  {RED}{console} is still not on PATH.{RST}")
        return cmd_show(args)


def _unknown(name: str) -> int:
    print(f"  {RED}unknown tool: {name}{RST}")
    print(f"  run {YEL}fed-tools list{RST} to see them all "
          f"{DIM}(launchable web tools: {', '.join(WEB)}){RST}")
    return 2


# --- self-install ---------------------------------------------------------------
def cmd_install(_args) -> int:
    """Symlink this launcher into ~/.local/bin so `fed-tools` works from anywhere.
    The link points at the git-tracked script, so `git pull` keeps it current."""
    banner()
    src = os.path.realpath(__file__)
    dest_dir = os.path.expanduser("~/.local/bin")
    dest = os.path.join(dest_dir, "fed-tools")
    os.makedirs(dest_dir, exist_ok=True)
    try:
        if os.path.islink(dest) or os.path.exists(dest):
            os.remove(dest)
        os.symlink(src, dest)
    except OSError as e:
        print(f"\n  {RED}could not link {dest}: {e}{RST}\n")
        return 1
    print(f"\n  {GRN}✓ linked{RST} {CYN}{dest}{RST}\n       {DIM}→ {src}{RST}")
    if dest_dir in os.environ.get("PATH", "").split(os.pathsep):
        print(f"\n  {DIM}run{RST} {YEL}fed-tools list{RST} {DIM}from anywhere.{RST}\n")
    else:
        print(f"\n  {YEL}note:{RST} {DIM}{dest_dir} isn't on your PATH yet — add to your shell profile:{RST}")
        print(f"    {YEL}export PATH=\"$HOME/.local/bin:$PATH\"{RST}\n")
    return 0


# --- registry drift check -------------------------------------------------------
def _fleet_root() -> str:
    return os.environ.get("MGF_ROOT") or os.path.expanduser("~/PycharmProjects")


def _fleet_web_consoles(root: str) -> list[str]:
    """Discover `*-web` repos that ship a runnable web server (a console script + a
    web-framework dependency), by dir/dist name — for drift-checking the registry.
    Skips headless libs like mgf-brand-web (whose only fastapi mention is the
    import-linter *forbidden* list)."""
    out = []
    if not os.path.isdir(root):
        return out
    for name in sorted(os.listdir(root)):
        pp = os.path.join(root, name, "pyproject.toml")
        if not (name.endswith("-web") and os.path.isfile(pp)):
            continue
        try:
            lines = open(pp, encoding="utf-8").read().splitlines()
        except OSError:
            continue
        has_script = any("[project.scripts]" in ln for ln in lines)
        has_web = any(
            re.search(r"\b(fastapi|uvicorn|starlette)\b", ln, re.I) and "forbidden" not in ln.lower()
            for ln in lines
        )
        if has_script and has_web:
            out.append(name)
    return out


def _fleet_console_scripts(root: str) -> tuple[dict[str, str], list[str]]:
    """Discover every console script the mgf-* fleet declares → ({command: repo}, unreadable).

    Lets `doctor` drift-check the CLI list the same way it checks WEB. An
    unparseable pyproject is RETURNED, not skipped: a checker that could not read
    its input must say so, never fold silence into a clean report."""
    import tomllib

    found: dict[str, str] = {}
    unreadable: list[str] = []
    if not os.path.isdir(root):
        return found, unreadable
    for name in sorted(os.listdir(root)):
        pp = os.path.join(root, name, "pyproject.toml")
        if not (name.startswith("mgf-") and os.path.isfile(pp)):
            continue
        try:
            with open(pp, "rb") as fh:
                data = tomllib.load(fh)
        except (OSError, ValueError):
            unreadable.append(name)
            continue
        for cmd in (data.get("project") or {}).get("scripts") or {}:
            found[cmd] = name
    return found, unreadable


def cmd_doctor(args) -> int:
    banner()
    root = _fleet_root()
    print(f"\n  {DIM}registry check against {root} {DIM}(scope: mgf-* repos) …{RST}\n")
    web_found = _fleet_web_consoles(root)
    cli_found, unreadable = _fleet_console_scripts(root)
    if not web_found and not cli_found and not unreadable:
        print(f"    {DIM}no fleet repos found (set MGF_ROOT to point at your checkouts){RST}\n")
        return 0

    print(f"  {BOLD}web consoles{RST}")
    web_registered = {_dist(t) for t in WEB.values()}
    web_drift = [n for n in web_found if n not in web_registered]
    for n in web_found:
        mark = f"{YEL}⚠ not registered{RST}" if n in web_drift else f"{GRN}● registered{RST}"
        print(f"    {mark}  {n}")
    for k, t in WEB.items():
        if "source" not in t and _dist(t) not in web_found:
            print(f"    {DIM}? {k:<10} registered but no repo found under {root}{RST}")

    print(f"\n  {BOLD}command-line tools{RST}")
    cli_registered = {r[0] for r in CLI}
    known = cli_registered | {t["console"] for t in WEB.values()} | set(CLI_EXEMPT)
    cli_drift = sorted(c for c in cli_found if c not in known)
    for c in sorted(cli_registered):
        where = cli_found.get(c)
        mark = f"{GRN}● registered{RST}" if where else f"{YEL}? no mgf-* repo declares it{RST}"
        print(f"    {mark}  {c}{f'  {DIM}({where}){RST}' if where else ''}")
    for c in cli_drift:
        print(f"    {YEL}⚠ not registered{RST}  {c}  {DIM}({cli_found[c]}){RST}")

    # Currency. `update --check` was built as a gate and nothing ever ran it, so three
    # consoles sat stale in plain sight. Folding it in here means the one command that
    # checks the tools plane checks all of it: registered, AND current.
    stale: list[str] = []
    unverifiable: list[str] = []
    if getattr(args, "offline", False):
        print(f"\n  {DIM}currency: skipped (--offline){RST}")
    else:
        print(f"\n  {BOLD}currency{RST}  {DIM}(devpi){RST}")
        for label, st in [(k, update_state(t)) for k, t in WEB.items()] + [
            (r[0], cli_update_state(r[3])) for r in CLI
        ]:
            if not st["installed"]:
                continue
            if st.get("unverifiable"):
                unverifiable.append(label)
                print(f"    {RED}? {label:<20}{RST} unverifiable  {DIM}(devpi unreachable){RST}")
            elif st["needs"]:
                stale.append(label)
                print(f"    {YEL}⟳ {label:<20}{RST} {st['cur']} {DIM}→{RST} {GRN}{st['new']}{RST}")
            else:
                print(f"    {GRN}● {label:<20}{RST} {DIM}{st['cur']}{RST}")

    rc = 0
    if stale:
        print(f"\n  {YEL}{len(stale)} tool(s) outdated:{RST} {', '.join(stale)}")
        print(f"  {DIM}fed-tools update (consoles) · uv tool upgrade <pkg> (CLIs){RST}")
        rc = 1
    if unverifiable:
        print(f"\n  {RED}could not verify {len(unverifiable)}:{RST} {', '.join(unverifiable)}")
        print(f"  {DIM}unverifiable is not current — say so rather than report clean.{RST}")
        rc = 1
    if unreadable:
        print(f"\n  {RED}could not read {len(unreadable)} pyproject(s):{RST} "
              f"{', '.join(unreadable)}")
        print(f"  {DIM}unchecked is not clean — fix these before trusting this sweep.{RST}")
        rc = 1
    if web_drift:
        print(f"\n  {YEL}{len(web_drift)} web console(s) not in the registry:{RST} "
              f"{', '.join(web_drift)}")
        print(f"  {DIM}add them to the WEB dict in fed-tools.{RST}")
        rc = 1
    if cli_drift:
        print(f"\n  {YEL}{len(cli_drift)} command-line tool(s) not in the registry:{RST} "
              f"{', '.join(cli_drift)}")
        print(f"  {DIM}add each to the CLI list — or to CLI_EXEMPT with a reason.{RST}")
        rc = 1
    if rc == 0:
        # The success line always states its own scope — including what it did NOT do.
        # "clean" that hides an unrun check is the defect this whole command exists to kill.
        scope = (
            "registered and current"
            if not getattr(args, "offline", False)
            else "registered (currency NOT checked — --offline)"
        )
        print(f"\n  {GRN}all {len(web_found)} web console(s) and {len(cli_registered)} "
              f"command-line tool(s) under {root}: {scope}.{RST}\n")
    else:
        print()
    return rc


def main(argv=None) -> int:
    p = argparse.ArgumentParser(prog="fed-tools", description="Magogi Foundation tools launcher.")
    sub = p.add_subparsers(dest="cmd")
    sub.add_parser("list", help="list every MGF tool")
    pr = sub.add_parser("run", help="install (if needed) + launch a web console")
    pr.add_argument("tool")
    pr.add_argument("--show", action="store_true", help="print the commands instead of running")
    ps = sub.add_parser("show", help="print any tool's install + run commands")
    ps.add_argument("tool")
    pu = sub.add_parser("update", help="update installed web console(s); --check only detects")
    pu.add_argument("tool", nargs="?", help="one console (default: all installed)")
    pu.add_argument("--check", action="store_true", help="report what's outdated; don't apply")
    sub.add_parser("install", help="symlink fed-tools into ~/.local/bin (invoke from anywhere)")
    pd = sub.add_parser("doctor", help="registry coverage + currency for the whole tools plane")
    pd.add_argument("--offline", action="store_true", help="skip the devpi currency check")
    args = p.parse_args(argv)
    if args.cmd == "run":
        return cmd_run(args)
    if args.cmd == "show":
        return cmd_show(args)
    if args.cmd == "update":
        return cmd_update(args)
    if args.cmd == "install":
        return cmd_install(args)
    if args.cmd == "doctor":
        return cmd_doctor(args)
    return cmd_list(args)


if __name__ == "__main__":
    sys.exit(main())
