架构说明见 docs/architecture.md。
YCode 是一个 Windows 桌面 AI 编程助手项目,包含:
agent.cpp: 基于 DeepSeek API 的本地命令行 Agent(36 个工具:文件/命令/搜索/Git/联网/任务/记忆/自更新/电脑控制,流式输出,会话自动恢复)。YZCodex/: 使用 Qt 6 和 C++17 编写的图形客户端(编辑器、文件树、终端、聊天、游戏开发工作区、实时预览)。YCodeEngine/: YCode 内置 C++17 游戏引擎内核,提供场景、2D 物理(盒/圆/胶囊碰撞、接触与命中事件、射线检测)、贴图绘制、音频、窗口绘制、事件总线、插件 ABI、插件加载器和游戏项目模板。build.bat、run_ycode.bat、manage_api_key.ps1: Windows 下的构建、启动和 API Key 管理脚本。
| 类别 | 工具 |
|---|---|
| 文件 | read_file write_file list_directory search_files search_content create_directory delete_file move_file get_file_info download_file |
| 命令 | execute_command(危险命令拦截 + 10 分钟超时) |
| 工程 | git_status git_diff git_commit git_push(提交/推送需授权) |
| 网络 | web_search fetch_url |
| 协作 | tasks(任务清单) memory(长期记忆) think(显式思考) |
| 自更新 | restart_agent rebuild_and_restart_ycode apply_self_changes |
| 电脑控制·查看 | screenshot screen_ocr list_windows list_processes get_cursor_position(只读,无需授权) |
| 电脑控制·操作 | mouse_click mouse_move mouse_scroll keyboard_type keyboard_press activate_window close_window start_app(需授权) |
Agent 可以直接操作你的电脑:截屏、用 Windows 内置 OCR 读取屏幕文字(返回每行文字和屏幕物理像素坐标)、移动/点击鼠标、输入文本(含中文)与快捷键、切换/关闭窗口、启动程序。
- 看屏幕:
screen_ocr是主要方式——截屏后用 Win10/11 内置 OCR(Windows.Media.Ocr,通过scripts/ycode_ocr.ps1调用,可用环境变量YCODE_OCR_SCRIPT覆盖脚本路径)识别文字并返回坐标;screenshot保存 PNG 供人查看。 - 授权:查看类工具免授权;操作类(鼠标/键盘/窗口/启动程序)需要用户授权——独立模式首次询问 y/n,托管模式请用户在聊天中发送
/allow-control(或/allow-dangerous)。每次控制操作会在控制台打印[电脑控制: ...]日志。 - 调试:
agent.exe --tool <工具名> '<json参数>'可直接执行单个工具并打印结果(无需 API Key),例如agent.exe --tool screen_ocr "{}"、agent.exe --tool mouse_click '{"x":100,"y":100}'。 - 坐标:所有坐标均为屏幕物理像素(进程已开启高 DPI 感知),与 OCR 返回的坐标一致。
- Windows
- Visual Studio 2022 C++ 工具链
- CMake 3.20+
- Qt 6.8+,MSVC 2022 64-bit
- vcpkg 安装的
libcurl
nlohmann/json 已 vendor 到仓库顶层 third_party/nlohmann/(单副本,Agent 与 YCodeEngine / YCodeSpine 共用),用于 Agent JSON 处理、YCodeEngine 场景加载与 YCodeSpine 序列化。Box2D 已 vendor 到 YCodeEngine/third_party/box2d/,用于 YCodeEngine 2D 物理。
构建脚本会自动尝试通过 vswhere 查找 Visual Studio。若你的安装路径不是默认位置,可先设置这些环境变量:
set VS_VCVARS64=C:\Path\To\VC\Auxiliary\Build\vcvars64.bat
set VCPKG_ROOT=C:\vcpkg
set VCPKG_TRIPLET=x64-windows
set QT_DIR=C:\Qt\6.8.0\msvc2022_64先在仓库根目录构建 Agent:
build.bat构建内置游戏引擎:
cd YCodeEngine
build.bat
cd ..再构建 Qt 客户端:
cd YZCodex
build.bat一键构建全部组件(agent + 引擎 + 客户端):
build_all.bat一键运行全部测试(引擎 + agent 逻辑测试 + YCodeSpine ctest):
run_tests.bat启动时客户端会自动从可执行文件位置向上查找仓库根目录。需要覆盖时可设置:
set YCODE_PROJECT_ROOT=D:\path\to\YCode一条命令跑全部(引擎 + agent 逻辑 + YCodeSpine + Qt 客户端 + 两道静态门禁):
run_tests.bat当前规模(实测):引擎 232 checks、agent 逻辑 390 checks、YCodeSpine 112 checks、Qt 客户端纯逻辑 24 用例 + 主窗口级 UI 25 用例;另有 check_scripts / check_docs 两道静态门禁与两个构建检查器自测。
各组件也能单独跑:
YCodeEngine 内置了针对 EventBus、Scene、SceneLoader、ResourceManager、PhysicsWorld2D 的单元测试,通过 CTest 运行:
cd YCodeEngine
cmake -S . -B build -A x64
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failureAgent 的安全与解析逻辑测试(危险命令识别 / 注入防护 / SSE 流式解析,需 Windows + vcpkg libcurl):
set VCPKG_INSTALLED=C:\vcpkg\installed\x64-windows
cl /EHsc /utf-8 tests\agent_logic_tests.cpp /I third_party /I %VCPKG_INSTALLED%\include /link /LIBPATH:%VCPKG_INSTALLED%\lib libcurl.lib shell32.lib /OUT:agent_tests.exe
agent_tests.exeQt 客户端有两层测试,都在 YZCodex 的 ctest 里:ycode_client_tests(纯逻辑:流式解析 / 路径解析 / 项目模板 / 配色对比度 / 命令输出解码)与 ycode_client_ui_tests(真实 MainWindow + offscreen 平台插件:窗口构造与退出、标签页生命周期与未保存确认、编辑器脏标记、底部终端)。
GitHub Actions 会在每次 push / pull request 时自动:在 Ubuntu 与 Windows 上构建 YCodeEngine 并运行测试;在 Windows 上构建 agent.exe 并运行 agent 逻辑测试;安装 Qt 6.8 后构建 YZCodex Qt 客户端并跑两套 ctest;另外单独跑脚本门禁与文档门禁(见 .github/workflows/ci.yml)。
| 门禁 | 守住什么 |
|---|---|
scripts/check_scripts.ps1 |
含非 ASCII 的 .ps1 必须带 UTF-8 BOM(否则 PowerShell 5.1 解析失败);含非 ASCII 的 .bat 必须 chcp 65001;.bat 必须是 CRLF 行尾(LF 会让 cmd.exe 错解整个脚本,报一堆与真因无关的错) |
scripts/check_docs.ps1 |
文档里反引号引用的文件与符号必须真实存在(防"文档说没实现、其实早实现了"这类过期结论) |
| 断言数下限 | 四套 C++ 测试都固定了断言数下限,防止测试被静默删除 |
scripts/check_build_locks.ps1 |
构建前检查 agent.exe / YCode.exe 是否正在运行——Windows 不允许覆盖运行中的 exe,否则只会看到看不懂的 LNK1104(自测已接入 run_tests.bat) |
scripts/check_render.ps1 / scripts/smoke_spine_demo.ps1 / scripts/smoke_agent_tools.ps1 |
渲染帧必须有实际内容(空白帧不算通过);--spine-demo 端到端加载链路必须成功;agent --tool 必须通过内容断言(中文文件名解码、read_file 逐字一致、write_file 真落盘、缺参不崩) |
仓库卫生(根目录的构建中间产物约 60 MB,agent.pdb 是崩溃栈解析依赖、不能删):
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\clean_artifacts.ps1 REM 演练
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\clean_artifacts.ps1 -Apply REM 真删自更新链冒烟(重建全部组件 + 重写桌面快捷方式,属开发者机器冒烟,不在 run_tests.bat 里):
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\smoke_self_update.ps1会话文件多进程争用冒烟(4 个 agent 同时写 agent_session.json,读者必须永远读到合法 JSON):
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\smoke_session_concurrency.ps1- 修复必须配一条会失败的回归测试,并且用
scripts/mutation_check.ps1把缺陷改回去确认这条测试真的会红 —— 永远通过的测试等于没有测试。powershell -NoProfile -ExecutionPolicy Bypass -File scripts\mutation_check.ps1 -List powershell -NoProfile -ExecutionPolicy Bypass -File scripts\mutation_check.ps1 -Mutation tab-close-no-confirm
- 取证优先:先写测试/探针证明缺陷存在,再动手改;修完把证据(命令、退出码、实际输出)记进
docs/defect-list.md。 - 编辑含中文的
.ps1之后必须补回 UTF-8 BOM(多数编辑器会丢掉),否则脚本在 PowerShell 5.1 下直接语法错误。 - 不要用
Copy-Item还原源码:它保留 mtime,MSBuild 会认为无需重编,变异产物会残留。改回内容后跑一次全量回归。 - 改了文档引用就顺手跑
scripts/check_docs.ps1:新增的文档引用会被 CI 校验,别让入口文档先漂移。 - 改动
.bat之后确认它还是 CRLF 行尾:LF 会让 cmd.exe 吞掉每行开头的字符,报出的错与真因毫无关系(本项目 7 个脚本中过招,现已由check_scripts.ps1把守)。 - 构建前若 YCode 正在运行,先关掉它:Windows 不允许链接器覆盖正在运行的
agent.exe,scripts/check_build_locks.ps1会提前给出占用者进程名与 PID。 - 跑变异验证之前先提交:
scripts/mutation_check.ps1会用git checkout还原现场,未提交的修复会被一起还原(脚本已拒绝在有未提交改动的文件上运行——别手工绕过它)。 - 路径一律 UTF-8,碰 Win32 就转宽字符:窄字符 API 按 ANSI 解释路径,中文路径会"文件明明存在却打不开"(#61/#62 的实际教训,agent/引擎/spine 三套测试都有中文路径用例钉着)。
运行前需要设置 DeepSeek API Key:
set DEEPSEEK_API_KEY=your-api-key-here可选环境变量(不设置则用默认值):
YCODE_API_URL:API 端点地址,默认https://api.deepseek.com/v1/chat/completions(兼容 OpenAI 格式的端点均可)。YCODE_MODEL:模型名,默认deepseek-v4-pro。
set YCODE_MODEL=deepseek-chat也可以使用:
.\manage_api_key.ps1客户端设置窗口中输入的 API Key 只在当前运行会话中使用,不会写入 Qt 设置文件;重启后建议从 DEEPSEEK_API_KEY 环境变量读取。不要把真实 API Key、会话文件或本地构建产物提交到仓库。
Agent 的 execute_command 与 delete_file 工具内置了破坏性操作拦截:
execute_command执行del/erase/rmdir/rd/rm/format/diskpart/shutdown/taskkill/reg/setx/bcdedit/takeown/icacls/cacls以及 PowerShell 的Remove-Item等命令前会被拦截。delete_file删除文件或目录前需要确认。
授权方式:
- 独立模式(终端直接运行
agent.exe):拦截时交互输入y确认。 - 托管模式(通过 YCode 客户端):在聊天中发送
/allow-dangerous授权,/deny-dangerous撤销授权。
search_files / search_content / list_directory 等工具会拒绝含 shell 元字符的参数,避免命令注入。
更多安全细节见 SECURITY.md。
YCode 已合并原 YiyangzaiEngine 方向,以后游戏开发能力归入同一个 YCode 项目。
Qt 客户端菜单 游戏开发 提供:
- 新建 YCode 游戏项目:生成 CMake 项目并链接内置
YCodeEngine。 - 打开 YCode 游戏项目:把文件树和终端切换到独立游戏工作区。
- 构建当前游戏项目:运行 CMake configure/build。
- 运行当前游戏项目:启动已构建的游戏可执行文件。
- 实时预览:一键构建并运行游戏,修改
src/、scenes/或CMakeLists.txt后自动重建并重启(热重载循环)。 - 构建 YCode Engine:在底部终端面板运行
YCodeEngine/build.bat。 - 打开引擎源码目录:进入内置引擎内核源码。
- 启动 AI 游戏开发模式:把 Agent 切换到围绕 YCodeEngine 的游戏开发上下文。
YCode 内部区分三个路径:
YCode root: YCode 自身源码根目录,用于 Agent、自更新和 Git 操作。YCodeEngine root: 内置游戏引擎源码目录。workspace root: 当前打开的用户游戏项目目录,用于文件树、终端、构建和运行。
YCodeEngine 当前包含:
EventBus: 发布/订阅事件总线。Scene/Entity/Transform2D: 轻量场景和游戏对象基础层,支持按属性检索实体(findEntitiesByProperty)。PhysicsWorld2D/BoxCollider2D/CircleCollider2D/CapsuleCollider2D: 基于 Box2D 的 2D 刚体物理封装,支持盒/圆/胶囊碰撞体、接触与命中事件回调、射线检测。ResourceManager/SceneLoader: 读取项目资源,并从 JSON 场景文件生成实体与physics2D刚体声明(box/circle/capsule)。Texture2D/AudioPlayer: 贴图加载绘制(GDI+,PNG/BMP/JPG)与 WAV 音频播放(可循环)。PluginLoader: 跨平台动态插件加载器。plugin.h: 稳定 C ABI 插件接口。Engine: 初始化、tick、shutdown 生命周期。Window/Key/Canvas2D: 最小窗口、键盘输入和 2D 绘制封装(矩形与贴图);Windows 下由 Win32/GDI 实现。
YCode Agent 修改自身源码、Qt 客户端源码、YCodeEngine、YCodeSpine、启动脚本或快捷方式配置后,可以调用 apply_self_changes 工具按变更位置自动选择热加载、重建或重启。客户端退出后,ycode_self_update.bat 会依次重建 agent.exe、YCode Engine、YCodeSpine、Qt 客户端(YCode.exe),更新桌面快捷方式,然后重新启动 YCode。
只需要重启 Agent 进程时,调用 restart_agent 即可。
源码部署者也可以在 YCode 菜单中选择 帮助 -> 检查更新...。YCode 会对比本地 Git 版本和 origin/main,发现新版本后执行 git pull --ff-only origin main,然后走同一套自更新流程。请用 git clone 部署项目;直接下载 ZIP 的目录没有 Git 元数据,无法自动拉取最新版。
本项目使用 MIT License,详见 LICENSE。