25 KiB
UniDesk CLI Reference
UniDesk 的统一 CLI 入口是根目录 scripts/cli.ts,运行方式固定为 bun scripts/cli.ts <command>。CLI 默认输出 JSON,所有成功和失败路径都必须向 stdout 写出结构化对象,避免无输出造成状态不可观测。
Command Model
help输出命令索引,适合作为交互式入口。--main-server-ip <ip> <command>默认通过公网 frontend 登录态调用主 server 的同源 API 代理,不要求计算节点持有主 server SSH key;显式提供--main-server-key或--main-server-transport ssh时才使用旧 SSH 传输。config show读取并校验根目录config.json,不从环境变量、默认值或隐藏文件静默补配置。check执行配置校验、文件存在性检查、scripts/TypeScript 检查、src/components/TypeScript 检查和 Docker Compose 配置检查。server start创建异步 job,在后台执行 Docker 构建和启动;命令本身只负责返回 job id、日志路径和启动命令。server stop创建异步 job,在后台停止固定 Compose project 中的全部 UniDesk 服务。server status查询公开端口、受限宿主端口、内部端口、主机 swap 摘要、Compose 容器、core/frontend/provider/database 健康检查和访问 URL;D601 Code Queue 使用的 PostgreSQL/OA Event Flow host mapping 必须出现在受限宿主端口而不是无条件公开入口中。低内存主 server 上swap.warning非空时,先执行server swap status或server swap ensure。server swap status|ensure [--path /swapfile] [--size 2GiB] [--dry-run]是主 server swap 管理入口。status仅读/proc/meminfo、/proc/swaps和/etc/fstab并返回 JSON;ensure在已有任何 active swap 时只报告 no-op,在无 active swap 时创建固定 swapfile、chmod 600、mkswap、swapon并尽量写入/etc/fstab。输出必须包含before、after、total memory、active swap、持久化状态、关键动作和错误详情;若 swap 已启用但 fstab 写入失败,状态为degraded,调用者需按返回的 detail 修复持久化。server logs返回logs/文件日志和 Docker 容器日志的尾部,默认限制输出大小,避免日志爆炸。实现必须只读取文件末尾字节,不得为了 tail 先把巨大日志完整读入 CLI 内存。server rebuild <backend-core|frontend|provider-gateway|todo-note|project-manager|baidu-netdisk|oa-event-flow>创建异步 job,先构建目标服务镜像,随后在.state/locks/server-compose.lock串行保护下用--no-deps --force-recreate替换目标 service 并等待容器healthy/running;该命令用于替代手工删除容器的兜底流程,其中todo-note、project-manager、baidu-netdisk和oa-event-flow只重建主 server 承载的对应后端,不会重建或删除 database 命名卷。Code Queue 部署在 D601,不再由server rebuild管理。provider attach <providerId> [--master-server URL] [--up] [--force]在新计算节点生成两项配置的 provider-gateway 挂载包:.state/provider-<ID>.env默认只包含UNIDESK_MASTER_SERVER与PROVIDER_ID,provider-<ID>.yml固定 Docker socket、pid: "host"、restart: always、只读/workspace和 SSH 维护私钥挂载;--up会立即执行生成的docker compose up -d --build。ssh <providerId> [ssh-like args...]通过 backend-core 内网 WebSocket broker 和 provider-gateway 的 Host SSH / WSL SSH 维护桥连接目标节点;无后续参数时进入远端登录 shell,有后续参数时按 ssh 远端命令体验执行并返回远端 exit code。ssh <providerId> apply-patch [tool args...] < patch.diff直接调用远端注入的apply_patch工具,并把本地 stdin 中的标准*** Begin Patch/*** End Patchpatch 流透传给目标节点。ssh <providerId> py [script-args...] < script.py把本地 stdin 落到远端临时.py文件后再以python3 -u执行并自动清理,避免再手写'python3 -'、heredoc 或多层引号;script-args会按 argv 安全透传给远端脚本。ssh <providerId> skills [--scope all|wsl|windows] [--limit N]发现目标节点上的 WSL/Linux skill 根目录;当 provider 是 WSL 时同一次调用还会扫描 Windows 用户目录下的.agents/skills与.codex/skills。microservice list/status/health/proxy通过 backend-core 内网 API 管理挂载在计算节点 Docker 中的用户服务(底层命令名仍为 microservice);health和proxy会走真实 backend-core -> provider-gateway -> 节点本机后端链路,proxy对超大 body 默认输出有界预览,规则见docs/reference/microservices.md。decision upload/list/show/health通过 backend-core 用户服务代理访问 D601 k3s Decision Center,用于上传会议记录/决议 Markdown、列出权威记录、查看详情和健康检查;它不得直连 D601 Service、NodePort 或 provider-gateway 业务 HTTP。deploy check/plan/apply从根目录deploy.json读取服务 repo 与 commit 期望状态,joinconfig.json和现有 manifest 后使用 target-side build 单一路径校验或更新直管服务与 k3s 代管服务;规则见docs/reference/deploy.md。codex deploy <commitId>是 Code Queue 兼容部署入口,会生成临时 desired manifest 并调用deploy apply --service code-queue的同一条 target-side build、k3s import、rollout 和 live commit 验证路径;详细规则见docs/reference/codex-deploy.md。codex task <taskId>通过 Code Queue 私有代理按任务 ID 查询结构化执行摘要;默认只返回有界 prompt/response 预览、执行 Provider、工作目录、最后 assistant message、最近工具调用摘要、attempt、judge、错误、耗时和 trace 翻页提示,适合在新队列任务中引用历史 session 且避免噪声爆炸。codex task <taskId> --trace --tail|--from-start|--after-seq N|--before-seq N --limit N按页拉取 Code Queue 的逻辑 trace;响应会返回nextAfterSeq、previousBeforeSeq、hasMore、hasBefore和下一页/上一页命令,默认--trace取最新一页,需要完整 prompt/最后 response 时加--full。codex output <taskId> --tail|--from-start|--after-seq N|--before-seq N --limit N [--full-text]按原始 output seq 分页读取底层记录;当 trace 行提示commandOmittedLines、bodyOmittedLines或rawSeqs时,用该命令按 seq 补取完整信息,默认仍有单条文本预览上限,显式--full-text才返回该页全文。codex judge <taskId> --attempt N [--dry-run] [--include-prompt]通过 Code Queue 私有代理按指定 attempt 单步复现 judge;后端会从 PostgreSQL task JSON 与 output 归档重建该 attempt 在真实队列 worker 中的QueueTask/CodexRunResult,再调用同一套 judge prompt builder 和 MiniMax 请求路径。默认会真实调用 MiniMax,--dry-run只返回 prompt/payload 大小、attempt 窗口和重建来源诊断,--include-prompt仅用于本地深度排查。- Code Queue 多队列 lane 由
codex命令命名空间管理:queues列表、queue create <queueId>创建、queue merge <sourceQueueId> --into <targetQueueId>合并、move <taskId> --queue <queueId>迁移;同一个 queue 内部串行执行,不同 queue 之间并行执行。迁移只允许尚未被 scheduler claim 的queued/retry_wait任务,必须满足startedAt=null、currentAttempt=0且没有 active thread/turn;已进入running/judging或已有 claim 标记的任务返回 409,不得被 move/merge 回写成 queued。合并会移动可迁移任务归属并自动删除源 queue 记录,只保留合并后的目标 queue;若 source 或 target queue 存在 active/claimed 任务,合并整体返回 409。合并后的目标 queue 按任务原queueEnteredAt/createdAt时间顺序串行,成功迁移 queued/retry_wait 任务后会立即调度目标 queue。 job list [--limit N] [--include-command]与job status <jobId|latest> [--tail-bytes N]查询.state/jobs/文件系统状态,是异步命令的可观测入口。job list默认只返回最新 50 条摘要;job status默认只返回 stdout/stderr 末尾 12000 字节,并带tailPolicy与完整日志路径。debug health、debug dispatch与debug task走真实内部 core、WebSocket、数据库、provider、系统指标、Docker 状态和 Host SSH 维护桥流程,只用于开发调试,不写入TEST.md的正式验收步骤。e2e run [--only pattern[,pattern...]] [--skip pattern[,pattern...]]使用 publicHost 派生的公开 frontend/provider ingress URL,并通过 Docker 内网验证 core API、PostgreSQL、provider self-connection、系统指标曲线、Docker 状态快照、provider.upgrade 预检和 Playwright 前端页面,是交付前的自动化 E2E 门禁;CLI 默认输出 check 状态摘要,完整诊断写入resultPath,日常迭代应优先用--only/--skip跑最小必要集合。
Async Job State
长时操作采用 Fire-and-Forget 模式:CLI 创建 .state/jobs/{jobId}.json,后台进程执行真实命令,并将 stdout、stderr 分别写入 .state/jobs/{jobId}.stdout.log 与 .state/jobs/{jobId}.stderr.log。调用者通过 bun scripts/cli.ts job status <jobId> 查询进度和尾部输出。
server rebuild 与 server start、server stop 一样必须通过返回的 job id 确认结果;不要把连续 server rebuild 命令理解成“前一个重建已完成”,因为两个命令只是在快速创建异步 job。重建 frontend 的标准流程是运行 bun scripts/cli.ts server rebuild frontend,随后轮询 bun scripts/cli.ts job status <jobId> 到 succeeded,再用 server status 或 e2e run 验证公网 frontend;重建 Todo Note 后端使用 bun scripts/cli.ts server rebuild todo-note,随后用 microservice health todo-note 和 microservice proxy todo-note /api/instances 验证;重建 Project Manager 后端使用 bun scripts/cli.ts server rebuild project-manager,随后用 microservice health project-manager 和 microservice proxy project-manager /api/projects 验证;重建 Baidu Netdisk 后端使用 bun scripts/cli.ts server rebuild baidu-netdisk,随后用 microservice health baidu-netdisk 和 microservice proxy baidu-netdisk /api/transfers 验证;重建 OA Event Flow 后端使用 bun scripts/cli.ts server rebuild oa-event-flow,随后用 microservice health oa-event-flow 和 microservice proxy oa-event-flow /api/diagnostics 验证。Code Queue 和 Decision Center 后端由 D601 k3s/k8s 控制面代管,必须使用 bun scripts/cli.ts deploy apply --service code-queue、bun scripts/cli.ts deploy apply --service decision-center 或 Code Queue 兼容入口 bun scripts/cli.ts codex deploy <commitId> 部署已 push 的 remote commit;部署 job 自身必须通过真实 /health 和 k3s Deployment annotation 证明不是旧服务在充数,之后再用 microservice health <service> 和对应私有代理 API 做人工复核。不得把 docker rm 手工兜底当成正式交付步骤。
新部署入口优先使用 deploy apply。旧的 server rebuild 和 codex deploy 只保留为兼容入口,后续实现应收敛到同一个 reconciler:从 remote commit 导出源码,在目标节点一次性代理构建镜像,部署后用 live commit 校验证明不是旧服务。
Output Contract
每条命令的最外层 JSON 包含 ok、command 和 data 或 error。失败时 CLI 设置非零退出码,但仍然输出 JSON 错误对象;错误对象应包含 name、message 和可用的 stack。
诊断命令默认采用渐进披露:server logs、job list/status、codex task/trace/output 和 microservice proxy 都必须有默认条数、字节数或文本预览上限;用户显式传 --limit、--tail-bytes、--full-text 或 --full 才扩大单次输出。CLI stdout 遇到下游 pipe 关闭的 EPIPE 必须安静退出,不得打印 Bun stack trace。
microservice proxy 是面向人工验证的私有后端读取入口。正式写入型用户服务操作由 frontend 同源代理或 E2E 直接调用 backend-core 完成,并由 config 中的 allowedMethods 限制;CLI proxy 默认仍作为 GET/HEAD 读取验证入口,必要时可显式加 --method POST|PUT|PATCH|DELETE 调用无需自定义请求体的受控调试/自测端点,例如 bun scripts/cli.ts microservice proxy baidu-netdisk /api/self-test --method POST --raw。为了避免 Pipeline snapshot 这类超大业务 JSON 造成 CLI 输出爆炸,响应 body 超过默认阈值时会返回 bodyOmitted=true、bodyPreview、bodyBytes 和 rawHint;--raw 仍受默认硬限额保护,需要完整 body 时显式添加 --raw --full,或用 --max-body-bytes <N> 调整预览阈值。正式 frontend 展示仍应优先使用业务控件和 __unideskArrayLimit 这类展示级裁剪参数,而不是默认倾倒完整 JSON。
network perf 用于生成组网性能前后对比数据。标准 Code Queue overview 读路径基准命令是 bun scripts/cli.ts network perf --service code-queue --path /api/tasks/overview?limit=30 --count 30 --concurrency 1 --label before,远程主 server 可用 bun scripts/cli.ts --main-server-ip 74.48.78.17 network perf ...。输出包含成功/失败数、状态码分布、x-unidesk-cache、x-unidesk-proxy-mode、x-unidesk-upstream-proxy-mode 分布和 min/p50/p90/p95/max;provider-gateway 长连接数据面验收应看到 proxyModeCounts.provider-ws-http-tunnel,adapter native Service 数据面验收应看到 upstream proxy mode 为 kubernetes-native-service,若出现 kubernetes-api-service-proxy 必须结合 /api/control-plane.nativeServiceProxy.failedServices 解释 fallback 原因。
Debug Contract
debug 子命令必须复用真实模块与真实端点,禁止维护平行实现。debug health 会摘要展示 /api/nodes/system-status 和 /api/nodes/docker-status,避免输出完整快照造成信息爆炸。debug dispatch 会在 backend-core 容器内调用内部 /api/dispatch,core 再通过 WebSocket 将 docker.ps、provider.upgrade、host.ssh、microservice.http 或 echo 任务下发给 provider gateway,因此它可以验证核心调度闭环,同时不需要公开 core REST API。provider.upgrade 默认使用 mode: "plan" 预检;需要验证一键升级时必须显式加 --mode schedule,并通过 --wait-ms 或 debug task 确认任务进入 succeeded、result 中包含 updater 容器信息和 policy: "always-enabled"。host.ssh 默认使用 mode: "probe" 做短超时维护桥自检;需要执行明确命令时使用 --ssh-command 进入 mode: "exec",并配合 --wait-ms 和 debug task 查看 stdout、stderr、exitCode 与 probeLine。microservice.http 只用于开发调试 provider-gateway 私有 HTTP 代理,正式用户入口应使用 microservice CLI 或 frontend 的用户服务页面。
SSH Command
ssh <providerId> [ssh-like args...] 是面向人的终端透传入口,不包装 JSON 输出。CLI 会在宿主机启动一个 docker exec -i unidesk-backend-core bun -e ... broker,broker 只连接 backend-core 的 Docker 内网 /ws/ssh,core 再把 stdin/stdout/stderr 流量通过目标 provider 的既有 WebSocket 转发到 provider-gateway,provider-gateway 最终执行维护用 SSH 连接宿主或 WSL sshd。TTY 策略固定为交互登录 shell 使用 ssh -tt,带远端命令的会话使用 ssh -T;脚本 stdin、apply-patch 和 py 这类命令模式不得被伪终端回显或注入控制字符。该入口不新增 core 公网端口,不暴露 database,也不改变 frontend/provider ingress 之外的公网边界。
bun scripts/cli.ts ssh D518 应表现为登录 D518 WSL 的 shell;bun scripts/cli.ts ssh D518 hostname 应像 ssh D518 hostname 一样只输出远端命令结果并返回远端 exit code。Provider ID 前的目标选择由 UniDesk 节点清单决定,-p、-i、-l、-o 等传统 ssh 传输参数由 provider-gateway 部署配置统一管理,CLI 会兼容性消费这些参数但不会覆盖节点侧维护桥配置。
core 只允许声明了 host.ssh capability 的 provider 使用 ssh 透传或 host.ssh dispatch;旧 provider 不支持该能力时必须快速失败并输出错误,不能把未知命令误判成 echo 成功。
本地 broker 默认等待 provider SSH 会话打开 60000ms,以便在目标节点同时有较多 microservice.http 任务时仍能建立维护会话;需要诊断慢连接时可用 UNIDESK_SSH_OPEN_TIMEOUT_MS=<ms> 临时调大,但最小有效值固定为 15000ms,避免把真实离线误判为长时间阻塞。
ssh <providerId> 会在远端会话启动时注入 /tmp/unidesk-ssh-tools/apply_patch、/tmp/unidesk-ssh-tools/glob 和 /tmp/unidesk-ssh-tools/skill-discover,并把该目录加入远端 PATH。apply_patch 接受标准 *** Begin Patch / *** End Patch patch 格式,便于通过 SSH 透传编辑远端仓库文件;glob 在远端用 Python 执行路径匹配,避免依赖 shell glob 展开;skill-discover 用于列出远端 Linux/WSL 与 Windows skill。目标节点需要具备 python3 和 base64。注入工具只写 /tmp/unidesk-ssh-tools,不修改目标仓库,交互式 shell 和远端命令都可以直接调用这些工具。
如果只是远端打小补丁,不需要再手写 ssh D601 'apply_patch' < patch.diff 这种命令拼接;正式入口是 bun scripts/cli.ts ssh D601 apply-patch < patch.diff。apply-patch 与 patch 等价,附加参数会原样透传给远端 apply_patch,例如 bun scripts/cli.ts ssh D601 apply-patch --help。标准单命令用法如下,不需要先创建本地 patch 临时文件:
bun scripts/cli.ts ssh D601 apply-patch <<'PATCH'
*** Begin Patch
*** Update File: /home/ubuntu/pipeline/scripts/src/nodeControl.ts
@@
-const value = "old";
+const value = "new";
*** End Patch
PATCH
如果只是想远端执行 Python 脚本,不要再手写 bun scripts/cli.ts ssh D601 'python3 -' < script.py。正式入口是 bun scripts/cli.ts ssh D601 py < script.py;CLI 会先把本地 stdin 写入远端临时 .py 文件,再以无缓冲模式执行并自动清理,同时对额外脚本参数逐个做 shell quoting,避免字符串转义问题。典型用法:
printf 'import sys\nprint(sys.argv)\n' | bun scripts/cli.ts ssh D601 py foo '--bar=baz'
ssh <providerId> py 的附加参数是脚本参数,不是 Python 解释器参数;如需 -m、-X 或多条 shell 命令,仍使用原始远端命令入口。为了保证 CLI 输出及时可见,helper 固定采用“临时文件 + python3 -u”模式;provider 命令模式不分配 TTY,因此脚本内容不应被远端回显。
ssh <providerId> skills 是远端 skill 发现入口,也可写作 ssh <providerId> skill discover。输出固定为 JSON,包含 node、roots、counts 和 skills:roots 会显示每个候选 skill 根目录是否存在、扫描到多少 skill 以及错误;skills 会给出 scope、name、description、path、skillMd 和可转换时的 windowsPath。默认扫描远端用户的 ~/.agents/skills、~/.codex/skills、可访问的 /root/.agents/skills、/root/.codex/skills;如果目标是 WSL,还会扫描 /mnt/c/Users/*/.agents/skills 与 /mnt/c/Users/*/.codex/skills,从而一次性看清 WSL 和 Windows 两套 skill。常用参数是 --scope wsl、--scope windows、--limit N、--max-depth N、--root <path> 和 --windows-root <path>;不要用宽泛的 Linux find /mnt/* 扫 Windows 盘,优先用这个结构化入口避免卡在 Windows 挂载层。
bun scripts/cli.ts ssh D601 skills --limit 80
bun scripts/cli.ts ssh D601 skills --scope windows --limit 40
Windows 工具链透传的 wrapper、路径转换、是否修改 skill、是否额外安装依赖等长期规则见 docs/reference/windows-passthrough.md;ssh skills 本身只负责发现,不会修改远端 skill。
ssh <providerId> find 是常用远端搜索的结构化入口,避免在 Host SSH / WSL SSH 透传里手写 find \( ... \)、*、管道和多层引号。它会把路径、谓词和 pattern 作为 argv 安全拼接,并支持重复 --name、--iname、--path 或 --ipath,重复 pattern 默认按 OR 组合。稳定参数包括 --max-depth/-maxdepth、--min-depth/-mindepth、--type/-type、--contains、--icontains、--name/-name、--iname/-iname、--path/-path、--ipath/-ipath、--mtime/-mtime、--mmin/-mmin、--size/-size、--sort 和 --limit N。典型用法:
bun scripts/cli.ts ssh D601 find /home/ubuntu --max-depth 4 --type d --icontains pika --limit 50 --sort
ssh <providerId> glob 是远端 glob 匹配入口,支持 --root DIR、--pattern PATTERN、--contains TEXT、--icontains TEXT、--type any|f|d、--limit N、--sort 和 --absolute。--contains 与 --icontains 可避免在本地 shell 中输入 *;若显式使用 --pattern '**/*.ts' 这类 pattern,仍应按本地 shell 规则加引号,防止参数到达 CLI 前已被本地 shell 展开。典型用法:
bun scripts/cli.ts ssh D601 glob --root /home/ubuntu/pikapython --pattern '**/*-test.cpp' --limit 20 --sort
ssh <providerId> argv <command> [args...] 是通用 argv 安全拼接入口;exec 是同义入口。它适合不需要 shell 管道的常用命令。find、glob 和 apply-patch 有专用入口;rg、grep、sed、nl、stat、du、ls、cat、head、tail、wc 和 pwd 可以直接作为 ssh 子命令使用,CLI 会对每个 argv token 做 shell quoting。需要管道、重定向、变量展开或多条命令时仍使用旧的自由远端命令入口,并把整段远端 shell 脚本作为一个本地参数传入。
通过 ssh <providerId> 执行多行脚本时,优先使用结构化 helper,例如 bun scripts/cli.ts ssh D601 py < script.py 或 printf ... | (bun scripts/cli.ts ssh D601 'bash -s') 这种单层 stdin 传输。不要在远端命令字符串里再嵌套 heredoc、复杂引号或 ssh 'python3 - <<EOF ...' 形态;多层 shell 解析容易把 stdin 绑定到错误进程,结果会打开远端交互解释器并留下悬挂的 broker/SSH 会话。长脚本需要复用时,优先通过 stdin 写入目标节点的临时脚本,再在同一个远端命令中显式执行并清理。
Remote Main Server Passthrough
--main-server-ip 是一个全局前缀,必须放在需要透传的命令同一次调用中,例如 bun scripts/cli.ts --main-server-ip 74.48.78.17 debug health。默认传输是公网 frontend:本地 CLI 读取本仓库 config.json 中的 frontend 登录账号密码,登录 http://<ip>:<frontendPort>/ 获取 HttpOnly session cookie,然后通过 frontend 的 /api/* 同源代理访问 backend-core 内网 API;因此计算节点只需要能访问公网 frontend,不需要主 server SSH key,也不需要打开 backend-core REST API 或 PostgreSQL 端口。
默认 frontend 传输支持 debug health、debug dispatch、debug task、microservice list/status/health/diagnostics/tunnel-self-test/proxy、decision upload/list/show/health、codex task <taskId>、codex output <taskId>、codex judge <taskId> --attempt N 和 ssh <PROVIDER_ID> <remote-command>。其中 ssh 的 remote frontend 传输使用 host.ssh dispatch 执行有界远端命令,适合 ssh D601 hostname 和 ssh D601 skills 这类自测;交互式登录 shell 仍应在主 server 本机 CLI 使用,或显式切换到旧 SSH 传输后在主 server 上执行。frontend 远程透传不会流式转发本地 stdin,因此 ssh py < script.py、ssh apply-patch < patch.diff 这类 stdin-backed helper 必须在主 server 本机运行,或显式切换到 --main-server-transport ssh。若确实需要旧行为,可使用 --main-server-key <key> 或 --main-server-transport ssh,这时 CLI 会通过 SSH 登录主 server 的 --main-server-root 目录执行同一个 bun scripts/cli.ts <command>。
计算节点可以用该入口测试自身的远程升级闭环,而不需要在计算节点公开 core REST API 或 database。标准顺序是:先运行 bun scripts/cli.ts --main-server-ip 74.48.78.17 debug health 确认主 server 看到当前 Provider 在线,且该 Provider labels 中 unideskCapabilities 包含 host.ssh、hostSshConfigured=true、hostSshKeyPresent=true;再运行 bun scripts/cli.ts --main-server-ip 74.48.78.17 debug dispatch <PROVIDER_ID> provider.upgrade --mode schedule --wait-ms 15000 触发真实 provider.upgrade;随后再次运行 debug health 确认节点重新上线;最后运行 bun scripts/cli.ts --main-server-ip 74.48.78.17 debug dispatch <PROVIDER_ID> host.ssh --wait-ms 15000 和 bun scripts/cli.ts --main-server-ip 74.48.78.17 ssh <PROVIDER_ID> hostname 验证 SSH 透传能力。provider-gateway 新部署或升级后没有完成这组 remote CLI 自测,不能视为交付完成。
远程透传的安全边界是公网 frontend 登录态和 frontend 到 backend-core 的内网代理;不要把 provider token、数据库端口或 backend-core REST API 暴露给计算节点。旧 SSH 传输只作为兼容路径保留,不得把“必须提供主 server SSH key”作为计算节点自测的前置条件。