PowerToys AI 贡献者指南:构建纪律、测试规范与工程边界的完整实践
本文以 PowerToys 仓库根目录的 AGENTS.md 为主体,系统讲解面向 AI 贡献者(以及人类开发者)的顶层工程规范:仓库区域划分、构建脚本与构建纪律、测试发现与运行规则、跨模块边界约束和提交前验证清单。读完后,你可以独立完成 PowerToys 从首次构建、失败排错到测试验证的全流程,并理解 Runner 与 Settings UI 之间 IPC 契约、src/common/ 共享库 ABI 稳定性等高风险区域的保护机制。
仓库区域总览:七大区域的职责划分
PowerToys 是面向 Windows 高级用户的生产力工具集合。AGENTS.md 开篇即用一张表划定了仓库的七个核心区域,这是理解后续所有构建、测试和边界规则的地基:
| 区域 | 位置 | 职责 |
|---|---|---|
| Runner | src/runner/ |
主可执行文件、托盘图标、模块加载器、热键管理 |
| Settings UI | src/settings-ui/ |
WinUI/WPF 配置应用,通过命名管道与 Runner 通信 |
| Modules | src/modules/ |
各个独立的 PowerToys 工具(每个工具一个子目录) |
| Common Libraries | src/common/ |
共享代码:日志、IPC、设置、DPI、遥测、通用工具 |
| Build Tools | tools/build/ |
构建脚本与自动化 |
| Documentation | doc/devdocs/ |
开发者文档 |
| Installer | installer/ |
基于 WiX 的安装程序项目 |
从源码结构看,这个划分与实现一一对应:src/runner/main.cpp 中维护着模块 DLL 的加载列表,src/runner/powertoy_module.h 封装了模块生命周期;src/settings-ui/ 下包含 Settings.UI、Settings.UI.Library、QuickAccess.UI 等多个 WinUI/WPF 项目。更深入的架构描述(四类模块:Simple Modules、外部应用启动器、上下文菜单模块、注册表模块)可见 架构总览;每个模块必须实现的 DLL 接口定义在 powertoy_module_interface.h,其方法契约与运行时调用逻辑(powertoy_create() → get_name() → enable() → set_config() → destroy())在 模块接口文档中有完整说明——这正是 Runner 能够统一管理约二十个模块接口 DLL 的基础。
Runner 与 Settings UI 之间的通信细节(JSON over Named Pipes、设置 schema 迁移、IPC 兼容性)在 Settings 系统文档中展开,这是 AGENTS.md 边界章节重点保护的区域。
编码约定与组件级自动生效指令
AGENTS.md 将编码约定收敛为三份必读文档,并额外引入了按目录作用域自动应用的组件级指令文件:
- 编码指南——依赖管理、测试要求、PR 管理流程
- 编码风格——格式化工具(XAML 用 XamlStyler、C++ 用
.clang-format)、C++/C#/XAML 风格规则 - 日志规范——C++ 侧 spdlog 与 C# 侧 Logger 的用法
组件级指令文件(instruction files)会在 AI 工具处理对应目录的文件时自动生效,其作用域声明在各文件头部的 frontmatter 中:
- Runner & Settings UI 指令,作用域
src/runner/**, src/settings-ui/**——核心规则包括:IPC/JSON 契约变更必须同步镜像到两侧代码;保持src/runner/main.cpp中的模块发现列表与新增/移除模块同步;设置 schema 变更必须附带迁移逻辑;UI 绑定操作需回 UI 线程 - Common Libraries 指令,作用域
src/common/**——核心规则包括:避免破坏公共头文件/API,修改公共接口必须全库搜索调用方;ABI 影响的 struct/class 布局变更需保持二进制兼容;热路径(hooks、定时器、序列化)警惕性能回退;新增第三方依赖须 MIT 许可或经 PM 团队批准,并登记到 NOTICE.md
这种"全局指南 + 目录作用域指令"的分层设计,使得约束在离代码最近的位置生效,是 AGENTS.md 整体工程哲学的体现:规则要具体、要可自动执行。
构建:前置条件与构建命令
前置条件
在开始构建前,AGENTS.md 明确了三个硬性前提:
- Visual Studio 2022 17.4 及以上版本,或 Visual Studio 2026
- Windows 10 1803(2018 年 4 月更新)或更新的系统
- 只需执行一次子模块初始化:
git submodule update --init --recursive
子模块初始化是必要的:C++ 侧日志库 spdlog 以 git submodule 形式置于 deps/ 目录,各 vcxproj 通过 spdlog.props 引入其头文件与库链接;src/common/ 下的共享工具(如 json.h、two_way_pipe_message_ipc.h)也依赖子模块内的第三方代码。
构建命令
AGENTS.md 给出的三条核心命令对应三种典型场景:
| 任务 | 命令 |
|---|---|
| 首次构建 / NuGet 恢复 | tools\build\build-essentials.cmd |
| 构建当前文件夹 | tools\build\build.cmd |
| 带选项构建 | build.ps1 -Platform x64 -Configuration Release |
构建脚本指南 对这三个入口有更细的语义,值得在实操前理解:
build-essentials.ps1:对 PowerToys.slnx 执行 NuGet 恢复,并构建"必需品"(runner 与 settings)。自动检测平台(x64/arm64)并初始化 VS 开发者环境。示例:./tools/build/build-essentials.ps1 -Platform arm64 -Configuration Releasebuild.ps1:构建当前目录下的任意.sln/.csproj/.vcxproj,接受额外 MSBuild 参数转发(如./tools/build/build.ps1 '/p:CIBuild=true'),也支持仅恢复依赖的-RestoreOnly开关build-installer.ps1(需谨慎使用):完整本地打包管线(restore、build、MSIX 签名、WiX v5 MSI/bootstrapper),关键选项-PerUser true|false、-InstallerSuffix wix5|vnext
两个 CMD 包装器 build.cmd 与 build-essentials.cmd 会将全部参数原样转发给对应的 PowerShell 脚本。脚本初始化 VS 环境的策略是:优先走 DevShell(Microsoft.VisualStudio.DevShell.dll / Enter-VsDevShell),失败后回退到 VsDevCmd.bat;若找不到 VS 安装,应从 "Developer PowerShell for VS 2022" 中运行,或确保 vswhere.exe 存在于 Program Files (x86)\Microsoft Visual Studio\Installer 下。
构建纪律:七条不可协商的规则
AGENTS.md 的 "Build discipline" 一节是全文最值得逐条遵守的部分,它定义了构建操作的纪律性流程:
- 一次操作一个终端(build → test 依次进行),中途不得切换或新开终端
- 修改代码后,先
cd到发生变化的项目目录(即包含改动文件对应.csproj/.vcxproj的目录) - 一律通过
tools/build/build.ps1或tools/build/build.cmd构建,不要直接调 msbuild - 首次构建或缺少 NuGet 包时,必须先跑
build-essentials.cmd - 退出码 0 = 成功;非零 = 失败——这条要当成绝对事实对待
- 构建失败时,阅读错误日志
build.<config>.<platform>.errors.log - 构建未成功之前,不要开始跑测试,也不要启动 Runner
构建日志的排错顺序
日志位于被构建的 solution/project 旁侧,AGENTS.md 与构建脚本指南共同定义了排错时的查阅顺序:
build.<configuration>.<platform>.errors.log—— 仅错误(先看这个)build.<configuration>.<platform>.all.log—— 完整日志build.<configuration>.<platform>.trace.binlog—— 用 MSBuild Structured Log Viewer 打开
从 BUILD-GUIDELINES.md 看,实际上还存在一个仅告警日志 build.<configuration>.<platform>.warnings.log,当 errors 为空但构建行为可疑时值得检查。
测试:发现、运行与三类测试
测试项目的发现方式
AGENTS.md 给出了一种不依赖记忆清单的测试项目定位法:
- 按产品代码前缀查找测试项目(例如
FancyZones、AdvancedPaste) - 在源码目录的同级或上 1–2 级目录中,查找命名为
<Product>*UnitTests或<Product>*UITests的文件夹
从仓库实际结构可以印证这一命名惯例,例如 src/modules/MouseUtils/ 下同时存在 MouseJump.Common.UnitTests、MouseJump.HotKeys.UnitTests、MouseJump.Models.UnitTests 与 MouseUtils.UITests 等项目;src/settings-ui/ 下则设有 Settings.UI.UnitTests。
运行测试的三条规则
- 先构建测试项目,等到退出码为 0
- 通过 Visual Studio Test Explorer(
Ctrl+E, T)或vstest.console.exe加过滤器运行 - 本仓库中避免使用
dotnet test——应使用 VS Test Explorer 或 vstest.console.exe
第 3 条是一个容易踩坑的仓库特定约束:PowerToys 的 C++/C# 混合工程依赖 VS 工具链生成的环境(含 WinAppSDK、WinRT 投影等),dotnet test 无法正确还原该环境。
三类测试及其环境要求
| 类型 | 要求 | 环境准备 |
|---|---|---|
| 单元测试 | 标准开发环境 | 无需额外准备 |
| UI 测试 | WinAppDriver v1.2.1、Windows Developer Mode | 安装对应版本的 WinAppDriver 并启用开发者模式 |
| Fuzz 测试 | OneFuzz、.NET 10 | 见 Fuzzing Tests 文档 |
关于 UI 测试,UI Tests 文档 补充了一个 AGENTS.md 未展开的重要现状:新测试应使用 Microsoft.PowerToys.UITest.Next 框架,它通过 winappcli 驱动 Windows UI Automation,并以 Microsoft.Testing.Platform 可执行文件的形式运行;而基于 WinAppDriver/Selenium 的旧版 Microsoft.PowerToys.UITest 框架保留用于既有套件与迁移基线。这意味着 AGENTS.md 中"安装 WinAppDriver v1.2.1"的要求主要适用于存量旧版 UI 测试;新增或迁移测试时还需要安装锁定版本的 winappcli 运行时(或设置 WINAPP_CLI_PATH),且 UI 测试必须运行在真实的交互式桌面上(session 0 中 UIA、前台输入与渲染均不可用)。
测试纪律与特殊硬件要求
AGENTS.md 对"改代码"与"写测试"的绑定关系提出了明确纪律:
- 变更行为时,添加或调整相应测试
- 若测试被跳过,必须说明理由(例如仅注释变更、仅字符串改名)
- 处理文件 I/O 或用户输入的新模块必须实现 fuzzing 测试——这一要求与 编码指南 中"安全团队要求处理文件 I/O 或用户输入的模块做 fuzzing"的表述一致,且 C# 与 C++ 模块的 fuzzing 实现方式不同(集成 Microsoft OneFuzz 服务)
两类模块还有额外的硬件前提:
- Mouse Without Borders:需要 2 台以上物理计算机(虚拟机不可行,因为宿主机与来宾机的鼠标输入会互相混淆)
- 多显示器工具:至少 2 个显示器,且其中一个应支持不同的 DPI 设置
边界:何时必须澄清、哪些区域重点保护
AGENTS.md 的 "Boundaries" 章节定义了贡献过程中的风险分级,这部分对保证跨模块变更质量尤为关键。
需要先澄清再继续的场景
- 扫描了相关文档后规格仍然含糊
- 跨模块影响(共享 enum/struct)不明确
- 涉及安全、提权或安装程序的变更
- 需要修改 GPO 或策略处理逻辑
重点保护区域
| 区域 | 风险点 | 参考 |
|---|---|---|
src/common/ |
ABI 破坏 | Common Libraries 指令 |
src/runner/、src/settings-ui/ |
IPC 契约、settings schema | Runner & Settings UI 指令 |
安装程序文件(installer/) |
影响发布 | 需要仔细评审 |
| 提权/GPO 逻辑 | 安全 | 确认策略处理无回归 |
四条红线(What not to do)
- 不要将未完成的特性合入 main(使用 feature 分支)
- 不要在不更新 runner 和 settings-ui 两侧的情况下破坏 IPC/JSON 契约
- 不要在热路径中加高噪声日志
- 不要在未获 PM 批准、且未更新 NOTICE.md 的情况下引入第三方依赖
其中 IPC 契约规则在 runner-settings-ui.instructions.md 中被进一步细化为四条可操作动作:同一 PR 内更新两侧、尽量保持向后兼容、为 schema 变更添加迁移逻辑、双向通信都要测试。
提交前验证清单
AGENTS.md 的 Validation Checklist 是收尾阶段的硬性门禁,交付前逐项核对:
- [ ] 构建干净且退出码为 0
- [ ] 测试已更新并在本地通过
- [ ] 无计划外的 ABI 破坏或 schema 变更
- [ ] Runner 与 settings-ui 之间的 IPC 契约一致
- [ ] 新依赖已登记到
NOTICE.md - [ ] PR 是原子的(一个逻辑变更),并关联了对应 issue
结合 编码指南 的 PR 流程看,这条清单之后还有仓库层面的审批要求:PR 需 code owners 批准;涉及安装程序文件(installer/ 下的 WiX 工程,如 PowerToys.wxs、Common.wxi)的 PR 会被重点评审,因为安装程序直接决定发布产物。
文档索引:AGENTS.md 的延伸地图
AGENTS.md 末尾的 Documentation Index 是进入 PowerToys 开发文档体系的入口,按主题分为三组:
核心架构
- 架构总览——模块接口总览、四类模块、公共资源管理
- Runner——
PowerToys.exe的启动流程(初始化日志 → 单实例互斥 → 托盘图标 → 低级键盘钩子 → 加载模块 DLL → 消息循环) - Settings 系统——Settings v2 的实现、与 Runner 的 IPC、GPO 集成
- 模块接口——
PowertoyModuleIface各方法的契约定义
开发
构建与工具
两份按目录作用域自动生效的指令文件(Runner & Settings UI 与 Common Libraries)则构成了约束体系中最贴近代码的一层。
小结
AGENTS.md 的价值不在于介绍 PowerToys 有哪些工具,而在于把"如何在这个仓库里安全地改代码"压缩成了一套可执行的规则:用 tools/build/ 脚本构建并以退出码裁决成败、用产品前缀规律定位测试项目且规避 dotnet test、把 src/common/ 的 ABI 与 runner/settings-ui 的 IPC 契约视为最高风险区、以 NOTICE.md 登记和原子 PR 收尾。对 AI 贡献者而言,这份文档与目录作用域指令文件共同构成了一个"规则即上下文"的体系——在动手之前读懂它,能显著降低跨模块变更引入回归的概率。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00