修复三连:WSL路径视图翻译、参数顺序自由、wsl.exe零管道防卡死,on加推送兜底

- fs_view:mcpcfg 内 POSIX 路径在 Windows 操作 WSL 目标时翻译为
  \\wsl.localhost UNC 视图,根除「两键路径不存在/mcpcfg.txt不存在」
  假错;报错与展示保留原文;read_cfg 返回 active_raw 等 4 个 raw 字段
- _hoist_shared:parse 前把共享 flag 提到最前,mcpctl/ocskill 子命令
  前后都能写 --target/--distro 等,根除 unrecognized arguments
- wsl_gate 统一门控:读操作 VM 未跑秒回提示,写操作显式打印后唤醒
  (45s 超时);status/mode/backup/_switch/push/pull 全接入
- _wsl_safe_run 零管道执行(stdin=DEVNULL+stdout/stderr 落临时文件)
  + _wsl_running 先查 --running 绝不无提示冷启动,_wsl_ip 全部改走,
  根除 wslrelay 继承管道句柄致 kill 后 EOF 永久阻塞(skill 菜单卡死
  必须 ctrl+C 的根因)
- mcpctl on 加 push_mcp_config:reload 前 PATCH /config 推送 mcp,
  双保险;ocskill list/dirs 连接前打进度行(flush)
- oc.py run_safe 护栏:子命令 KeyboardInterrupt/SystemExit/异常
  一律回菜单,不再杀穿整个菜单进程
- README 补稳定性设计表与推送双保险链路说明
This commit is contained in:
ypshidifu
2026-09-23 15:31:55 +08:00
parent d56cc01058
commit f7b7695aa7
4 changed files with 413 additions and 48 deletions
+19
View File
@@ -135,6 +135,25 @@ python mcpctl.py off --no-reload # 只对调文件,不调用重载
热重载打的是 `POST /api/location/reload`,会重建 location 并重读磁盘配置,MCP 立即生效;
失败时配置文件已经对调完成,重启 OC 一样生效。
**开启方向多了「推送兜底」(双保险)**:`on` 在对调+写 flag 之后、reload 之前,
先把活配置里的 `mcp` 用 `PATCH /config` 推进**运行中的 OC**(三连尝试:SDK
`client.config.update({config})` → `({body})` → 原生 fetch)。推送成功再 reload
= 双保险,MCP 百分百加载;推送失败不阻断,自动降级为原 reload 单通道。
三个入口(TUI 插件 `/mcpon`、server 插件 `mcp_switch`、本 CLI `mcpctl on`)行为一致。
### 稳定性设计(WSL 相关)
| 问题 | 修复 |
| --- | --- |
| WSL 路径假错「两键路径不存在 / mcpcfg.txt 不存在」 | mcpcfg 内部是 POSIX 路径(`/root/...`),Windows 上曾被解析成 `C:\root`。现在统一过 `fs_view()` 翻译成 `\\wsl.localhost\<发行版>\...` 再访问;报错与展示仍用**原文**(你在 txt 里看到的样子) |
| 参数顺序被 argparse 拒(`mcpctl status --target wsl` 报 unrecognized) | `_hoist_shared()` 在解析前把共享 flag(`--target/--distro/--port/--timeout/--password/--no-reload/--ignore-mode`)提到最前,**子命令前后都能写** |
| WSL 没跑时读配置卡死/假错 | `wsl_gate` 统一门控:**读操作**(status / mode 查看 / backup)VM 没跑秒回提示;**写操作**(on/off/mode 设置 / push / pull)显式打印「正在唤醒」后再拉起 VM(超时 45s),唤醒失败给清晰指引 |
| `wsl.exe` 超时后进程永久卡死(必须 ctrl+C) | 所有 `wsl.exe` 调用改走 `_wsl_safe_run`:`stdin=DEVNULL` + stdout/stderr 落**临时文件**(零管道)+ 先查 `-l -q --running` 绝不无提示冷启动。根因是管道句柄被 wslrelay 等后代继承,client 被 kill 后 `communicate()` 等 EOF 永不返回 |
| 菜单被子命令 `raise SystemExit` 杀死 | `oc.py` 的 `run_safe()` 护栏:`KeyboardInterrupt` → 已取消回菜单;`SystemExit` → 报告信息回菜单;异常 → 打印错误回菜单,菜单本体永不退出 |
`list` / `dirs` 连接 OC 前会先打印「正在探测 OpenCode API 连接…」进度行(flush),
几秒无响应时一眼看出是在探测而不是死了。
---
## 三、连不上 OC 怎么办