Files
pikasTech-unidesk/docs/reference/windows-passthrough.md
T
2026-05-25 18:02:40 +00:00

16 KiB
Raw Blame History

Windows Passthrough Reference

Windows 透传用于让 WSL provider 通过 UniDesk 的 Host SSH / WSL SSH 维护桥调用 Windows 侧工具链、驱动和 skill,同时尽量保持一套可维护的 skill 入口。它的目标不是把 Windows 当成新的 provider,而是让 ssh <PROVIDER_ID> 进入 WSL 后,可以稳定触达 Windows cmd.exe、PowerShell、Python、Node/npm、Keil、COM 串口和 USB 调试器。

Architecture

标准链路是:本机或计算节点 CLI 调用 bun scripts/cli.ts ssh <PROVIDER_ID> ...main server 的 backend-core 通过 provider-gateway 的既有 WebSocket 把终端流量转给目标 providerprovider-gateway 再用只读挂载的维护私钥连到目标 WSL sshd。进入 WSL 后,Windows-only 工具由 WSL 用户目录下的轻量 wrapper 调用 Windows 可执行文件。

这条链路分三层维护:

  • provider-gateway 只负责 Host SSH / WSL SSH 维护桥,不直接理解 Keil、串口或业务 skill。
  • WSL wrapper 负责路径转换、当前目录转换、Windows 进程启动、UTF-8 输出和 cmd/PowerShell 差异。
  • skill wrapper 负责把用户仍然熟悉的 keilserial-monitorboard-comm 命令映射到正确运行侧,避免维护两套互相分叉的 skill。

UniDesk Win Route

简单 Windows cmd.exe 命令不需要依赖节点侧 win-cmd wrapper。UniDesk CLI 内置 win route

tran <PROVIDER_ID>:win cmd ver
tran <PROVIDER_ID>:win/c/test cmd cd

<PROVIDER_ID>:win 只定位到 WSL provider 的 Windows host cmd 执行面,后面的 cmd <command-line> 才是操作。<PROVIDER_ID>:win/<drive>/<path> 使用 slash 语法设置 Windows cwd,例如 D601:win/c/test 会在 Windows cmd 内执行 cd /d "C:\test"。该入口固定在运行用户命令前设置 chcp 65001>nulPYTHONUTF8=1PYTHONIOENCODING=utf-8,因此中文 stdout/stderr 和 Python 子进程默认按 UTF-8 处理。

长期命名只允许 win,不允许 win32win route 仍复用 provider-gateway 的 Host SSH / WSL SSH 维护桥抵达目标 WSL provider,但不会依赖 WSL 登录 shell 的 Windows PATH,也不再通过节点侧 win-cmd wrapper 二次转发。CLI 固定从 /mnt/c/Windows 启动 Windows PowerShell UTF-8 launcher,再由 launcher 执行 C:\Windows\System32\cmd.exe /d /s /c <command-line>PowerShell 只负责把 Console/Input/OutputEncoding 设为 UTF-8 并保留 cmd 的 exit code,用户命令语义仍属于 Windows cmd.exe。需要 Keil、串口、Windows Node/npm 或复杂路径转换时,继续使用下文的 skill/wrapper 入口,直到对应能力被纳入 UniDesk 内置 route。

Skill Discovery

先用 UniDesk SSH 透传内置的 skill 发现入口确认目标节点上 WSL 与 Windows 两侧 skill 的实际位置:

bun scripts/cli.ts ssh <PROVIDER_ID> skills --limit 80
bun scripts/cli.ts ssh <PROVIDER_ID> skills --scope windows --limit 40
bun scripts/cli.ts --main-server-ip <MAIN_SERVER_IP> ssh <PROVIDER_ID> skills --scope wsl --limit 20

ssh <PROVIDER_ID> skills 输出 JSON,包含 rootsskills。WSL provider 会同时扫描 WSL/Linux 的 ~/.agents/skills~/.codex/skills,以及 Windows 用户目录下的 /mnt/c/Users/*/.agents/skills/mnt/c/Users/*/.codex/skills。不要用宽泛的 find /mnt/* 搜 Windows 盘;Windows 挂载层可能因权限、索引或设备状态导致长时间阻塞。

Wrapper Contract

WSL 用户的 ~/.local/bin 是推荐 wrapper 放置位置,并应在 SSH 登录 shell 的 PATH 中优先于系统路径。wrapper 名称和职责固定如下:

  • win-powershell <powershell-command>:用于 Windows 发现、WMI/CIM、注册表、设备和 JSON 输出;应设置 UTF-8 输出,并用 Set-Location -LiteralPath 进入 Windows 当前目录。
  • win-cmd <cmd-line>:用于 .cmd.bat 或必须走 cmd.exe 的 legacy 工具;应先写入 Windows 临时 .cmd 文件再执行,避免 UNC 当前目录警告和带空格路径引号错误。
  • win-argpath <arg>:把 /mnt/<drive>/... 或存在的 WSL 路径转换为 Windows 路径,其余参数原样返回。
  • win-py <args...>:调用 Windows py.exe -3,并对路径参数做 /mnt/<drive>X:\... 的转换。
  • win-node <args...>:调用 Windows node.exe,适合必须运行在 Windows 设备上下文中的 Node 脚本。
  • win-npm <args...>:调用 Windows npm.cmd;涉及 COM 口、USB 设备或 Windows-only npm 依赖时优先使用它。
  • win-skill-path <skill-name>:在 Windows .agents/skills.codex/skills 中定位 skill 根目录,供上层 skill wrapper 复用。

win-cmd 不应直接从 WSL 默认 UNC cwd 运行 cmd.exe /C <command>。稳定做法是选择一个 Windows 可写临时目录,例如 C:\Temp,生成 .cmd 文件,在脚本中 chcp 65001cd /d "<Windows cwd>",再执行用户命令。这样可同时处理 C:\Program Files 这类带空格路径和 Windows 工具不支持 UNC 当前目录的问题。

Path And CWD Rules

Windows 可执行文件只能稳定访问 Windows 盘符路径。WSL wrapper 应遵循这些规则:

  • 当前目录在 /mnt/<drive>/... 下时,自动转换为 <DRIVE>:\... 作为 Windows cwd。
  • 当前目录不在 /mnt/<drive> 下时,默认使用 C:\Windows,或由调用者显式设置 WIN_CWD
  • 参数中存在的 /mnt/<drive>/... 路径应转换为 Windows 路径;普通参数、IP、端口、JSON 字符串不应被转换。
  • 需要 Windows 工具直接读写的工程仓库应放在 Windows 盘符挂载路径下;WSL 原生 /home/... 更适合作为 UniDesk、脚本和临时 Linux 工作区。
  • 从 WSL 到 Windows 的搜索优先使用 win-powershellssh <PROVIDER_ID> skills,再用结构化 glob/find 缩小到已知目录。

Skill Compatibility Strategy

不要为 Windows 和 WSL 分别维护两套业务逻辑分叉的 skill。推荐策略是保留一个用户可见命令入口,在 wrapper 中选择正确运行侧:

  • keil:依赖 Windows Keil、CMSIS-DAP/ST-Link/J-Link 驱动、注册表和工程路径,WSL 入口应调用 Windows 侧 keil skill 的 keil-cli.py,通常经 win-py 执行。
  • serial-monitor:访问 Windows COM 口时必须运行在 Windows Node/npm 上,WSL 入口应通过 win-npm --prefix <windows-skill-dir> run cli -- ... 调用。
  • board-comm:当前 JSON-RPC over TCP 不依赖 Windows 驱动,可直接用 WSL Python 运行 WSL 侧 skill;只有未来新增 serial transport 时才需要再评估是否切到 Windows 侧。

工程级 wrapper 可以保留 *-wsl 别名,例如 keil-wslserial-monitor-wslboard-comm-wsl,但用户文档中的正式入口仍应优先写 keilserial-monitorboard-comm,避免让任务 prompt 绑定到某台机器的一次性脚本名。

Skill Modification And Bootstrap Status

Windows 透传机制不要求修改 WSL skill 的业务代码。标准交付边界应区分三类内容:

  • UniDesk 内置能力:ssh <PROVIDER_ID> skillsapply-patchglobpy 等 helper 由 UniDesk CLI 在 SSH 会话启动时注入 /tmp/unidesk-ssh-tools,属于开箱即用能力;它们不修改远端 skill 目录。
  • 节点 bootstrapwin-cmdwin-powershellwin-pywin-npmwin-skill-path 以及 keilserial-monitorboard-comm 的 WSL wrapper 属于节点运行环境 bootstrap,通常放在目标 WSL 用户的 ~/.local/bin;这不是 skill 本身开箱即用的一部分。
  • skill 代码:除非明确要把 wrapper 能力合入某个 skill,否则不得为了某台节点直接改 ~/.agents/skills/<skill>~/.codex/skills/<skill> 的业务代码;如果确实修改了 skill CLI 或 SKILL.md,必须按该 skill 的测试和文档规则独立验收。

因此,判断一个节点是否“开箱即用”时要分别检查:UniDesk CLI 是否支持 ssh skills,目标 WSL 是否已有 wrapper bootstrapWindows 侧是否已有 Keil/Node/npm/Python/驱动,目标 skill 是否已有依赖。缺少 wrapper 或 Windows 工具链时,应报告为节点环境未 bootstrap 完成,而不是把它误判成 skill 逻辑失败。

当前推荐不在 wrapper 中自动安装依赖。serial-monitor 所需 Windows node_modules、Keil pack、pyOCD、USB probe 驱动、COM 驱动等都应由节点 bootstrap 或人工安装完成;wrapper 只负责调用和给出明确错误。这样可以避免 agent 在硬件节点上静默安装版本不明的依赖,导致后续验收不可复现。

Dependency Bootstrap

Windows 透传依赖分为四类:UniDesk 侧能力、WSL 侧基础环境、Windows 侧工具链、skill 本地依赖。它们应由节点 bootstrap 或人工维护显式安装,不应由业务任务中的 wrapper 静默安装。

UniDesk And WSL Prerequisites

WSL provider 至少需要:

  • WSL sshd 已启动,provider-gateway 容器可用维护私钥免密登录目标 WSL 用户。
  • 目标 WSL 用户 PATH 包含 ~/.local/bin,用于放置 win-* 与 skill wrapper。
  • WSL 内有 python3base64bashwslpathUniDesk SSH 注入的 pyapply-patchglobskill-discover 依赖这些基础命令。
  • WSL 可访问 Windows 盘符挂载,例如 /mnt/c/mnt/d/mnt/f
  • 如果 provider-gateway 跑在 Docker Desktop daemon 上,容器到 WSL sshd 的 host.docker.internal:22 链路必须可用。

WSL wrapper bootstrap 至少应安装或生成这些脚本:

mkdir -p ~/.local/bin
# win-cmd, win-powershell, win-argpath, win-py, win-node, win-npm, win-skill-path
# keil, serial-monitor, board-comm wrappers
chmod +x ~/.local/bin/win-* ~/.local/bin/keil ~/.local/bin/serial-monitor ~/.local/bin/board-comm

这些 wrapper 属于节点环境,不应提交到 UniDesk 仓库,除非后续专门新增一个受版本管理的 provider bootstrap 脚本。

Windows Toolchain Prerequisites

Windows 侧至少需要按目标硬件场景安装:

  • Python Launcherpy.exe 可用,且 py -3 指向 Python 3。
  • Node.js/npmnode.exenpm.cmd 可用;涉及 COM 口的 TypeScript skill 应运行在 Windows Node 上。
  • Keil MDKUV4.exe 可用,Keil Pack 已安装到工程需要的 MCU 系列。
  • pyOCDWindows Python 环境中可用 python -m pyocd,用于 CMSIS-DAP 探头检测和 pyOCD backend 下载。
  • USB 调试器驱动:CMSIS-DAP、DAPLink、ST-Link 或 J-Link 对应驱动可被 Windows 识别。
  • 串口驱动:目标板 UART bridge 在 Windows 设备管理器中显示为 COMx
  • PowerShell:用于 WMI/CIM 设备发现、路径诊断和 Windows 侧环境检查。

推荐的只读检查命令:

win-powershell "Get-Command py.exe,node.exe,npm.cmd -ErrorAction SilentlyContinue | Select-Object Name,Source | ConvertTo-Json"
win-powershell "Get-CimInstance Win32_SerialPort | Select-Object DeviceID,Name,Description,PNPDeviceID | ConvertTo-Json -Depth 3"
win-cmd "where py && where node && where npm"

Keil 与 pyOCD 检查应通过 skill 入口完成:

keil status
keil list-devices -p <project.uvprojx>

Skill Dependencies

各 skill 的依赖安装边界如下:

  • keilWindows 侧 ~/.agents/skills/keil 应已存在 keil-cli.pyconfig.json 与所需 Python 依赖;Windows Python 中必须能导入 pyOCD。Keil pack 和 probe 驱动属于 Windows 工具链依赖,不属于 WSL wrapper 自动安装范围。
  • serial-monitorWindows 侧 ~/.agents/skills/serial-monitor 需要已执行过 npm install,生成对应 Windows 平台的 node_modules。从 WSL 调用时应使用 win-npm --prefix <windows-skill-dir> run cli -- ...,不要复用 WSL 的 node_modules 去访问 Windows COM 口。
  • board-commJSON-RPC over TCP 可直接使用 WSL 侧 ~/.agents/skills/board-comm 与 WSL Python;如果 check 因缺少 pyright 失败,但 jrpctcp 正常,不应阻塞硬件通信验证。若未来增加 serial transport,再按运行侧补充 Windows 依赖。

依赖安装必须显式、可复现,并优先在对应 skill 的 SKILL.md 或节点 bootstrap 文档中记录。业务任务中如果发现依赖缺失,应输出缺失项、建议安装命令和验证命令,而不是直接静默安装。

Verification Matrix

节点完成依赖 bootstrap 后,至少运行以下验证:

bun scripts/cli.ts ssh <PROVIDER_ID> skills --limit 20
bun scripts/cli.ts ssh <PROVIDER_ID> -- 'export PATH="$HOME/.local/bin:$PATH"; command -v win-cmd win-powershell win-py win-npm keil serial-monitor board-comm'
bun scripts/cli.ts ssh <PROVIDER_ID> -- 'export PATH="$HOME/.local/bin:$PATH"; win-py -V; win-npm -v'
bun scripts/cli.ts ssh <PROVIDER_ID> -- 'export PATH="$HOME/.local/bin:$PATH"; keil status'
bun scripts/cli.ts ssh <PROVIDER_ID> -- 'export PATH="$HOME/.local/bin:$PATH"; serial-monitor ports'
bun scripts/cli.ts ssh <PROVIDER_ID> -- 'export PATH="$HOME/.local/bin:$PATH"; board-comm debug build-jrpctcp-request get api'

硬件项目级验收还应覆盖真实 buildprogram、串口抓取和 board-comm jrpctcp get api。如果只有依赖检查通过但没有真实硬件闭环,不能宣称该工程已完成下载和通信验收。

Hardware Workflow

Keil/串口/board-comm 的通用顺序如下:

  1. ssh <PROVIDER_ID> skills 确认 WSL 与 Windows skill 位置。
  2. win-powershellserial-monitor ports 确认可见 COM 口。
  3. keil statuskeil list-devices -p <project.uvprojx> 确认 Keil、pyOCD 和 USB probe。
  4. keil build --wait -p <project.uvprojx> -t <target> 构建。
  5. serial-monitor server start --forceserial-monitor monitor start -p <COMx> -b <baud> 先打开串口。
  6. keil program --wait ... -u <probe_uid> 下载并运行。
  7. serial-monitor fetch --session-only --no-dedup -l <N> 抓取串口证据。
  8. board-comm jrpctcp --host <board_ip> --port <port> get api 验证主动通信面。

多 probe 同时在线时,keil programkeil detect 必须显式传 -u <probe_uid>。若 Keil UV4 backend 报缺少 flash/download metadata,可优先用 pyOCD backend 完成下载;是否补齐 UV4 工程下载配置应作为工程维护问题处理,而不是 SSH/Windows 透传问题。

Code Queue Windows Native Codex

Code Queue 支持在提交任务时选择 executionMode=windows-native。该模式用于 D601 这类 WSL ProviderD601 Code Queue 先通过本节点执行环境建立任务运行环境,但容器内不启动 codex;容器只运行 stdio relay,连接到 WSL 侧 bridge,再由 bridge 调用 Windows 宿主原生 codex app-server --listen stdio://。这样 UniDesk 控制面到 Provider 的临时断连不会直接终止 Windows Codex 进程。

约束:

  • 只支持非主 server WSL Provider 和 Codex 模型;minimax-m2.7 / OpenCode port 不走该模式。
  • 工作目录必须在 /mnt/<drive>/... 下,供 win-cmd 转换为 Windows 盘符 cwdD601 默认提示为 /mnt/f/Work/ConStart
  • Windows 侧必须已安装 codex,且 WSL wrapper win-cmd 可用;可用 bun scripts/cli.ts ssh D601 -- 'export PATH="$HOME/.local/bin:$PATH"; win-cmd "where codex && codex --version"' 验证。
  • 任务 JSON、列表、Trace 摘要和前端卡片必须显示 executionMode,便于区分默认容器 Codex 与 Windows 原生 Codex。

Remote Frontend Limits

--main-server-ip ... ssh <PROVIDER_ID> <command> 走 frontend 登录态和 host.ssh dispatch,适合短命令和 skill discovery。它不流式转发 stdin,也受 provider-gateway 的 host.ssh command length 限制;apply-patchpy < stdin、超长 inline 脚本和需要完整终端流的操作应在 main server 本机 CLI 上执行,或显式走旧 SSH transport。

ssh <PROVIDER_ID> skills 在 remote frontend 模式下使用短 inline 发现脚本以避开命令长度限制;如果输出被任务历史截断,应改在 main server 本机 CLI 执行同一命令以获得完整 stdout。

Safety Rules

  • Windows 透传只用于节点诊断、硬件工具链和人工维护,不得作为 provider-gateway 自重建通道;provider-gateway 升级仍必须走 provider.upgrade mode=schedule
  • 不要把 Windows 透传 wrapper 写入业务仓库根目录;它们属于节点运行环境,应放在 WSL 用户目录或节点私有 bootstrap 脚本中。
  • 不要在 wrapper 中静默安装依赖;缺少 py.exe、Node/npm、Keil、COM 驱动或 probe 驱动时,应输出明确错误并让节点 bootstrap 修复。
  • 不要把 Windows 用户目录、串口日志、Keil 日志、SSH key 或 provider token 提交到 UniDesk 仓库。
  • 串口抓取和烧录会影响真实硬件状态;执行前应确认目标 project、target、probe UID、COM 口和 baud rate。