diff --git a/CHANGELOG.md b/CHANGELOG.md index b5ea7f5..10fde2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - Handle the real Serena 1.7/FastMCP structuredContent.result string envelope before parsing symbols or references. Preserve error, empty-result, malformed and shortened-response semantics; do not discard unknown envelope metadata or silently prefer text over unsupported structured data. - Add an opt-in real Serena acceptance command using an explicitly supplied installed command. It exercises overloaded C# identities, ambiguity, reference locations, direct upstream body evidence, legitimate empty results, process interruption with unavailable restart, inactive projects and owned-process cleanup. It neither installs dependencies nor reconnects the parent Codex client. +- Acceptance recorded on 2026-09-08: merged main `10496e0` passed 313 core tests with one optional skip; the pinned Serena 1.7.0/Roslyn isolated acceptance passed seven stages. These checks do not verify a pre-existing client connection or other upstream versions. + ## 0.12.4 - Repomix health and packing launch an installed JavaScript bin directly with the current Node executable and separate arguments, eliminating the cmd/npx shell chain. Local package bin discovery and explicit absolute customCliPath are supported; shell wrappers and npx caches are no longer invoked. Missing or invalid entries use the builtin packer without installing anything. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e92ad9d..93a4643 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,8 +25,10 @@ Keep changes bounded to the problem. Tool registration, schema and validation be For a version change, align `package.json`, the root entries in `package-lock.json`, `src/Core/Config.ts`, the Host project version, README and Skill. Do not edit dependency metadata to change the product's Node requirement. Dependency changes need an explicit maintenance scope; update npm/NuGet locks there and validate locked restores. `.gitattributes` and `.editorconfig` define formatting for touched files; do not reformat the repository in a functional PR. -Before merging a topic branch, record the problem, changes, failures and actual verification in the existing work log. Require successful Node 22/24 and CodeQL results for the exact PR head. Keep independent review and author self-review distinct, and identify unverified integrations. Repository branch-protection settings require a separate owner decision; this document does not establish enforced protection. A successful CodeQL run also does not prove existing alerts are closed. +Before merging a topic branch, record the problem, changes, failures and actual verification in the existing work log. Require successful Node 22/24 and CodeQL results for the exact PR head. Keep independent review and author self-review distinct, and identify unverified integrations. Changes to repository protection require an owner decision; the verified policy is recorded below. A successful CodeQL run also does not prove existing alerts are closed. On 2026-09-08, the owner authorized applying main protection. The read-back confirmed required pull requests, strict Node 22/24 regression and three CodeQL analysis checks bound to GitHub Actions, enforcement for administrators, resolved conversations, and disabled force pushes/deletions. The single-maintainer policy requires zero GitHub approvals; this does not constitute an independent review. Re-read GitHub settings when verifying current enforcement. SDK policy follows [Microsoft global.json guidance](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json); dependency locking uses [NuGet locked restore](https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#locking-dependencies). + +Current implementation is described in the [architecture guide](WinCode-架构与数据流说明.md). Remaining work is maintained in the [active engineering plan](WinCode-下一轮工程化迭代计划书.md); completed work belongs in CHANGELOG and the append-only work log. For documentation-only changes, verify local links, commands, version claims and evidence boundaries; do not claim a new runtime regression without running it. diff --git a/README.md b/README.md index a1a3399..847bd98 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ MIT license

+文档导航 / Documentation: [架构与数据流](WinCode-架构与数据流说明.md) · [当前路线图](WinCode-迭代路线图.md) · [待实施计划](WinCode-下一轮工程化迭代计划书.md) · [Skill 与 MCP 配置](WinCode-Skill制作与MCP配置指南.md) · [工作记录](docs/codex_worklog.md) + ## English WinCode is a local MCP server built for Windows and .NET engineering. It bridges project architecture analysis with non-invasive desktop UI inspection, enabling coding agents to debug desktop applications across source declarations, runtime control hierarchies, and annotated screenshots in a unified workflow. @@ -30,10 +32,10 @@ Current source version: **0.12.5**. All UI tools are strictly read-only and non- git clone https://github.com/linnnn89/WinCode.git cd WinCode npm ci -npm run build +npm run check -# Build the native Windows UI helper -dotnet publish tools/WinCode.UIA.Host/WinCode.UIA.Host.csproj -c Release -r win-x64 --no-self-contained +# Verify the complete Gateway / Release Host / Skill delivery +npm run delivery:verify ``` Add WinCode as a stdio MCP server in your agent client configuration: @@ -131,6 +133,8 @@ The 2026-09-08 check of the current Codex connection against TavernDesk source p ### Architecture and resource control +See the [architecture, data-flow and verification-gate guide](WinCode-架构与数据流说明.md) for the current component boundaries, request sequences, storage lifecycle and delivery checks (Chinese). + ```text Coding agent ── stdio MCP ── WinCode ├─ Code adapters: Serena / Repomix / Built-in text fallbacks @@ -139,7 +143,7 @@ Coding agent ── stdio MCP ── WinCode └─ Window tree + screenshot ``` -- **Target PID Absolute Immunity:** UI inspection executes out-of-process via an isolated helper (`tools/WinCode.UIA.Host`). All process cleanups target only the owned helper process tree via Windows `taskkill /T`; the inspected target application is never terminated or injected. +- **Owned-process cleanup:** UI inspection executes out-of-process via an isolated helper (`tools/WinCode.UIA.Host`). All process cleanups target only the owned helper process tree via Windows `taskkill /T`; the inspected target application is never terminated or injected. - **Concurrency Protection:** UI inspection and health checks share a serial execution mutex to prevent native UIA message pump deadlocks. Workspace switches safely drain in-flight calls before changing cache namespaces. - **Byte-Bounded Cache:** Memory and disk caches enforce strict byte caps (default 32 MiB serialized memory, 128 MiB disk quota including disk-spilled overflow snapshots). Debounced file watching (150 ms) and index probing invalidate the ~2.5s fingerprint memo upon disk changes. @@ -183,7 +187,7 @@ The default `compact` response contains one JSON text block; `responseFormat: "l ### Development and validation -The [CI workflow](.github/workflows/ci.yml) runs `npm run check` on pull requests and main pushes using Windows, Node.js 22/24 and .NET SDK 10.0.303. It performs locked builds, core regression, production stdio and delivery verification, and uploads bounded reports even on failure. Interactive desktop/UI and real Serena acceptance remain separate. Check the actual run result; adding a workflow does not configure branch protection or establish a passing build. +The [CI workflow](.github/workflows/ci.yml) runs `npm run check` on pull requests and main pushes using Windows, Node.js 22/24 and .NET SDK 10.0.303. It performs locked builds, core regression, production stdio and delivery verification, and uploads bounded reports even on failure. Interactive desktop/UI and real Serena acceptance remain separate. Check the actual run result. Main protection was verified on 2026-09-08 with required Node 22/24 and three CodeQL checks; approvals are zero under the single-maintainer policy. See [CONTRIBUTING](CONTRIBUTING.md) for enforcement and evidence boundaries. ```powershell npm ci @@ -221,10 +225,10 @@ WinCode 是面向 Windows 与 .NET 工程研发的本地 MCP 服务。它将项 git clone https://github.com/linnnn89/WinCode.git cd WinCode npm ci -npm run build +npm run check -# 编译 C# 原生 UI 取证宿主 -dotnet publish tools/WinCode.UIA.Host/WinCode.UIA.Host.csproj -c Release -r win-x64 --no-self-contained +# 核对 Gateway / Release Host / Skill 完整交付物 +npm run delivery:verify ``` 在 Agent 客户端配置文件中添加 stdio MCP 服务(以支持 `mcpServers` 的客户端为例): @@ -374,7 +378,7 @@ Coding Agent ── stdio MCP ── WinCode ### 本地开发与测试验证 -[CI 工作流](.github/workflows/ci.yml) 在 PR 和 main 推送时使用 Windows、Node.js 22/24 与 .NET SDK 10.0.303 执行 `npm run check`,覆盖锁定构建、核心回归、生产 stdio 和交付校验,失败时也上传有界报告。交互桌面/UI 和真实 Serena 验收仍单独执行。通过与否以实际运行结果为准;添加工作流不会自动配置分支保护。 +[CI 工作流](.github/workflows/ci.yml) 在 PR 和 main 推送时使用 Windows、Node.js 22/24 与 .NET SDK 10.0.303 执行 `npm run check`,覆盖锁定构建、核心回归、生产 stdio 和交付校验,失败时也上传有界报告。交互桌面/UI 和真实 Serena 验收仍单独执行。通过与否以实际运行结果为准。2026-09-08 已核对 main 保护要求 Node 22/24 和三项 CodeQL 检查;单维护者策略要求 approval=0,不代表已获独立审核。详见 [贡献指南](CONTRIBUTING.md)。 ```powershell npm ci diff --git "a/WinCode-Skill\345\210\266\344\275\234\344\270\216MCP\351\205\215\347\275\256\346\214\207\345\215\227.md" "b/WinCode-Skill\345\210\266\344\275\234\344\270\216MCP\351\205\215\347\275\256\346\214\207\345\215\227.md" index 94f8c91..6ebace5 100644 --- "a/WinCode-Skill\345\210\266\344\275\234\344\270\216MCP\351\205\215\347\275\256\346\214\207\345\215\227.md" +++ "b/WinCode-Skill\345\210\266\344\275\234\344\270\216MCP\351\205\215\347\275\256\346\214\207\345\215\227.md" @@ -1,143 +1,92 @@ -# WinCode Skill 制作、安装与 MCP 配置指南 +# WinCode Skill 安装、维护与 MCP 配置指南 -适用于本仓库 v0.8–v0.9 系列。以下以 Windows、Codex 和 `I:/WinCode` 为例;其他用户须替换为自己的仓库路径。客户端界面名称可能随版本变化。 +适用于 **0.12.5**,核对日期 2026-09-08(北京时间)。以下使用本机 `I:/WinCode` 路径举例;其他机器必须替换路径。客户端界面名称随版本变化,以实际界面为准。 -## 1. Skill 与 MCP 各做什么 +## 1. 三个独立对象 -- **Skill**:指导 Agent 何时、怎样调用工具,按需读取操作手册。 -- **MCP**:运行 WinCode,提供实际的代码分析、窗口发现和 UI 取证工具。 +- **Skill 手册**指导 Agent 选择工具和使用规范字段,不启动服务器。 +- **磁盘交付物**包含 Gateway、原生 UI Host、构建身份和交付清单。 +- **MCP 连接实例**是客户端已经启动的进程;更新源码、构建或复制 Skill 都不会自动更新这个进程。 -两者分别安装。复制 Skill 不会启动或注册 MCP;只有 MCP 也能调用工具,但没有本技能提供的操作指导。不需要把整个项目复制到技能目录,也不需要另建 HTTP 服务。 +架构与数据流见 [架构说明](WinCode-架构与数据流说明.md)。待办见 [当前计划](WinCode-下一轮工程化迭代计划书.md),不要按历史计划重复安装和升级。 -## 2. 制作一个低上下文开销的 Skill +## 2. 构建与交付核对 -本仓库已提供可直接使用的 [skills/wincode](skills/wincode/SKILL.md): +预先准备 Windows x64、Git、Node 24(22 兼容;不再支持 20)以及 `global.json` 锁定的 .NET SDK 10.0.303。已发布的 framework-dependent Host 需要 .NET 10 Windows Desktop 运行时。安装前提组件属于环境准备,不由下列检查隐式完成。 -```text -skills/wincode/ -├── SKILL.md -└── references/ - ├── code.md # 工作区、上下文、符号、影响分析 - ├── ui.md # 窗口、后台截图、XAML 候选 - └── diagnostics.md # 连接、健康状态、审计提醒 -``` - -`SKILL.md` 的 YAML 头仅声明名称与简短用途,正文仅保留手册路由和共享边界。目前入口为 17 行、约 0.9 KB;文件字节数不等于 Token 数。 - -```yaml ---- -name: wincode -description: 使用 WinCode MCP 分析 Windows/.NET 工作区,或读取桌面窗口、截图与 XAML 源码候选。 ---- -``` - -制作或维护原则: - -1. 描述用于技能选择,保持精准,不写长功能清单。 -2. 入口明确“仅读取当前任务对应手册”,不默认加载全部文件。 -3. 每份手册只保留调用顺序、关键参数、必要示例和结果边界。 -4. 不复制 README、完整工具 Schema、源码、更新记录或测试报告。 -5. 参数变化时修改对应手册,再同步安装副本;公共规则只维护一处。 -6. 不增加每次调用必做的健康探测、全仓扫描或截图。代码先取小片段,UI 无视觉需求用 `capture: "none"`。 - -按需加载取决于客户端和 Agent 的实际执行。Skill 不能消除 MCP Schema、工具结果和图片本身的上下文成本,也不保证固定 Token 消耗。 - -## 3. 准备 WinCode 程序 - -先安装项目要求的 Node.js(当前 README 标明 >=18),运行以下命令。UI 取证还需要 Windows x64 与 .NET 10 SDK;下面发布方式依赖本机相应 .NET 运行时。Serena/Repomix 的可选能力和前置条件见 [README](README.md)。 +在仓库根目录执行: ```powershell -Set-Location I:/WinCode npm ci -npm run build - -# 需要 Windows UI 取证时构建 Host -dotnet publish tools/WinCode.UIA.Host/WinCode.UIA.Host.csproj -c Release -r win-x64 --no-self-contained +npm run check +npm run delivery:verify ``` -以上命令会安装锁定的 Node 依赖并恢复/构建 .NET 依赖。普通使用不需要构建 WPF 测试夹具。确认存在 `dist/index.js`;UI Host 发布产物位于 `tools/WinCode.UIA.Host/bin/Release/net10.0-windows/win-x64/publish/`。 +`check` 进行类型检查、Gateway 构建、锁定 NuGet restore、Release Host/控制台夹具构建、核心回归、新 stdio 验证与交付清单生成。交互桌面验收另执行 `npm run check:desktop`,需要可用 Windows 桌面。真实 Serena/TavernDesk 验收单独选择,详见 [CONTRIBUTING](CONTRIBUTING.md)。 -## 4. 安装 Skill +`npm run build` 只构建 Gateway,不能单独证明原生 Host、Skill 和整个交付物一致。生产使用发布的 Release Host;`npm run dev` 才显式启用开发回退。报告位于 `test-tmp/check/`,内容哈希不是发布签名。 -Codex 本例使用当前用户的 `.agents/skills`。其他 Agent 请使用其支持的技能目录,不能假定所有客户端共用该路径。 +## 3. Skill 的规范来源与同步 -首次安装,在 PowerShell 执行: +仓库维护四份手册:[SKILL.md](skills/wincode/SKILL.md)、[代码](skills/wincode/references/code.md)、[UI](skills/wincode/references/ui.md)、[诊断](skills/wincode/references/diagnostics.md)。入口只负责路由,共享规则与字段按工具族查阅;不把全部手册塞进每次会话。 + +对本机已约定的安装目录,先检查,再按需同步: ```powershell -$skillSource = 'I:/WinCode/skills/wincode' -$skillParent = Join-Path $env:USERPROFILE '.agents/skills' -$skillTarget = Join-Path $skillParent 'wincode' -if (Test-Path -LiteralPath $skillTarget) { - throw '已存在 wincode 技能,请先比较并备份本地修改,再更新。' -} -New-Item -ItemType Directory -Path $skillParent -Force | Out-Null -Copy-Item -LiteralPath $skillSource -Destination $skillTarget -Recurse +npm run skill:check -- C:/Users/40218/.agents/skills/wincode +npm run skill:sync -- C:/Users/40218/.agents/skills/wincode +npm run skill:check -- C:/Users/40218/.agents/skills/wincode ``` -最终入口必须是 `%USERPROFILE%/.agents/skills/wincode/SKILL.md`,不要多套一层 `wincode` 目录。 - -**路径适配**:当前 [诊断手册](skills/wincode/references/diagnostics.md) 使用 `I:/WinCode` 的本机示例;仓库放在其他位置时,同步替换安装副本中的启动路径和日志检测脚本路径。工作区示例路径也应按任务替换。 +这些是路径示例,不是跨机器通用目录。同步只管理四份文件,先备份被修改的已有文件,再写入;额外文件不受管,不修改 MCP 配置。受管文件中的本地修改会被仓库版本替换,因此规范更新应先进入仓库;不要把个人配置混入手册。首次同步也可创建目标目录。受管手册改变后重新生成并核对交付清单。 -重新加载客户端或开启新会话,检查技能列表是否出现 `wincode`,再用 `$wincode` 显式调用。实际发现时机以客户端为准。更新技能时先比较安装副本,保留用户自定义内容;不要直接覆盖整个技能父目录。 +**未知字段保持容忍,但不会生效。** 参数名称、大小写、类型和范围以手册字段表为准。例如 `automationId` 是规范字段,`automationID` 不会成为筛选条件;仅含未知字段的 query 仍缺少必需条件。适配器配置字段不能伪装成 MCP 请求参数。 -## 5. 配置 MCP:图形界面与 CLI 二选一 +## 4. 注册 stdio MCP -### 方法 A:Codex 自定义 MCP 界面 +在客户端添加 stdio 服务器,分别填写: -打开自定义 MCP 添加页面,逐项填写: - -| 字段 | 内容 | -|---|---| +| 配置项 | 本机示例 | +| --- | --- | | 名称 | `wincode` | -| 类型 | `STDIO` | -| 启动命令 | `node` | +| 命令 | `node`,或该机器 Node 可执行文件的绝对路径 | | 参数 1 | `I:/WinCode/dist/index.js` | | 参数 2 | `--workspace` | -| 参数 3 | `I:/WinCode` | -| 环境变量、环境变量传递 | 初次配置可留空 | - -**每个参数独立一项**。不要把 `codex mcp add ...` 放进“启动命令”,它是注册命令,不是服务器程序。路径含空格时,独立参数字段填写完整路径,不额外输入引号字符。 - -若客户端找不到 `node`,在终端用 `(Get-Command node).Source` 查出可执行文件绝对路径,填入启动命令。保存并启用后,让客户端重新连接。 - -### 方法 B:Codex CLI - -在终端执行,而不是填到上面的界面里: - -```powershell -codex mcp add wincode -- node I:/WinCode/dist/index.js --workspace I:/WinCode +| 参数 3 | 需要分析的工作区绝对路径,例如 `I:/New-tarven` | + +参数应为独立数组项,不要拼成一条 shell 字符串。若客户端接受 `mcpServers` 配置,可使用: + +```json +{ + "mcpServers": { + "wincode": { + "command": "node", + "args": ["I:/WinCode/dist/index.js", "--workspace", "I:/New-tarven"] + } + } +} ``` -路径含空格时使用终端引号,例如 `"D:/My Projects/WinCode/dist/index.js"`。命令会修改 Codex MCP 配置;已有同名服务时先检查现有配置,不重复注册。该语法已通过本机 `codex mcp add --help` 核对。 - -配置中的 `--workspace` 是初始项目。分析另一个项目时调用 `workspace_open` 切换即可,不需要重新安装 Skill。不同客户端应分别配置,不要同时用两种方法重复添加同一服务。 - -## 6. 最小验收 +不同客户端配置格式可能不同;本例不能直接替代 Codex 自身配置文件格式。不要重复注册多个同名或路径不同的旧实例。WinCode 走 stdio,无需另设 HTTP 服务。 -1. 技能列表出现 `wincode`:只说明 Skill 已发现。 -2. MCP 工具列表出现 `wincode_hello_world`、`wincode_ui_inspect` 等:说明工具已加载。 -3. 让 Agent 调用 `wincode_hello_world({})`:检查返回状态;可用或 fallback 不等于 Serena 语义连接成功。 -4. 用 `$wincode 打开某项目并查看依赖概览` 验证代码路径;使用自己的真实项目路径。 -5. UI 验收另行指定目标窗口;未知 PID/HWND 时先限定进程枚举,再定向取证。不要为连通性测试读取所有窗口内容。 +## 5. 验证实际连接 -UI 后台截图应同时传真实 PID/HWND 和 `backgroundOnly: true`,不会主动激活或还原目标窗口。遮挡应用可能输出黑图或陈旧图,不能只凭返回成功断定截图正确。内置 Host 访问 UI 会显示 REC/WinCoding 标志并记录审计;不要绕过。 +1. 让客户端重新建立 WinCode 连接,再调用 `wincode_hello_world`;核对实例身份、版本、buildId 和工具 schema,而不仅看软件版本字符串。 +2. 用 `npm run delivery:verify` 检查磁盘交付物;将磁盘身份与实际连接对应起来。独立启动的新 stdio 会话通过不等于当前宿主已重连。 +3. 对目标工作区执行一次规范请求,确认返回的是该工作区及声明范围。需要主动健康探测时调用 `wincode_diagnose_project({})`。 -只修改文档时无需运行会影响前台的整套 GUI 测试。若使用 skill-creator 自带校验器,Windows 中文文件建议用 `python -X utf8 <校验器路径>/quick_validate.py <技能目录>`;普通用户安装技能不依赖该校验器。 +0.12.1 起 hello 不主动启动探测进程;unknown/null 表示未探测,不代表不可用。已知健康结果也可能陈旧。旧版本 hello 的行为不能套用新版说明。 -## 7. 常见问题 +0.12.5 已通过固定 Serena 1.7.0/Roslyn 的隔离真实验收;隔离安装不表示默认客户端已启用上游。0.12.4 起 Repomix 直接执行已安装 JavaScript bin,不再使用 cmd/npx 包装链,也不会自动下载;非标准安装和降级边界见诊断手册。 -| 现象 | 处理 | -|---|---| -| Skill 可见,工具不可用 | 检查 MCP 是否配置、启用并重新连接;Skill 不提供执行后端。 | -| `node` 或 `dist/index.js` 找不到 | 检查绝对路径、Node 安装和 `npm run build` 结果。 | -| `HOST_UNAVAILABLE` | 检查 Host 发布产物、运行时或显式 Host 配置;重复安装 Skill 无效。 | -| `AUDIT_BUSY` | 等当前 Helper 完成;不要杀目标应用。 | -| 日志达到阈值 | 阅读工具返回的大小和路径提醒,按授权保留证据后清理,不静默删除。 | +## 6. 常见偏差 -审计目录为 `%LOCALAPPDATA%/WinCode/logs/ui-audit`,1 MiB 提醒、2 MiB 前预留结束空间并停止新访问。只读检测: - -```powershell -pwsh -NoProfile -File I:/WinCode/scripts/check-ui-audit.ps1 -``` +| 现象 | 核对与处理 | +| --- | --- | +| 源码是新版,hello 返回旧版 | 核对实际命令、路径、instanceId 和启动时间;通过客户端重连,不以强杀宿主或复制文件冒充完成 | +| 字段被忽略,结果不像预期 | 对照规范字段表和实际工具 schema;容忍未知字段并不赋予其语义 | +| Host 缺失或身份不符 | 完整执行锁定构建和 delivery:verify;不混用旧 DLL、新 Gateway 或开发 Host | +| Serena/Repomix 不可用 | 先区分策略禁用、尚未探测、命令缺失、握手成功但语义不可用;检查 source/fallbackReason,不把降级当语义验收成功 | +| UI 查不到或出现多个目标 | 核对 PID/HWND 和大小写准确的查询;只有 complete 且 unique 才能声称唯一定位 | -明确需要桌面弹窗时加 `-Desktop`。检测脚本不删除文件;`test-tmp` 是测试输出目录,与正式审计目录不同。 +更新后仍无法核对客户端身份时,保留“客户端未验收”状态与实际证据,不反复尝试未声明参数。 diff --git "a/WinCode-\344\270\213\344\270\200\350\275\256\345\267\245\347\250\213\345\214\226\350\277\255\344\273\243\350\256\241\345\210\222\344\271\246.md" "b/WinCode-\344\270\213\344\270\200\350\275\256\345\267\245\347\250\213\345\214\226\350\277\255\344\273\243\350\256\241\345\210\222\344\271\246.md" index 767c706..8c4ce2a 100644 --- "a/WinCode-\344\270\213\344\270\200\350\275\256\345\267\245\347\250\213\345\214\226\350\277\255\344\273\243\350\256\241\345\210\222\344\271\246.md" +++ "b/WinCode-\344\270\213\344\270\200\350\275\256\345\267\245\347\250\213\345\214\226\350\277\255\344\273\243\350\256\241\345\210\222\344\271\246.md" @@ -1,241 +1,61 @@ # WinCode 下一轮工程化迭代计划书 -编制时间:2026-09-08,北京时间。核查基线:`main@3be2c49a2dc2e24bd22f076a515acbc73ac2c76e`,源码版本 `0.11.2`。 +更新日期:2026-09-08(北京时间)。实施基线:**0.12.5 / main 10496e0**。状态:**以下工作尚未实施;涉及行为取舍的策略需在实施前确认。** -编制时状态:方案待确认,尚未实施。该次审查仅做隔离复现和计划编制,没有修改生产代码、依赖、运行环境或 GitHub 设置,也没有提交或推送。**2026-09-08 用户已要求根据本书逐级实施;当前执行进度见第 9 节。** +已完成的 WP1–WP5、Repomix 安全修复和真实 Serena 隔离验收已从待办移除,历史见 [CHANGELOG](CHANGELOG.md) 与 [工作记录](docs/codex_worklog.md)。方向总览见 [路线图](WinCode-迭代路线图.md),现状见 [架构说明](WinCode-架构与数据流说明.md)。 -本书承接[原迭代路线图](WinCode-迭代路线图.md),作为下一轮执行与验收依据。原路线图保留历史决策;本书不把已完成的 Serena 身份修复、SDK v2、UI→源码导航再次列为新功能。 +## 目标与边界 -## 1. 下一轮目标 +下一轮集中验证失败恢复与长期运行可靠性,沿用 Gateway → Registry/Router → Core/能力接口 → Adapter/Host 的结构。先证明具体缺口,再做局部修复;不因 Router 较大就机械拆层,不增加微服务、插件框架、消息队列或新数据库。 -将 WinCode 从依靠局部补丁和单次验收维持的工具,推进为**契约明确、依赖方向稳定、资源生命周期可验证、交付可复现的小型软件产品**。 +已确认策略继续有效:Node 24 主支持、22 兼容;未知字段容忍并忽略,已声明字段严格校验且在 Skill 列出;hello 不主动探测;UI 取证不操作目标应用;安装与真实上游使用隔离目录。输出范围、候选与已证实事实必须分开表达。 -本次审查的判断是:项目已经具备有价值的基础,包括 TypeScript strict、资源管理、工作区请求排空、源码预算、运行身份、生产 stdio 检查、Windows CI 和隔离 UI 夹具。主要缺口在于这些规则没有覆盖所有执行路径,也没有全部成为合并和发布条件。 +## E1:工作区切换失败一致性(优先) -下一轮不以新增工具数、文件数或测试数量验收。完成后必须能明确回答: +**当前证据:** [ToolRouter.openWorkspace](src/Core/ToolRouter.ts) 在工作区根更新后还会重置、初始化和绑定适配器;这些后续步骤失败时,不能仅凭 Workspace 内部回滚推定整个切换原子性。当前为静态审查发现的风险,尚无本轮故障注入复现。 -1. 任意公开工具实际接受的输入,是否与公布的 schema 一致? -2. 语义上游不可用、扫描提前停止、配置关闭、请求取消时,结果是否仍然可信? -3. 停止操作返回时,哪些资源已关闭、哪些失败,是否有证据? -4. 从一个明确提交构建出来的 Gateway、原生 Host 和使用手册,是否属于同一套交付? -5. 一次修改若破坏这些规则,是否会在合并前被自动发现? +1. 在根切换、缓存/会话更新、适配器 dispose/reset/initialize/rebind 各阶段注入失败与取消。 +2. 检查失败后的根路径、缓存命名空间、watcher、上游绑定、请求占用和下一次请求行为。 +3. 根据复现选择最小恢复策略,并补充回归;禁止错误发生后以“已成功切换”继续返回混合证据。 -**建议本轮暂停 R7–R9 功能扩展,完成下述五个工作包后重新评估。**不计划通用插件系统、DI 容器、跨进程服务平台、全仓缓存重写或 XAML/C# 解释器。 +**验收:** 各故障点结果可解释;后续请求只读同一工作区,或明确拒绝并给出恢复动作;无旧缓存串入、重复 watcher 或自有进程残留。覆盖成功、失败、取消及再次切换。 -## 2. 本次核查结果与证据等级 +**USER_DECISION_REQUIRED:** 若需改变外部行为,推荐切换未提交时保留旧工作区,提交后无法完整恢复时明确进入需恢复状态;是否要求失败后一律自动回滚,应在故障证据齐备后确认。不预先承诺跨适配器事务回滚。 -已读取引用对话「WinCode迭代路线图」最后一次分析,并重新检查当前源码、包配置、工作日志、真实 GitHub CI 和分支规则。以下结论不直接沿用对话中的判断。 +## E2:trash 部分完成与恢复 -| 编号 / 优先级 | 当前问题 | 本次证据与边界 | 工程含义 | -| --- | --- | --- | --- | -| F01 / P0 | Windows CI 仍失败 | main 的 [CI 34177655445](https://github.com/linnnn89/WinCode/actions/runs/34177655445):Node 20 回归为 234 pass、1 fail、1 skip,stdio 被跳过;Node 24 全流程通过。失败是 `runtime-contract.test.ts` 清理 `other` 目录的 `EBUSY` | 不能以本地通过或 CodeQL 通过替代交付成功 | -| F02 / P0 | main 缺少强制合并检查 | GitHub API 返回 `protected=false`、required checks 为空,分支 rules 返回 `[]` | CI 存在,但尚不是强制合并条件;本轮未修改设置 | -| F03 / P1 | Serena 降级扫描上限和完成状态失真 | 直接调用当前实现,三个子目录各 210 处引用,实际返回 **202** 条,同时 `queryComplete=true`、`truncated=false` | 数据非语义与扫描不完整是两个独立状态,不能混用 | -| F04 / P1 | 限定文件仍先读取其他源码 | 指定 `a/Uses.cs`,读取跟踪仍记录 a、b、c 三个目录的源码;扫描器直接 `readFile()`,没有单文件/总读取预算 | 调用方给出的范围没有成为底层执行边界 | -| F05 / P1 | 合法 JSON 中的源码文字被当成上游错误 | `isError=false` 的有效符号结果,源码分别含 `No active project` 和 `没有激活项目`,均降级并丢失该符号 | 协议解析与业务正文缺少明确边界 | -| F06 / P1 | `Repomix.useCli=false` 未落实 | 受控 spawn 替身记录到版本探测请求;模拟探测成功后仍进入 CLI packing。未真正启动外部 CLI | 配置被当成偏好,未成为不可绕过的执行规则 | -| F07 / P1 | 公布输入类型没有被实际执行 | 实际 SDK InMemoryTransport 调用符号工具,`query` 为对象仍成功,适配器收到 `"[object Object]"`;未知字段也未拒绝。当前 schema 对 query 明确要求 string,但未声明关闭未知字段 | `tools/list` 与 hello 同源不等于 handler 符合契约;需要真实运行时校验 | -| F08 / P1 | 生命周期规则没有贯穿所有路径 | `WorkspaceWatch.stop()` 不等待关闭事件;ResourceManager 提前清空记录并吞掉所有 dispose 异常;Serena/Context 的主要代码查询链没有请求 signal,UI 链已有 signal | 有管理器不等于关闭完成或取消完整。**尚未证明永久句柄泄漏,也未锁定 EBUSY 的具体占用者** | -| F09 / P2 | Gateway 与业务边界耦合 | Gateway 直接调用 `router.serena`;参数校验、switch 分发、错误分类、资源准入和序列化集中在 `McpServer.ts`;CompositeTools 从具体 SerenaAdapter 导入业务数据类型 | 新工具仍需多点同步修改,测试较多依赖覆盖私有成员 | -| F10 / P2 | 交付身份和支持政策不完整 | 构建清单覆盖 TS 产物,未包含 C# Host/交付手册;FlaUI 健康响应写死 version=`1.0.0`。仓库只有 Node lock,未跟踪 NuGet lock/global.json;SECURITY 仍称 0.8.x 为活跃版本 | 无法用一份证据确认安装的是哪套 Gateway、Host、手册;维护承诺与实现漂移 | -| F11 / P2 | 验收入口和证据保存缺口 | `test:all` 只有默认回归和 `test:ui`,不含 `test:ui-code`;CI 没有测试报告 artifact 上传步骤;真实 Serena 链仍没有本轮验收证据 | 测试总数不能说明哪些产品能力已验收,失败后的复查成本较高 | +**当前证据:** [Workspace.moveToTrash](src/Core/Workspace.ts) 先 rename 再写元数据;后一步失败可能返回失败,但文件已经移动。需用隔离夹具复现,不能对真实用户文件试错。 -F03–F07 的隔离探针及 JSON 结果位于 `test-tmp/engineering-review-20260908/`,按既有规则忽略。探针运行于 Node 24.19.0,使用临时源码及受控上游;它们不是实际 Serena 集成测试。没有在本机 Node 20 重现 EBUSY,没有运行本轮完整 GUI 或全量回归。 +1. 注入 rename 失败、rename 成功后元数据失败、恢复步骤失败。 +2. 保留源路径、实际目标位置与失败阶段,使已移动文件可找回。 +3. 验证再次请求不会把“失败”误当成完全未执行;恢复动作不能覆盖已有文件。 -主要代码依据:[SerenaAdapter](src/Adapters/SerenaAdapter.ts)、[RepomixAdapter](src/Adapters/RepomixAdapter.ts)、[McpServer](src/Gateway/McpServer.ts)、[ToolRouter](src/Core/ToolRouter.ts)、[WorkspaceWatch](src/Core/WorkspaceWatch.ts)、[ResourceManager](src/Core/ResourceManager.ts)、[构建脚本](scripts/build.mjs)、[CI](.github/workflows/ci.yml)。 +**验收:** 任何结果均能解释文件实际位置;不丢失或覆盖内容;重复请求和重启后恢复有明确边界。 -## 3. 目标架构与不可破坏的规则 +**USER_DECISION_REQUIRED:** 推荐准确报告部分完成并提供恢复信息;若选择自动移回,需要明确冲突与回滚失败的行为。公共结果字段变更须先确认兼容方案,再更新 Skill 和契约测试。 -### 3.1 依赖方向 +## E3:有界混合负载验收 -下图是建议目标,不代表当前已全部满足。保留现有目录和 ToolRouter 组装方式,按改动需要逐步收紧依赖。 +现有有限次数的顺序/并发生命周期测试不能证明真实上游长时间运行稳定,也没有证据据此断言存在泄漏。 -```mermaid -flowchart TD - Client[Codex / 其他 MCP 客户端] --> Gateway[Gateway:schema 校验、协议、序列化] - Gateway --> Router[ToolRouter:用例入口、工作区准入与排空] - Router --> UseCases[Context / CompositeTools:任务编排] - UseCases --> Contracts[窄接口与查询结果类型] - Adapters[Serena / Repomix / FlaUI] --> Contracts - Router --> Adapters - Adapters --> Upstreams[上游 MCP / 本地扫描 / 原生 Host] - Router --> Resources[ResourceManager:资源所有权与关闭] -``` +先运行一个不超过 5 分钟、100 次调用的小样本,在隔离的两个工作区交替查询、切换、取消,并模拟自有上游退出。记录调用延迟、输出量、Gateway/自有子进程 PID、可取得的内存和句柄趋势、清理结果。预算扩大或安装其他上游前另行确认。 -ToolRouter 是允许知道具体实现的组装位置;Gateway 不再访问适配器实例,CompositeTools 依赖实际需要的查询接口。不要为了这张图引入一个新的运行时框架。 +**验收:** 无跨工作区证据污染、请求占用永久不释放、自有进程残留;区分启动增长、缓存稳定平台与持续增长趋势。报告实际采样条件和不可观察项目,不把一次内存峰值当泄漏或把短测当耐久证明。复用现有脚本和报告目录,不建大型基准平台。 -### 3.2 工具契约只有一个权威定义 +固定 Serena 1.7.0/Roslyn 的七项真实验收已经通过;在其相关路径变更后按需重跑。真实 Repomix 包完整兼容性仍待获准环境准备后验证。普通 CI 不自动覆盖这些上游。 -每个工具的名称、别名、JSON Schema、输入校验、执行入口和输出策略集中定义。`tools/list`、hello 的 schema hash 和实际校验使用同一份 schema;跨字段路径/范围约束在该工具的验证函数内处理。 +## E4:结果与错误契约渐进整理 -优先复用已安装 SDK 的公开 `@modelcontextprotocol/server/validators/ajv`。本次已直接验证其 `AjvJsonSchemaValidator.getValidator()` 可接受合法输入、拒绝错误类型及 schema 明确禁止的未知字段。**不新增验证库,不自行实现 JSON Schema 解释器。** +当前 UI、代码和 Gateway 错误格式不同。先盘点高频失败:范围无效、目标歧义、预算截断、取消、上游不可用、部分完成;为每类明确稳定错误码、来源、可重试条件和恢复提示。 -可用静态工具表加按用例分组的模块;它只承担注册与类型组织,不承担动态插件发现、服务定位或依赖注入。第一批迁移 `find_code_symbol/find_references/prepare_context`,随后覆盖 workspace、UI 和维护工具,避免并行维护两套长期机制。 +**验收:** 现有成功响应和调用方式兼容,客户端无需解析自然语言识别已纳入的失败;未知/不完整状态不被改写成成功或否定结论。只处理实际用例涉及的字段,不一次性替换所有结果信封。 -### 3.3 结果可信度分为独立维度 +**USER_DECISION_REQUIRED:** 新公共响应字段及兼容策略需在盘点后确认;不把 MCP 的可选结构化输出能力当作必须全面重写接口的理由。 -| 维度 | 必须表达的含义 | 不得推导的结论 | -| --- | --- | --- | -| 证据来源 | 语义上游、本地文字、运行 UI、声明文件 | 本地文字不能证明符号身份 | -| 执行完成度 | 在声明范围内完成,或因预算、取消、错误而停止 | `degraded` 不能自动表示“扫描已完成” | -| 返回覆盖 | 实际返回了哪些完整行/节点,哪些被裁剪 | 片段完整不等于整个方法/任务完整 | -| 身份与时效 | 请求工作区、运行实例、实际产物、源码哈希 | 同版本号不等于同构建,文件候选不等于运行绑定 | +## 交付与检查关口 -先建立小型内部查询结果类型,把既有公开字段从它一致地映射出来;不立刻替换所有公开响应为一个大而空的统一对象。缺失证据用 unknown/partial 及原因表达,不能默认为成功或空结果。 +每个工作包独立形成可审查变更,先记录触发问题和失败样例,再做最小修复。影响交付输入时执行 `npm run check`;UI 路径变化增加 `npm run check:desktop`,上游路径变化增加对应 opt-in 实测。文档单独修改只做链接、命令、版本和事实一致性核对。 -### 3.4 资源生命周期有实际完成语义 +沿用已授权的版本流程:针对性复测与 debug → 对应版本和 Skill 同步 → PR 精确提交的 Node 22/24 与三项 CodeQL 检查 → 合并 → 主分支交付核对。实际客户端重连另行核对,不能用磁盘版本或新测试会话代替。每步写入既有工作日志;作者自审不等同独立审核。 -每个 watcher、子进程、timer、transport 明确唯一 owner;“发起关闭”“已关闭”“关闭失败”不能混为一谈。重复关闭共享同一结果。只管理 WinCode 自己创建的资源,用户应用 PID 不纳入清理。 - -请求的取消和截止时间从 Gateway 贯穿 ToolRouter、Context、Adapter 到文件扫描/上游调用。工作区切换仍先阻止新请求、排空旧工作;不能只让外层 Promise 提前返回,留下后台扫描继续运行。 - -`ResourceManager` 继续负责汇集资源;不用它的计数清零冒充 OS 句柄释放。保留“尽力关闭全部资源”,同时报告真正失败,区分已关闭的幂等情况与未知失败。 - -### 3.5 预算是执行规则 - -有界读取必须同时约束遍历、单文件、总字节、匹配数量、处理时间和最终序列化。结果上限触发后,所有递归分支停止;限定文件请求不能读取其他源码。 - -预算语义统一,参数值按任务区分。目录预览、源码扫描、UI 和图片不必共享一个数值或一个忽略目录集合。复用被证明相同的小函数,不建设通用扫描平台。 - -## 4. 执行顺序、交付物与验收 - -建议 **五个工作包、五个独立版本 PR**。版本号为当前基线上的建议;实施时先检查 main,避免与其他工作冲突。每包完成 Debug、复测和独立审查后,按最终提交的检查结果合并,再进入下一包。 - -| 顺序 / 建议版本 | 主题 | 粗估有效工作量 | 退出条件 | -| --- | --- | --- | --- | -| WP1 / 0.11.3 | 修复当前稳定性与降级缺陷 | 2–3 个工程日 | F01、F03–F06 关闭,当前支持矩阵恢复通过;D3 确认后启用现有检查的合并保护 | -| WP2 / 0.12.0 | 工具契约与模块边界 | 2–3 个工程日 | 所有公开工具和别名通过实际 schema/handler 一致性验证 | -| WP3 / 0.12.1 | 取消、资源关闭、诊断语义 | 2–3 个工程日 | 关键生命周期有故障注入和真实进程退出证据 | -| WP4 / 0.12.2 | 构建、发布和项目维护规范 | 2–3 个工程日 | 干净环境可重复构建与验证完整交付,合并门槛生效 | -| WP5 / 0.12.3 | 真实上游与产品任务验收 | 1–3 个工程日 | 完成真实集成矩阵,或按明确限制交付并保留未通过项 | - -总估计 9–15 个工程日,是规划量级,不是日历承诺。WP1 完成后以实际修改量和根因更新估计;不假设增加 Agent 数量即可线性压缩。执行者负责实现和证据,独立审查者负责反证与范围审核,用户负责兼容政策和外部设置等重大决定。 - -### WP1:先让现有能力可靠 - -**修改范围:**SerenaAdapter、RepomixAdapter、WorkspaceWatch/直接相关关闭路径,以及对应测试和 CI 的失败诊断输出。不要在这一包同时拆 Gateway。 - -实施次序: - -1. 固定当前 CI 失败样本;记录 watcher 关闭事件、WinCode 所有的相关子进程及测试清理顺序。Node 20/24 分别单独和并发运行工作区切换测试。不得先把 Node 20 job 删掉。 -2. 修复 `useCli=false` 的 initialize、health、pack 三条入口,先判断配置再使用旧健康缓存;禁用状态直接使用内置路径。复查它是否参与临时目录占用,不预设 EBUSY 一定来自 watcher。 -3. 如果缺少关闭完成等待,修补 owner 的等待路径;确认关闭后的短暂 Windows 占用才使用原生 `fs.rm` 有限重试,超限仍失败并保留诊断,不能吞异常。Node 已提供 [FSWatcher close](https://nodejs.org/docs/latest-v24.x/api/fs.html#event-close-1) 与 [rm 重试参数](https://nodejs.org/docs/latest-v24.x/api/fs.html#fspromisesrmpath-options)。 -4. Serena 本地 scanner 返回结果及停止原因;全局引用上限 200 必须跨目录生效。候选首轮建议限制为:单文件 256 KiB、总读取 8 MiB、最多 5000 个遍历项、符号最多 500 条,截止时间沿用现有 fileScanMs。先固定内部常量和测试,不新增一组公开调参工具。 -5. `relativePath` 在进入扫描前限定读取;逐目录/文件/行检查停止条件。到限、超时、不可读、编码不支持均不能报告完整。相应缓存只保存含真实完成状态的结果,更新受影响缓存键或清理兼容规则。 -6. Serena 响应先区分协议错误与有效 JSON;兼容旧纯文本错误时,仅对非 JSON 错误文本识别固定模式。合法源码中的中英文错误文字不改变项目激活状态。 - -**验收门槛:**202 条反例回到不超过 200 且明确不完整;限定单文件时其他源码读取数为 0;禁用 CLI 的三条入口启动命令数为 0;真错误仍降级、合法 JSON 保留;取消/大文件/不可读与多目录样本覆盖。关闭专项修复后每个支持 Node 版本完成 10 次顺序、10 次并发工作区切换/停止/清理,0 失败、0 取消、无 WinCode 遗留进程;这是有限稳定性证据,不宣称永不出现文件锁。 - -最后运行支持矩阵完整 CI 和生产 stdio;保留首次失败与修复后的结果。CodeQL 单独列示。 - -### WP2:把公开契约落实到执行 - -**修改范围:**Gateway/Protocol、按用例分组的工具定义、ToolRouter 用例入口及直接涉及的查询类型;不用全仓重命名制造大 diff。 - -- 统一“解析工具名/别名 → schema 校验 → 跨字段校验 → 请求准入 → 用例执行 → 输出/错误序列化 → 释放准入”的顺序。非法参数不得触发扫描、进程探测或工作区变更。 -- 保留当前工具名和别名、compact/legacy、图片独立 block、预算与现有有效输入。对象/数组/数字不得以 `String()` 强制变成搜索词。 -- 让 Gateway 调用 ToolRouter 的明确用例方法;Serena 的业务类型移到不依赖具体 Adapter 的小型契约模块,原导出可暂时兼容。CompositeTools 只依赖实际使用的查询接口。 -- 外部 JSON 入口用 unknown,校验后进入明确类型;逐步替代边界上的 any。避免一轮开启全仓新的 TS 选项并顺手改掉所有历史告警。 -- 为未知字段、空字符串、错误类型、范围互斥、缺失参数建立行为表。默认建议关闭未知字段;该兼容变化见第 7 节,不能静默实施。 -- 增加少量依赖边界测试,复用已安装 TypeScript:Gateway 不直接导入/访问 Adapter,业务契约不导入 Gateway/具体上游;只检查明确规则,不引入完整架构扫描服务。 - -**验收门槛:**每个公开工具及别名均有实际 MCP 调用;schema 与 handler 输入行为一致;F07 反例返回明确输入错误且底层调用数为 0;列表/hello/hash/执行定义保持同源;合法历史调用的结果、预算、错误和图片行为无意外变化。一个新工具只增加一个权威定义和必要实现,不再修改多个相互独立的名单。 - -### WP3:关闭和取消可观察、可验证 - -**修改范围:**ResourceManager、ToolRouter、WorkspaceWatch、Context、Adapter 的请求参数/关闭路径及相关测试。保持现有锁、排空和所有权机制。 - -- 引入最小内部操作上下文(signal、截止时间),覆盖代码扫描和上游调用;UI 已有的取消能力保留并复测。预算由具体操作持有,不借此增加万能 Context 服务。 -- 关闭结果保留资源 owner、kind、最终状态和有限错误摘要;幂等已关闭不报故障,真正失败可诊断。单个清理失败不跳过其他资源,也不伪造整体成功。 -- 核对子进程 `exit/close`、stdio 关闭、孙进程回收的责任边界;仅跟踪自有进程。测试应核对实际 PID 退出,不能只看 activeProcessCount=0。 -- 区分被动身份/已知状态快照和主动健康探测。hello 查询身份不应隐式触发无关 CLI/上游启动;保留旧主动探测需求的明确入口或选项,具体兼容契约先固定再改。 -- 对初始化失败、运行中取消、排队时取消、切换时取消、关闭失败、重复关闭建立状态转换表。错误只记录定位需要的摘要,不默认写入源代码、输入框内容或凭据。 - -**验收门槛:**上述状态转换逐项通过;请求取消后底层工作在既定截止时间/清理宽限内结束,随后请求仍可成功;工作区切换不返回旧工作区证据;任一关闭失败可见且不阻断其他清理;被动身份查询外部进程启动数为 0。无需为此引入遥测服务。 - -### WP4:建立可复现的交付和维护规则 - -**修改范围:**构建/验证脚本、CI、项目约定、支持文档、原生 Host 的身份字段及必要 DTO 边界。现有 Host 已有 BoundedUiSearch、UiPropertyEvidence、CaptureQuality 等拆分,不重复建立另一套。 - -1. **固定构建输入。**保留 npm lock;为 Host 使用 NuGet lock 与锁定恢复,给 .NET SDK 写明确的版本/roll-forward 政策;补 `.gitattributes` 和 `.editorconfig`,规定文本行尾,避免相同逻辑因 checkout 换行策略改变 sourceHash。更新锁文件只能出现在明确的依赖维护 PR。[NuGet 官方机制](https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#locking-dependencies) -2. **统一交付清单。**继续保留 Gateway manifest,增加一个交付级清单关联 Git 提交、Node/.NET 构建环境、Gateway、Host 二进制及必要 sidecar、受管 Skill 哈希。不要用时间戳或绝对安装路径参与内容身份;声明哈希证明本地一致性,不冒充签名真实性。 -3. **Host 身份可信。**健康结果不再写死 `1.0.0`;用真实 Host 版本/构建信息核对。发现旧 Host/缺文件时明确不一致,不自动改用 Debug 产物或临时编译以掩盖发布缺失。开发模式与交付模式的可用路径需明确区分。 -4. **形成一个本地验收入口。**拟新增 `check`:类型检查 → Gateway 构建 → Host 与两个控制台夹具预构建 → 非交互回归 → 生产 stdio/契约检查;拟新增 `check:desktop`:隔离 WPF 预构建 → UI/协议 → UI 源码修复闭环。真实上游另设明确 opt-in 入口。这些是建议命令,当前尚不存在。`test:all` 要么包含承诺的套件,要么更名并写清范围。维护一个小型套件清单,检查新增测试未被意外遗漏。 -5. **CI 保留可复查证据。**失败时仍上传限额测试报告、命令/环境、build/schema hash 和资源摘要;公开 runner 只使用仓内合成夹具,禁止上传 TavernDesk 正文、个人配置或截图。交互桌面验收不伪装成 hosted runner 已执行。 -6. **合并条件生效。**D3 确认且 WP1 恢复通过后,先启用现有 main 必需状态检查、禁止直接推送和 force push;WP4 再随新增检查更新规则,required checks 与矩阵实际名称一致。独立审查必须有记录;单维护者仓库不要求作者完成自己无法提交的 GitHub approve,可使用独立审查报告加无未解决严重问题作为人工门槛。[GitHub 分支保护](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches) -7. **维护文档保持一致。**增加精简 CONTRIBUTING,包含构建/测试入口、PR 规则和依赖方向;修正 SECURITY 的支持版本及无法保证的响应承诺。清理 IAdapter、ExtensionManager 中“FlaUI 未实现”等过期表述,冻结无实际用户的插件入口;是否移除要检查引用和公共兼容性。不批量改写已有历史日志。 - -**验收门槛:**干净 checkout 按文档成功构建和检查,不借用已有 dist/bin;两次构建的内容身份稳定,替换旧 Host/手册后能检测不一致;交付可在非仓库工作目录启动并完成 stdio/Host 握手;版本支持表、README、package engines、CI 矩阵一致;真实 required checks 生效后才声称“合并受保护”。旧版本可通过保留完整产物和配置说明回退,不使用不可逆就地覆盖作为默认升级方式。 - -### WP5:用真实集成决定是否进入下一轮功能开发 - -**修改范围:**明确 opt-in 的验收脚本、合成/专用夹具、汇总报告与必要缺陷修复;不借集成测试自动安装上游或读取个人数据。 - -- **Serena:**对实际安装版本的 C# 项目运行“同名/重载 → 完整身份 → 引用 → 源码正文”,覆盖合法空结果、项目未激活、上游中断、降级扫描,记录命令版本和协议信息。mock 身份测试保留,但不代替此项。 -- **UI:**复用既有隔离 WPF 源码修复闭环,以及固定 TavernDesk 测试目录;检查 PID/HWND、状态、XAML/C# 候选、源码哈希和修复后结果。截图质量提示只作为提示,不以 API 成功或像素有变化证明画面可用。 -- **产品价值:**沿用现有小样本记录方法,增加 4–6 个“未知位置或 UI→源码”的任务。记录定位是否正确、关键证据缺口、调用数、UTF-16 字符、可测耗时和跨调用重复源码行;已知文件读取继续允许原生工具。已有四项对照显示 MCP 起步调用更多,不能只挑有利样本宣传普遍提速。 - -**验收门槛:**发布说明有“能力 × 环境 × 真实/受控 × 结果”的矩阵;已通过、失败、跳过、未验证分开。真实 Serena 若因安装/激活条件未满足,工程修复可以独立交付,但不得宣称真实语义集成已通过,WP5 保持部分完成。只有新证据证明当前能力确实拿不到关键内容时,才重开 R7–R9。 - -## 5. 每个 PR 的完成定义 - -必须同时满足: - -- 问题与改动可追溯:关联本书 F 编号/工作包,给出一个具体失败或能力缺口,不以“优化架构”作为唯一理由。 -- 写明有效输入、错误输入、降级、取消、关闭和兼容影响中本次涉及的项;修复类先保留失败反例,结构调整先固定现有行为。 -- 改动只覆盖该工作包;新抽象必须有现有调用方和明确职责,无法说明的先不加入。 -- 本地定向验证通过,受影响完整套件与最终提交的 required CI/CodeQL 通过;任何 skip 写明原因,不以重跑直到绿代替修复。 -- 独立审查检查至少一个“测试通过但结论仍可能失真”的场景;作者自审不冒称独立审查。严重问题归零后合并。 -- README/Skill/支持策略中受影响部分同步;工作日志记录命令、环境、版本/build/schema、失败过程、结论边界和 PR。 -- 使用普通 revert 或保留完整旧产物可回退。接口调整提供兼容映射/迁移说明;不通过 force push 改写已经发布的历史。 - -若修改量超出单次可靠审查范围,按职责拆 PR,保留相同里程碑退出条件,不为压缩 PR 数合入未验证的半成品。 - -## 6. 成功判据与停止条件 - -| 维度 | 本轮结束时应达到 | -| --- | --- | -| 接口一致性 | 所有公开工具和别名均实际验证;错误类型、未知字段政策与公布 schema 一致 | -| 降级可信度 | 全局预算有效,所有提前终止有原因;没有“扫描没完成却声明完整”的已知样本 | -| 生命周期 | 关键取消/关闭场景有完成证据、错误可见、自有进程无残留;不触碰目标应用进程 | -| 发布可复现 | 干净环境可构建验证,Gateway/Host/Skill 身份可对应;替换错误产物能被发现 | -| 工程门槛 | required CI 生效,失败报告可获取,独立审查与版本兼容政策可执行 | -| 使用价值 | 真实集成与任务证据表支持能力声明;不把 mock、字符估算或局部样本扩大为通用结论 | - -达到这些条件后结束治理轮次,不继续为了代码外观拆文件。若需要重写资源管理器、引入新解析器/服务、扩大支持平台或改变产品边界,停止该分支并提交新决策,不纳入本书的“普通细节”。 - -## 7. 需用户决定的事项 - -本书给出推荐,**不把写入计划视为已经获准改变兼容性、依赖或外部配置**。 - -| 决策 | 推荐与可选路线 | 未确认时如何处理 | -| --- | --- | --- | -| D1 / Node 支持政策 | 推荐 Node 24 为主要运行环境、22 为兼容环境;20 作为现有兼容线先保留定位和修复,之后明确结束支持或限期维护。Node 官方目前将 20 标为 EOL,22/24 为 LTS;SDK 最低版本不能替代产品支持政策。[官方状态](https://nodejs.org/en/about/previous-releases) | 保持已接受的 `>=20` 和 20/24 检查,不通过删除失败 job 掩盖缺陷;新增矩阵及最终 engines 变更另行确认 | -| D2 / 输入严格性 | 推荐 WP2 统一拒绝未知字段/错误类型,保留合法旧输入和工具别名;若有依赖字符串数字或额外字段的真实调用方,先给有期限的兼容规则 | 本轮仅计划;执行前盘点真实调用形态,锁定行为表,不静默改变公共接口 | -| D3 / 合并保护 | 推荐 main 强制通过支持矩阵和 CodeQL,禁止直接推送/force push;独立审查结果作为合并依据 | 可编写仓内 CI 和规则说明;未经确认不改 GitHub rules/权限,不声称已受保护 | -| D4 / 真实上游环境 | 推荐复用实际已安装 Serena 和专用 C# 夹具;若缺运行时、包或语言服务,先报告所需资源/版本/成本 | 不自动下载模型、上游二进制或改全局配置;该验收项标未验证 | -| D5 / 静态风格工具 | 当前先用既有 TS strict、编译器、editorconfig 和局部约定。若后续需要 ESLint 等新依赖,只采用少量能发现真实问题的规则 | 不把安装新 lint/格式化依赖作为前四包的必需前置,不进行全仓格式化 | - -## 8. 执行起点 - -用户确认总体方案后,先从 **WP1 / 0.11.3** 开始:保留 CI 失败证据,确认相关资源关闭,再修复四类已证实问题;不要先做文件拆分或扩大功能。WP2 之前固定 D2 行为表;支持矩阵变更和 GitHub 保护分别在 D1、D3 明确后落实。 - -本轮方案参考了引用对话的最新分析,但将其“集中补丁”进一步扩展为有验收条件的工程治理:**先恢复可信行为,再统一契约与生命周期,最后把它们固化为可重复的交付规则。** - -## 9. 执行记录 - -- 2026-09-08:总体实施已授权,按每个版本复测、Debug、独立审查、PR、核对检查再合并推进。WP1 在 `codex/wp1-stability` 实施;不提前标记后续工作包完成。 -- D1:用户明确同意 Node 升级。WP1 先保留 Node 20/24 故障复测,WP4 同步 Node 24 主支持、22 兼容及最低版本政策。 -- D2:用户明确选择保持容忍模式。WP2 校验已声明字段,容忍额外字段;Skill 手册必须写清规范字段、类型、必填/可选、互斥与示例,未声明字段不保证生效。该决定取代第 7 节的严格未知字段推荐。 -- D3:GitHub 分支保护仍待确认,不将 Node 升级或字段政策决定扩大解释为修改 GitHub 设置的授权。 -- WP1 已完成:0.11.3 / [PR #22](https://github.com/linnnn89/WinCode/pull/22) 于 2026-09-08 合并,main=`31b7dd1`。最终 Node 20/24 CI 与 CodeQL 通过,各版回归 267 pass、1 skip,10 顺序+10 并发生命周期通过。失败反例、独立审查及短路径测试修正见 [工作日志](docs/codex_worklog.md)。 -- WP2 正在实施:0.12.0,按用户 D2 决定保留额外字段容忍、校验已声明字段,并在现有 Skill 文件明确规范字段,不新增验证依赖。 -- 新发现 F12:GitHub [code scanning #1](https://github.com/linnnn89/WinCode/security/code-scanning/1) 在 `31b7dd1` 仍为 open/medium,Repomix 启用路径经 cmd 处理环境路径。只读方案为 Node 直启已安装 JS 入口、移除 shell 链;涉及 npx 缓存/PATH 包装脚本兼容变化,已单独请求决定,未擅自实施或关闭告警。 -- GitHub 经验落实:参考 [Node watcher 实现](https://github.com/nodejs/node/blob/main/lib/internal/fs/watchers.js) 与 [VS Code 生命周期管理](https://github.com/microsoft/vscode/blob/main/src/vs/base/common/lifecycle.ts) 的 owner、幂等及失败语义;复用现有 ResourceManager,未引入新的管理框架。 -- 2026-09-08 更新:WP2 / 0.12.0 已按精确 head CI 合并 PR #23(main=39d2b20)。WP3 / 0.12.1 实施中,用户已确认 hello 被动、diagnose 主动;后续默认由主代理推进,独立审核与自审分别记载。 -- 2026-09-08 20:16:48(北京时间):WP3 / 0.12.1 的精确 head CI 通过并合并 [PR #24](https://github.com/linnnn89/WinCode/pull/24),main=227463e。WP4 / 0.12.2 正在执行:已实现 Node 24/22、SDK/NuGet 锁定、统一 check 和桌面入口、交付清单、真实 Host 身份与维护文档;首轮核心 300 pass/1 skip、桌面 35/35。最终干净检出与 CI 尚待完成;D3/F12 继续保留未决,不将自审写成独立审查。 -- WP4 干净检出经一次目录名假设修正后两次完整 check 通过,内容身份稳定;非仓库 cwd 的 stdio 与原生 Host health 通过。D3 未决,因此仅建立仓内检查和精确 head 人工核对,不声明 GitHub 已强制保护。详情与失败证据见工作日志。 -- 2026-09-08 20:44:51(北京时间):WP4 / 0.12.2 精确 head 的 Node 22/24 与 CodeQL 全通过,合并 [PR #25](https://github.com/linnnn89/WinCode/pull/25),main=ba94c00。D3 仍未决,工程交付完成不等于分支保护已生效。 -- WP5 / 0.12.3:已完成新 stdio 精准范围、固定 TavernDesk 六导航→源码候选、真实 WPF 修复闭环和实际截图核对;产品任务 30 次调用/67103 UTF-16 字符,127 显示源码行中 42 行重复,不宣称普遍提速。实际 Codex hello 仍为 0.11.2,安装 Skill 已备份同步。真实 Serena 命令缺失、用户新导入角色卡尚待定位,按本计划保持部分完成;详见工作日志验收矩阵。F12/D3 未决状态不变。 -- WP5 新卡补充:用户指明书架角色后,入库、原始 JSON 字段保持、头像文件与书架截图已核对;在新 0.12.3 Gateway/Host 中,同名两文本节点正确返回完整但 ambiguous,不猜测唯一项。含真实卡的六导航取证再度 6/6;详情动作/聊天、真实 Serena、当前 Codex 重连仍未验收。不会把 Computer Use 误归属问题记为 WinCode 故障。 -- 2026-09-08 21:43(北京时间)补充:用户同意尝试四项检查后,D3 main 保护已启用并回读,F12 经 PR #27 合并后 CodeQL alert #1 自动 fixed。用户另行批准隔离安装 Serena(1 GB / 15 分钟上限),真实 1.7.0/Roslyn 链暴露并定位 FastMCP result 包装兼容缺陷;0.12.5 修复及七项真实验收已进入最终回归。正文证据为直接上游 oracle,WinCode 符号/引用为真实 adapter;父 Codex 重连仍未完成,详见工作日志。 +每包验收失败即停在该包定位原因,不叠加下一包掩盖失败。新依赖、运行环境、重要公共接口或恢复政策超出既有决定时先确认。本计划不预设版本号或工期,避免把尚未复现的风险包装成已确定修复规模。 diff --git "a/WinCode-\346\236\266\346\236\204\344\270\216\346\225\260\346\215\256\346\265\201\350\257\264\346\230\216.md" "b/WinCode-\346\236\266\346\236\204\344\270\216\346\225\260\346\215\256\346\265\201\350\257\264\346\230\216.md" new file mode 100644 index 0000000..00ead5b --- /dev/null +++ "b/WinCode-\346\236\266\346\236\204\344\270\216\346\225\260\346\215\256\346\265\201\350\257\264\346\230\216.md" @@ -0,0 +1,245 @@ +# WinCode 架构、数据流与检查关口 + +**基线:0.12.5,main `10496e0`;核对日期:2026-09-08(北京时间)。** + +本说明描述当前源码中已实现的结构。GitHub 分支保护已在本次只读核查中确认;历史实测结果见[工作记录](docs/codex_worklog.md)。源码版本、磁盘构建和客户端当前连接是三个不同对象,不能互相替代。 + +## 1. 整体定位与结构 + +WinCode 是一个运行在本机的 **MCP 工具网关**:接收编码 Agent 的结构化请求,组织代码或桌面证据,再把正文与证据边界一起返回。Agent 的模型推理在客户端侧;WinCode 自身没有模型推理服务或向量数据库。 + +主体采用**分层单体 + 外部工具适配器 + 进程外桌面取证**。每个 Gateway 进程只有一个活动工作区;外部上游与 UI Helper 各有独立生命周期。 + +```mermaid +flowchart TB + Client["Codex / 其他 MCP 客户端\n模型推理、请求选择、用户授权"] + subgraph Node["WinCode Node 进程"] + Gate["Gateway\nMCP 接入 · 工具契约 · 参数校验 · 响应封装"] + Router["ToolRouter\n组件装配 · 用例入口 · 工作区切换 · 生命周期"] + Use["用例与证据处理\nContext / Architecture / Impact / Refactor / UiReview"] + State["横向状态与资源\nWorkspace · Session · Cache · Watch · ResourceManager"] + Adapters["适配器\nSerenaAdapter · RepomixAdapter · FlaUiAdapter"] + Gate --> Router + Router --> Use + Router --> State + Use --> Adapters + Router --> Adapters + end + Client <-->|"MCP / stdio"| Gate + Adapters <-->|"MCP / stdio"| Serena["Serena 进程\n语言服务器:C# 使用 Roslyn"] + Adapters <-->|"Node 直启 JS / 输出文件"| Repomix["已安装的 Repomix CLI\n缺失时使用内置打包器"] + Adapters <-->|"stdin 请求 / stdout JSON"| Host[".NET UIA Host\nFlaUI · Win32 · 截图 · 审计"] + Host -->|"只读取证"| App["目标 Windows 应用\n独立 PID / HWND"] + State <--> Disk["本地文件系统\n源码 · 项目文件 · 缓存 · trash"] + Use -->|"有界读取"| Disk + Serena --> Disk + Repomix --> Disk +``` + +图中箭头表示主要调用或数据联系,不表示每条请求都经过全部组件。原生 Host 的进程隔离用于故障与生命周期控制,**不等于操作系统安全沙盒**。 + +| 层 / 模块 | 负责什么 | 设计边界与源码入口 | +|---|---|---| +| 启动层 | 解析 workspace/development 参数,创建 Router 和 MCP Server,处理退出 | [index.ts](src/index.ts);当前入口以默认配置和 CLI 参数启动,不是通用配置中心 | +| Gateway | 列举工具、校验输入、执行工具、封装结果 | [McpServer](src/Gateway/McpServer.ts)、[ToolRegistry](src/Gateway/ToolRegistry.ts);不直接调用适配器字段 | +| ToolRouter | 创建并组合组件,提供用例入口,协调请求与工作区生命周期 | [ToolRouter](src/Core/ToolRouter.ts);这是装配与协调中心,不只是名称路由表 | +| 核心能力契约 | 定义符号、引用、打包、UI、操作取消等数据类型 | [CodeQueries](src/Core/CodeQueries.ts)、[ContextPacking](src/Core/ContextPacking.ts)、[UiContracts](src/Core/UiContracts.ts)、[OperationContext](src/Core/OperationContext.ts) | +| 用例层 | 项目结构分析、上下文组织、影响评估、重构建议、UI→源码候选 | [Context](src/Core/Context.ts)、[CompositeTools](src/CompositeTools);消费窄接口,保留来源与不完整状态 | +| 适配器层 | 上游协议、响应解析、超时、失败降级及子进程管理 | [Adapters](src/Adapters);Serena 的语义结果与本地文本结果分开标识 | +| 原生 Host | 按 PID/HWND 取证,执行有界 UIA 搜索及截图 | [Program.cs](tools/WinCode.UIA.Host/Program.cs)、[BoundedUiSearch](tools/WinCode.UIA.Host/BoundedUiSearch.cs)、[UiAudit](tools/WinCode.UIA.Host/UiAudit.cs) | +| 构建交付层 | 锁定构建、回归、stdio 验证、产物身份、Skill 一致性 | [check.mjs](scripts/check.mjs)、[delivery-manifest](scripts/delivery-manifest.mjs)、[sync-skill](scripts/sync-skill.mjs) | + +`ExtensionManager` 目前保留兼容接口,没有内置注册项,不承担实际插件生态或工具发现职责。Gateway 当前列出 15 个工具名称,其中包含影响分析别名;工具名称数量不等于独立业务能力数量。 + +## 2. 一次请求怎样通过系统 + +```mermaid +sequenceDiagram + participant A as MCP 客户端 + participant G as Gateway / Registry + participant R as ToolRouter + participant U as 用例 / 适配器 + participant E as 文件或外部进程 + A->>G: tools/call:名称 + JSON 参数 + G->>G: 检查退出/取消、工具名称、Schema + G->>G: 剔除未知字段,检查已知字段组合 + alt 参数无效 + G-->>A: 错误;业务能力不执行 + else 普通请求 + G->>R: acquireRequestSlot(signal) + R->>R: 等待工作区切换结束,增加在途计数 + G->>U: 经 Router 执行对应能力 + U->>E: 有界读取 / 上游 RPC / Helper 请求 + E-->>U: 数据、错误或不完整结果 + U-->>G: 结果 + 来源 + 覆盖/降级状态 + G->>G: 按该工具的响应规则封装、裁剪 + G-->>A: MCP 文本 / 可选图片 + G->>R: finally 释放在途计数 + else workspace_open + G->>R: 专用切换流程,避免等待自身在途计数 + R-->>G: 新工作区摘要或切换失败 + G-->>A: 有界摘要 + end +``` + +**输入契约只有一个注册来源。** WorkspaceTools、CodeTools、UiTools 将 Schema、额外校验和执行函数组织在同一工具定义中;ToolRegistry 同时生成工具列表和分发索引,并计算 schemaHash。 + +**容忍未知字段,严格校验已知字段。** 未声明字段可出现在协议请求中,但会在递归整理参数时被剔除,不能影响业务或原生请求;声明字段不做字符串→数字等隐式类型转换。例如,拼错 `lineRanges` 不会自动启用范围检索。 + +**准入不是全局限流器。** 在途计数主要用于保护工作区切换和关闭;当前没有一个统一的“全部请求最多并发 N 个”策略。UI 请求及 UI 健康探测另有适配器互斥锁。 + +## 3. 代码证据的数据流 + +```mermaid +flowchart LR + Input["任务 + 已知位置"] --> Route{"已有何种定位信息?"} + Route -->|"lineRanges"| Lines["按指定文件/行范围读取"] + Route -->|"scopeFiles + symbol"| Local["文件内声明匹配\n局部窗口,语义覆盖不完整"] + Route -->|"scopeFiles"| Files["指定文件预览\n或有预算的全文"] + Route -->|"尚无明确范围"| Discover["任务关键词 / 候选 / focusAreas\nSerena 查询或文本降级"] + Discover --> Select["候选排序与去重\n选取有限文件"] + Lines --> Evidence["Evidence\n文件 · 实际行范围 · 正文 · 定位方式"] + Local --> Evidence + Files --> Evidence + Select --> Evidence + Evidence --> Pack["需要时补充打包\n显式候选闭集使用内置打包"] + Pack --> Budget["ContextResponse 最终序列化\n正文、元数据、转义共同计费"] + Budget --> Result["最终可见证据\n覆盖范围 · 缺失原因 · 后续请求"] +``` + +### 3.1 三种数据不要混用 + +| 数据 | 生产者 → 使用者 | 必须随数据保留的信息 | +|---|---|---| +| 符号 / 引用 | SerenaAdapter → Context、Impact、Refactor | `source`、`namePath`、文件、行、`queryComplete`、歧义、截断;引用行的 `lineKind` | +| 源码正文 | 文件读取 / 打包 → ContextResponse → Agent | 实际起止行、末行是否完整、`locationKind`、省略原因与范围覆盖 | +| 项目结构 | Workspace / DotNetGraph → ArchitectureAnalyzer | 从 `.sln`、`.csproj` 等文件提取的声明关系;不代表 MSBuild 动态求值后的实际编译图 | + +`prepare_context.candidateFiles` 是优先候选,不承诺排除其他发现路径;`scopeFiles` 与 `lineRanges` 才明确限定相应读取范围。RepomixAdapter **内部**收到显式 `candidateFiles` 时则视为闭集,避免转入全仓 CLI 打包。这两个层次的同名参数不能混为一谈。 + +### 3.2 语义链与降级链 + +SerenaAdapter 懒连接真实上游,先握手、获取工具列表,再查询。状态分为命令已发现、握手成功、项目激活、语义查询可用;前一层成功不自动推导后一层成功。 + +真实符号结果保留完整 `namePath` 和重载标识。简名对应多个身份时返回 ambiguous,引用查询不擅自选择第一项;指定身份查询仍要核对完成状态。上游失败时可使用有文件数、字节数和时间预算的本地正则扫描,结果明确为文本降级。 + +0.12.5 处理了真实 Serena/FastMCP 的 `structuredContent.result` 字符串包装;合法空数组和零引用保留语义来源,错误或不支持的结构不会被当作成功。ImpactAnalyzer 对身份不唯一或查询不完整的情况保留 `UNKNOWN`;零引用不构成“可以安全删除”的证明。 + +### 3.3 输出预算位于最后一公里 + +`maxTokens` 当前按 UTF-16 字符数 / 4 估算,最终 MCP 文本块的 JSON 转义、元数据及 legacy 附加文本共同占预算。它不是模型 tokenizer 的精确结果。 + +ContextResponse 在最终裁剪后重新计算范围覆盖,区分读取阶段不足和响应预算不足,并给出缺失区间或后续请求。符号窗口没有解析方法结束边界,`symbolCoverage=unknown` 不能被显示的几行正文替代。 + +## 4. 桌面取证与源码候选的数据流 + +```mermaid +flowchart TB + Req["PID / HWND / query / capture"] --> Validate["Gateway + UiContracts 参数校验"] + Validate --> Mutex["FlaUiAdapter 串行锁\n外部截止时间 / 取消"] + Mutex --> Native["启动自有 Release Host\n一份请求,收集 JSON 响应"] + Native --> Audit["审计准入 + 目标窗口归属复核"] + Audit --> Search["有界 UIA 搜索\n节点数 / 深度 / 时间"] + Search --> Unique{"完整搜索且唯一命中?"} + Unique -->|"是"| Snapshot["选中子树 / 状态 / 可选截图"] + Unique -->|"否"| Partial["歧义、未找到或不完整\n返回候选,不猜测子树"] + Snapshot --> Return["响应预算、审计结束、Host 清理\n协议/能力版本核对"] + Partial --> Return + Return --> UiReview["UiReview 复用同一次快照"] + UiReview --> Xaml["指定 XAML 候选\n属性字面量与节点对应"] + Xaml --> CSharp["指定 C# 候选\n赋值、处理器、方法声明位置"] + CSharp --> Out["runtime evidence + source candidates\n行号 / 哈希 / nextRequest"] +``` + +- UIA 属性和截图来自目标应用的实际窗口;应用是否提供 AutomationId/Name 决定可检索程度。缺失可访问性信息不等于网关查询代码故障。 +- 有查询条件时,只有 `SearchComplete` 且恰好一个命中才展开选中子树;找到一个节点但搜索未完成,仍不能声称唯一。 +- `backgroundOnly` 要求 PID/HWND,走后台捕获政策;图像质量为 `unknown` 或低变化提示时,不声称截图一定可读。 +- UI→XAML→C# 是候选证据链。动态绑定、模板、资源字典没有被完整求值;保持 `runtimeSourceVerified=false`。源码候选读取失败时保留已取得的 UI 快照。 +- Host 使用 UIA/Win32 读取目标窗口;取消与超时清理自有 Helper,不终止目标应用。该设计不提供点击、输入或聊天生成能力。 +- 审计保存开始/结束等简要记录;达到阈值时提醒或拒绝新 UI 访问。日志是本地可写文件,不提供防篡改保证。 + +## 5. 状态、存储与生命周期 + +### 5.1 数据在哪里 + +| 数据位置 | 保存内容 | 生命周期 / 边界 | +|---|---|---| +| Node 进程内 | 当前 session、请求计数、适配器连接状态、内存缓存、资源记录 | 每 Gateway 一个活动工作区;退出后不保留这些内存状态 | +| 启动配置的 `cacheDir`,默认 `.cache/wincode` | 缓存 JSON、打包临时文件、overflow 正文 | 按工作区 namespace 隔离;切换项目保留缓存目录,避免向每个项目散写缓存 | +| 工作区源码与项目文件 | 输入证据 | 代码分析通常读取;不会因为生成重构计划就自动修改源码 | +| 配置的 `trashDir` | 被移动的文件和 `.meta.json` 元数据 | `safe_move_to_trash` 是实际写操作;路径/真实路径检查后移动,非永久删除 | +| `%LOCALAPPDATA%/WinCode/logs/ui-audit` | UI 取证审计 | 有容量准入;不自动删除审计来恢复访问 | +| `dist/`、Host Release 发布目录 | Gateway 与原生交付产物 | 构建/交付脚本管理;客户端进程不会因文件更新自动重载 | +| `test-tmp/` | 检查报告、隔离夹具、本轮获准安装的真实上游 | 开发验收数据,不提交到 Git;真实上游安装不等于默认连接已配置 | +| 已安装 Skill 目录 | Agent 使用手册 | 独立于源码和运行进程;同步前备份,之后核对内容 | + +缓存同时使用工作区 namespace、fingerprint 与 TTL。Watcher 使文件变化能失效短期 fingerprint 记忆;内存默认预算 32 MiB,磁盘默认 128 MiB(含 overflow),单项默认 2 MiB。这些是缓存数据预算,**不是整个 Node 进程 RSS 的硬上限**。 + +源码、磁盘状态和多个调用之间不存在数据库式快照事务;Watcher/fingerprint/TTL 也不能保证每次观察均与外部写入同步。需要判断新鲜度时应结合实际文件哈希、结果范围及变更时间。 + +### 5.2 工作区切换 + +`工作区互斥锁 → 暂停普通请求进入 → 等待旧请求结束 → 校验/打开目标 → 更新 namespace/session/fingerprint → 重绑 watcher → 关闭并重建相关上游状态 → 恢复请求准入`。 + +旧请求不能在限定时间内结束时,拒绝切换;等待期间可以取消。开始提交切换后完成必要收尾,当前实现不承诺跨文件系统、适配器与缓存的事务性回滚。 + +### 5.3 取消与退出 + +代码用例把客户端 signal 与操作 deadline 传入扫描/上游路径。当前代码用例总预算由 Serena 连接、调用和文件扫描预算合成(默认 43 秒);具体外部操作还有各自超时。UI 另有 Helper 超时,默认 10 秒。原生调用或单次磁盘 I/O 不一定能立即中断。 + +关闭时拒绝新请求、取消代码操作、等待在途请求,并依次尝试停止 watcher、各适配器、扩展兼容项,刷新缓存写入、关闭 session 和资源管理器。主要关闭路径保留聚合错误,重复 dispose 共享结果;不能仅凭进程计数为零证明所有清理成功。ResourceManager 保存有限的进程内清理记录,真实验收另检查已知自有 PID 是否退出。 + +## 6. 检查关口:阻止什么,依据是什么 + +| 关口 | 位置 | 检查 / 处理 | 不能据此声称什么 | +|---|---|---|---| +| G1 工具契约 | ToolRegistry | 名称、类型、范围、字段组合;未知字段剔除 | 容忍拼写错误不表示对应能力生效 | +| G2 请求与工作区 | Gateway / ToolRouter | 取消/关闭检查;切换互斥与在途排空 | 不是所有请求统一串行,也不是多租户隔离 | +| G3 文件与范围 | Workspace、Context、UI 源码 mapper | 相对/真实路径、工作区边界、候选数量、文件/读取预算 | 路径检查不是 OS 沙盒或完整文件事务 | +| G4 上游启动 | 各 Adapter | 配置禁用、可用性、超时;Repomix Node 直启 JS | 已安装脚本本身的可信性没有因此被证明 | +| G5 语义身份 | SerenaAdapter / ImpactAnalyzer | 完整身份、重载、歧义、协议错误、完成状态 | fallback、零引用或非空结果不等于安全重构 | +| G6 UI 准入 | Host / UiAudit | PID-HWND 归属、后台策略、审计容量、搜索预算 | computer-use 其他链路的窗口归属不是本模块证据 | +| G7 UI 返回 | Host / FlaUiAdapter | 文本/图片/管道预算、协议与 inspectionVersion | 像素有变化不等于画面可用,候选不等于绑定已证实 | +| G8 最终正文 | ContextResponse / UiResponse | 最终序列化预算、截断、省略与范围信息 | 正文覆盖不等于任务推理充分,估算字符不等于精确 token | +| G9 生命周期 | OperationContext / ResourceManager / Router | deadline、取消、自有进程关闭、缓存写入排空 | 单一 dispose 返回或资源计数不是全部外部进程的证据 | +| G10 交付一致性 | 构建清单 / delivery verify | Gateway、完整 Host 发布文件、配置与 Skill 的版本/哈希 | 内容一致性不是数字签名,磁盘新版不等于连接新版 | +| G11 合并 | GitHub 保护与 CI | Node 22/24 + 三项 CodeQL、PR、管理员约束、禁止 force push/删除 | CI 绿色不证明真实桌面/Serena已验收,也不证明所有安全告警关闭 | + +G1–G10 分布在运行时和本地交付工具中;G11 依赖远端仓库配置。人工授权、是否接受重构方案、是否安装真实上游等,仍属于客户端/维护流程的决策,不能把 Skill 的文字说明当成服务器权限系统。 + +## 7. 从源码到客户端实际使用 + +```mermaid +flowchart LR + Source["源码 / 契约 / 依赖锁"] --> Build["锁定构建\nNode 22/24 · 固定 .NET SDK"] + Build --> Check["check\n类型检查 · 核心回归 · 新 stdio"] + Check --> Manifest["交付清单\nGateway + 全部 Host 文件 + Skill"] + Manifest --> PR["PR 精确提交 CI\n必需检查通过"] + PR --> Merge["保护规则下合并"] + Merge --> Disk["主分支构建 / Skill 同步"] + Disk --> Reconnect["客户端重新建立连接"] + Reconnect --> Identity["hello:实例 / buildId / schemaHash\n核对实际请求行为"] + Build -.-> Desktop["独立验收\n桌面 WPF / TavernDesk / 真实 Serena"] +``` + +`hello` 从 0.12.1 起只读已知状态;主动检查使用 `diagnose_project`。未知值明确保留为 unknown/null,历史健康结果可能陈旧。Gateway 初始化仍会初始化适配器,轻量 hello 不表示整个启动过程没有探测成本。 + +当前分支保护强制 Node 22/24 回归和 CodeQL 的 JavaScript/TypeScript、C#、Actions 三项检查,对管理员生效;按单维护者政策要求的 GitHub approval 数量为 0。**因此独立审核仍是额外流程,不是仓库规则已保证的事实。** + +真实 Serena、交互桌面验收分别是 opt-in 命令,没有被普通 CI 自动覆盖。0.12.5 已有真实 Serena/Roslyn 的七项隔离实测;源码正文其中使用了直接上游 oracle,不应推广成 WinCode 已提供完整方法正文接口。 + +## 8. 当前设计的工程成熟度与明确边界 + +已经形成的结构约束包括:统一工具契约、Router 用例入口、Core 能力接口、适配器进程边界、工作区生命周期、证据元数据、最终输出预算以及可复查的交付清单。[架构边界测试](tests/architecture-boundaries.test.ts) 检查 Gateway 不跨过 Router 访问适配器、CompositeTools 不导入 Adapter、Core 不反向依赖 Gateway 等具体规则。 + +维护时仍应认识以下边界: + +1. **ToolRouter 同时承担装配、状态和生命周期协调。** 当前职责集中且可定位;扩展功能应走既有用例与契约,不继续把具体上游访问塞进 Gateway。 +2. **结果协议有工具族差异。** UI 使用 success/errorCode 等字段,代码结果侧重 source/completeness,部分 Gateway 错误仍为文本;目前不能宣称全软件已有单一错误信封。 +3. **检查是分路径落实的。** 范围读取、候选 mapper、目录扫描和 trash 各自设边界;不能把某条路径的检查推广到所有低层文件调用。 +4. **生成计划与执行修改分开。** 重构工具提供建议与检查清单;代码修改、编译、Git 提交与 PR 操作由外部工程协作工具执行。trash 是需要特别识别的实际文件写入口。 +5. **运行时一致性仍需客户端参与。** Gateway 实例身份、原生 Host 身份与交付清单提供核对依据,但系统没有自动替客户端重连旧 MCP 实例的能力。 + +本说明的架构图、数据表与关口表共同描述当前实现;新增功能应说明接入哪条数据流、使用哪个现有契约、在哪个关口拒绝或降级,以及如何留下真实验收证据。 + +下一轮可靠性工作见[待实施计划](WinCode-下一轮工程化迭代计划书.md):工作区切换后续步骤失败的一致性、trash 移动后元数据失败的部分完成语义、有界混合负载验收,以及错误契约渐进整理。前两项来自静态调用链审查,仍需故障注入确认;后两项是验证和一致性改进,不能据此断言当前已有泄漏或必须整体重构。 diff --git "a/WinCode-\350\277\255\344\273\243\350\267\257\347\272\277\345\233\276.md" "b/WinCode-\350\277\255\344\273\243\350\267\257\347\272\277\345\233\276.md" index d477634..6f98a80 100644 --- "a/WinCode-\350\277\255\344\273\243\350\267\257\347\272\277\345\233\276.md" +++ "b/WinCode-\350\277\255\344\273\243\350\267\257\347\272\277\345\233\276.md" @@ -1,271 +1,40 @@ # WinCode 迭代路线图 -更新日期:2026-09-08(北京时间) +更新日期:2026-09-08(北京时间)。当前源码基线:**0.12.5 / main 10496e0**。 -用途:后续开发、审查与验收的工作参考。本文记录建议和决策边界,不表示其中功能已经实施或发布。 +本文件只保留未完成方向与进入条件。已完成的 R1–R6、WP1–WP5 不再作为待办重复执行;版本变更见 [CHANGELOG](CHANGELOG.md),过程与验收边界见 [工作记录](docs/codex_worklog.md)。 -下一轮计划入口:[WinCode 下一轮工程化迭代计划书](WinCode-下一轮工程化迭代计划书.md)(2026-09-08,基线 0.11.2 / main@3be2c49)。本次核查确认 main 的 Windows Node 20 回归仍失败;下一轮优先稳定性、契约、生命周期与交付规范,详细方案尚待确认,历史章节不替代该计划。 +## 当前基线 -## 当前维护状态(2026-09-08) +已落地工作区摘要、运行身份与契约核对、精准范围证据、统一参数校验、取消与资源回收、锁定构建及交付清单。未知字段保持容忍并忽略,规范字段见 [Skill](skills/wincode/SKILL.md);hello 读取已知状态,需要主动探测时使用 diagnose_project。 -R1–R6 已实现并进入 main,当前主任务连接的 R1–R3 验收见第 14 节。0.11.1 已完成修复及本地验证,范围为安装手册一致性、符号片段完整性/有界补读、截图质量提示;发布与验证结果见工作日志。原第 1–11 节保留初始设计及其当时基线,不能作为当前待办或运行版本。R7–R9 继续按真实阻塞进入;8–12 个真实任务与原生工具的成本对照仍是后续评价建议,未以现有脚本基准冒充完成。 +0.12.4 的 Repomix 无 shell 启动修复已合并,GitHub 安全告警 #1 已自动标记 fixed;0.12.5 的 Serena/FastMCP 兼容修复已合并,固定 Serena 1.7.0/Roslyn 的七项隔离验收通过。主分支保护已启用,单维护者策略 approval=0,不能据此宣称独立审核已完成。 -本轮维护补充:当前主连接已核对加载 0.11.1,并完成四项真实源码问题的原生/MCP 起步对照;其中导入页面生命周期仍为部分验收,没有宣称完整开发任务对照已完成。已据 24 行窗口的实际补读成本调整取证手册,新增 Windows PR 自动回归;细节与远端结果见工作日志。下一步扩充样本应优先未知位置或 UI 到源码任务,避免重复证明已知文件读取的同一结论。 +0.12.5 主分支核心回归为 313 通过、1 项可选跳过;这不等于所有真实应用或长时间运行场景均已验证。历史 Yuki/TavernDesk 导航到源码验收已经完成,不再列为未开始;角色聊天等应用业务行为不属于该证据范围。 -首轮全新 Windows CI 暴露等待超时提前退出和短路径目录监听崩溃,纳入 0.11.2 局部修复及专项回归。此范围变化由真实失败驱动,未提前进入 R7–R9;当前连接与后续构建版本的区别继续按实际 hello 记录。 +## 下一轮优先级 -## 1. 初始结论与优先顺序(历史设计) - -下一阶段先解决真实使用中的上下文浪费与版本错配,再修正语义查询正确性,随后扩展 UI 到源码的调查能力。 - -| 顺序 | 迭代 | 目标 | 完成门槛 | -| --- | --- | --- | --- | -| 1 | R1:首次打开工作区减量 | `workspace_open` 默认只返回身份、项目摘要和少量入口,目录按需读取 | 宽目录和发布产物不能撑爆首次响应;摘要仍足以开始任务 | -| 2 | R2:运行实例与能力核对 | 区分源码、构建产物、运行实例、客户端缓存的工具定义 | 能识别旧构建或旧工具参数,给出准确的重连/重建指引 | -| 3 | R3:精准取证闭环验收 | 在实际连接中重验同一 TavernDesk 任务 | 目标方法和实际源码范围正确;覆盖不足、截断和缺失原因可核对 | -| 4 | R4:Serena 查询契约修复 | 完整保留符号身份,消除自动选首项和虚假零结果 | 同名、重载、解析失败及上游降级均不产生错误的确定性结论 | -| 5 | R5:MCP SDK v2 独立迁移 | 在兼容性方案明确后偿还协议依赖技术债 | 网关与 Serena client 同时迁移,既有工具行为和生命周期通过回归 | -| 6 | R6:UI → XAML → C# 调查链 | 将已有运行时证据与源码候选串联 | 能提供控件状态、XAML 声明及相关 C# 候选,同时保留证据边界 | -| 7 | R7:按需 MSBuild 求值 | 解决真实项目的条件配置和引用偏差 | 用明确 Configuration/TFM 重现声明级解析无法回答的问题 | -| 8 | R8:WPF 深层诊断实验 | 验证 Binding/DataContext 等确有必要的新增证据 | 隔离样本证明诊断价值、运行时兼容性和资源释放,再决定集成 | -| 9 | R9:未知位置任务的 Repo Map | 改善不知道文件位置时的候选排序 | 在相同初始信息和预算下提高取证成功率,已知位置请求不增加扫描 | - -R1 → R2 → R3 是用户根据实测明确提出的近期顺序。R4 仍是语义功能继续扩展前的正确性前提:R3 可先验证现有本地范围读取,不能因此宣称 Serena 语义链已经可靠。R5 之后保留原对话最终复核的排序;R7–R9 根据真实需求进入,不按版本号强行排期。 - -建议按独立小改动推进 R1、R2,并用 R3 作为近期交付验收。本文使用 R1–R9 作为稳定工作编号;原对话的 `0.9.1 / 0.10 / 0.11` 只是建议版本,不沿用为发布承诺。 - -## 2. 依据、基线与归因 - -### 2.1 资料与核查范围 - -- 路线来源:[WinCode迭代路线图](chatgpt-conversation://6a9ed4e8-dbf8-83ee-8359-3666dca09d24)。已读取可见的四轮内容,以最后一次自我复核为主要参考,同时保留此前关于解析状态、位置转换和验收的有效建议。对话提到的独立研究报告附件未在返回记录中提供,本文不将其视为已审阅的一手报告。 -- 实测来源:[优化 Agent 使用效率](thread://01a07c3b-7c6a-78d2-8f06-528c2038cafe?hostId=local)。已读取最近工作记录,并结合用户本次补充的故障表与明确优先顺序。 -- 本地基线:`I:\WinCode`,分支 `codex/agent-efficiency-round1`,HEAD `6fba44a7404960257e5c749210892477ad26845c`;`package.json` 和 `WINCODE_VERSION` 均为 `0.9.0`。开始整理时 Git 工作区干净。旧对话引用的 `main@b492491` 不作为本地基线,也不据此声称当前远端最新状态。 -- 本次进行了源码、锁文件、文档和官方上游资料的只读核对,并对当前 WinCode MCP 做了工作区打开、版本读取和一次限定行范围读取。没有重跑 TavernDesk、GUI 验收或代码回归。 - -### 2.2 TavernDesk 实测:分别归因 - -| 现象 | 归因 | 已有证据与状态 | 对路线图的影响 | -| --- | --- | --- | --- | -| 打开项目返回发布 DLL、`.publish-verify/`、`work/` 等大量目录项 | WinCode 默认输出策略 | 历史实测由用户概括为约 5 万 token;本次未取得原始完整响应重新计量,不将其当作精确模型 token 基准。当前源码仍默认返回目录树 | R1,优先解决 | -| 源码已有精准参数,当时已连接工具未暴露这些参数及新版覆盖信息 | WinCode 构建/部署/连接与能力可见性链路 | 当时无法验证新版精准取证,候选请求返回文件头后又补 `rg` 和定点读取;不能单凭现象确定是旧 `dist`、旧进程还是客户端 schema 缓存 | R2 后接 R3,避免凭源码版本反复试新参数 | -| “角色”完整遍历 66 个节点仍未找到 | TavernDesk UI 可访问性 | 六个导航按钮已在该次工作中补齐名称和稳定标识,随后 `NavCharacters` 唯一命中;本文未再次实机验证 | 保留为 R3 的已知样本;不列为待修 WinCode 查询缺陷 | -| computer use 将 `[TEST] TavernDesk` 归属到 AiPPT,两次无法选窗 | computer use 窗口识别链路 | 该链路失败时,WinCode 仍能按明确 PID/HWND 检查和截图 | 单列外部阻碍,不据此重写 FlaUI 或新增点击功能 | -| 每次重新选择语言、导入角色 | 测试环境组织 | 该次工作已固定 `I:\New-tarven\work\TAVERN-TEST`,验证重启保留角色且不重复导入 | 后续日常验收复用专用隔离目录;首次启动测试另用全新目录 | - -“已修复”在本表中指引用工作记录中的完成状态,不代表修改已进入 TavernDesk 发布包,也不代表本次重新验收通过。 - -### 2.3 当前代码与连接补充核查 - -| 核查项 | 当前发现 | 解读 | +| 顺序 | 未完成方向 | 进入与完成标准 | | --- | --- | --- | -| 工作区打开 | `WorkspaceManager.openWorkspace()` 固定调用 `getDirectoryTree(2)`;网关直接序列化整个结果 | 目录树已有深度限制,但没有总节点数或整响应字符预算。大量同级文件仍可造成巨大输出,不能仅靠调小深度修复 | -| 版本信息 | 当前 MCP `wincode_hello_world` 返回 `0.9.0`、工作区和工具名列表 | 已有版本信息,但缺少构建身份与参数级能力核对;不能写成“完全没有版本接口” | -| 精准参数 | 当前会话暴露的 `wincode_prepare_context` schema 已含 `scopeFiles`、`symbol`、`lineRanges`,本次行范围调用也被接受 | 历史旧连接问题不能直接套用于本会话;这仍不足以证明 TavernDesk 全流程已通过 | -| 范围与覆盖 | 本次请求 `SerenaAdapter.ts` 第 483–705 行,实际返回 483–576,`truncated=true`;同时 `queryComplete=true`、`evidenceInsufficient=false` | 返回已标截断,但这两个字段不能代替请求范围覆盖或任务充分性判断;作为 R3 的具体反证样本 | -| 语义身份 | `CodeSymbol` 无完整 `namePath`;`findReferencesDetailed()` 缺路径时选首个候选,映射代码删除重载后缀 | 静态确认有身份丢失及误选路径;本次未连接真实 Serena 复现误查输出 | -| SDK | 声明为 `@modelcontextprotocol/sdk: ^1.6.1`,锁文件实际为 `1.30.0` | 不能将版本范围误读为运行 1.6.1;仍需区分锁文件与运行实例实际依赖 | - -源码定位见 [Workspace.ts](src/Core/Workspace.ts) 的 `openWorkspace/getDirectoryTree`、[McpServer.ts](src/Gateway/McpServer.ts) 的工作区和 hello handler、[Protocol.ts](src/Gateway/Protocol.ts)、[ContextResponse.ts](src/Gateway/ContextResponse.ts) 和 [SerenaAdapter.ts](src/Adapters/SerenaAdapter.ts)。本表记录的是本文基线,后续修改后需更新。 - -## 3. R1:让首次打开成为紧凑摘要 - -**目标:打开工作区后,Agent 能确认项目身份并选择下一步,不必先接收目录清单。** - -建议最小范围: - -1. 默认返回规范化工作区标识、项目类型/语言、主要 solution 或工程摘要、Git 摘要和少量入口路径。树、工程明细和完整统计按需获取。 -2. 对整份响应设预算,包含 JSON 转义、路径、项目数组、忽略说明与错误信息,不能只限制 `fileTree`。建议默认不超过 8,000 个 UTF-16 字符,入口不超过 8 个;这是待实施时确认的初始建议值,不是当前能力或模型 token 硬上限。 -3. 目录读取复用既有扫描代码,支持指定子目录、深度、节点/条目数及响应预算。返回实际扫描范围、截断与省略原因;优先使用一次小范围浏览,不先制造分页状态服务。 -4. 发布产物默认不进入入口预览,但不要把所有 `work/`、未知目录或 DLL 永久排除出用户可请求范围。浏览过滤不得改变符号检索、缓存指纹或源码纳入规则。 -5. 避免为简短摘要先递归建立大树、逐项统计发布文件大小再裁掉输出;采集成本和序列化成本分别检查。首轮不引入索引数据库或后台扫描器。 -6. 明确默认响应变化及兼容方式。需要旧结构的调用可按需获取有界明细;兼容模式不能恢复无上限输出。目录能力放入现有入口还是独立窄工具,在实施前结合调用方确认。 - -主要落点:[Workspace.ts](src/Core/Workspace.ts)、[ToolRouter.ts](src/Core/ToolRouter.ts)、[McpServer.ts](src/Gateway/McpServer.ts)、[Protocol.ts](src/Gateway/Protocol.ts),以及对应测试和使用手册。 - -**验收:**相同输入下保留项目身份与关键入口;浅层宽目录、发布目录、大工程列表和大量省略说明均受同一预算约束;按需目录仍能取到明确指定的合法路径。记录首次输出字符数、耗时和补取调用数,不能以“输出少了但找不到项目”为成功。未完整扫描的统计标为部分或未知。 - -**反证:**`maxDepth=1` 下仍存在数百个 DLL;或者树已移除,但 `metadata.projectList/omittedDirectories` 继续随仓库规模增长。 - -## 4. R2:核对真正运行的实例与工具能力 - -**目标:在使用新参数前,先知道连接到什么构建、客户端实际能调用什么接口。** - -复用现有 hello/diagnose 与 MCP `tools/list`,建议补充三类紧凑信息: - -- 运行版本和构建身份:版本号、构建时嵌入的 revision/build 标识,以及必要的启动标识。构建身份未知时明示未知;不能用被分析仓库的 Git HEAD 冒充 WinCode 构建,也不能用后来更新的磁盘文件冒充已加载版本。 -- 工具契约标识:从实际注册的工具定义计算 schema 标识,按需返回指定工具的支持参数。默认不重复输出所有工具的完整 JSON schema,不新建 Capability Registry。 -- 核对结果:分别记录源码期望能力、运行实例声明、客户端当前暴露的 schema,以及一次实际调用结果。schema 相同不证明实现相同;相同 `0.9.0` 也不证明构建相同。 - -建议排查顺序:检查运行构建 → 检查实际 `tools/list`/客户端参数 → 必要时构建或重连 → 再核对一次 → 做一个小请求。遇到旧 schema,结束对新参数的重复尝试;不要自动下载更新、重启所有客户端或改全局配置。已在实施任务中获得的授权不重复申请。 - -验收脚本可复用已安装的 MCP SDK,在同一 stdio 会话中读取 hello、`tools/list` 并调用一个已知小范围,避免把不同进程的信息拼成一次成功核对。独立脚本只能证明它连接的进程;Codex 等宿主实际暴露的参数和真实调用还需单独核对。`tools/list_changed` 可帮助支持该通知的客户端刷新定义,但不能让旧进程自动载入新代码。 - -主要落点:[Config.ts](src/Core/Config.ts)、[Protocol.ts](src/Gateway/Protocol.ts)、[McpServer.ts](src/Gateway/McpServer.ts)、现有构建流程和 [代码手册](skills/wincode/references/code.md)。构建身份的生成方式应保持轻量,不另建发布平台。 - -**验收:**同版本不同构建能区分;只有源码更新但旧进程仍运行时不误报升级完成;服务端已更新而客户端 schema 仍旧时有明确提示;不支持的参数不得被静默忽略并返回看似成功的文件头。成功判据必须包含真实小调用,不能只有版本字符串或编译成功。 - -## 5. R3:验证精准取证闭环与实际覆盖 - -已有精准能力应先在实际连接上验收,不重新实现一套上下文工具。沿用当前路由:已知行号用 `lineRanges`;已知文件和声明名用 `scopeFiles + symbol`;仅知文件用 `scopeFiles`;不知道文件时才进行发现。 - -### 5.1 返回范围的最小补强 - -保留当前 `source`、`queryComplete`、`truncated`、`fileIssues`、`relatedFiles.bodyStatus` 及 selected/packed/returned 文件数的语义,补充可核对的请求范围与实际返回范围。字段名称在实施前确认,但应表达以下区别: - -| 信息 | 必须表达的含义 | -| --- | --- | -| 请求范围 | 用户希望读取的文件、行区间或声明目标 | -| 返回范围 | 最终序列化并实际显示的源码区间,不能回显请求终点冒充实际终点 | -| 覆盖状态 | 对请求范围的完整、部分、未返回或无法判断;不等于“已经回答研究/开发问题” | -| 缺口原因 | 响应预算、片段上限、文件越界、缺失、不可读、声明歧义、不支持等实际原因 | -| 后续最小操作 | 缩小范围、补未返回区间或先消歧;只有可靠计算得到的范围才建议补取 | - -若请求范围或符号本体在预算裁剪后不完整,应同步更新覆盖信息,不能只在裁剪前计算。重复片段不应被重复计入覆盖。`scopeFiles + symbol` 仍是本地声明模式匹配,不能把范围覆盖完整升级为语义查询完整。 - -### 5.2 同场景验收 - -1. 复用 `I:\New-tarven\work\TAVERN-TEST` 专用隔离环境和已导入的固定测试角色;测试前核对专用标记、数据根和启动回执。仅首次启动场景使用全新环境,避免重复初始化混入工具效率测量。 -2. 先记录 WinCode 运行构建和客户端工具 schema。使用当前 TavernDesk 源码确定本次目标方法与预期范围,不凭记忆硬编码已经变化的行号。 -3. 分别验证已知方法、已知行号、仅知文件、未知文件四种初始信息。已知方法请求应直接命中声明附近,而不是先返回文件头再补 shell 阅读。 -4. 覆盖长方法、声明在文件末尾、超过文件末尾的请求、同名方法、小预算截断、末行只返回部分字符、多文件请求只返回一部分、缺文件、修改后重取和工作区切换。行号落在返回区间内也不证明该行正文完整;正文裁剪必须进入覆盖判断。返回不足本身允许发生,错误地宣称覆盖才是失败。 -5. UI 复查继续使用当前有效 PID/HWND 和 `NavCharacters` 等稳定 selector;不复用前次响应的节点 ID。computer use 无法选窗单列,不使 WinCode 成功取证被误判失败。 -6. 对修复前后使用相同初始信息、相同目标和相同预算。记录成功/失败、首次命中、总调用数、补 `rg`/定点读取次数、文本字符、重复显示行、耗时及初始化耗时。模型 token 如无可靠计量则不报告为精确值。 - -复用 [benchmark-agent-efficiency.ts](scripts/benchmark-agent-efficiency.ts) 与既有测试结构,先做单轮小样本;实际 TavernDesk 验收结果与合成夹具报告分开。已有十类基准采用本地回退且关闭 GUI,不能替代真实连接验证,也不能据此宣称通用 Agent 提速。 - -**完成门槛:**R1 输出有界、R2 连接能力已核对、R3 目标与范围正确,且每个失败能区分 WinCode、应用、computer use 或环境来源。先用这些结果决定下一步,不因仍有重复调用就直接增加跨调用缓存。 - -## 6. R4:修复 Serena 符号身份与解析状态 - -[Serena 上游源码](https://github.com/oraios/serena/blob/main/src/serena/tools/symbol_tools.py) 使用文件位置和 name path 定位符号,并明确支持重载索引。当前 WinCode 存在首项选择和身份压缩路径,值得作为独立正确性修复。 - -最小范围: - -- `CodeSymbol` 保留上游原始 `name_path`,显示名可另行简化;`[0]`、`[1]`、容器路径不得在身份传递中丢失。 -- 已有完整 name path 与文件路径时原样传给引用查询;只有简单名称时,在限定范围内唯一匹配才继续。多候选返回歧义和有界候选列表,零候选与查询失败分别表达。 -- 保留 `symbolName`、`relativePath` 的既有入口,新增可选精确身份参数;检查缓存键和调用方,防止选中的身份在下一层又被还原为短名称。候选发现未完成时,单个可见结果也不能直接认定唯一。 -- 区分合法空响应、缩略结果、不支持的格式和解析失败;按有证据的上游格式处理分组、kind 和行号规则,不把未知格式自动转成语义成功的空数组。 -- 检查 `ImpactAnalyzer` 的身份透传和唯一性判断,不只在 Gateway 增加参数。相同文件并不天然代表唯一符号;不完整或歧义结果继续保留 `UNKNOWN`。 - -主要落点:[SerenaAdapter.ts](src/Adapters/SerenaAdapter.ts)、[ImpactAnalyzer.ts](src/CompositeTools/ImpactAnalyzer.ts)、[Protocol.ts](src/Gateway/Protocol.ts)、[McpServer.ts](src/Gateway/McpServer.ts),必要时调整 [Context.ts](src/Core/Context.ts) 的身份透传。复用现有 mock Serena 与 C# 夹具;不引入通用 Symbol Service。 +| 1 | 工作区切换中途失败的一致性 | 故障注入确定提交边界;失败后每个请求只使用同一个工作区的根、缓存与适配器状态 | +| 2 | trash 移动成功、元数据写入失败的恢复语义 | 可定位已移动文件,结果准确表达部分完成,重试不造成二次误操作 | +| 3 | 有界混合负载与真实上游验证 | 在明确时间和资源预算内测试切换、取消、查询、上游退出;记录进程、资源趋势及跨工作区隔离 | +| 4 | 逐步统一错误与证据输出 | 先统一高频失败的稳定错误码和必要元数据,保留已有客户端兼容性 | -**验收样本:**同文件不同类同名方法、不同文件同名方法、重载、唯一符号、真实零结果、首行/其他行位置、缩略或无效响应,以及 Serena 不可用的本地降级。检查实际发出的 `name_path + relative_path` 和最终返回源码位置。mock 契约通过与真实 Serena/C# 验收分开记录。 +具体工作包、验收与待决策略见 [下一轮工程化迭代计划书](WinCode-下一轮工程化迭代计划书.md)。现有分层见 [架构与数据流说明](WinCode-架构与数据流说明.md)。以上是待实施建议,不是已修复结论。 -## 7. R5:MCP SDK v2 作为独立迁移 +## 尚需补齐的验收 -截至 2026-09-08,官方将 v2 列为稳定版本线,并说明 v1 在 v2 发布后至少继续维护六个月。因此迁移有现实依据,但不把它描述为本次已确认的紧急漏洞,也不从“至少六个月”推定一个精确停更日。[官方仓库](https://github.com/modelcontextprotocol/typescript-sdk) +- **实际客户端重连**:最近一次观测的 Codex 实例仍为 0.11.2;不能用新 stdio 测试替代宿主连接验证。重连后核对 hello 的版本、实例、构建与 schema,再执行代表性工具请求。该历史观察不是对任意当前客户端的实时判断。 +- **真实 Repomix 包兼容性**:已验证真实 Node 启动夹具和参数安全边界,尚未验证固定版本上游 Repomix 的完整打包行为。需要准备获准的隔离环境后再测。 +- **成本对照**:现有固定任务验证不等于 8–12 个真实任务的完整对照。只有决定继续优化检索成本时才补齐;比较正确完成率、调用数、输出量、重复取证和耗时,字符数不冒充 token。 -官方迁移说明要求 Node.js 20+;项目当前 README 仍声明 Node.js 18+。这意味着不能把迁移写成单纯替换 import 而忽略运行环境兼容性。MCP 包迁移与启用新协议行为也应分开,保持当前协议行为的兼容性验收。[官方迁移指南](https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2)、[协议版本迁移说明](https://ts.sdk.modelcontextprotocol.io/v2/migration/support-2026-07-28) +## 条件性研究,不列入近期必做版本 -`USER_DECISION_REQUIRED`:实施 R5 前确认支持的 Node.js 最低版本、SDK/Zod 依赖方案及升级范围;如果必须保留 Node.js 18,需另定维护策略,不能静默抬高门槛。 - -实施范围包括 Gateway server、Serena MCP client、stdio/in-memory transport、`src/`、`tests/`、`scripts/` 与相关 fixtures。按实际接口选择拆包与 schema 迁移方式;使用 codemod 也要检查整个包及未自动处理的位置。依赖安装和环境变更应纳入随后获批的实施方案,本次未执行。 - -**验收:**工具名/别名、输入校验、错误、取消、超时、工作区排空、子进程清理、compact/legacy 输出和图片分离均保持既定行为;实际工具列表能正常读取,客户端可以真实调用。Tool Registry 仅在迁移确有必要时局部整理,不单开大重构,也不混入新功能或新协议默认行为。 - -## 8. R6–R9:后续能力及进入条件 - -### R6:UI → XAML → C# - -复用现有 `UiReview` 的单次 UI 快照及 `UiSourceMapper` 的声明线索:运行时控件 → AutomationId/文本 → XAML 候选 → `Command / Click / Binding` 字符串 → C# 声明候选 → 引用与限定上下文。当前已能提取部分声明,下一步重点是导航和紧凑组合,不能把它们重新列为未实现功能。 - -第一版先用显式候选文件完成小闭环;如果真实任务表明猜 XAML 文件仍是主要成本,再加有界候选文件建议。用户给定的 UI `candidateFiles` 仍是闭集;不要与代码 `prepare_context.candidateFiles` 的优先语义混淆。源码候选、命令名相似、`CanExecute` 命名惯例都不是运行时因果证明,继续保留 `runtimeSourceVerified=false`。 - -以“已知禁用按钮”的隔离样本验证状态、XAML、候选实现和修复后复查;同名 Command、模板复用、旧构建对应新源码、Binding 无法静态确定时必须保留缺口。UIA Host 只做为此需要的局部拆分。 - -### R7:按需 MSBuild 求值 - -进入条件是实际遇到 `Directory.Build.props/targets`、Condition、imports、多 TFM 或配置相关引用,且现有声明图产生可复现差异。沿用 [DotNetGraph.ts](src/Core/DotNetGraph.ts) 的快速声明模式,优先研究官方 `-getProperty/-getItem` 求值,明确 Configuration、TFM、来源及失败原因;第一版不引入常驻 Roslyn/MSBuild 服务。[Microsoft Learn](https://learn.microsoft.com/en-us/visualstudio/msbuild/evaluate-items-and-properties?view=vs-2022) - -求值不自动附带 restore/build;在明确允许求值的工作区执行,复用现有子进程、超时、取消及资源回收。SDK/import 缺失时保留声明级结果和不完整说明,不能自动下载补齐,也不能把不同 TFM 的依赖无说明合并。 - -### R8:WPF 深层诊断实验 - -只有 R6 之后仍有真实问题被 Binding、DataContext、属性来源或模板内部信息阻塞时,才做小型实验。参考 [SnoopWPF](https://github.com/snoopwpf/snoopwpf) 和 [WPFVisualTreeMcp](https://github.com/faze79/WPFVisualTreeMcp),验证一个已知错误 Binding、DataContext 类型/路径、.NET 10 WPF 兼容性及退出后的订阅/连接释放。 - -这些项目的存在不证明 WinCode 集成已经可行。默认保留 FlaUI 的进程外只读取证;应用内接入或注入属于新的路线,需在专用测试应用上明确启用。首个实验通过前不承诺产品集成,不复制完整注入器或自研 XAML Binding 求值器,也不借机加入点击、输入和属性写入。 - -### R9:未知位置任务的 Repo Map - -仅当真实任务表明未知文件定位仍是主要成本时,参考 [Aider Repo Map](https://aider.chat/docs/repomap.html) 的按相关性选择有限代码信息的方法。优先利用已经可靠的项目关系与符号/引用信息,不直接搬入整套 Python/Tree-sitter 排名工具链。 - -已知文件、符号或行范围的请求继续走直达路径。验收比较相同初始信息下的定位质量、调用数和输出量;先证明排名有收益,再讨论缓存及失效策略,不增加默认全仓预扫描。 - -## 9. GitHub 经验综合 - -本节结合 GPT-6(High)子智能体的一手资料检索补充。只吸收能直接解决 R1–R3 或降低实现风险的机制;上游具体实现同样需要检查边界,不能因为项目成熟就直接复制。 - -| 上游经验与一手资料 | 本项目的最小吸收方式 | 判断与限制 | -| --- | --- | --- | -| [Serena ListDirTool](https://github.com/oraios/serena/blob/main/src/serena/tools/file_tools.py):按路径、递归选项和忽略规则读取目录,并限制结果长度 | R1 默认摘要;指定目录按需展开;省略情况有界表达 | 近期采用访问方式。上游先扫描再限长,不能照搬后声称扫描成本有界 | -| [GitHub MCP Server](https://github.com/github/github-mcp-server#tools):部分列表工具提供分页及 `fields` 字段选择 | R1 默认只选必要摘要字段;宽目录确需续读时再加小型分页契约 | 字段选择思想可先用,不必向 WinCode 暴露通用查询语言。MCP 的列表分页规范不自动成为自定义目录工具的标准 | -| [MCP Inspector CLI](https://github.com/modelcontextprotocol/inspector/blob/main/clients/cli/README.md):从实际连接读取服务信息、列工具、调用工具 | R2 复用当前 SDK 做同会话核对,并另核对真实宿主连接 | 近期采用诊断方法。当前 [Inspector README](https://github.com/modelcontextprotocol/inspector/blob/main/README.md) 要求 Node.js ≥22.19,本文不建议为了诊断顺手引入该依赖或升级环境 | -| [Repomix readRepomixOutputTool](https://github.com/yamadashy/repomix/blob/main/src/mcp/tools/readRepomixOutputTool.ts):返回总行数、实际读取行数和起止行 | R3 分离请求范围、最终返回范围与可靠可计算的未返回范围,支持无状态补取 | 近期吸收输出信息组织。检索时上游返回 `endLine` 的分支仍可能回显超过 EOF 的请求终点;应作为反例测试,不能照搬 | -| [Aider benchmark](https://github.com/Aider-AI/aider/blob/main/benchmark/benchmark.py):将版本/配置、尝试成功率、错误、耗时与 token 等一起记录 | R3 先验证固定任务是否正确完成,再比较输出量、调用数与重复取证 | 近期吸收小样本评价方法,不引入大型 benchmark 平台、新模型服务或排行榜;宿主 token 未实测时只记录字符估算 | - -目录分页如后续采用,可参考 [MCP 分页规范](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/pagination) 的游标思想,但目录工具的路径、排序、失效与续读条件仍需自行明确;首版不为此维护全仓快照。 - -综合取舍:这些经验主要细化 R1–R3 的验收与实现边界,支持既定近期排序。子智能体提出的“控件一直定位到 XAML/C#”完整自动调查样本归入 R6;R3 先用现成的定位信息验证已经实现的精准读取,避免把新功能开发混入旧能力验收。[FlaUInspect](https://github.com/FlaUI/FlaUInspect) 的信息组织留给 R6;Snoop/WPF 深检及 Repo Map 仍按进入条件安排。 - -以上是对上游机制的借鉴建议,具体成本仅能判断为局部适配或需要进一步设计;本轮没有集成或测得性能提升。上游源码会变化,正式实施时按当时版本复核。 - -## 10. 暂缓项与实施决策 - -暂缓 Capability Registry、Theia 式 DI/plugin host、OpenHands runtime、Cline Agent 架构、大型 Extension System、通用 Symbol Service、模型专属 tokenizer、Repomix 整体重构,以及没有失效证据支持的跨调用缓存。既有 `ExtensionManager` 也不因本文而顺手改造。 - -Repomix 的个别有用做法可独立参考;当前显式候选打包会走内置 bounded packer,因此不将切换 Repomix provider 作为近期主线。继续明确字符数/4只是预算估算。 - -| 事项 | 状态与处理 | -| --- | --- | -| R1 → R2 → R3 的近期顺序 | 用户本次已明确,无需重复确认排序 | -| R1 预算初值、目录入口、旧响应兼容方式 | `USER_DECISION_REQUIRED`:实施前给出小型接口草案和调用方影响;本文数值为建议 | -| R2 构建身份/schema 标识、R3 覆盖字段 | `USER_DECISION_REQUIRED`:新增公开字段需先对齐契约;优先复用现有定义和响应 | -| R4 精确身份参数及歧义响应 | `USER_DECISION_REQUIRED`:确认兼容形态后实施,不静默更换公共接口 | -| R5 最低 Node 版本及依赖升级 | `USER_DECISION_REQUIRED`:有实际兼容性变化,单独处理 | -| R7 求值、R8 新接入、额外依赖或下载 | 只有进入相应阶段且实施范围获确认后执行 | -| Git 提交、推送、发布、全局 MCP 更新 | 本次文档整理不包含这些动作;此前其他任务的发布指令不作为本次执行命令 | - -这些是后续实施的决策点,不阻止本次路线图交付。不会因为条目出现在路线图里就自动执行。 - -## 11. 交付与持续维护口径 - -- 每轮记录基线、目标、实际改动、使用的运行实例、针对性验证、失败与限制;继续增订 [工作日志](docs/codex_worklog.md),不要为每个小步骤新增计划文件。 -- 区分源码存在、编译通过、隔离测试通过、实际 MCP 接入通过、真实应用 GUI 通过和已发布。mock 测试或本地 benchmark 不替代真实上游和客户端验收。 -- 每轮至少核查一个具体反例:输出很短却丢失关键入口;版本相同但构建不同;参数存在但 handler 未实现;范围元数据正确但正文被截断;单个可见候选来自未完成搜索;UI 状态来自旧进程。 -- 测试采用现有非交互回归与专用夹具,GUI/真实上游按任务需要单独运行。只复用明确的专用测试资料,避免个人数据库与配置;长期复用测试环境时记录初始状态,避免残留状态掩盖缺陷。 -- 以正确对象、足够证据、减少无效调用和受控资源为收益,不以类数、工具数、测试数或引入项目数量评价迭代。 - -本文编制仅新增路线图并在既有日志中记录;所列实现与验收仍以之后的实际工作结果更新。 - -## 12. 实施授权与进度(2026-09-08,北京时间) - -用户在文档完成后授权按本路线图迭代,每个版本经复测、Debug 后单独推送 PR 并合并。因此第 10 节的文档阶段授权边界由本节更新:R1–R6 按上述最小方案实施,普通接口细节沿用现有契约;R7–R9 仍须满足各自进入条件。全局 MCP 配置与其他应用数据不自动纳入修改范围。 - -用户随后明确“接受 node20”:R5 采用 Node.js 20 为最低运行版本,允许该阶段所需 SDK v2 依赖迁移;不包含另装 Inspector 或升级系统 Node。 - -| 版本 | 范围与状态 | 验证边界 | +| 方向 | 触发证据 | 最小实验及限制 | | --- | --- | --- | -| 0.9.1 / R1 | [PR #14](https://github.com/linnnn89/WinCode/pull/14) 已合并,main 7ce737f | 非交互回归 169 pass、1 skip;最终入口筛选修正后专项 9/9。真实 TavernDesk 独立 MCP 响应 3705 字符,保留 solution、应用项目入口;CodeQL 通过 | -| 0.9.2 / R2 | [PR #15](https://github.com/linnnn89/WinCode/pull/15) 已合并,main 2cbf443 | 专项 8/8,非交互回归 177 pass、1 skip,独立 stdio 契约与实际正文核对通过;CodeQL 通过 | -| 0.9.3 / R3 | [PR #16](https://github.com/linnnn89/WinCode/pull/16) 已合并,main 0351111;当前主连接新版验收已补齐,见第 14 节 | 专项 34/34;非交互回归 186 pass、1 skip;CodeQL 通过。真实 TavernDesk 新 stdio 8 场景通过 | -| 0.9.4 / R4 | [PR #17](https://github.com/linnnn89/WinCode/pull/17) 已合并,main 95446c3 | 新增 27 项;完整回归 213 pass、1 skip;CodeQL、stdio/TavernDesk 复测通过,真实 Serena LSP 未验收 | -| 0.10.0 / R5 | [PR #18](https://github.com/linnnn89/WinCode/pull/18) 已合并,main 9d9053b | typecheck/build、stdio/TavernDesk、非交互回归 213 pass、1 skip;GUI/协议 34/34,CodeQL 通过;工具 schemaHash 与 R4 相同 | -| 0.11.0 / R6 | [PR #19](https://github.com/linnnn89/WinCode/pull/19):显式 C# 候选与 Gateway 实现、复测完成;远端合并状态见 PR | 专项 15/15,非交互回归 228 pass、1 skip,UI/协议 34/34,隔离源码修复闭环 1/1;最终构建 TavernDesk 8 场景及 UI→赋值→方法正文通过 | -| R7–R9 | 条件阶段,尚未进入 | 依据真实阻塞决定是否实施 | - -## 13. Codex 旧版本连接诊断(2026-09-08) - -用户要求专用 GPT-6 xHigh 子代理只读分析。07:32–07:34 北京时间的对照显示:主任务 hello 仍为 0.9.0,启动于 06:31:39;新子代理 hello 为 0.9.4、build 校验通过,启动于 07:32:07。两者的 WinCode 配置均指向 `node I:/WinCode/dist/index.js --workspace I:/WinCode`,新连接的 buildId 与当时磁盘 manifest 一致。 - -结论是旧连接仍持有构建前启动的进程,重编译磁盘不会替换存活实例;没有证据支持这组对照由错误安装路径或旧磁盘产物导致。仅 schema 缓存也不能解释旧 hello 的版本和启动时间。相关 Node 进程来自同一 Codex 后端;旧 PID 与任务仅按启动时间关联,未直接锁定,不能据此批量终止进程。 - -无需结束主任务即可由构建后新建的代理连接验证新版;必须注明它是新连接,父连接仍旧。官方 App Server 提供 `config/mcpServer/reload`,本机应用代码也有调用点,但当前工具未暴露,且未核实单服务器、无扰动刷新保证,因此本次未调用;本机 CLI 的 `mcp --help` 无 restart/reconnect 子命令。[官方 App Server 文档](https://learn.chatgpt.com/docs/app-server) - -后续可在独立小改动中考虑 hello 暴露自身 PID,让关联直接可证;这不会自动修复既有旧进程,本轮不混入 SDK 迁移或 UI 源码导航。 - -## 14. 当前主连接补充验收(2026-09-08) - -用户要求完成 TavernDesk 实测问题的下一轮迭代。核对当前 main@8f997d8 后,R1–R3 已包含在代码中;本次补齐当前主任务实际连接的验收,没有重复开发。当前连接已于北京时间 08:25:54 启动,hello 返回 0.11.0、build.status=verified、revision=8f997d8,实例 1b949eb7-14e4-45c6-9cbd-6e6c21eef32a;首末核对一致。这更新了第 13 节此前主连接仍旧的状态,不代表其他任务连接已刷新。 +| R7:按需 MSBuild 求值 | Condition、imports、Directory.Build.* 或多 TFM 导致声明图与实际依赖出现可复现差异 | 保留快速声明图,实验按配置/TFM 求值并标注来源;不自动 restore/build,不隐式下载 SDK,不增加常驻服务 | +| R8:WPF 深层诊断 | 实际任务被 Binding、DataContext 或模板信息阻塞,现有 UIA/源码证据不足 | 在专用测试应用验证一个明确诊断问题及退出清理;应用内接入/注入是新路线,须另行确认 | +| R9:未知位置任务 Repo Map | 对照证明文件定位仍是主要成本 | 先用既有项目和符号关系验证有限排名收益;已知范围继续直达,不默认全仓预扫描 | -真实连接打开 TavernDesk 默认响应 3705 字符,无目录树;按需目录浏览限制 10 项且明确截断。scopeFiles+symbol 返回 ShowCharactersAsync,第 309 行声明及正文核对通过;1–223 行在足预算下完整覆盖,512 token 预算时仅完整覆盖 9 行并明确半截尾行。原始响应已按实际源文件和 UTF-16 字符预算验证,记录在 test-tmp/tavern-host-acceptance-20260908.json;26 项相关回归通过。没有重新启动应用、访问个人数据库、修改 MCP 配置或安装依赖;已恢复活动工作区为 I:/WinCode。后台空白截图、computer use 窗口归属和真实 Serena LSP 不属于本次已解决项。 +研究入口沿用 [MSBuild 求值文档](https://learn.microsoft.com/en-us/visualstudio/msbuild/evaluate-items-and-properties?view=vs-2022)、[SnoopWPF](https://github.com/snoopwpf/snoopwpf)、[Aider Repo Map](https://aider.chat/docs/repomap.html)。它们是后续复核入口,不表示本轮已检索最新实现或完成集成。实施前固定上游版本,先证明收益再决定引入依赖。 diff --git a/docs/codex_worklog.md b/docs/codex_worklog.md index d3ec759..56ddc6a 100644 --- a/docs/codex_worklog.md +++ b/docs/codex_worklog.md @@ -110,13 +110,13 @@ ## 2026-09-07 12:12(北京时间)— 保存 v0.6 参考方案 -- 按用户要求在根目录新增 [WinCode v0.6运行时UI取证实施方案](../WinCode%20v0.6运行时UI取证实施方案.md),保存完整范围、架构、协议、生命周期、截图预算、测试与后续路线。 +- 按用户要求在根目录新增 [WinCode v0.6运行时UI取证实施方案](https://github.com/linnnn89/WinCode/blob/67239e3bcdad2ed6572b7407925906f521567dba/WinCode%20v0.6%E8%BF%90%E8%A1%8C%E6%97%B6UI%E5%8F%96%E8%AF%81%E5%AE%9E%E6%96%BD%E6%96%B9%E6%A1%88.md),保存完整范围、架构、协议、生命周期、截图预算、测试与后续路线。 - 文档明确为参考方案,v0.6 仅 UI 取证,v0.7 源码联动后置;未实施功能、安装依赖或控制真实应用。 - 验证:文件已生成,核对章节结构;本次仅文档变更,不运行代码测试。 ## 2026-09-07 14:00(北京时间)— WinCode v0.6 运行时 UI 取证全量实施交付 -- 目标:按照 [WinCode v0.6运行时UI取证实施方案](../WinCode%20v0.6运行时UI取证实施方案.md),完成 Windows 桌面应用程序 UI 自动化取证功能(C# FlaUI.UIA3 Host、TypeScript UiContracts & FlaUiAdapter、MCP 工具 `wincode_ui_inspect` 及 ToolRouter 深度集成)。 +- 目标:按照 [WinCode v0.6运行时UI取证实施方案](https://github.com/linnnn89/WinCode/blob/67239e3bcdad2ed6572b7407925906f521567dba/WinCode%20v0.6%E8%BF%90%E8%A1%8C%E6%97%B6UI%E5%8F%96%E8%AF%81%E5%AE%9E%E6%96%BD%E6%96%B9%E6%A1%88.md),完成 Windows 桌面应用程序 UI 自动化取证功能(C# FlaUI.UIA3 Host、TypeScript UiContracts & FlaUiAdapter、MCP 工具 `wincode_ui_inspect` 及 ToolRouter 深度集成)。 - 架构设计与关键改动: 1. **Step 1: C# UIA Host 与独立测试夹具 (PR #2)**: - 新建 `tools/WinCode.UIA.Host`(.NET 10 console, `net10.0-windows`, `win-x64`, FlaUI.UIA3 5.0.0)。 @@ -505,3 +505,25 @@ - 报告 test-tmp/serena-acceptance/1788874762075-31176/report.json 与 1788874881144-38796/report.json;每次记录真实结果、PID 退出、dispose 成败,测试 C# 源码保持一致。进一步自审加强为核对引用预览中 > 标记所在行,避免“周围文本同时有另一重载”造成假阳性;最终复测回执另存本地。查询已隔离安装目录对应 python/dotnet 进程,没有残留匹配进程。Serena 环境最终约 632 MB,复用 Python 3.13.7,无全局 PATH 修改、无全局 Serena 启用。 - 首轮 0.12.5 全量回归和 stdio 通过,交付阶段因检查运行期间补充 package.json 维护命令触发源码/构建指纹不一致而失败;这是有效的一致性保护。冻结变更后完整重跑,不绕过交付校验。失败报告 2026-09-08T13-40-56-234Z-core。 - 当前 Codex 旧连接仍需客户端重连;没有提供可调用的重连接口,不用结束 Codex/强杀 Gateway 冒充成功。作者自审,未新增独立审查或子代理。 + +## 2026-09-08 21:56 — 当前架构、数据流与检查关口说明(北京时间) + +- 根据 0.12.5/main 10496e0 源码核对启动、Gateway/Registry、Router、Context/Response、Serena/Repomix/FlaUI、原生 Host、工作区/缓存/资源生命周期和交付脚本,新增根目录 WinCode-架构与数据流说明.md,README 增加入口。 +- 五张 Mermaid 图覆盖分层、请求时序、代码证据、桌面取证、构建到连接;配套数据存放表与 G1–G11 检查关口表。区分运行时校验、测试约束、远端保护、客户端授权,明确未知字段容忍、内部/外部 candidateFiles 语义、最终序列化覆盖、候选与运行时绑定、缓存与进程 RSS 等边界。 +- 本轮 GitHub 只读回查 main 保护仍生效:strict Node 22/24 与三项 CodeQL,对管理员生效,approval=0;未改变远端设置。架构边界以源码为据,不用历史 README 或测试总数代替实现。 +- 自审补充当前限制:Router 职责集中、错误响应尚非单一格式、不同文件路径各自校验、重构计划不执行修改、客户端需自行重连。文档为独立架构参考,不扩展生产功能。 +- 验证:文档本地链接、代码围栏及五个图块检查通过;git diff --check 通过。未运行代码回归,未安装 Mermaid 渲染器,未把文本结构检查写成视觉渲染验收。 + +## 2026-09-08 22:12 — Markdown 当前状态同步(北京时间) + +- 按用户要求核对 14 份项目 Markdown,将两份根目录计划收敛为 0.12.5 基线的未完成工作;移出已实现的 R1–R6/WP1–WP5 步骤,历史留在版本记录、工作日志和 Git 中,不另建归档计划。 +- 新待办为工作区切换失败一致性、trash 部分完成恢复、有界混合负载、错误契约渐进整理。前两项是静态风险、尚待故障注入;重要恢复策略和公共接口列出待决事项,没有实施或承诺全局重构。 +- 更新双语 README 导航及锁定构建入口、Skill/MCP 安装维护指南、Host 协议和截图限制、贡献指南、架构说明与 0.12.5 验收记录。修正 Host“零副作用”和截图成功保证等过度表述。 +- 回查本地最终回执:main 10496e0、核心回归 313 通过/1 可选跳过、真实 Serena 七项通过、告警 #1 fixed、分支保护已启用。保留客户端重连、真实 Repomix 包验收及完整成本对照的证据缺口;未重新把旧宿主连接记作最新版本。 +- SECURITY 与四份规范 Skill 已符合当前版本和容忍策略,保持正文;skill:check 实测四份安装文件一致,无需重复部署。补修历史日志中两处已删除 v0.6 方案的链接,改指 Git 中已确认存在的原提交,仅修链接、不改当时事件结论。 +- 验证:14 份 Markdown 的本地链接与围栏检查、规范命令对照、旧状态扫描、git diff --check;复核既有测试报告,不将其计作本轮新回归。文档外链未做在线存活检查,Mermaid 未重新渲染;本轮没有代码、依赖、环境或远端变更。 + +## 2026-09-08 — 文档更新上传授权(北京时间) + +- 用户要求上传至 linnnn89/WinCode;沿用既有 PR、必需检查通过后合并流程。本次仅提交当前九份 Markdown 变更,不变更软件版本或运行环境。 +- 上传前确认 origin 地址正确、本地 main 与 origin/main 一致、无其他打开的 PR,git diff --check 通过。实际远端检查及合并结果以该 PR 回执为准。 diff --git a/tools/WinCode.UIA.Host/README.md b/tools/WinCode.UIA.Host/README.md index 6ebe291..22a7396 100644 --- a/tools/WinCode.UIA.Host/README.md +++ b/tools/WinCode.UIA.Host/README.md @@ -1,86 +1,48 @@ # WinCode.UIA.Host -Windows UI Automation (FlaUI.UIA3) 一次性取证进程。 - -## 职责边界 -1. **单次执行**:接收 stdin JSON,执行单次有界 UIA 遍历与可选截图,输出 stdout 纯净 JSON 后退出。 -2. **零副作用**:只 attach 目标进程窗口,绝不主动启动、激活焦点或杀死目标进程。 -3. **坐标系统**: - - 采用 `SetProcessDpiAwarenessContext(PerMonitorV2)`。 - - 所有输出矩形(`bounds`, `captureOrigin`, `relativeBounds`)均为**物理屏幕像素**。 - - 截图采用 `DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS)` 获取物理扩展边框。根节点 `relativeBounds (-9, 0)` 等偏移量系 Windows DWM 阴影扩展边框所致,为正常物理像素差值。 -4. **截屏管线**: - - 优先级 1: `PrintWindow(hwnd, hdc, PW_RENDERFULLCONTENT)`,可截取 GPU 硬件加速的 WPF 窗口且不受普通遮挡影响。 - - 优先级 2: `PrintWindow(hwnd, hdc, 0)`。 - - 优先级 3: 桌面 DC `BitBlt`。 - - 优先级 4: `CopyFromScreen`(使用 GDI 兼容的 `PixelFormat.Format32bppRgb`)。 - - 响应包含 `captureMethod`(例如 `printWindowDwm`)。 - -## 协议示例 - -### 1. 输入 (stdin) +0.12.5 的 Windows UI Automation(FlaUI.UIA3)一次性取证进程。实现入口为 [Program.cs](Program.cs),面向 Agent 的规范参数见 [UI 手册](../../skills/wincode/references/ui.md),整体数据流见 [架构说明](../../WinCode-架构与数据流说明.md)。 + +## 职责和边界 + +接收 stdin JSON,执行有界窗口发现或 UIA 取证,输出 stdout JSON 后退出。Gateway 的 FlaUIAdapter 管理自有 Host 的超时、取消和进程回收;被检查的应用不属于其进程所有权。 + +Host 不点击、不输入、不写目标控件属性,不主动启动或终止目标应用。它会产生自身进程、审计日志及按策略显示的取证提示,因此不应描述为“零副作用”。审计和内容哈希是诊断证据,不是防篡改或来源签名。 + +## 请求与结果 + +下面是内部 stdin 请求示例,PID/HWND 必须替换为实际目标;`schemaVersion`、`requestId`、`action` 和 `timeoutMs` 是内部 Host 协议字段,不应照搬为 MCP 工具参数。 + ```json { "schemaVersion": "1.0", - "requestId": "req-123", + "requestId": "example-inspect", "action": "inspect", - "pid": 25864, - "hwnd": "0x60766", - "capture": "annotated", - "maxDepth": 6, - "maxNodes": 300, + "pid": 12345, + "hwnd": "0x123ABC", + "capture": "none", + "backgroundOnly": true, + "readStates": true, + "query": { "automationId": "NavCharacters", "maxSearchNodes": 1000, "maxMatches": 10 }, + "maxDepth": 4, + "maxNodes": 100, "timeoutMs": 10000 } ``` -### 2. 正常响应 (stdout) -```json -{ - "schemaVersion": "1.0", - "protocolVersion": "1.0", - "requestId": "req-123", - "success": true, - "pid": 25864, - "hwnd": "0x60766", - "captureOrigin": { "x": 2044, "y": 669, "width": 1032, "height": 741 }, - "captureMethod": "printWindowDwm", - "tree": { - "id": 1, - "parentId": null, - "automationId": "WinCodeWpfFixtureRoot", - "name": "WinCode UI Review Fixture", - "controlType": "Window", - "className": "Window", - "bounds": { "x": 2035, "y": 669, "width": 1050, "height": 750 }, - "relativeBounds": { "x": -9, "y": 0, "width": 1050, "height": 750 }, - "isEnabled": true, - "isOffscreen": false, - "children": [] - }, - "totalNodes": 32, - "maxDepthReached": 4, - "truncated": false, - "annotatedPngBase64": "..." -} -``` +协议版本 `1.0`、取证结构 `inspectionVersion: 2` 和程序集产品版本是不同概念。实际 Host 的 `hostIdentity` 用于核对版本、构建配置和框架,不能从请求或磁盘文件名推断响应身份。 -### 3. 多窗口候选响应 -```json -{ - "schemaVersion": "1.0", - "protocolVersion": "1.0", - "requestId": "req-124", - "success": false, - "errorCode": "MULTIPLE_WINDOWS", - "errorMessage": "Could not resolve target window for PID 1234 / HWND .", - "candidateWindows": [ - { - "hwnd": "0x30882", - "title": "WinCode UI Review Fixture", - "className": "Window", - "bounds": { "x": 100, "y": 100, "width": 700, "height": 500 }, - "isIconic": false - } - ] -} -``` +结果应结合 `success/errorCode`、目标窗口、搜索完整性与匹配数量、截断原因、状态证据、截图信息和审计状态解释。查询字段按大小写精确 AND 匹配;只有遍历完整且唯一才展开命中子树。截断后的单个候选不能认定唯一,未知状态不等于 false,多窗口歧义不能自动挑第一个。 + +## 截图与坐标 + +采用 PerMonitorV2 DPI 感知,矩形和截图坐标为物理像素。DWM 扩展边框与 UIA 根矩形可能不同,因此相对坐标出现负偏移不自动意味着定位错误。 + +截图优先尝试 PrintWindow;成功与图像内容取决于目标应用及渲染状态,不能保证所有 GPU/WPF 窗口都可正确捕获。`backgroundOnly=true` 要求明确 PID/HWND,禁用桌面屏幕回退;最小化窗口不作为后台截图成功处理。非后台限制模式才允许按实现尝试桌面 DC/屏幕回退。 + +读取 `captureMethod` 和 `captureQuality`,区分截图 API 返回成功与画面内容可信;质量检测不是语义识别。树查询、截图、审计分别有自己的结果边界,不因获得一张 PNG 就宣称全部取证完成。 + +## 构建与验证 + +从仓库根目录运行 `npm run check` 完成锁定还原、Release Host 构建与交付校验;需要交互桌面时另运行 `npm run check:desktop`。构建要求固定 SDK 10.0.303,framework-dependent Host 需要 .NET 10 Windows Desktop 运行时。完整命令与报告边界见 [贡献指南](../../CONTRIBUTING.md)。 + +生产默认只使用发布的 Release Host;Debug/dotnet-run 回退需显式开发模式。更新 Host 后核对完整交付文件集和实际响应身份,不能只替换一个 DLL。