diff --git a/docs/PLAN.md b/docs/PLAN.md index d016c32..920fb53 100644 --- a/docs/PLAN.md +++ b/docs/PLAN.md @@ -1,6 +1,7 @@ # 总体规划:把 DeepSeek Harness 升级为 Codex 级智能助手 -> 状态:进行中。本文件是路线图,随开发更新。 +> 状态:**暂停**(用户 API 余额不足,2026-08-17)。目标已挂起,续作时从 +> `docs/computer-use-PROGRESS.md` 的已知问题开始。 ## 目标 @@ -31,12 +32,15 @@ - [x] 端到端验证:任务自动执行、重启保留 - [ ] GUI 管理面板(下一阶段) -### 3️⃣ 电脑操作模式(核心) -- [ ] screen_capture(截图) -- [ ] screen_vision(mmx M3 视觉识别元素/坐标) -- [ ] screen_click / screen_type / screen_key(user32) -- [ ] screen_list_windows / screen_ui_tree(UI Automation) -- 闭环:截图 → 看懂 → 操作 → 再看 +### 3️⃣ 电脑操作模式(进行中,因余额暂停) +- [x] dsh-computer 插件(8 工具注册,已运行) +- [x] screen_capture 截图 ✅(实测 1707x1067) +- [x] 视觉链路(mmx M3 直连 API)✅ +- [x] screen_move/click/type/key/list_windows/ui_tree 工具编写完成 +- [ ] 修 screen_vision 语法错误(一行式 IIFE) +- [ ] 修 screen_list_windows 经宿主 shell 返回空的问题 +- [ ] 闭环实测:截图→看懂→点击→再看 +- 详细进度与排查方案:docs/computer-use-PROGRESS.md ### 4️⃣ 内置浏览器操控 - [ ] Edge CDP 驱动(导航/点击/填表/截页) diff --git a/docs/computer-use-PROGRESS.md b/docs/computer-use-PROGRESS.md new file mode 100644 index 0000000..89b7779 --- /dev/null +++ b/docs/computer-use-PROGRESS.md @@ -0,0 +1,33 @@ +# 电脑操作模式 — 进度与踩坑记录(暂停待续) + +> 用户因 API 余额不足暂停开发。本文件记录已完成的进展与未解决问题,便于续作。 + +## 已完成 ✅ + +- **dsh-computer 插件**(comp-4/pkg-12,host-only,已运行):8 个工具注册 + - `screen_capture` — 全虚拟屏幕截图 → PNG(**实测成功**,1707x1067) + - `screen_vision` — MiniMax M3 视觉分析(node 直连 NVIDIA API,带 429 重试) + - `screen_move` / `screen_click` — user32 SetCursorPos + mouse_event + - `screen_type` / `screen_key` — SendKeys + - `screen_list_windows` / `screen_ui_tree` — EnumWindows + UI Automation +- **视觉链路验证**:mmx 脚本与直连 API 均可用(429 限流已恢复) + +## 已知问题 🔧(续作时优先修) + +1. **screen_vision 语法错误**:node 视觉脚本的一行式 IIFE 有括号问题(`[stdin]:12`)。 + 修复方案:改成多行格式化脚本(本仓库 tools/ 下有样例结构)。 +2. **screen_list_windows 经插件调用返回空**:脚本本体与 LF-only stdin 均在本机 pwsh + 验证正常(能列出真实窗口),但经宿主 ctx.shell 执行时 stdout 为空。 + 疑点:宿主 shell 执行器对含空格 command 的 stdin 管道处理(node 的 stdin 正常, + powershell 的不行);或 Add-Type 在 executor 环境下静默失败。 + 排查建议:让工具在 exitCode==0 时也返回 stderr;或改用 `pwsh -Command -`; + 或把 PS 脚本先落盘为 .ps1 文件再 `powershell -File` 执行。 +3. **沙箱**:宿主 ctx.shell 默认 workspace-write 本机不可用 → 必须显式 + `sandboxPolicy: danger-full-access`(已解决,见 plugins/*/host.js)。 + +## 验证过的关键机制(写插件必读) + +- ShellExecRequest **没有 args 字段** → 脚本走 stdin、数据走 env 或 JS 字面量 +- `res.stdout` 是 `CollectedOutput`(取 `.text`);结果字段 `res.exitCode`;工作目录 `workdir` +- `btoa` base64 曾引发中文乱码 → 数据用 `JSON.stringify(JSON.stringify(...))` 嵌入 +- 本机 EnumWindows 脚本(tools/test-enum.ps1)输出真实窗口列表可作基准 diff --git a/tools/test-enum.ps1 b/tools/test-enum.ps1 new file mode 100644 index 0000000..8546ac0 --- /dev/null +++ b/tools/test-enum.ps1 @@ -0,0 +1,28 @@ +Add-Type -TypeDefinition @' +using System;using System.Runtime.InteropServices;using System.Text; +public class W { + [DllImport("user32.dll")] public static extern bool EnumWindows(EnumProc cb, IntPtr l); + [DllImport("user32.dll")] public static extern int GetWindowText(IntPtr h, StringBuilder s, int n); + [DllImport("user32.dll")] public static extern int GetWindowTextLength(IntPtr h); + [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr h); + [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr h, out RECT r); + public delegate bool EnumProc(IntPtr h, IntPtr l); + [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left,Top,Right,Bottom; } +} +'@ +$list = New-Object System.Collections.ArrayList +$cb = [W+EnumProc]{ param($h,$l) + if ([W]::IsWindowVisible($h)) { + $len = [W]::GetWindowTextLength($h) + if ($len -gt 0) { + $sb = New-Object System.Text.StringBuilder($len + 1) + [W]::GetWindowText($h,$sb,$sb.Capacity) | Out-Null + $r = New-Object W+RECT + [W]::GetWindowRect($h,[ref]$r) | Out-Null + [void]$list.Add(("{0}|{1}|{2},{3},{4},{5}" -f $h,$sb.ToString(),$r.Left,$r.Top,$r.Right,$r.Bottom)) + } + } + return $true +} +[W]::EnumWindows($cb,[IntPtr]::Zero) | Out-Null +$list | ForEach-Object { Write-Output $_ }