Files
pikasTech-unidesk/scripts/src/help.ts
T
2026-07-11 22:25:56 +02:00

1023 lines
81 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// SPEC: PJ2026-01060509 出站诊断 draft-2026-06-26-p8-egress-job-friction.
// SPEC: PJ2026-01060703 CI/CD branch follower draft-2026-07-03-p0-branch-follower.
// Static CLI help for job aliases and server lifecycle progressive disclosure.
import { join } from "node:path";
import { ghHelp, ghScopedHelp } from "./gh";
import { authBrokerHelp } from "./auth-broker";
import { platformDbHelp } from "./platform-db";
import { secretsHelp } from "./secrets";
import { healthHelp } from "./health";
import { repoRoot } from "./config";
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|--scripts-typecheck-timeout-ms N|--check-heartbeat-ms N|--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; long command checks emit progress heartbeats and bounded timeout details." },
{ command: "health [--json|--full|--skills-dir path|--threshold-bytes N]", description: "Check repo skill SKILL.md size health; files over 10 KiB alert and must move lower-frequency detail into .agents/skills/<skill_id>/references/." },
{ 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|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: "server restart <backend-core|frontend|dev-frontend-proxy|provider-gateway|pk01-postgres-relay|code-queue-mgr|project-manager|baidu-netdisk|oa-event-flow>", description: "No-build single-service Compose restart for reviewed main-server maintenance recovery; returns an async job and validates the recreated container." },
{ 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; provider WebSocket carries control and host.ssh.tcp-pool carries stdin/stdout/stderr data." },
{ command: "trans gh:/owner/repo[/pr|/issue][/number[/1]] ls|cat|rg|apply-patch", description: "Treat GitHub PRs/issues as virtual text directories; `issue ls --search/--state` covers filtered reads, `cat|rg` reads first-floor body text, and `apply-patch` updates `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 automatic endpoint byte/SHA-256 verification; downloads stream stdout over host.ssh.tcp-pool." },
{ 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> sh|bash [arg...] <<'SH|BASH' ...", description: "Run a remote POSIX sh or Bash body from local stdin; the operation name declares the shell dialect, and removed `script`/`shell` operations fail with a migration hint." },
{ 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|sh|bash|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 explicit `sh` or `bash` 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] [--check-path] [--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; --check-path (currently todo-note only) validates the path/method against the registered CLI-side endpoint catalog without contacting upstream." },
{ 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: "todo-note list|show|add|update|complete|reopen|remind|delete|undo|redo|create|rename|delete-list|health", description: "Manage Todo Note through concise list/todo resource commands; default output is a bounded table and --json is explicit." },
{ 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|--body text|--summary text] [--title text] [--tag tag]", description: "Get or create today's diary entry using the service's real current date; --edit saves today's Markdown and optional explicit summary." },
{ 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|--body text] [--summary text] [--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, keeping summary independent from body." },
{ 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: "cicd status --node <NODE>", description: "Show one node's CI/CD closeout summary across current Pipelines-as-Code consumers, including PipelineRun, Argo and runtime readiness." },
{ command: "cicd gitea-actions-poc plan|status", description: "Archived read-only CI/CD migration evidence for GH-1548/GH-1549; never use as a delivery or closeout path." },
{ command: "cicd branch-follower status|events|logs|taskrun|runtime|debug-step", description: "退役 branch-follower 的只读历史诊断;当前 lane 只使用 cicd status 与 platform-infra pipelines-as-code status/history 观察自动链。" },
{ command: "dev-env validate|prewarm-images|worktree add", description: "Validate D601 guardrails, prewarm dev images, or create UniDesk task worktrees with .worktreecopy local config copying." },
{ 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, issue/comment apply_patch body patching, comment delete, token diagnostics, PR closeout preflight, hard delete unsupported, and guarded PR merge." },
{ command: "git github-push-fallback [--repo owner/name] [--branch branch] [--host-name host-or-ip] [--confirm]", description: "Plan or execute a one-shot GitHub push through ssh.github.com:443 without editing remotes; use only for reviewed DNS/port-22 push fallback." },
{ command: "commander contract|plan --dry-run|smoke --dry-run|approval request --dry-run", description: "Host Codex commander skeleton contract, no-daemon smoke plan, and dry-run approval preview without live bridges or message sends." },
{ command: "web-probe run|script|observe|sentinel --node <node> --lane <lane>", description: "Run YAML-selected HWLAB Web probes, long observe/analyze sessions, project-management MDTODO commands, and Web sentinel control through the single top-level web-probe entrypoint." },
{ command: "hwlab nodes control-plane|git-mirror|hwpod-preinstall|secret|test-accounts --node <node> --lane <lane>", description: "Manage HWLAB node/lane runtime prerequisites, including NC01 YAML-declared k3s infra/tools-image/Argo bootstrap, HWPOD preinstall configRefs, redacted test-account preparation, and NC01 v0.3 runtime lane, with the node identity passed as data." },
{ command: "hwlab nodes control-plane|git-mirror|hwpod-preinstall|secret|test-accounts --node NC01 --lane v03", description: "Operate the NC01 HWLAB v0.3 development and deployment lane from YAML source truth." },
{ command: "agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|send|control-plane|git-mirror", description: "Use AgentRun v0.1 resource primitives with low-noise human output by default; session follow-up uses send only and the server decides internal steer vs turn." },
{ command: "platform-infra sub2api|langbot|n8n|webterm|wechat-archive ...", description: "Deploy platform-infra services such as Sub2API, LangBot, n8n and Web Terminal, manage YAML-controlled public Caddy/FRP exposure and WeChat archive workflows, and inspect status/logs without printing secrets." },
{ command: "secrets plan|sync|status", description: "Plan, push and inspect YAML-declared local secret source keys to Kubernetes Secrets without printing or reverse-engineering values." },
{ command: "platform-db postgres plan|status|export-secrets|apply", description: "Manage YAML-declared host-native PostgreSQL 16 on PK01 for Sub2API/platform state, with PostgreSQL native TLS and redacted secret exports." },
{ command: "hwlab cd audit --env dev | hwlab cd status --env dev | hwlab cd apply --env dev --dry-run", description: "Archived HWLAB DEV CD diagnostics only; current HWLAB rollout uses NC01 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> [--target <id>] [--timeout-ms N]", description: "Disabled legacy Code Queue deploy path; use the dev-only artifact consumer instead." },
{ command: "codex submit|steer|resume|queue create|queue merge|move", description: "Frozen legacy Code Queue write commands; use agentrun create/apply/send for new commander work. Historical codex task/tasks/output/read/unread/queues remain available for archive troubleshooting." },
{ 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> / codex resume <taskId>", description: "Frozen legacy execution mutation entries; use agentrun send/logs/events/result/ack/cancel against AgentRun resources instead." },
{ 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] [--limit N] [--page N|--offset N]", description: "Read legacy Code Queue archive summaries. Legacy queue create/merge and move are frozen; use agentrun create/apply/get/cancel for new work." },
{ command: "job|jobs list [--limit N] [--include-command]", description: "List async jobs from /root/.unidesk/.state/jobs with a bounded default page and progress summaries." },
{ command: "job status|get|read <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 /root/.unidesk/.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 ssh-pool <providerId>", description: "Show bounded host.ssh.tcp-pool labels for one provider, including ready/claimed/desired/lastError." },
{ command: "debug egress-proxy <providerId>", description: "Show provider-gateway egress proxy tunnel counts, stale tunnel diagnosis, active target summaries, and recent closed tunnel lifecycle without URL credential leakage." },
{ command: "debug provider-rootfs <providerId>", description: "Run a read-only provider-gateway rootfs diagnostic over trans: image id, runtime smoke, docker system df snapshot errors, and recent host_ssh lifecycle lines." },
{ 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|restart" : `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|code-queue-mgr|project-manager|baidu-netdisk|oa-event-flow>",
restart: "bun scripts/cli.ts server restart <backend-core|frontend|dev-frontend-proxy|provider-gateway|pk01-postgres-relay|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 routine Rust iteration; only reviewed backend-core main-server online may use the constrained rebuild path",
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",
restart: "server restart is for no-build single-service recovery when the existing image is already present and the goal is to refresh runtime state",
},
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 type SshHelpScope =
| "argv" | "exec" | "git" | "node" | "kubectl" | "logs"
| "sh" | "bash" | "py" | "ps" | "cmd"
| "pwd" | "ls" | "cat" | "head" | "tail" | "stat" | "wc" | "rg" | "find" | "glob" | "skills"
| "apply-patch" | "apply-patch-v1" | "upload" | "download";
type SshOperationHelp = {
group: "process" | "shell" | "filesystem" | "patch" | "transfer";
description: string;
usage: string[];
notes?: string[];
};
const SSH_OPERATION_HELP: Record<SshHelpScope, SshOperationHelp> = {
argv: {
group: "process",
description: "以原始 argv 边界运行一个远端进程;需要管道、变量或重定向时改用 sh/bash。",
usage: ["trans <route> argv <command> [args...]", "trans D601:/workspace argv git status --short --branch"],
},
exec: {
group: "process",
description: "在 k3s workload route 中运行进程,并可显式透传 stdin 或指定容器内 cwd。",
usage: ["trans <provider>:k3s:<namespace>:<workload>[:<container>] exec [--cwd /path] [--stdin] -- <command> [args...]"],
},
git: {
group: "process",
description: "在 host/workspace 或 Windows workspace route 中运行 Git convenience wrapper。",
usage: ["trans <provider>:/workspace git status --short --branch", "trans <provider>:win/<drive>/<path> git diff --check"],
},
node: {
group: "process",
description: "在目标 route 中直接运行 Node.js argv。",
usage: ["trans <route> node -e 'console.log(process.version)'"],
},
kubectl: {
group: "process",
description: "在 k3s control-plane route 上执行有界 kubectl 诊断。",
usage: ["trans <provider>:k3s kubectl get pods -n <namespace>"],
},
logs: {
group: "process",
description: "从 k3s control-plane 或 workload route 读取有界日志。",
usage: ["trans <provider>:k3s:<namespace>:<workload> logs --tail 80", "trans <provider>:k3s logs -n <namespace> -l <selector> --tail 120"],
},
sh: {
group: "shell",
description: "从 stdin 或单个命令字符串执行远端 POSIX /bin/sh。",
usage: ["trans <route> sh <<'SH'", "trans <route> sh -- '<command && command>'"],
notes: ["sh -- 只接受一个 shell command string;单进程多 argv 使用 argv。"],
},
bash: {
group: "shell",
description: "仅在需要 pipefail、数组、[[ ]] 等 Bash 语法时执行远端 Bash。",
usage: ["trans <route> bash <<'BASH'", "trans <route> bash -- '<bash command>'"],
},
py: {
group: "shell",
description: "从本地 stdin 执行远端 Python 源码,并保留 script argv。",
usage: ["trans <route> py [script-args...] < script.py"],
},
ps: {
group: "shell",
description: "在 Windows route 中执行 PowerShell 源码或 argvroute 已包含 win。",
usage: ["trans <provider>:win[/<drive>/<path>] ps <<'PS'", "trans <provider>:win ps '<PowerShell source>'"],
},
cmd: {
group: "shell",
description: "在 Windows route 中以 UTF-8 环境执行 cmd.exe/batch。",
usage: ["trans <provider>:win[/<drive>/<path>] cmd <<'CMD'", "trans <provider>:win cmd ver"],
},
pwd: { group: "filesystem", description: "读取 Windows workspace 当前目录。", usage: ["trans <provider>:win/<drive>/<path> pwd"] },
ls: { group: "filesystem", description: "有界列出 Windows workspace 文件。", usage: ["trans <provider>:win/<drive>/<path> ls --limit 50"] },
cat: { group: "filesystem", description: "读取远端文本文件;二进制文件使用 download。", usage: ["trans <route> cat <path>"] },
head: { group: "filesystem", description: "按行读取远端文本文件开头。", usage: ["trans <route> head -n 40 <path>"] },
tail: { group: "filesystem", description: "按行读取远端文本文件结尾。", usage: ["trans <route> tail -n 40 <path>"] },
stat: { group: "filesystem", description: "读取远端文件元数据。", usage: ["trans <route> stat <path>"] },
wc: { group: "filesystem", description: "统计远端文本的行、词、字符或字节。", usage: ["trans <route> wc [-l|-w|-m|-c] <path>"] },
rg: { group: "filesystem", description: "执行有界远端 ripgrepWindows route 使用受控 UTF-8 子集。", usage: ["trans <route> rg [options] <pattern> [path...]"] },
find: { group: "filesystem", description: "不依赖 shell quoting 的结构化远端 find。", usage: ["trans <route> find <path...> [--contains TEXT] [--limit N]"] },
glob: { group: "filesystem", description: "通过远端 helper 执行有界 glob 匹配。", usage: ["trans <route> glob [--root DIR] [--pattern PATTERN] [--limit N]"] },
skills: { group: "filesystem", description: "发现 WSL/Linux 及可选 Windows skill 目录。", usage: ["trans <provider> skills [--scope all|wsl|windows] [--limit N]"] },
"apply-patch": {
group: "patch",
description: "默认远端文本修改入口;本地 v2 engine 计算变更,route 仅负责读写。",
usage: ["trans <route> apply-patch [--cwd /path] < patch.diff"],
notes: ["失败后重读当前目标块并缩小 hunk;不得自动回退 apply-patch-v1 或整文件 upload。"],
},
"apply-patch-v1": {
group: "patch",
description: "显式调用 legacy remote apply_patch helper;只作为人工确认后的兼容入口。",
usage: ["trans <route> apply-patch-v1 [--allow-loose] < patch.diff"],
},
upload: {
group: "transfer",
description: "上传必要的二进制文件或生成物并自动核对字节数与 SHA-256。",
usage: ["trans <route> upload <local-file> <remote-file>"],
notes: ["远端文本读取使用 cat/rg,修改使用 apply-patch。"],
},
download: {
group: "transfer",
description: "下载必要的二进制文件或生成物并自动核对字节数与 SHA-256。",
usage: ["trans <route> download <remote-file> <local-file>"],
},
};
const SSH_OPERATION_GROUPS = {
process: ["argv", "exec", "git", "node", "kubectl", "logs"],
shell: ["sh", "bash", "py", "ps", "cmd"],
filesystem: ["pwd", "ls", "cat", "head", "tail", "stat", "wc", "rg", "find", "glob", "skills"],
patch: ["apply-patch", "apply-patch-v1"],
transfer: ["upload", "download"],
} as const satisfies Record<SshOperationHelp["group"], readonly SshHelpScope[]>;
const SSH_HELP_SCOPES = Object.keys(SSH_OPERATION_HELP) as SshHelpScope[];
const SSH_HELP_SCOPE_SET = new Set<string>(SSH_HELP_SCOPES);
function sshEntrypoint(): "trans" | "tran" | "ssh" {
const rawEntrypoint = process.env.UNIDESK_SSH_ENTRYPOINT?.trim();
return rawEntrypoint === "trans" || rawEntrypoint === "tran" || rawEntrypoint === "ssh" ? rawEntrypoint : "ssh";
}
export function sshHelpScope(args: string[]): SshHelpScope | undefined {
const [top, helpToken, scope] = args;
if (top !== "ssh" || args.length !== 3 || !isHelpToken(helpToken) || !SSH_HELP_SCOPE_SET.has(scope ?? "")) return undefined;
return scope as SshHelpScope;
}
export function sshHelp(scope: SshHelpScope | undefined = undefined): unknown {
if (scope === "download") return sshDownloadHelp();
if (scope !== undefined) return sshOperationHelp(scope);
const entrypoint = sshEntrypoint();
const operationGroups = Object.fromEntries(
Object.entries(SSH_OPERATION_GROUPS).map(([group, operations]) => [group, operations.join(" | ")]),
);
return {
command: `${entrypoint} --help`,
output: "json",
description: "通过 provider-gateway bridge 访问 Host SSH、WSL、Windows 或 k3s 目标。",
routeSyntax: {
general: `${entrypoint} <route> <operation> [operation-args...]`,
hostWorkspace: "<provider>:/absolute/workspace",
k3sControlPlane: "<provider>:k3s",
k3sWorkload: "<provider>:k3s:<namespace>:<workload>[:<container>]",
windowsWorkspace: "<provider>:win[/<drive>/<path>]",
githubContent: "gh:/<owner>/<repo>[/issue|/pr]/<number>",
},
operationGroups,
scopedHelp: {
command: `${entrypoint} --help <operation>`,
availableOperationCount: SSH_HELP_SCOPES.length,
examples: [`${entrypoint} --help apply-patch`, `${entrypoint} --help download`, `${entrypoint} --help ps`],
},
boundaries: [
"route 只定位目标,route 后的 token 全部交给 operation parser。",
"单进程优先 argvshell 逻辑显式使用 sh/bashWindows 使用 ps/cmd。",
"远端文本读取优先 cat/rg,修改优先 apply-patchupload/download 仅用于必要的二进制或生成物。",
"普通 trans 短连接上限保持 60s;长流程使用受控 submit-and-poll 入口。",
],
};
}
function sshOperationHelp(scope: Exclude<SshHelpScope, "download">): unknown {
const entrypoint = sshEntrypoint();
const detail = SSH_OPERATION_HELP[scope];
return {
command: `${entrypoint} --help ${scope}`,
output: "json",
scope,
group: detail.group,
description: detail.description,
routeSyntax: `${entrypoint} <route> ${scope} [operation-args...]`,
usage: detail.usage.map((value) => value.replace(/^trans\b/u, entrypoint)),
notes: detail.notes ?? [],
next: [`${entrypoint} --help`, `${entrypoint} --help ${scope}`],
};
}
function sshDownloadHelp(): unknown {
const configuredRepoRoot = process.env.UNIDESK_TRANS_REPO_ROOT?.trim() || null;
const entrypoint = sshEntrypoint();
return {
command: `${entrypoint} --help download`,
output: "json",
scope: "download",
description: "下载一个必要的二进制文件或生成物,并自动核对远端/本地字节数与 SHA-256;远端文本改用 cat/rg/apply-patch。",
runtime: {
entrypoint,
repoRoot,
cliPath: join(repoRoot, "scripts", "ssh-cli.ts"),
cwdSelectsRepoRoot: false,
rootSelection: {
environmentVariable: "UNIDESK_TRANS_REPO_ROOT",
configuredValue: configuredRepoRoot,
explicitExample: `UNIDESK_TRANS_REPO_ROOT=${repoRoot} trans --help download`,
note: "The PATH wrapper selects its source root independently of cwd; set UNIDESK_TRANS_REPO_ROOT explicitly when validating a worktree implementation.",
},
},
usage: [
"trans <route> download <remote-file> <local-file>",
"trans <route> download --inactivity-timeout-ms <milliseconds> <remote-file> <local-file>",
"trans --help download",
],
options: {
"--inactivity-timeout-ms <milliseconds>": "Allow a controlled progress-emitting download to stay open while data continues flowing; ordinary trans operations retain the short runtime budget.",
},
contract: {
hint: "避免对远端文本反复 upload/download;读取优先使用 cat/rg,修改优先使用 apply-patch。",
pathOrder: ["remote-file", "local-file"],
transport: "host.ssh.tcp-pool",
strategy: "tcp-pool-stdout-stream",
progress: "unidesk.ssh.download.progress JSON is emitted on stderr with bytes, remainingBytes and throughputBytesPerSecond.",
verification: {
automatic: true,
fields: ["bytes", "sha256"],
success: "verified=true and verification.match.{bytes,sha256}=true",
partialFilePolicy: "The local target is removed when streaming or verification fails.",
},
},
examples: {
host: "trans D601:/tmp download /tmp/trace.json ./trace.json",
k3sWorkload: "trans NC01:k3s:hwlab-v03:hwlab-cloud-api:hwlab-cloud-api download /tmp/trace.json ./trace.json",
windowsDrive: "trans D601:win download 'D:\\tmp\\trace.json' ./trace.json",
explicitWorktree: `UNIDESK_TRANS_REPO_ROOT=${repoRoot} trans NC01:k3s:hwlab-v03:hwlab-cloud-api:hwlab-cloud-api download /tmp/trace.json ./trace.json`,
},
notes: [
"A k3s download requires a workload route; the control-plane-only <provider>:k3s route cannot name a remote file inside a workload.",
"Windows drive-letter paths are mapped through the same provider's WSL /mnt/<drive> host route before verified stdout streaming.",
"The final JSON result is the integrity proof; a separate manual sha256sum comparison is not required.",
],
};
}
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] [--check-path] [--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|deployment|storage",
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]",
"bun scripts/cli.ts decision deployment plan|render|status [--config config/unidesk-host-k8s.yaml]",
"bun scripts/cli.ts decision deployment apply --dry-run|--confirm [--config config/unidesk-host-k8s.yaml]",
"bun scripts/cli.ts decision storage plan|status|verify [--config config/unidesk-host-k8s.yaml]",
"bun scripts/cli.ts decision storage migrate --dry-run|--confirm [--config config/unidesk-host-k8s.yaml]",
],
description: "Operate Decision Center through the registered user-service proxy and manage its NC01 YAML-first k8s deployment.",
};
}
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 plan --target-use-percent 59 --include-state-artifacts --state-artifact-keep-days 14 --full",
"bun scripts/cli.ts gc plan --include-codex-sessions --include-merged-worktrees --include-state-stale-scratch",
"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 YAML-configured bounded one-time disk relief for file logs, Docker json logs, systemd journal, Docker BuildKit cache, allowlisted /tmp artifacts, opt-in UniDesk .state/session/worktree retention, scoped remote core dumps and explicitly scoped database trace telemetry retention.",
safety: {
default: "plan is read-only and mutation=false",
runGuard: "run requires --confirm",
configSource: "config/unidesk-cli.yaml#gc owns retention windows, include defaults, worktree roots/baseRef, scan budgets, output limits and .state allowlist roots",
protected: ["PostgreSQL PGDATA", "Docker volumes", "Docker images", ".state/recovery", ".state/codex-queue/codex-home", ".state/deploy/work", ".state/baidu-netdisk", "Codex auth/config", "active/unmerged/dirty worktree/runtime image/snapshot", "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": "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 /root/.unidesk/.state/playwright-browsers cache",
"--include-tool-caches": "local and remote explicit opt-in: remove rebuildable npm/npx/Bun package caches from fixed allowlisted paths",
"--include-state-artifacts": "manual local gc only: opt in to stale UniDesk .state artifact retention for allowlisted diagnostic files and deploy artifact direct directories",
"--state-artifact-keep-days N": "keep recent UniDesk .state artifacts for N days; default 14; must be a positive integer",
"--include-state-stale-scratch": "manual local gc only: opt in to YAML allowlisted stale .state scratch roots; roots and keepHours come from config/unidesk-cli.yaml#gc",
"--include-codex-sessions": "manual local gc only: delete inactive session files under YAML codexSessions.root after codexSessions.keepHours; never deletes auth/config",
"--include-merged-worktrees": "manual local gc only: remove inactive .worktree entries whose HEAD is merged into or cherry-equivalent to YAML baseRef; run rechecks full clean status before deletion",
"--worktree-scan-budget-ms N": "temporary override for YAML mergedWorktrees.scanBudgetMs; over-budget worktrees are protected, not deleted",
"--worktree-cherry-check-timeout-ms N": "temporary override for YAML mergedWorktrees.cherryCheckTimeoutMs",
"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 low-risk gc systemd timer from config/unidesk-cli.yaml#gc.policyTimer",
"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",
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]",
],
description: "Inspect the local host Codex commander skeleton contract, dry-run planner, no-daemon smoke validation plan, state helpers, trace summary aggregator, and approval draft preview.",
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",
"token and secret values must never be printed",
],
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 trace|deploy|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 trace list [--root ~/.codex] [--limit 30]",
"bun scripts/cli.ts codex trace active [--root ~/.codex]",
"bun scripts/cli.ts codex trace grep --session <id> --pattern 'playwright|auth-login-failed' [--since ISO]",
"bun scripts/cli.ts codex trace grep --session <id> --messages --pattern 'Playwright|web-probe'",
"bun scripts/cli.ts codex trace grep --session <id> --failed-only [--tool exec_command]",
"bun scripts/cli.ts codex trace grep --pattern 'playwright|auth-login-failed' [--file sessions/...jsonl] [--since ISO]",
"bun scripts/cli.ts codex trace collect [--root ~/.codex] [--output /root/.unidesk/.state/codex-trace/<timestamp>] [--limit 30]",
"bun scripts/cli.ts codex trace show --session <id> [--root ~/.codex] [--tail-bytes 12000]",
"bun scripts/cli.ts codex deploy <commitId> # disabled legacy deployment entry",
"bun scripts/cli.ts agentrun get tasks --queue commander --limit 20",
"bun scripts/cli.ts agentrun describe aipodspec/Artificer",
"bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin",
"bun scripts/cli.ts agentrun apply -f - --dry-run",
"bun scripts/cli.ts agentrun logs session/<sessionId> --tail 100",
"bun scripts/cli.ts codex submit # frozen legacy write entry; returns legacy-code-queue-frozen",
"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 agentrun send session/<sessionId> --prompt-stdin",
"bun scripts/cli.ts codex steer <taskId> # frozen legacy write entry",
"bun scripts/cli.ts codex resume <taskId> # frozen legacy write entry",
"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] # legacy archive read-only",
],
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: "Legacy Code Queue submit is frozen; new runtime placement is selected by AgentRun task payloads.",
permissionVisibility: "Legacy Code Queue read commands expose historical runner metadata only; new tasks use AgentRun resource primitives.",
},
submitSummary: {
default: "codex submit/enqueue now returns ok=false, frozen=true, degradedReason=legacy-code-queue-frozen and AgentRun replacement commands.",
replacement: "Use bun scripts/cli.ts agentrun apply -f - with a quoted YAML heredoc for structured work, or agentrun create task --aipod Artificer --prompt-stdin for one prompt task.",
noDoubleWrite: "UniDesk does not mirror AgentRun submissions into old Code Queue and does not migrate old history into AgentRun.",
rawDrillDown: "Use codex tasks/task/output/read/unread/queues only for legacy archive inspection.",
},
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.",
},
localTrace: {
defaultRoot: "~/.codex",
defaultIncludes: ["sessions/*.jsonl", "history.jsonl", "shell_snapshots", "*.log", "trace-named text files"],
defaultExcludes: ["auth/config", "sqlite", "cache/.tmp/generated_images/plugins/skills"],
active: "codex trace active finds open Codex session JSONL files from /proc without requiring lsof and prints copyable session ids.",
grep: "codex trace grep supports --session <id>, --messages, --tools, --tool <name>, and --failed-only. It defaults to active/recent sessions, uses rg/raw prefiltering for speed, prioritizes messages/tool inputs, and folds tool outputs unless --include-output or -o wide is explicit.",
output: "Default output is concise text/table; use -o json|yaml|name|wide for machine or wider output.",
collectOutput: "/root/.unidesk/.state/codex-trace/<timestamp>/manifest.json",
note: "Use --root <dir> to scan another local Codex trace directory; collect copies bounded files locally and never uploads or deletes source files.",
},
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: {
agentRunCommander: "bun scripts/cli.ts agentrun get tasks --queue commander --limit 20",
agentRunAipod: "bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin",
agentRunSubmit: "bun scripts/cli.ts agentrun apply -f - --dry-run",
agentRunTrace: "bun scripts/cli.ts agentrun logs session/<sessionId> --tail 100",
frozenLegacySubmit: "bun scripts/cli.ts codex submit --prompt-file /tmp/code-queue-prompt.md",
},
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.",
},
description: "Operate legacy Code Queue as a read-only archive through bounded task/output/read/unread/queues views. New task dispatch, retry/resume, queue mutation, move, and workdir mutation are frozen and replaced by AgentRun resource primitives via bun scripts/cli.ts agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|send.",
};
}
function jobHelp(): unknown {
return {
command: "job|jobs list|status|get|read|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 jobs get <jobId|latest> [--tail-bytes N]",
"bun scripts/cli.ts job cancel <jobId>",
],
description: "Inspect or cancel fire-and-forget job state from /root/.unidesk/.state/jobs with structured progress summaries and bounded log tails. `jobs get/read` are compatibility aliases for `job status`; server lifecycle commands return this drill-down by default and reserve full JSON for --full/--raw.",
};
}
function debugHelp(): unknown {
return {
command: "debug health|ssh-pool|egress-proxy|provider-rootfs|dispatch|task",
output: "json",
usage: [
"bun scripts/cli.ts debug health",
"bun scripts/cli.ts debug ssh-pool <providerId>",
"bun scripts/cli.ts debug egress-proxy <providerId>",
"bun scripts/cli.ts debug provider-rootfs <providerId>",
"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. ssh-pool and egress-proxy are separate so SSH/control readiness is not conflated with long download tunnel activity; do not use debug commands 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|worktree add",
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] [--target <id>] [--no-pull] [--dry-run]",
"bun scripts/cli.ts dev-env worktree add .worktree/<task> --branch <branch> [--from origin/master] [--copy-local] [--overwrite-local] [--json]",
],
description: "Validate D601 unidesk-dev guardrails, prewarm foundation images, or create task worktrees with allowlisted local config copying.",
};
}
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 [--target <id>]",
"bun scripts/cli.ts artifact-registry render [--target <id>]",
"bun scripts/cli.ts artifact-registry status [--target <id>]",
"bun scripts/cli.ts artifact-registry health [--target <id>]",
"bun scripts/cli.ts artifact-registry install [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --service baidu-netdisk --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --service frontend --env prod --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --service frontend --env dev --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service decision-center --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service decision-center --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service project-manager --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service oa-event-flow --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service code-queue-mgr --commit <full-sha> --dry-run [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service findjob --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service findjob --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service pipeline --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service pipeline --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service met-nonlinear --commit <full-sha> --dry-run [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service met-nonlinear --commit <full-sha> --dry-run [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service k3sctl-adapter --commit <full-sha> --dry-run [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service mdtodo --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service mdtodo --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service claudeqq --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env prod --service claudeqq --commit <full-sha> [--dry-run] [--run-now] [--target <id>]",
"bun scripts/cli.ts artifact-registry deploy-service --env dev --service code-queue --commit <full-sha> --dry-run [--target <id>]",
],
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, findjob, pipeline, met-nonlinear, k3sctl-adapter, and dev-only code-queue as standardized consumers; Todo Note uses NC01 PaC/Argo",
"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>",
},
},
};
}
function agentRunHelpSummary(): unknown {
return {
command: "agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|send|control-plane|git-mirror",
output: "human by default; use -o json|yaml or --raw",
usage: [
"bun scripts/cli.ts agentrun get tasks --queue commander --limit 20",
"bun scripts/cli.ts agentrun describe task/<taskId>",
"bun scripts/cli.ts agentrun events run/<runId> --after-seq 0 --limit 100",
"bun scripts/cli.ts agentrun logs session/<sessionId> --tail 100",
"bun scripts/cli.ts agentrun result run/<runId> --command <commandId>",
"bun scripts/cli.ts agentrun ack task/<taskId>",
"bun scripts/cli.ts agentrun dispatch task/<taskId>",
"bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin",
"bun scripts/cli.ts agentrun control-plane status",
],
description: "Operate AgentRun v0.1 resources with Kubernetes-style verbs and progressive disclosure. Legacy queue/runs/commands/runner/sessions bridge groups remain for raw compatibility.",
};
}
function platformInfraHelpSummary(): unknown {
return {
command: "platform-infra sub2api|egress-proxy|langbot|n8n|webterm|wechat-archive|gitea ...",
output: "json",
usage: [
"bun scripts/cli.ts platform-infra sub2api plan",
"bun scripts/cli.ts platform-infra sub2api status [--full|--raw]",
"bun scripts/cli.ts platform-infra sub2api codex-pool validate",
"bun scripts/cli.ts platform-infra sub2api codex-pool trace --request-id <requestId>",
"bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-image status",
"bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-probe --account unidesk-codex-hy --confirm",
"bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-report",
"bun scripts/cli.ts platform-infra egress-proxy benchmark --target D601 --profile no-mirror --confirm",
"bun scripts/cli.ts platform-infra egress-proxy benchmark-status --target D601 --profile no-mirror",
"bun scripts/cli.ts platform-infra egress-proxy traffic --target D601 --sample-seconds 15",
"bun scripts/cli.ts platform-infra egress-proxy k3s-build-benchmark --targets D601,D518 --profile no-mirror-600m --dry-run",
"bun scripts/cli.ts platform-infra langbot plan",
"bun scripts/cli.ts platform-infra langbot apply --confirm",
"bun scripts/cli.ts platform-infra langbot status",
"bun scripts/cli.ts platform-infra langbot query --path /api/v1/platform/bots",
"bun scripts/cli.ts platform-infra n8n plan",
"bun scripts/cli.ts platform-infra n8n apply --confirm",
"bun scripts/cli.ts platform-infra n8n status",
"bun scripts/cli.ts platform-infra n8n validate --full",
"bun scripts/cli.ts platform-infra webterm apply --confirm",
"bun scripts/cli.ts platform-infra webterm status",
"bun scripts/cli.ts platform-infra webterm validate",
"bun scripts/cli.ts platform-infra webterm logs --target local-7682 --tail 100",
"bun scripts/cli.ts platform-infra wechat-archive plan",
"bun scripts/cli.ts platform-infra wechat-archive apply --confirm",
"bun scripts/cli.ts platform-infra wechat-archive validate --full",
"bun scripts/cli.ts platform-infra wechat-archive pull --remote-path /UniDesk/WeChatArchive/...",
"bun scripts/cli.ts platform-infra wechat-archive wcf-host-status --full",
"bun scripts/cli.ts platform-infra wechat-archive collector-status --full",
"bun scripts/cli.ts platform-infra gitea status --target NC01",
"bun scripts/cli.ts platform-infra gitea validate --target NC01",
"bun scripts/cli.ts platform-infra gitea mirror status --target NC01",
"bun scripts/cli.ts platform-infra gitea mirror webhook status --target NC01",
"bun scripts/cli.ts platform-infra pipelines-as-code status --target NC01",
"bun scripts/cli.ts platform-infra pipelines-as-code history --target NC01 --limit 10",
],
description: "Operate platform-infra services such as Sub2API, shared egress-proxy benchmarks, LangBot, n8n, Web Terminal, WeChat archive workflows, the YAML-controlled Codex pool, and internal Gitea for the GH-1548/GH-1549 CI/CD migration.",
};
}
function hwlabNodeHelpSummary(): unknown {
return {
command: "hwlab nodes control-plane|git-mirror|hwpod-preinstall|observability|secret|test-accounts --node <node> --lane <lane>",
output: "json",
usage: [
"bun scripts/cli.ts hwlab nodes control-plane infra plan --node NC01 --lane v03",
"bun scripts/cli.ts hwlab nodes control-plane infra status --node NC01 --lane v03",
"bun scripts/cli.ts hwlab nodes control-plane infra tools-image status --node NC01 --lane v03",
"bun scripts/cli.ts hwlab nodes control-plane infra argo status --node NC01 --lane v03",
"bun scripts/cli.ts hwlab nodes control-plane infra egress-benchmark --node NC01 --lane v03 --profile no-mirror --confirm",
"bun scripts/cli.ts hwlab nodes control-plane infra ci-build-benchmark --node NC01 --lane v03 --profile no-mirror-full --confirm",
"bun scripts/cli.ts hwlab nodes control-plane infra ci-build-benchmark status --node NC01 --lane v03 --profile no-mirror-full",
"bun scripts/cli.ts hwlab nodes control-plane status --node NC01 --lane v03",
"bun scripts/cli.ts hwlab nodes git-mirror status --node NC01 --lane v03",
"bun scripts/cli.ts hwlab nodes hwpod-preinstall plan --node NC01 --lane v03 --dry-run",
"bun scripts/cli.ts hwlab nodes observability performance-summary --node NC01 --lane v03",
"bun scripts/cli.ts hwlab nodes secret status --node NC01 --lane v03 --name <secret>",
"bun scripts/cli.ts hwlab nodes test-accounts status --node NC01 --lane v03",
"bun scripts/cli.ts hwlab nodes test-accounts sync --node NC01 --lane v03 --confirm",
],
description: "Operate NC01 HWLAB v0.3 runtime prerequisites from YAML source truth. The infra subcommand manages node-local CI/CD, git-mirror, public Dockerfile tools image, egress benchmarks, and declarative Argo CD prerequisites; hwpod-preinstall renders NC01/v03 HWPOD/MDTODO/gateway configRefs without runtime mutation; observability reads runtime metrics and authenticated Web Performance summaries; test-accounts prepares UniDesk YAML-declared admin/test account API keys with redacted sourceRef/fingerprint output. Web probe commands moved to top-level `bun scripts/cli.ts web-probe`.",
};
}
function webProbeHelpSummary(): unknown {
return {
command: "web-probe run|script|observe|sentinel --node <node> --lane <lane>",
output: "json",
usage: [
"bun scripts/cli.ts web-probe run --node NC01 --lane v03 --wait-messages-ms 1000",
"bun scripts/cli.ts web-probe observe start --node NC01 --lane v03 --target-path /workbench --sample-interval-ms 5000",
"bun scripts/cli.ts web-probe observe collect webobs-xxxx --view turn-summary",
"bun scripts/cli.ts web-probe observe collect webobs-xxxx --view timeline --turn 1",
"bun scripts/cli.ts web-probe sentinel plan --node NC01 --lane v03 --dry-run",
"bun scripts/cli.ts web-probe sentinel inspect-url 'https://monitor.pikapython.com/?run=sentinel-run-xxxx'",
"bun scripts/cli.ts web-probe sentinel inspect-id trc_xxxx --node NC01 --lane v03 --sentinel jd01-web-probe-sentinel",
],
description: "Run target node/lane HWLAB Cloud Web probes, long observe/analyze sessions, project-management MDTODO commands, and Web sentinel YAML-first control through a single top-level implementation. Monitor-web links and evidence ids should enter through sentinel inspect-url/inspect-id before report or observe drill-down.",
};
}
function cicdHelpSummary(): unknown {
return {
command: "cicd status --node <NODE>",
output: "text by default; use --json, --raw, or -o json|yaml for machine output",
usage: [
"bun scripts/cli.ts cicd status --node NC01",
"bun scripts/cli.ts cicd status --node NC01 --full",
],
description: "Node-level CI/CD status is the primary read path for PaC-migrated consumers. Gitea Actions and branch-follower are archived diagnostics and are not delivery or closeout paths.",
};
}
function hwlabLegacyRuntimeHelpSummary(): unknown {
return {
command: "hwlab g14 retirement",
output: "json",
usage: [
"bun scripts/cli.ts hwlab g14 retirement status",
"bun scripts/cli.ts hwlab g14 retirement plan",
],
description: "Archived legacy helper surface. Current HWLAB development and deployment use NC01 node commands.",
};
}
function hwlabHelpSummary(): unknown {
return {
command: "hwlab nodes|g14|cd",
output: "json",
usage: [
"bun scripts/cli.ts hwlab nodes control-plane status --node NC01 --lane v03",
"bun scripts/cli.ts hwlab cd audit --env dev",
],
description: "HWLAB operations. Current runtime work uses NC01 node commands; old cd/g14 surfaces are archived diagnostics only.",
};
}
function helpFallback(help: unknown, error: unknown): unknown {
if (typeof help !== "object" || help === null || Array.isArray(help)) return help;
return {
...help,
degraded: true,
degradedReason: "help-module-load-failed",
error: error instanceof Error ? error.message : String(error),
};
}
async function loadHelp(loader: () => Promise<unknown>, fallback: unknown): Promise<unknown> {
try {
return await loader();
} catch (error) {
return helpFallback(fallback, error);
}
}
export async function staticNamespaceHelp(args: string[]): Promise<unknown | null> {
const [top, sub] = args;
if (!args.slice(1).some(isHelpToken)) return null;
if (top === "config") return configHelp();
if (top === "health") return healthHelp();
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" && sub === "trace") return null;
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 ghScopedHelp(args.slice(1)) ?? ghHelp();
if (top === "cicd") return loadHelp(async () => (await import("./cicd")).cicdHelp(), cicdHelpSummary());
if (top === "agentrun") return loadHelp(async () => (await import("./agentrun")).agentRunHelp(), agentRunHelpSummary());
if (top === "platform-infra" && (sub === "pipelines-as-code" || sub === "pac")) {
return loadHelp(
async () => (await import("./platform-infra-pipelines-as-code")).runPlatformInfraPipelinesAsCodeCommand({} as never, args.slice(2)),
platformInfraHelpSummary(),
);
}
if (top === "platform-infra" && sub === "gitea") {
return loadHelp(
async () => (await import("./platform-infra-gitea")).runPlatformInfraGiteaCommand({} as never, args.slice(2)),
platformInfraHelpSummary(),
);
}
if (top === "platform-infra" && sub === "observability") {
return loadHelp(
async () => (await import("./platform-infra-observability")).runPlatformObservabilityCommand({} as never, args.slice(2)),
platformInfraHelpSummary(),
);
}
if (top === "platform-infra") return loadHelp(async () => (await import("./platform-infra")).platformInfraHelp(), platformInfraHelpSummary());
if (top === "platform-db") return platformDbHelp();
if (top === "secrets") return secretsHelp();
if (top === "web-probe") return loadHelp(async () => (await import("./web-probe")).webProbeHelp(), webProbeHelpSummary());
if (top === "hwlab" && (sub === "node" || sub === "nodes") && args[2] === "web-probe") return null;
if (top === "hwlab" && (sub === "node" || sub === "nodes") && args[2] === "control-plane" && args[3] === "infra") {
return loadHelp(async () => (await import("./hwlab-node-control-plane")).hwlabNodeControlPlaneInfraHelp(), hwlabNodeHelpSummary());
}
if (top === "hwlab" && (sub === "node" || sub === "nodes") && args[2] === "control-plane" && (args[3] === "platform-maintenance" || args[3] === "legacy-cicd")) {
const scope = args[3];
return loadHelp(async () => (await import("./hwlab-node-help")).hwlabNodeHelp(scope), hwlabNodeHelpSummary());
}
if (top === "hwlab" && (sub === "node" || sub === "nodes") && args[2] === "test-accounts") {
return loadHelp(async () => (await import("./hwlab-test-accounts")).hwlabTestAccountsHelp(), hwlabNodeHelpSummary());
}
if (top === "hwlab" && (sub === "node" || sub === "nodes") && args[2] === "hwpod-preinstall") {
return loadHelp(async () => (await import("./hwlab-node-hwpod-preinstall")).hwlabNodeHwpodPreinstallHelp(), hwlabNodeHelpSummary());
}
if (top === "hwlab" && (sub === "node" || sub === "nodes")) return loadHelp(async () => (await import("./hwlab-node")).hwlabNodeHelp(), hwlabNodeHelpSummary());
if (top === "hwlab" && sub === "g14") return loadHelp(async () => (await import("./hwlab-legacy-runtime")).hwlabLegacyRuntimeHelp(), hwlabLegacyRuntimeHelpSummary());
if (top === "hwlab") return loadHelp(async () => (await import("./hwlab-cd")).hwlabHelp(), hwlabHelpSummary());
return null;
}