import { ghHelp } from "./gh";
import { authBrokerHelp } from "./auth-broker";
import { hwlabHelp } from "./hwlab-cd";
import { hwlabG14Help } from "./hwlab-g14";
import { agentRunHelp } from "./agentrun";

export function rootHelp(): unknown {
  return {
    entry: "bun scripts/cli.ts",
    output: "json",
    commands: [
      { command: "help", description: "List supported commands." },
      { command: "--main-server-ip <ip> <command>", description: "Run selected commands through the public frontend API; use --main-server-key only for legacy SSH transport." },
      { command: "config show", description: "Validate and print config.json as the single source of truth." },
      { command: "check [--full|--files|--scripts-typecheck|--components|--compose|--logs|--recovery-guardrails|--rust] | check recovery-guardrails", description: "Run the lightweight default syntax/config gate or the low-noise read-only D601 recovery guardrails; Rust is opt-in and only allowed from D601 CI/dev execution." },
      { command: "server start", description: "Fire-and-forget build/start for database, backend-core, frontend, provider gateway, and managed main-server user services." },
      { command: "server stop", description: "Fire-and-forget docker-compose down for the fixed UniDesk stack." },
      { command: "server status", description: "Show fixed ports, containers, service health, and public URLs." },
      { command: "server swap status|ensure [--path /swapfile] [--size 2GiB] [--dry-run]", description: "Inspect or idempotently create host swap for low-memory main-server operation." },
      { command: "server logs [--tail-bytes N]", description: "Return bounded tails from file logs and docker logs." },
      { command: "server cleanup plan [--min-age-hours N] [--limit N]", description: "Dry-run Docker image cleanup plan only: list active/protected images, stale candidates older than the default 24h threshold, risk, estimated reclaim, and manual review commands without deleting anything." },
      { command: "gc plan|run|db-trace|policy|remote [--confirm] [--logs-keep-days N] [--include-browser-cache]", description: "One-time main-server or remote provider disk relief and low-risk anti-bloat policy for logs, journald, allowlisted /tmp artifacts, scoped core dumps and explicit trace telemetry retention; plan is read-only and run requires --confirm." },
      { command: "server rebuild <backend-core|frontend|dev-frontend-proxy|provider-gateway|todo-note|code-queue-mgr|project-manager|baidu-netdisk|oa-event-flow>", description: "Maintenance-only local Compose rebuild for reviewed main-server services; frontend standard release must use CI artifact plus deploy apply dev/prod artifact consumers." },
      { command: "provider attach <providerId> [--master-server URL] [--up] [--force] | provider triage <providerId> [--observed-error text] [--observed-scope scope] [--microservice id ...] [--full|--raw]", description: "Generate the minimal external provider-gateway env/compose bundle or run the low-noise read-only provider health triage contract." },
      { command: "trans <route> [operation args...] (alias of ssh <route> ...)", description: "Open a Host SSH / WSL SSH maintenance session through the provider-gateway bridge; `trans` is the short alias for this ssh passthrough path." },
      { command: "trans gh:/owner/repo[/pr|/issue][/number[/1]] ls|cat|rg|patch-apply", description: "Treat GitHub PRs/issues as virtual text directories; `ls --full` shows state/floors/body length, and `patch-apply` updates first-floor `body.md` through UniDesk gh plus apply-patch v2." },
      { command: "trans <route> apply-patch < patch.diff", description: "Default remote text patch entry: apply a standard patch with the local TypeScript v2 engine while the remote route only reads and writes files." },
      { command: "trans <route> upload <local-file> <remote-file> | trans <route> download <remote-file> <local-file>", description: "Transfer whole files through SSH passthrough with remote temp files, automatic endpoint byte/SHA-256 verification, and client-side chunk fallback." },
      { command: "trans <providerId> apply-patch-v1 [tool args...] < patch.diff", description: "Fallback to the injected legacy remote apply_patch helper directly over SSH passthrough and stream the patch from local stdin." },
      { command: "trans <providerId> py [script-args...] < script.py", description: "Run remote Python from local stdin through SSH passthrough without nested shell quoting; extra args become script argv." },
      { command: "trans <providerId> script [--shell sh|bash] [script-args...] <<'SCRIPT' ...", description: "Run a remote shell script from local stdin using shell -s; default sh inherits provider proxy env and gets the portable printf helper used by shell/script." },
      { command: "trans <providerId> skills [--scope all|wsl|windows] [--limit N]", description: "Discover WSL/Linux and, for WSL providers, Windows skill directories in one SSH passthrough call." },
      { command: "trans <providerId> find <path...> [--max-depth N] [--type d|f|l] [--contains TEXT] [--iname PATTERN] [--limit N] [--sort]", description: "Run a structured remote find command without nested shell quoting or parentheses." },
      { command: "trans <providerId> glob [--root DIR] [--pattern PATTERN] [--contains TEXT] [--type any|f|d] [--limit N] [--sort]", description: "Run remote glob matching through the injected helper without shell glob expansion." },
      { command: "trans <providerId>:/absolute/workspace <operation args...>", description: "Route directly into a host workspace while keeping the operation parser independent from the location." },
      { command: "trans <providerId>:k3s[:namespace:workload[:container]] <kubectl|logs|exec|script|apply-patch|apply-patch-v1|command> ...", description: "Locate a native k3s control plane or workload with route syntax, then run a separate operation with KUBECONFIG fixed and argv assembled by the CLI." },
      { command: "trans <providerId> argv <command> [args...]", description: "Run a non-interactive remote command with each argv token shell-quoted by UniDesk before SSH passthrough; use `trans <providerId> script` when shell features are required." },
      { command: "microservice list", description: "List UniDesk-managed user services and their provider/runtime mapping." },
      { command: "microservice status <id>", description: "Show one user service config, repository reference, backend mapping, and runtime status." },
      { command: "microservice health <id> [--compact|--raw|--full]", description: "Probe one user service through backend-core -> provider-gateway HTTP proxy; default output is compact, and code-queue uses a commander-safe liveness summary unless raw/full is requested." },
      { command: "microservice proxy <id> <path> [--method GET|POST|PUT|PATCH|DELETE] [--body-json JSON|--body-file path|--body-stdin] [--raw] [--max-body-bytes N]", description: "Access a private user-service backend path through the same frontend-only proxy used by WebUI; JSON request bodies are supported for controlled write/debug endpoints." },
      { command: "microservice diagnostics <id> [--full|--raw]", description: "Split k3sctl-managed proxy health into a compact summary by default; use --full/--raw for complete evidence." },
      { command: "microservice tunnel-self-test <id>", description: "Trigger an expected provider HTTP tunnel failure and verify requestId/stage diagnostics are returned." },
      { command: "decision upload <markdown-file> [--title text] [--type meeting|decision|goal|external_goal|internal_goal|blocker|debt|experiment] [--level|--priority G0|G1|G2|G3|P0|P1|P2|P3|none] [--doc-no DC-...] [--doc-type DCSN|GOAL|PLAN|RPRT|ACTN|ISSU|RETR|RQST|RESP|MINS] [--doc-priority P0|P1|P2|P3] [--signer text] [--issued-at ISO]", description: "Upload a meeting note or decision/requirement record through backend-core -> decision-center user-service proxy." },
      { command: "decision diary import <markdown-file> [--source-file path] [--tag tag] [--include-entries]", description: "Import a dated work log Markdown into PostgreSQL diary entries split as YYYY-MM/YYYY-MM-DD.md." },
      { command: "decision diary list [--month YYYY-MM] [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--limit N] [--include-body]", description: "List daily Markdown diary entries stored by Decision Center." },
      { command: "decision diary history [--month YYYY-MM] [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--limit N] [--include-body]", description: "Read diary history through the productized history API alias." },
      { command: "decision diary today [--edit --body-file path] [--title text] [--tag tag]", description: "Get or create today's diary entry using the service's real current date; --edit saves today's Markdown." },
      { command: "decision diary months", description: "List available Decision Center diary months with day counts." },
      { command: "decision diary show <YYYY-MM-DD|id> [--source-file path]", description: "Show one daily diary Markdown entry; source-file disambiguates same-day entries from multiple imports." },
      { command: "decision diary edit|upsert <YYYY-MM-DD|id> --body-file path [--title text] [--source-file path] [--tag tag]", description: "Create or edit one daily diary entry through PUT /api/diary/entries/:idOrDate via backend-core proxy." },
      { command: "decision list [--doc-no DC-...] [--doc-type ...] [--doc-priority P0|P1|P2|P3] [--year YYYY] [--type ...] [--status ...] [--level|--priority ...] [--limit N] [--include-body]", description: "List Decision Center records through the user-service proxy; bodies are omitted unless --include-body is set." },
      { command: "decision requirement list|create|show|update|upsert [id|docNo] [--title text] [--body-file path] [--type external_goal|internal_goal|goal|decision|blocker|debt|experiment] [--doc-no DC-...] [--doc-type ...] [--doc-priority P0|P1|P2|P3] [--signer text] [--issued-at ISO]", description: "Manage productized requirement records over the PostgreSQL records model, excluding meeting records." },
      { command: "decision show <id|docNo>", description: "Show one Decision Center record." },
      { command: "deploy check|plan|apply [--file deploy.json|--env dev|prod] [--service id] [--commit full-sha] [--dry-run] [--force]", description: "Reconcile services from origin/master:deploy.json environments; --commit overrides one reviewed artifact consumer such as frontend for release/v1 validation or rollback. code-queue artifact consumption is dev-only." },
      { command: "dev-env validate|prewarm-images", description: "Validate D601 unidesk-dev guardrails or prewarm dev foundation images into native k3s containerd through a bounded async job." },
      { command: "artifact-registry plan|render|status|health|install|deploy-backend-core|deploy-service", description: "Manage the D601 host-managed CNCF Distribution registry and run pull-only artifact CD for supported services, including D601 direct, k3s-managed, and code-queue dev-only consumers." },
      { command: "auth-broker contract|health --dry-run|credential-request --dry-run|pr-preflight --dry-run", description: "Inspect the P0 Rust auth broker and CLI adapter contract without reading token values, writing GitHub, or starting services." },
      { command: "gh preflight|auth|issue|pr", description: "Run safe GitHub issue and PR CRUD/lifecycle operations through REST with body-file update replace/append, comment delete, token diagnostics, PR closeout preflight, hard delete unsupported, and guarded PR merge." },
      { command: "commander contract|plan --dry-run|smoke --dry-run|approval request --dry-run|prompt-lint --kind gpt55-pr", description: "Host Codex commander skeleton contract, no-daemon smoke plan, dry-run approval preview, and advisory GPT-5.5 PR prompt boundary lint without live bridges, message sends, or submit gating." },
      { command: "hwlab g14 monitor-prs | hwlab g14 control-plane status|apply|trigger-current|runtime-migration|cleanup-runs|cleanup-released-pvs | hwlab g14 git-mirror status|apply|sync|flush | hwlab g14 tools-image status|build", description: "Start the G14 PR monitor, run bounded v0.2 Tekton/Argo control-plane, manual PipelineRun trigger, runtime migration, CI workspace retention, manual devops-infra git mirror/relay maintenance, or fixed HWLAB CI tools image actions through UniDesk G14 routes; long confirmed trigger/sync/flush actions return async jobs by default." },
      { command: "agentrun v01 control-plane status|trigger-current|refresh", description: "Run bounded AgentRun v0.1 Tekton/Argo status, manual PipelineRun trigger, and Argo refresh operations through UniDesk G14 routes." },
      { command: "hwlab cd audit --env dev | hwlab cd status --env dev | hwlab cd apply --env dev --dry-run", description: "Legacy D601 HWLAB DEV CD wrapper kept for explicit old-path diagnostics; current HWLAB rollout uses G14 GitOps." },
      { command: "code-agent-sandbox", description: "Independent Code Agent Sandbox service skeleton for adapter, mode, and credential-boundary diagnostics." },
      { command: "schedule list|get|runs|run|retry-run|delete", description: "Manage backend-core scheduled tasks and run history; schedule run <id> supports --wait-ms N and retry-run reuses the failed run's schedule." },
      { command: "schedule upsert-pgdata-backup [--time HH:MM] [--remote-base /SERVER_DATA/UNIDESK_PG_DATA]", description: "Create or update the daily PGDATA physical backup task that uploads monthly rotated archives to Baidu Netdisk." },
      { command: "codex deploy <commitId> [--provider-id D601] [--timeout-ms N]", description: "Disabled legacy Code Queue deploy path; use the dev-only artifact consumer instead." },
      { command: "codex prompt-lint [prompt|--prompt-file path|--prompt-stdin]", description: "Dry-run lint a runner prompt for DEV test class read-only/live-read/live-mutating authorization without echoing prompt text or touching live services." },
      { command: "codex submit [prompt] [--prompt-file path|--prompt-stdin] [--queue queueId] [--provider-id id] [--cwd path] [--model model] [--execution-mode mode] [--max-attempts N] [--reference-task-id id] [--dry-run]", description: "Submit a Code Queue task through backend-core -> code-queue proxy; --dry-run shows the structured request, routing recommendation, and prompt live-authorization lint while real success only confirms the write and task id." },
      { command: "codex skills-sync --dry-run [--full]", description: "Inspect the controlled runner skills hostPath lifecycle contract without copying files, restarting services, reading secrets, or mutating live runner paths." },
      { command: "codex execution-plane [--full|--raw]", description: "Read-only D601 native k3s Code Queue execution-plane inspection; compares formal deployments, deprecated Compose residuals, commit markers, pod digest, and mounted worktree HEAD." },
      { command: "codex pr-preflight [--remote] [--push-dry-run --push-dry-run-ref refs/heads/probe/<name>] [--pr-create-dry-run --pr-create-dry-run-head <head>] [--issue N] [--full|--raw]", description: "Read-only PR admission check with compact commander output by default; use --full or --raw to expand the full runtime preflight, tool, and observation payload." },
      { command: "codex task <taskId> [--detail] [--trace --tail|--from-start|--after-seq N|--before-seq N --limit N] [--full]", description: "Fetch the bounded review view by default; --detail is still capped, while --full/trace/output explicitly expand evidence." },
      { command: "codex tasks [--view commander|supervisor|full] [--queue id] [--status status[,status]] [--unread|--unread-only] [--limit N] [--before-id id]", description: "Show Code Queue task state with progressive disclosure; --view commander is the recommended bounded host-commander loop, supervisor keeps compact sections, and full returns detailed rows." },
      { command: "codex unread [summary|list|mark-read] [--queue id] [--repo owner/name] [--issue N] [--status succeeded,failed,canceled] [--limit N] [--view summary|full] [--full] [--confirm]", description: "Summarize unread terminal backlog by repo, issue, status and queue with compact rows by default; per-task command blocks require --full/list, and batch mark-read requires --confirm." },
      { command: "codex output <taskId> [--tail|--from-start|--after-seq N|--before-seq N --limit N] [--full-text]", description: "Fetch paged raw Code Queue output records; default caps large limits/text previews, --full-text explicitly expands one seq window." },
      { command: "codex read <taskId>", description: "Mark one reviewed terminal task read and return terminal metadata plus final response; prompt/tool logs stay behind drill-down commands." },
      { command: "codex dev-ready", description: "Fetch execution-container readiness, including sanitized skill injection status from /api/dev-ready." },
      { command: "codex judge <taskId> --attempt N [--dry-run] [--include-prompt]", description: "Replay one stored Code Queue attempt through the same judge context builder and MiniMax judge call path used by the live queue worker." },
      { command: "codex steer <taskId> [prompt|--prompt-file path|--prompt-stdin] [--steer-id id] [--dry-run] [--no-retry|--retry-attempts N] [--full|--raw]", description: "Push a corrective prompt into a running Code Queue task with a steerId/idempotency key; retryable tunnel aborts get bounded trace confirmation before any retry guidance." },
      { command: "codex resume <taskId> [prompt|--prompt-file path|--prompt-stdin] [--resume-id id] [--dry-run] [--full|--raw]", description: "Queue a follow-up turn on a terminal Code Queue task, preserving the original task/thread/PR context and suppressing duplicate resumeId delivery without echoing the prompt." },
      { command: "codex steer-confirm <taskId> --steer-id <id> [--raw]", description: "Read-only lookup for a steerId in task trace so deliveryUnconfirmed can be resolved without resending the corrective prompt." },
      { command: "codex interrupt|cancel <taskId>", description: "Request interrupt for a running Code Queue task, or cancel a queued/retry_wait task, through the same private proxy." },
      { command: "codex (queues [--full|--all] | queue create <queueId> | queue merge <sourceQueueId> --into <targetQueueId> | move <taskId> --queue <queueId>)", description: "List low-noise queue summaries by default, including effective activity counts that distinguish scheduler-local queues, DB running tasks, and heartbeat-fresh runners; full queue rows require --full/--all." },
      { command: "job list [--limit N] [--include-command]", description: "List async jobs from .state/jobs with a bounded default page and progress summaries." },
      { command: "job status <jobId|latest> [--tail-bytes N]", description: "Show job state with a structured progress summary and bounded stdout/stderr tails." },
      { command: "job cancel <jobId>", description: "Cancel a queued/running async job through the .state/jobs control entry and keep a terminal canceled record." },
      { command: "debug health", description: "Probe internal core, nodes, system/Docker status, frontend, provider ingress, and public boundary." },
      { command: "debug dispatch [providerId] [docker.ps|provider.upgrade|host.ssh|microservice.http|echo] [--wait-ms N]", description: "Submit a real internal-core dispatch request for CLI debugging." },
      { command: "debug task <taskId|latest>", description: "Read a dispatched task record from internal core for CLI debugging." },
      { command: "network perf [--service code-queue --path /api/tasks/overview?limit=30 --count N --concurrency N --label before|after]", description: "Benchmark frontend -> backend-core -> provider/adapter user-service networking and report latency/proxy-mode distributions." },
      { command: "ci install|status|run|publish-backend-core|publish-user-service|run-dev-e2e|logs", description: "Manage D601/G14 native k3s Tekton CI; artifact publish commands build commit-pinned images in CI without deploying CD." },
      { command: "e2e run [--only pattern[,pattern...]] [--skip pattern[,pattern...]]", description: "Run selected public/internal/Playwright E2E checks; use --only for focused iteration and rerun without filters for final regression." },
      { command: "bun scripts/playwright-cli.ts screenshot|open|eval ...", description: "Repo-owned Playwright wrapper for commander browser checks; headless by default, supports storage-state --session, and returns JSON guidance for unsupported interactive daemon commands." },
    ],
  };
}

export function isHelpToken(value: string | undefined): boolean {
  return value === "help" || value === "--help" || value === "-h";
}

export function serverHelp(action: string | undefined = undefined): unknown {
  return {
    command: action === undefined || isHelpToken(action) ? "server start|stop|status|swap|logs|cleanup|rebuild" : `server ${action}`,
    output: "json",
    description: "Manage the fixed main-server Docker Compose stack without exposing backend-core REST publicly.",
    usage: {
      start: "bun scripts/cli.ts server start",
      stop: "bun scripts/cli.ts server stop",
      status: "bun scripts/cli.ts server status",
      swap: "bun scripts/cli.ts server swap status|ensure [--path /swapfile] [--size 2GiB] [--dry-run]",
      logs: "bun scripts/cli.ts server logs [--tail-bytes N]",
      cleanup: "bun scripts/cli.ts server cleanup plan [--min-age-hours N] [--limit N]",
      rebuild: "bun scripts/cli.ts server rebuild <backend-core|frontend|dev-frontend-proxy|provider-gateway|todo-note|code-queue-mgr|project-manager|baidu-netdisk|oa-event-flow>",
    },
    cleanupPlan: {
      dryRunOnly: true,
      mutation: false,
      scope: "docker images only",
      defaultMinAgeHours: 24,
      protectedByDefault: [
        "running containers and their image IDs",
        "stopped containers and their image IDs until the container is reviewed separately",
        "deploy.json/CI.json current commit-pinned images",
        "database named volume, registry storage, Baidu Netdisk state and staging directories",
      ],
      forbidden: ["docker prune", "docker volume rm", "compose down -v", "database cleanup without verified backup"],
    },
    publicEntrypoints: {
      frontend: "prod UniDesk frontend",
      devFrontend: "dev UniDesk frontend proxy to D601 unidesk-dev/frontend-dev",
      providerIngress: "provider-gateway WebSocket ingress",
    },
    rustBoundary: {
      masterServer: "do not use server rebuild backend-core for Rust iteration; it would build locally",
      d601: "use deploy apply --env dev --service backend-core and CI for Rust build/check",
    },
    maintenanceOnly: {
      frontend: "server rebuild frontend is not standard release evidence; publish 127.0.0.1:5000/unidesk/frontend:<commit> with CI, then consume it with deploy apply --env dev/prod --service frontend --commit <full-sha>",
      userServices: "server rebuild for main-server user services is reserved for local maintenance, bootstrap or recovery and must not replace commit-pinned artifact CD",
    },
    nonRebuildableBoundary: {
      upstreamImages: ["filebrowser", "filebrowser-d601"],
      infrastructure: ["database", "k3sctl-adapter"],
      d601ExecutionPlane: ["code-queue"],
      policy: "unsupported objects return unsupported-server-rebuild and must not be coerced into main-server Compose source builds",
    },
  };
}

export function sshHelp(): unknown {
  return {
    command: "ssh",
    output: "json",
    description: "Open a Host SSH / WSL SSH maintenance session through the provider-gateway bridge.",
    usage: [
      "trans <route>",
      "trans <providerId> argv <command> [args...]",
      "trans <providerId>:/absolute/workspace apply-patch < patch.diff",
      "trans <route> upload <local-file> <remote-file>",
      "trans <route> download <remote-file> <local-file>",
      "trans <providerId> apply-patch-v1 [--allow-loose] < patch.diff",
      "trans <providerId> py [script-args...] < script.py",
      "trans <providerId> script [--shell sh|bash] [script-args...] <<'SCRIPT'",
      "trans <providerId> shell [--shell sh|bash] \"sed -n '1,20p' a && sed -n '1,20p' b\"",
      "trans <providerId> skills [--scope all|wsl|windows] [--limit N]",
      "trans <providerId> find <path...> [--contains TEXT] [--limit N]",
      "trans <providerId> glob [--root DIR] [--pattern PATTERN]",
      "trans D601:/home/ubuntu/workspace/hwlab-dev git status --short --branch",
      "trans D601:win cmd ver",
      "trans D601:win/c/test cmd cd",
      "trans D601:win skills [--scope agents|codex|all] [--limit N]",
      "trans D601:k3s",
      "trans D601:k3s kubectl get pods -n hwlab-dev",
      "trans G14:k3s",
      "trans G14:k3s kubectl get pipelineruns -n hwlab-ci",
      "trans D601:k3s script <<'SCRIPT'",
      "trans D601:k3s:hwlab-dev:hwlab-cloud-api/app pwd",
      "trans D601:k3s:hwlab-dev:hwlab-cloud-api/app apply-patch <<'PATCH'",
      "trans D601:k3s:hwlab-dev:hwlab-cloud-api apply-patch-v1 <<'PATCH'",
      "tar -C /path/to/files -cf - . | trans D601:k3s:unidesk:code-queue/root/unidesk exec --stdin -- tar -xf - -C /root/unidesk",
      "trans D601:win/c/test apply-patch <<'PATCH'",
      "trans D601:win upload ./tool.mjs F:\\Work\\hwlab\\.tmp\\tool.mjs",
      "trans D601:win download F:\\Work\\hwlab\\.tmp\\tool.mjs ./tool.mjs",
      "trans D601:k3s:hwlab-dev:hwlab-cloud-api node -e 'console.log(process.version)'",
      "trans D601:k3s:hwlab-dev:hwlab-cloud-api script <<'SCRIPT'",
      "trans D601:k3s:hwlab-dev:hwlab-cloud-api logs --tail 80",
      "trans G14:k3s logs -n agentrun-ci -l tekton.dev/pipelineRun=<run> --tail 120",
    ],
    notes: [
      "trans --help and trans <route> --help print this JSON help and never open an interactive session; the underlying ssh subcommand keeps the same help behavior.",
      "For non-interactive remote commands, prefer argv for a single process and script/stdin for shell logic.",
      "For one-line remote shell logic without a heredoc, use `script -- '<command && command>'`; outer shell operators written outside trans, such as `trans G14:/repo sed ... && sed ...`, are parsed by the local shell before UniDesk starts and therefore cannot be redirected by the CLI. The explicit `shell '<command>'` operation remains available for the same sh -c path.",
      "When a one-line shell command is easier to type through the script path, `script -- '<command && command>'` runs that single string through the remote shell without waiting for stdin. When `script --` is followed by multiple tokens, it stays a direct argv form for commands such as `trans D601:/work script -- sed -n '1,20p' file`.",
      "script and shell helper modes inject a tiny POSIX-compatible printf wrapper before user shell text, so portable printf headings such as `printf \"--- section ---\\n\"` work consistently under dash/sh and bash. Direct argv commands are unchanged.",
      "For arbitrary stdin streams into a workload command, use a workload route plus `exec --stdin -- <command> ...`; this keeps the route as location-only and avoids heredoc/base64/tar shell wrapping.",
      "`apply-patch` is the default remote text patch entry and uses the v2 local line-based patch engine with remote read/write operations, including Windows routes such as `D601:win/c/test`, so long Unicode/Chinese lines and pure insertion hunks avoid the legacy remote shell hunk parser. Its stdout/stderr follows Codex apply_patch text output rather than UniDesk JSON output; on multi-file failure, stderr lists applied hunks before the first failed hunk and the failed hunk, then stops like Codex apply_patch.",
      "`upload` and `download` are the default whole-file transfer entries for non-text and generated files. They write through remote temp files, verify byte count and SHA-256 on both sides, and return `verification.automatic=true`, `verification.verified=true`, and `verification.match.{bytes,sha256}=true`; this JSON is the transfer integrity proof, so callers do not need a separate manual `sha256sum` check. The client falls back from a single stdin payload to bounded chunks before treating provider-gateway limits as a server-side problem.",
      "`apply-patch-v1` is the only legacy fallback entry: it rejects low-context update hunks by default, reports the matched file:line for each hunk on stderr, and only accepts --allow-loose when the caller has manually reviewed an intentionally ambiguous insertion.",
      "script defaults to target /bin/sh and inherits provider proxy variables such as HTTP_PROXY/HTTPS_PROXY/ALL_PROXY/NO_PROXY; use --shell bash only for bash syntax such as pipefail, arrays, or [[ ... ]], not as a proxy workaround.",
      "Route syntax is `{provider}:{plane}[:{scope...}] {operation} [operation-args...]`: the first argv token locates a distributed target only, and every following token belongs to the operation parser. Host workspace routes use `<provider>:/absolute/workspace`; WSL providers can use `<provider>:win cmd <command-line>` to run Windows host cmd.exe with UTF-8 defaults, and `<provider>:win/c/test cmd cd` maps the Windows cwd to `C:\\test`; native k3s providers such as D601 and G14 use <provider>:k3s for the control plane, <provider>:k3s:<namespace>:<workload> for a workload, and <provider>:k3s:<namespace>:<workload>/<pod-workspace> for a pod workspace.",
      "Use `win`, not `win32`; the win route sets chcp 65001, PYTHONUTF8=1, and PYTHONIOENCODING=utf-8 before running the requested cmd command line.",
      "`<provider>:win skills` discovers the current Windows user's `%USERPROFILE%\\.agents\\skills` by default; use `--scope all` to include `%USERPROFILE%\\.codex\\skills`.",
      "Do not put operation names in any colon route segment, including nested k3s namespace/workload/container segments.",
      "Do not use post-provider shorthand such as `trans G14 k3s ...`; write `trans G14:k3s ...` so location and operation stay separated.",
      "If an ssh-like remote command fails with timeout/kex/exit-255 friction, stderr includes one low-noise UNIDESK_SSH_HINT JSON line with the argv retry command.",
      "Non-interactive ssh/trans/tran operations have a hard top-level runtime timeout capped at 60s. Timeout writes UNIDESK_SSH_RUNTIME_TIMEOUT or UNIDESK_TRAN_TIMEOUT_HINT and disconnects the broker; long CI/CD, trace, logs, build, or hardware work must use submit-and-poll / short query loops instead of keeping trans open.",
      "Only slow ssh/trans/tran runtime writes UNIDESK_SSH_TIMING JSON to stderr; operations over 10s are marked level=warning even when they succeed, because slow successful calls are a distributed performance monitoring signal. Check provider latency, remote command cost, helper bootstrap, or remote patch optimization before repeating high-frequency work. Routine short calls do not emit timing noise.",
      "The local trans/tran wrapper must not add provider/plane directory locks; rely on k8s/Tekton/Argo/Lease or server-side TTL queues for coordination.",
      "Use -- before a remote command that intentionally starts with a dash.",
    ],
  };
}

function configHelp(): unknown {
  return {
    command: "config show",
    output: "json",
    usage: "bun scripts/cli.ts config show",
    description: "Validate and print the root config.json single source of truth.",
  };
}

function microserviceHelp(): unknown {
  return {
    command: "microservice list|status|health|diagnostics|tunnel-self-test|proxy",
    output: "json",
    usage: [
      "bun scripts/cli.ts microservice list",
      "bun scripts/cli.ts microservice status <id> [--full|--raw]",
      "bun scripts/cli.ts microservice health <id> [--compact|--full|--raw]",
      "bun scripts/cli.ts microservice diagnostics <id> [--full|--raw]",
      "bun scripts/cli.ts microservice tunnel-self-test <id>",
      "bun scripts/cli.ts microservice proxy <id> <path> [--method GET|POST|PUT|PATCH|DELETE] [--body-json JSON|--body-file path|--body-stdin] [--raw] [--full] [--max-body-bytes N]",
    ],
    description: "Access UniDesk-managed user services through the same backend-core/provider proxy path used by the WebUI.",
  };
}

function decisionHelp(): unknown {
  return {
    command: "decision upload|list|show|health|diary|requirement",
    output: "json",
    usage: [
      "bun scripts/cli.ts decision upload <markdown-file> [--title text] [--type meeting|decision] [--doc-no DC-...]",
      "bun scripts/cli.ts decision list [--doc-no DC-...] [--doc-type GOAL] [--doc-priority P0] [--year YYYY] [--limit N]",
      "bun scripts/cli.ts decision show <id|docNo>",
      "bun scripts/cli.ts decision health",
      "bun scripts/cli.ts decision diary import|list|history|months|today|show|edit|upsert ...",
      "bun scripts/cli.ts decision requirement list|create|show|update|upsert ... [--doc-no DC-...] [--doc-type GOAL] [--doc-priority P0] [--signer text] [--issued-at ISO]",
    ],
    description: "Operate Decision Center through the registered user-service proxy.",
  };
}

function providerHelp(): unknown {
  return {
    command: "provider attach|triage",
    output: "json",
    usage: [
      "bun scripts/cli.ts provider attach <providerId> [--master-server URL] [--up] [--force]",
      "bun scripts/cli.ts provider triage <providerId> [--observed-error text] [--observed-scope scope] [--microservice id ...] [--full|--raw]",
    ],
    description: "Generate the minimal provider-gateway attach env/compose bundle or run the read-only provider health triage contract.",
  };
}

function gcHelp(): unknown {
  return {
    command: "gc plan|run|db-trace|policy|remote",
    output: "json",
    usage: [
      "bun scripts/cli.ts gc plan",
      "bun scripts/cli.ts gc run --confirm",
      "bun scripts/cli.ts gc plan --logs-keep-days 7 --docker-log-max-bytes 50M --journal-target-size 512M",
      "bun scripts/cli.ts gc run --confirm --build-cache-all --include-browser-cache",
      "bun scripts/cli.ts gc run --confirm --include-browser-cache",
      "bun scripts/cli.ts gc db-trace plan --before-date 2026-05-25",
      "bun scripts/cli.ts gc db-trace run --confirm --before-date 2026-05-25 --vacuum-full",
      "bun scripts/cli.ts gc policy plan",
      "bun scripts/cli.ts gc policy install",
      "bun scripts/cli.ts gc remote G14 plan",
      "bun scripts/cli.ts gc remote G14 plan --target-use-percent 50 --include-hwlab-registry",
      "bun scripts/cli.ts gc remote G14 run --confirm",
      "bun scripts/cli.ts gc remote G14 status --job-id <id>",
      "bun scripts/cli.ts gc plan --full",
    ],
    description: "Plan or execute bounded one-time disk relief for file logs, Docker json logs, systemd journal, Docker BuildKit cache, allowlisted /tmp artifacts, scoped remote core dumps and explicitly scoped database trace telemetry retention.",
    safety: {
      default: "plan is read-only and mutation=false",
      runGuard: "run requires --confirm",
      protected: ["PostgreSQL PGDATA", "Docker volumes", "Docker images", "Baidu Netdisk staging/backups", "D601 registry storage"],
      database: "default gc run is database diagnostic-only; gc db-trace is the explicit trace telemetry retention path and requires --confirm plus --vacuum-full",
    },
    options: {
      "--logs-keep-days N": "delete UniDesk file logs older than N days; default 7",
      "--file-log-max-bytes SIZE": "compact newer large file logs above SIZE; default 50M",
      "--file-log-tail-bytes SIZE": "tail bytes kept when compacting file logs; default 20M",
      "--docker-log-max-bytes SIZE": "truncate Docker json-file logs above SIZE; default 50M",
      "--journal-target-size SIZE": "vacuum systemd journal to SIZE; default 512M",
      "--build-cache-until DURATION": "prune Docker builder cache unused for duration; default 24h",
      "--build-cache-all": "prune all Docker builder cache without an until filter",
      "--tmp-min-age-hours N": "delete allowlisted /tmp artifacts older than N hours; default 24",
      "--core-dump-min-age-hours N": "remote only: delete untracked allowlisted core.<pid> dumps older than N hours; default 1",
      "--no-core-dumps": "remote only: do not include scoped core dump cleanup candidates",
      "--include-hwlab-registry": "remote G14 only: opt in to conservative HWLAB registry tag and stale manifest-revision retention plus official registry garbage-collect",
      "--registry-gc-only": "remote G14 only: run official registry garbage-collect without deleting additional tags; intended for interrupted registry retention recovery",
      "--registry-keep-per-repo N": "remote registry only: keep at least N newest tags per service repo; default 20, minimum 1",
      "--registry-min-age-hours N": "remote registry only: keep all tags newer than N hours; default 48, minimum 0",
      "--target-use-percent N": "remote only: evaluate whether planned candidates can reduce root filesystem use to N%; reports required reclaim, projected use, shortfall and safe-stop decision",
      "--job-id ID": "remote status only: inspect a long-running remote gc job",
      "--limit N": "number of candidates returned and executed by run when --full is not set; default 50",
      "--result-limit N": "number of per-candidate run results returned when --full is not set; default 50",
      "--full|--raw": "return and run against all candidates rather than the default bounded page",
      "--include-browser-cache": "also remove repo-local .state/playwright-browsers cache",
      "db-trace --before-date YYYY-MM-DD": "plan or delete default trace telemetry event types before the date",
      "db-trace run --vacuum-full": "rewrite public.oa_events after deletion so df can reclaim disk; requires maintenance window",
      "policy plan|install": "render or install journald caps and a daily file-log plus allowlisted /tmp low-risk gc systemd timer",
      "remote <providerId> plan|run": "run bounded GC through UniDesk SSH passthrough on a provider host; G14 protects HWLAB k3s/runtime/PVC/workspace paths, and HWLAB registry retention is explicit opt-in with workload-ref, digest-closure, recent-tag and per-repo tag protection",
      "--no-file-logs|--no-docker-logs|--no-journal|--no-build-cache|--no-tmp|--no-db-summary": "disable one collector",
    },
    reference: "docs/reference/gc.md",
  };
}

function commanderHelp(): unknown {
  return {
    command: "commander contract|plan|smoke|approval|prompt-lint",
    output: "json",
    usage: [
      "bun scripts/cli.ts commander contract",
      "bun scripts/cli.ts commander plan --dry-run [--session-id id]",
      "bun scripts/cli.ts commander smoke --dry-run [--session-id id]",
      "bun scripts/cli.ts commander approval request --action <action> --dry-run [--reason text] [--task-id id]",
      "bun scripts/cli.ts commander prompt-lint --kind gpt55-pr (--prompt-file <file>|--stdin)",
    ],
    description: "Inspect the local host Codex commander skeleton contract, dry-run planner, no-daemon smoke validation plan, state helpers, trace summary aggregator, approval draft preview, and advisory GPT-5.5 PR prompt boundary lint.",
    boundary: [
      "the current skeleton is local-only and never attaches to live bridges",
      "dry-run commands never open SSH, PTY, or stdio bridges",
      "high-risk actions only produce a <=200 char Chinese ClaudeQQ approval draft and notification-path-unavailable blocker",
      "authorized future sends must use backend-core /api/microservices/claudeqq/proxy, not local skill or powershell paths",
      "prompt-lint is commander advisory output and does not change codex submit default behavior",
      "token and secret values must never be printed",
    ],
    promptLint: {
      command: "bun scripts/cli.ts commander prompt-lint --kind gpt55-pr --prompt-file <path>",
      stdin: "cat prompt.md | bun scripts/cli.ts commander prompt-lint --kind gpt55-pr --stdin",
      outputFields: ["ok", "missingClauses", "riskLevel", "suggestedPatchSnippet"],
      fullPromptEchoed: false,
      gate: "advisory-only; not a business PR gate and not a Code Queue submit admission change",
    },
    reference: "docs/reference/host-codex-commander.md",
  };
}

function scheduleHelp(): unknown {
  return {
    command: "schedule list|get|runs|run|retry-run|delete|upsert-pgdata-backup",
    output: "json",
    usage: [
      "bun scripts/cli.ts schedule list",
      "bun scripts/cli.ts schedule get <id>",
      "bun scripts/cli.ts schedule runs --limit N",
      "bun scripts/cli.ts schedule runs [scheduleId] [--limit N]",
      "bun scripts/cli.ts schedule run <id> [--wait-ms N]",
      "bun scripts/cli.ts schedule retry-run <failedRunId>",
      "bun scripts/cli.ts schedule delete <id>",
      "bun scripts/cli.ts schedule upsert-pgdata-backup [--time HH:MM] [--remote-base path]",
    ],
    description: "Manage backend-core scheduled tasks and run history through the private core API. Global runs use schedule runs --limit N; schedule-specific runs pass a non-numeric schedule id.",
  };
}

function codexHelp(): unknown {
  return {
    command: "codex deploy|prompt-lint|submit|task|tasks|unread|output|read|dev-ready|skills-sync|execution-plane|pr-preflight|judge|steer|resume|interrupt|cancel|queues|queue|move",
    output: "json",
    usage: [
      "bun scripts/cli.ts codex deploy <commitId> # disabled legacy deployment entry",
      "bun scripts/cli.ts codex prompt-lint [prompt|--prompt-file path|--prompt-stdin]",
      "bun scripts/cli.ts codex submit [prompt] [--prompt-file path|--prompt-stdin] [--queue id] [--model model] [--dry-run]",
      "cat <<'PROMPT' | bun scripts/cli.ts codex submit --prompt-stdin --queue <id> --dry-run",
      "bun scripts/cli.ts codex submit --prompt-file /tmp/code-queue-prompt.md --queue <id> --dry-run",
      "bun scripts/cli.ts codex task <taskId> [--detail] [--trace --tail|--from-start|--after-seq N|--before-seq N --limit N] [--full]",
      "bun scripts/cli.ts codex tasks [--view commander|supervisor|full] [--queue id] [--status succeeded,running] [--unread|--unread-only] [--limit N] [--before-id id]",
      "bun scripts/cli.ts codex unread [--repo owner/name] [--issue N] [--limit N]",
      "bun scripts/cli.ts codex unread mark-read [--repo owner/name] [--issue N] [--limit N] --confirm",
      "bun scripts/cli.ts codex output <taskId> [--tail|--from-start|--after-seq N|--before-seq N --limit N] [--full-text]",
      "bun scripts/cli.ts codex read <taskId>",
      "bun scripts/cli.ts codex dev-ready",
      "bun scripts/cli.ts codex skills-sync --dry-run [--full]",
      "bun scripts/cli.ts codex execution-plane [--full|--raw]",
      "bun scripts/cli.ts codex pr-preflight [--remote] [--push-dry-run --push-dry-run-ref refs/heads/probe/<name>] [--pr-create-dry-run --pr-create-dry-run-head <head>] [--issue N] [--full|--raw]",
      "bun scripts/cli.ts codex judge <taskId> --attempt N [--dry-run] [--include-prompt]",
      "bun scripts/cli.ts codex steer <taskId> [prompt|--prompt-file path|--prompt-stdin] [--steer-id id] [--dry-run] [--no-retry|--retry-attempts N] [--full|--raw]",
      "bun scripts/cli.ts codex resume <taskId> [prompt|--prompt-file path|--prompt-stdin] [--resume-id id] [--dry-run] [--full|--raw]",
      "bun scripts/cli.ts codex steer-confirm <taskId> --steer-id <id> [--raw]",
      "bun scripts/cli.ts codex interrupt|cancel <taskId>",
      "bun scripts/cli.ts codex queues [--commander] [--full|--all] [--limit N] [--page N|--offset N] | queue create <queueId> | queue merge <sourceQueueId> --into <targetQueueId> | move <taskId> --queue <queueId>",
    ],
    promptInput: {
      recommended: ["--prompt-stdin", "--prompt-file"],
      stdin: "Use a quoted heredoc or pipe when the prompt contains newlines, quotes, backticks, JSON, Markdown tables, or shell-sensitive text.",
      file: "Use --prompt-file for reviewed or reusable dispatch prompts; --file is an alias.",
      positional: "Keep positional prompt usage to short one-line smoke prompts only.",
      sourceRule: "Exactly one prompt source is accepted: positional prompt, --prompt-file, or --prompt-stdin.",
    },
    executionMode: {
      validModes: ["default", "windows-native"],
      boundary: "--execution-mode selects Code Queue runtime placement, not Codex sandbox permissions.",
      permissionVisibility: "Submit dry-runs show requested/effective mode; real submit responses include service runnerPermissions.sandbox and approvalPolicy.",
    },
    submitSummary: {
      default: "Real codex submit is a compact write confirmation: accepted status, submitted task ids, submitted status/source, queue ids, promptOmitted=true, queue counts, activity and drill-down commands.",
      listSemantics: "Task id previews are bounded objects; if a count is nonzero but ids are omitted or unavailable, the field sets idsUnavailable=true and does not print items=[] as if the list were empty.",
      splitBrainLive: "When split-brain-live heartbeat evidence is present, submit summaries keep the live disposition visible and continue to count heartbeat/database active tasks as active.",
      rawDrillDown: "Use queue.listPreviewPolicy.rawCommand or bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview?limit=30 --raw --full for raw queue detail.",
    },
    readOutput: {
      default: "codex read marks a terminal task read and returns terminal metadata, final response, last error/judge, counts, and drill-down commands.",
      disclosure: "Full prompt, tool logs, and feedback prompts are not printed by codex read; use codex task/detail/trace/output for progressive disclosure.",
    },
    unreadTriage: {
      default: "codex unread is read-only by default and returns counts, buckets, compact task rows, and one-time drill-down templates; per-task command blocks require --full or list.",
      mutationGuard: "Batch mark-read is blocked unless the explicit mark-read subcommand is used with --confirm; use codex read <taskId> for per-task review.",
      disclosure: "Raw prompt, final response, trace and output are omitted; use the returned task/detail/trace/output/read commands for drill-down.",
    },
    queuesSummary: {
      default: "codex queues defaults to commander-first summary mode; --commander is an explicit alias, while --full keeps the same bounded queue rows with compatibility metadata.",
      commanderPath: "data.queues.commander",
      stableRowsPath: "data.queues.items[]",
      fields: ["activeRunnerCount", "source", "target=15", "slotDeficit", "runningTasks", "heartbeat.fresh", "heartbeat.risk", "heartbeat.staleRecoveryCandidates", "queuedCount"],
      rule: "Use data.queues.commander.activeRunnerCount and slotDeficit for quick capacity decisions; activeQueueIds are scheduler-local and can be empty during split-brain live.",
    },
    executionPlane: {
      command: "bun scripts/cli.ts codex execution-plane",
      mutation: false,
      kubeconfig: "/etc/rancher/k3s/k3s.yaml",
      namespace: "unidesk",
      defaultPolicy: "compact drift/residual summary; deployments, pods and services require --full, raw sanitized observations require --raw",
      blockers: ["deployment-drift", "deprecated-compose-residual", "d601-k3s-guard-blocked"],
    },
    examples: {
      promptLint: "bun scripts/cli.ts codex prompt-lint --prompt-file /tmp/code-queue-prompt.md",
      stdin: [
        "cat <<'PROMPT' | bun scripts/cli.ts codex submit --prompt-stdin --queue <id> --dry-run",
        "<multi-line prompt body>",
        "PROMPT",
      ],
      file: "bun scripts/cli.ts codex submit --prompt-file /tmp/code-queue-prompt.md --queue <id> --dry-run",
      dryRunThenSubmit: "Run with --dry-run first; remove --dry-run to submit exactly the same payload.",
    },
    disclosure: {
      defaultPolicy: "low-noise JSON by default; write commands confirm persistence, list/detail/output commands return bounded summaries with drill-down commands",
      expand: ["codex task <taskId> --full", "codex task <taskId> --trace --limit N", "codex output <taskId> --after-seq N --limit N --full-text", "codex tasks --view full --limit N", "codex skills-sync --dry-run --full", "codex execution-plane --full"],
    },
    activityFields: {
      path: "data.queues.activity and data.supervisor.activity",
      effectiveActiveTaskCount: "Commander-facing active count derived from database active/running tasks and heartbeat-fresh runners.",
      commanderConcurrency: "Use data.supervisor.commanderConcurrency.activeRunnerCount or data.queues.commanderConcurrency.activeRunnerCount for concurrency decisions; the block states the 15-runner arithmetic and intervention signal.",
      schedulerLocalActiveQueueCount: "Only queues currently visible in this scheduler-local active-run slot view; zero does not override DB or heartbeat activity.",
      heartbeatFreshActiveTaskCount: "Heartbeat-effective active runner count used to avoid split-brain zero-active mistakes.",
    },
    supervisorView: {
      activeRunning: "Use data.supervisor.activeRunning.count for exact active running+judging count when exact=true; data.supervisor.running.returned is only the compact row page.",
      redline: "data.supervisor.activeRunning.redline names the count field, routine target, burst redline, hard redline, and decisionReady flag.",
      limitSemantics: "filters.requestedLimit preserves the user input; filters.limit/effectiveLimit shows the capped query budget; section outputBudget/rowPage show returned-row caps.",
    },
    promptLiveAuthorization: {
      classes: ["read-only", "live-read", "live-mutating"],
      defaultWhenMissing: "read-only",
      command: "bun scripts/cli.ts codex prompt-lint --prompt-file <path>",
      embeddedIn: ["codex submit --dry-run", "codex steer --dry-run"],
      reference: "docs/reference/code-queue-supervision.md#dev-测试授权分级",
    },
    description: "Operate Code Queue through the stable backend-core private proxy path with bounded activity summaries for queue and supervisor views. Real submit/steer success is a low-noise write confirmation and does not echo prompt text; steer output includes steerId, delivery state, and a bounded trace confirmation command; terminal steer rejection returns compact status plus codex task/read/submit follow-up commands, with upstream/raw details behind --full or --raw.",
  };
}

function jobHelp(): unknown {
  return {
    command: "job list|status|cancel",
    output: "json",
    usage: [
      "bun scripts/cli.ts job list [--limit N] [--include-command]",
      "bun scripts/cli.ts job status <jobId|latest> [--tail-bytes N]",
      "bun scripts/cli.ts job cancel <jobId>",
    ],
    description: "Inspect or cancel fire-and-forget job state from .state/jobs with structured progress summaries and bounded log tails.",
  };
}

function debugHelp(): unknown {
  return {
    command: "debug health|dispatch|task",
    output: "json",
    usage: [
      "bun scripts/cli.ts debug health",
      "bun scripts/cli.ts debug dispatch [providerId] [docker.ps|provider.upgrade|host.ssh|microservice.http|echo] [--wait-ms N]",
      "bun scripts/cli.ts debug task <taskId|latest>",
    ],
    description: "Debug the real core/provider/dispatch paths; do not use these as formal TEST.md acceptance steps.",
  };
}

function networkHelp(): unknown {
  return {
    command: "network perf",
    output: "json",
    usage: "bun scripts/cli.ts network perf [--service id --path /api/path --count N --concurrency N --label text]",
    description: "Benchmark frontend/backend/provider user-service networking with bounded JSON latency summaries.",
  };
}

function e2eHelp(): unknown {
  return {
    command: "e2e run",
    output: "json",
    usage: "bun scripts/cli.ts e2e run [--only pattern[,pattern...]] [--skip pattern[,pattern...]]",
    description: "Run selected public/internal/Playwright E2E checks; use filters for focused iteration and full run for final regression.",
  };
}

function devEnvHelp(): unknown {
  return {
    command: "dev-env validate|prewarm-images",
    output: "json",
    usage: [
      "bun scripts/cli.ts dev-env validate [--manifest path] [--kubectl-dry-run]",
      "bun scripts/cli.ts dev-env prewarm-images [--image image] [--provider-id D601] [--no-pull] [--dry-run]",
    ],
    description: "Validate D601 unidesk-dev guardrails or prewarm foundation images into native k3s containerd.",
  };
}

function artifactRegistryHelp(): unknown {
  return {
    command: "artifact-registry plan|render|status|health|install|deploy-backend-core|deploy-service",
    output: "json",
    usage: [
      "bun scripts/cli.ts artifact-registry plan [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry render [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry status [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry health [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry install [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --service baidu-netdisk --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --service frontend --env prod --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --service frontend --env dev --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env dev --service decision-center --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service decision-center --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service project-manager --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service oa-event-flow --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service code-queue-mgr --commit <full-sha> --dry-run [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service todo-note --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env dev --service findjob --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service findjob --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env dev --service pipeline --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service pipeline --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env dev --service met-nonlinear --commit <full-sha> --dry-run [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service met-nonlinear --commit <full-sha> --dry-run [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service k3sctl-adapter --commit <full-sha> --dry-run [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env dev --service mdtodo --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service mdtodo --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env dev --service claudeqq --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env prod --service claudeqq --commit <full-sha> [--dry-run] [--run-now] [--provider-id D601]",
      "bun scripts/cli.ts artifact-registry deploy-service --env dev --service code-queue --commit <full-sha> --dry-run [--provider-id D601]",
    ],
    description: "Manage the declaration, rendered files and readonly checks for the D601 host-managed CNCF Distribution artifact registry.",
    boundary: [
      "registry endpoint is D601 loopback 127.0.0.1:5000 only",
      "service is host-managed by systemd + Docker Compose, not k3s-managed",
      "install writes the rendered host unit/config and starts the registry",
      "deploy-backend-core only pulls commit-pinned backend-core artifacts and does not build backend-core on the master server",
      "deploy-service currently supports backend-core, baidu-netdisk, prod/dev frontend, decision-center, mdtodo, claudeqq, project-manager, oa-event-flow, code-queue-mgr, todo-note, findjob, pipeline, met-nonlinear, k3sctl-adapter, and dev-only code-queue as standardized consumers",
      "findjob and pipeline have D601 direct dev/prod Compose artifact consumers; met-nonlinear is runtime-verification blocked; k3sctl-adapter is supervisor-only",
      "code-queue has no prod artifact deploy target; dev requests are dry-run evidence only unless a human operator or supervisor authorizes DEV apply outside Code Queue",
      "status and health use provider-gateway Host SSH readonly checks",
    ],
    legacyEntrypoints: {
      "deploy-backend-core": {
        deprecated: true,
        enabled: false,
        replacement: "bun scripts/cli.ts deploy apply --env prod --service backend-core --commit <full-sha>",
      },
    },
  };
}

export function staticNamespaceHelp(args: string[]): unknown | null {
  const [top, sub] = args;
  if (!args.slice(1).some(isHelpToken)) return null;
  if (top === "config") return configHelp();
  if (top === "microservice") return microserviceHelp();
  if (top === "decision" || top === "decision-center") return decisionHelp();
  if (top === "provider") return providerHelp();
  if (top === "gc") return gcHelp();
  if (top === "commander") return commanderHelp();
  if (top === "schedule") return scheduleHelp();
  if (top === "codex") return codexHelp();
  if (top === "job") return jobHelp();
  if (top === "debug") return debugHelp();
  if (top === "network") return networkHelp();
  if (top === "e2e") return e2eHelp();
  if (top === "dev-env") return devEnvHelp();
  if (top === "artifact-registry") return artifactRegistryHelp();
  if (top === "auth-broker") return authBrokerHelp();
  if (top === "gh") return ghHelp();
  if (top === "agentrun") return agentRunHelp();
  if (top === "hwlab" && sub === "g14") return hwlabG14Help();
  if (top === "hwlab") return hwlabHelp();
  return null;
}
