17 KiB
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 把终端流量转给目标 provider,provider-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 负责把用户仍然熟悉的
keil、serial-monitor、board-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
tran <PROVIDER_ID>:win skills --limit 20
<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>nul、set "PYTHONUTF8=1" 和 set "PYTHONIOENCODING=utf-8",因此中文 stdout/stderr 和 Python 子进程默认按 UTF-8 处理;环境变量必须使用 cmd 引号写法,避免 set VAR=1 && ... 把分隔符前的空格写进变量值。
长期命名只允许 win,不允许 win32。win 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。
<PROVIDER_ID>:win skills 是 Windows 用户 skill 发现入口,默认读取当前 Windows 用户 %USERPROFILE%\.agents\skills,输出 JSON 中包含 roots、counts 和每个 skill 的 name、path、skillFile、description。需要同时读取 %USERPROFILE%\.codex\skills 时使用 --scope all;只看 Codex skill 时用 --scope codex。该入口用于替代手写 cmd dir、powershell Get-ChildItem 或宽泛扫描用户目录。
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,包含 roots 和 skills。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...>:调用 Windowspy.exe -3,并对路径参数做/mnt/<drive>到X:\...的转换。win-node <args...>:调用 Windowsnode.exe,适合必须运行在 Windows 设备上下文中的 Node 脚本。win-npm <args...>:调用 Windowsnpm.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 65001、cd /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-powershell或ssh <PROVIDER_ID> skills,再用结构化glob/find缩小到已知目录。
Skill Compatibility Strategy
不要为 Windows 和 WSL 分别维护两套业务逻辑分叉的 skill。推荐策略是保留一个用户可见命令入口,在 wrapper 中选择正确运行侧:
keil:依赖 Windows Keil、CMSIS-DAP/ST-Link/J-Link 驱动、注册表和工程路径,WSL 入口应调用 Windows 侧keilskill 的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-wsl、serial-monitor-wsl、board-comm-wsl,但用户文档中的正式入口仍应优先写 keil、serial-monitor 和 board-comm,避免让任务 prompt 绑定到某台机器的一次性脚本名。
Skill Modification And Bootstrap Status
Windows 透传机制不要求修改 WSL skill 的业务代码。标准交付边界应区分三类内容:
- UniDesk 内置能力:
ssh <PROVIDER_ID> skills、apply-patch、glob、py等 helper 由 UniDesk CLI 在 SSH 会话启动时注入/tmp/unidesk-ssh-tools,属于开箱即用能力;它们不修改远端 skill 目录。 - 节点 bootstrap:
win-cmd、win-powershell、win-py、win-npm、win-skill-path以及keil、serial-monitor、board-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 bootstrap,Windows 侧是否已有 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 内有
python3、base64、bash、wslpath;UniDesk SSH 注入的py、apply-patch、glob和skill-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 Launcher:
py.exe可用,且py -3指向 Python 3。 - Node.js/npm:
node.exe和npm.cmd可用;涉及 COM 口的 TypeScript skill 应运行在 Windows Node 上。 - Keil MDK:
UV4.exe可用,Keil Pack 已安装到工程需要的 MCU 系列。 - pyOCD:Windows 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 的依赖安装边界如下:
keil:Windows 侧~/.agents/skills/keil应已存在keil-cli.py、config.json与所需 Python 依赖;Windows Python 中必须能导入 pyOCD。Keil pack 和 probe 驱动属于 Windows 工具链依赖,不属于 WSL wrapper 自动安装范围。serial-monitor:Windows 侧~/.agents/skills/serial-monitor需要已执行过npm install,生成对应 Windows 平台的node_modules。从 WSL 调用时应使用win-npm --prefix <windows-skill-dir> run cli -- ...,不要复用 WSL 的node_modules去访问 Windows COM 口。board-comm:JSON-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'
硬件项目级验收还应覆盖真实 build、program、串口抓取和 board-comm jrpctcp get api。如果只有依赖检查通过但没有真实硬件闭环,不能宣称该工程已完成下载和通信验收。
Hardware Workflow
Keil/串口/board-comm 的通用顺序如下:
ssh <PROVIDER_ID> skills确认 WSL 与 Windows skill 位置。win-powershell或serial-monitor ports确认可见 COM 口。keil status和keil list-devices -p <project.uvprojx>确认 Keil、pyOCD 和 USB probe。keil build --wait -p <project.uvprojx> -t <target>构建。serial-monitor server start --force和serial-monitor monitor start -p <COMx> -b <baud>先打开串口。keil program --wait ... -u <probe_uid>下载并运行。serial-monitor fetch --session-only --no-dedup -l <N>抓取串口证据。board-comm jrpctcp --host <board_ip> --port <port> get api验证主动通信面。
多 probe 同时在线时,keil program、keil 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 Provider:D601 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 盘符 cwd;D601 默认提示为/mnt/f/Work/ConStart。 - Windows 侧必须已安装
codex,且 WSL wrapperwin-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-patch、py < 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。