diff --git a/.agents/skills/unidesk-trans/references/full.md b/.agents/skills/unidesk-trans/references/full.md index 9df4ba37..1a4c1727 100644 --- a/.agents/skills/unidesk-trans/references/full.md +++ b/.agents/skills/unidesk-trans/references/full.md @@ -28,7 +28,7 @@ trans D601:/home/ubuntu/workspace/unidesk-dev sh <<'SH' SH ``` -**规则**: workspace 路径写在 route 第一个 token,不写进 `cd` 串。反面示例:~~`trans G14 sh -- 'cd /root/hwlab && git status'`~~ +**规则**: workspace 路径写在 route 第一个 token,不写进 `cd` 串。显式 host workspace 进入失败必须返回 `UNIDESK_SSH_CWD_FAILED` 和非零退出,不得静默落回默认目录;provider-gateway 侧完整语义见 `docs/reference/provider-gateway.md`。反面示例:~~`trans G14 sh -- 'cd /root/hwlab && git status'`~~ ### k3s route diff --git a/docs/reference/cli.md b/docs/reference/cli.md index d6ee10ab..61ca90f6 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -403,7 +403,7 @@ trans D601 find /home/ubuntu --max-depth 4 --type d --icontains pika --limit 50 trans D601 glob --root /home/ubuntu/pikapython --pattern '**/*-test.cpp' --limit 20 --sort ``` -`ssh` 的 route 语法是 `{provider}:{plane}[:{scope...}] {operation} [operation-args...]`。第一个 argv token 只负责定位分布式目标,不表达操作;第一个 token 后面的所有 token 才进入 operation 解析器。Host workspace route 使用 `:/absolute/workspace`,例如 `D601:/home/ubuntu/workspace/hwlab-dev`,CLI 会把该路径作为远端 cwd 传给 Host SSH 维护桥,后续 `pwd`、`git`、`sh`、`bash`、`apply-patch` 和旧 `apply-patch-v1` fallback 等操作仍按同一套 operation parser 执行。`:host:/absolute/workspace` 是等价长写法;workspace 必须是绝对路径,远端是否存在由维护桥实际 `cd` 失败或成功证明。 +`ssh` 的 route 语法是 `{provider}:{plane}[:{scope...}] {operation} [operation-args...]`。第一个 argv token 只负责定位分布式目标,不表达操作;第一个 token 后面的所有 token 才进入 operation 解析器。Host workspace route 使用 `:/absolute/workspace`,例如 `D601:/home/ubuntu/workspace/hwlab-dev`,CLI 会把该路径作为远端 cwd 传给 Host SSH 维护桥,后续 `pwd`、`git`、`sh`、`bash`、`apply-patch` 和旧 `apply-patch-v1` fallback 等操作仍按同一套 operation parser 执行。`:host:/absolute/workspace` 是等价长写法;workspace 必须是绝对路径,远端是否存在由维护桥实际 `cd` 失败或成功证明。显式 host workspace 进入失败必须返回 `UNIDESK_SSH_CWD_FAILED` 和非零退出,不得静默落回默认目录;完整 provider-gateway 语义见 `docs/reference/provider-gateway.md`。 当前稳定 plane 包括 `win` 和 `k3s`。`win` plane 的 operation 是 Windows 操作,不是 POSIX shell 别名:`:win ps` 在 WSL provider 上启动 Windows PowerShell,stdin heredoc 会被写入临时 `.ps1` 后执行;`:win cmd` 启动 Windows host 的 `cmd.exe`,stdin heredoc 会被写入临时 `.cmd` 后执行;`:win skills` 发现 Windows skill 目录。需要 Windows 当前目录时使用 slash 路由 `:win//`,例如 `D601:win/c/test ps` 会先在 PowerShell 内 `Set-Location -LiteralPath 'C:\test'`,`D601:win/c/test cmd cd` 会先在 cmd 内执行 `cd /d "C:\test"`。`D601:win/c/test git ...` 是 cmd convenience wrapper,覆盖 `status`、`diff`、非交互 `commit -m ...` 等常规 argv 形态;会打开编辑器或需要 shell 审阅的 git 命令仍用 `ps` 或 `cmd` 包装。`win32` 不是合法 plane,调用者必须改用 `win`。 diff --git a/docs/reference/provider-gateway.md b/docs/reference/provider-gateway.md index 23332c4f..c52b6e5e 100644 --- a/docs/reference/provider-gateway.md +++ b/docs/reference/provider-gateway.md @@ -186,6 +186,8 @@ WSL provider 需要调用 Windows-only 工具链时,优先在 WSL 用户的 `~ 维护桥通过真实 WebSocket dispatch 暴露为 `host.ssh` 命令。默认 payload 使用 `mode: "probe"`,远端只执行一个短命令并返回 `UNIDESK_SSH_TEST user=... host=... bridge=host.ssh cwd=...`;需要人工诊断时可以显式使用 `mode: "exec"` 与 `command` 字段执行有界命令。所有 `host.ssh` 执行都必须有超时,stdout/stderr 在 task result 中截断展示;自动升级和普通任务仍必须使用 Docker socket 与 `provider.upgrade`,不得把 WSL SSH 维护桥当成调度通道。 +Host SSH 的 cwd 语义必须区分默认目录和显式 workspace。未传 cwd 时可以进入 `HOST_REMOTE_CWD`,失败后再落到登录目录;但 `trans :/absolute/workspace ...` 或等价 `host.ssh` payload 显式携带 cwd 时,provider-gateway 必须先 `cd` 到该目录,失败时返回非零并在 stderr 输出 `UNIDESK_SSH_CWD_FAILED`,其中 `failureKind=cwd-failed`、`cwd=`。显式 workspace 不得静默 fallback 到 `/root`、`HOST_REMOTE_CWD` 或登录目录;否则 workspace 预检、`git status`、`apply-patch` 和 source truth 判断会误落到错误目录。 + 面向人的终端入口是 `trans [ssh-like args...]`。无后续参数时打开远端登录 shell,有后续参数时执行远端命令并返回远端 exit code;该入口的 client 侧仍连接 backend-core 内网 `/ws/ssh` broker,core 只用 provider WebSocket 下发 open/dispatch 控制消息,终端 stdin/stdout/stderr 数据面必须走 provider 主动连接 main server 的 `host.ssh.tcp-pool` TCP warm pool,不新增计算节点入站要求,也不保留旧 WebSocket 数据 fallback。传统 ssh 传输参数由 provider-gateway 环境变量统一控制,CLI 只负责把 Provider ID 后的远端命令和终端 stdin/stdout/stderr 透传过去。非交互单进程远端命令优先使用 argv 入口:`trans D601 argv true`;需要 shell 特性时在 operation 位置显式写 `sh` 或 `bash`,例如 `trans D601 sh -- ''` 或 `trans D601 bash -- ''`。WSL 节点需要同时看清 Linux/WSL 与 Windows 两套 skill 时,使用 `trans skills`,该命令只通过已建立的维护桥读取 `SKILL.md` 元数据,不要求 provider-gateway 新增业务 API。 验证 WSL SSH 桥时,先在目标 WSL 中启动 sshd 并确保维护公钥写入目标用户的 `authorized_keys`,再确认目标 provider 注册 labels 中 `unideskCapabilities` 包含 `host.ssh`。运行 `bun scripts/cli.ts debug dispatch host.ssh --wait-ms 15000` 后,结果应在 `debug task latest` 或前端任务历史中显示 `status: succeeded`、`probeLine` 含 `UNIDESK_SSH_TEST`、`exitCode: 0`,并且目标节点 labels 中 `hostSshKeyPresent` 为 true;随后运行 `trans argv true` 验证非交互 argv 维护命令,再运行 `trans hostname` 验证近似原生 ssh 的远端命令体验。在计算节点本机自测时,使用 remote CLI 透传同一组命令:`bun scripts/cli.ts --main-server-ip 74.48.78.17 debug health`、`bun scripts/cli.ts --main-server-ip 74.48.78.17 debug dispatch host.ssh --wait-ms 15000`、`bun scripts/cli.ts --main-server-ip 74.48.78.17 ssh argv true` 和 `bun scripts/cli.ts --main-server-ip 74.48.78.17 ssh hostname`;默认 remote CLI 走公网 frontend 登录态,不需要主 server SSH key。健康检查必须能看到该 Provider 在线、`hostSshConfigured=true`、`hostSshKeyPresent=true`、`hostSshTarget` 正确、`unideskCapabilities` 包含 `host.ssh`,probe 必须返回 `UNIDESK_SSH_TEST`,`ssh argv true` 与 `ssh hostname` 必须 exit code 为 0。如果 D518 这类 WSL 节点没有公网 SSH 入口,也必须通过这个 provider-gateway 自连维护桥完成验证,而不是要求主 server 直接连节点公网 22 端口;旧版 provider 未声明 `host.ssh` 时必须先升级 provider-gateway,否则 core 会拒绝 SSH 透传。