修复 Cocos 内置桥接与客户端项目打开链路

修复 Cocos 内置插件提示词,禁止回退到项目内 MCP 扩展

移除 agc_cocos_execute 对项目写锁的无关依赖

将项目对话读取移到 blocking worker,避免客户端窗口阻塞

为 Windows 开发与发行构建默认启用 Cocos 编辑器执行能力

补充 Cocos Inspector 引导、桥接协议和客户端回归验证
This commit is contained in:
2026-09-12 23:24:45 +08:00
parent fd904ea144
commit 1be6e6756c
29 changed files with 1127 additions and 103 deletions
@@ -2,7 +2,17 @@
## 目标
目标是在用户已打开 Cocos Creator 项目时,由 AGC 识别正确的 Creator 主进程,并在进程内注入随包 JavaScript bootstrap;用户不需要在 Cocos 项目中手动安装扩展。桥接核心独立于 Tauri,随 Cocos 插件包分发,位于 `plugins/agc-cocos-editor/native/cocos-editor-bridge`。2026-09-10 已验证通过 Node 自带的运行中 Inspector 激活入口完成引导,具体见本文“Inspector 注入调研”;这条路径尚未替换当前 crate 的 DLL 实现。
用户打开 Cocos Creator 项目后,AGC 在正确的 Creator 主进程内安装随包 JavaScript bootstrap;用户无需手动安装项目扩展。核心位于 `plugins/agc-cocos-editor/native/cocos-editor-bridge`,通过 Node Inspector 引导、通过 named pipe 执行业务代码。
## 2026-09-12 冷启动连接合同
`cocos-editor-execute` 同时启用 `windows-bootstrap`:DirectProject、Runtime 和插件适配器的 execute 在发送业务代码前统一验证项目/PID,复用已就绪 pipe,否则通过目标进程的 Node Inspector 安装编译进 crate 的 bootstrap。引导只允许目标 PID 所有的回环 Inspector;再次检查 Inspector 返回的 PID、可执行文件、项目路径和 Creator 版本。Windows 调试 handler 必须位于目标可执行映像的可执行内存中,不允许任意地址、外部端口或 DLL 输入。
bootstrap 安装与业务 execute 分离,安装只发送一次,随后等待带正确身份的 `ping` 回执。`connect` 仅在该握手成功后保存连接并返回 `connected: true`。本次开启的 Inspector 在断开 WebSocket 后通过 pipe 关闭;已有 Inspector 保持原状。bootstrap 超时或握手失败不得发送业务代码;已发送业务代码的超时仍按原有 `needs-reconciliation` 合同禁止重放。
Windows 开发和发行构建均默认启用 `cocos-editor-execute`,明确的 feature 参数或开发 feature 环境覆盖仍受尊重。验收必须分别覆盖默认/启用 feature 编译、协议回归、真实 Creator 无预装桥的首次连接与后续执行;fixture 通过不等同于真实编辑器验收。
插件宿主的普通 RPC 保持 10 秒写入/响应期限;声明编辑器适配器的插件响应期限为 90 秒,写入仍限 10 秒。Cocos 插件内部期限为 85 秒,覆盖最长 15 秒引导与 60 秒命令,先于宿主截止。DirectProject 与 Runtime 继续使用自身的工具期限和不确定结果阻断。
## 边界
@@ -10,10 +20,10 @@ Cocos Creator 3.x 是 Electron/Node 编辑器,不能复用 Unity Mono 的 Core
1. 读取 Creator 主进程的 PID、父 PID、可执行文件和 `--project` 参数;Electron renderer、GPU、utility、crashpad 子进程被排除。
2. 对 PID、项目目录和 payload 做同一目标校验。项目目录必须是绝对路径、可解析目录并包含 `package.json`;Creator 版本只从 `package.json.creator.version` 读取。
3. 在启用 `windows-injection` feature 时,通过 `OpenProcess`、`VirtualAllocEx`、`WriteProcessMemory` 和 `CreateRemoteThread(LoadLibraryW)` 加载受信任 DLL。
4. 提供 `ping/status/execute` 协议、Windows pipe 客户端和 `payload/bootstrap.cjs`。native payload 只在具备受支持的 Node/V8 上下文调度时尝试送入 Creator 主进程并调用 `install(Editor)`,不写入项目扩展目录。
3. 在 `windows-bootstrap` 下,按内核 TCP 表选择目标 PID 的回环 Inspector,必要时激活目标主映像内的 Node debug handler。跨进程命名互斥锁串行化同一 PID 的引导,避免 GUI、Runner 和插件同时安装。
4. 提供 `ping/status/execute` 协议、Windows pipe 客户端和编译进 crate 的 `payload/bootstrap.cjs`。bootstrap 在 Node 主上下文调用 `install(Editor)`,不写入项目扩展目录。Rust 的 `\\?\` 盘符和 UNC 路径在进入 Node `realpathSync` 前转换为普通路径。
当前 DLL 实现仍只返回 `injected-unverified`,不能作为可交付的注入入口。它在 `windows-injection` 下构建 C++ payload 并尝试通过窗口钩子调用 V8;其中 `RequestInterrupt → run_bootstrap → Script::Run` 违反 V8 的中断回调约束,不能因编译或 DLL 加载成功而认定安全可用。`HandleScope` 的存储大小和 C++ Local/MaybeLocal 的调用约定也不能通过裸指针替代来推断。后续接入采用下述 Inspector 引导,不再依赖这条未经验证的 native 路径。
单独的 `windows-injection` DLL 实验入口仍只返回 `injected-unverified`,不能作为正式连接或验收依据。其中 `RequestInterrupt → Script::Run` 不满足 V8 中断回调约束;标准开发、发行、connect 和 execute 均使用 Inspector 引导,不启用该实验入口。
## Feature 开关
@@ -25,13 +35,14 @@ cocos-editor-bridge = { path = ".../plugins/agc-cocos-editor/native/cocos-editor
- `process-discovery`:启用 Windows Creator 主进程发现;不加载 Windows 注入 API。
- `windows-transport`:在已注入 payload 后启用本机 named pipe 的 `ping/status/execute` 命令传输。
- `windows-bootstrap`:启用 `windows-transport` 和 Windows x64 Node Inspector 引导;仅桌面目标引入 HTTP/WebSocket 和进程 API。
- `windows-injection`:隐含启用 `windows-transport`,并启用 Windows native DLL 注入实现。
AGC 或其它桌面宿主应将 `windows-injection` 作为单独的发行构建开关,服务端和非桌面构建保持 `default-features = false`。
标准 Windows 客户端使用 `windows-bootstrap`;服务端和非桌面构建保持 `default-features = false`。
AGC 不再内置 Cocos 专属 Tauri 命令。适配器 `cocos-editor` 由插件包 `plugins/agc-cocos-editor` 提供,实现通用 `EditorAdapter`(`prepare` / `inject` / `ping` / `status` / `execute` / `detect` / `connect` / `disconnect`),由宿主按 manifest 的 `adapter` 字段注册;插件入口通过 `host.rpc` 触发这些操作,宿主校验 `editor.rpc` 权限后路由到 native 模块。
Runtime 只广告一个 `cocos.editor.execute` 工具,代码输入使用当前项目根,目标 PID 由 crate 内部唯一匹配;默认命令权限为 confirm,具体运行档沿用已有 Runtime 策略。进程发现留在 crate 内部作为目标校验步骤,不建立客户端扫描服务或独立发现入口。默认 AGC 构建不启用 Cocos 集成;桌面构建需显式传 `--features cocos-editor`,命令执行需传 `--features cocos-editor-execute`,注入构建再传 `--features cocos-editor-injection`。注入只加载插件包 payload 目录里的 `cocos-editor-bridge.dll`(打包后位于 `<resource_dir>/plugins/agc-cocos-editor/native/payload`),适配器拒绝任何其它路径,避免变成任意 DLL 注入器。
Runtime 只广告 `cocos.editor.execute`,代码输入使用当前项目根,目标 PID 由 crate 内部唯一匹配;具体权限沿用已有 Runtime 策略。Windows 的标准 dev/release 脚本统一默认选择 `cocos-editor-execute`,它包含 `windows-bootstrap`;显式 feature 参数优先。纯 Cargo 默认 feature 仍为空。进程发现只用于内部目标校验,不建立客户端扫描服务,不向模型公开 PID、端口或 Inspector。
## 插件包形态
@@ -59,7 +70,7 @@ Cocos Creator 项目,并将其标记为 `cocos` 项目类型。选择目录后
## 第一阶段命令协议
DirectProject 的现役 `agc_tools` 目录通过 Windows `cocos-editor-execute` feature 注册 `agc_cocos_execute`,参数只有 `code`。客户端在 blocking worker 内调用插件 native 模块,保留项目锁和现有项目权限;当前 bridge 出现执行结果不确定后拒绝后续 execute。旧 Runtime 的对应工具名为 `cocos.editor.execute`,继续使用它已有的 pending action、权限和恢复语义;插件入口注册的同名命令走宿主 `host.rpc` → `EditorAdapter` 路径,两条路径共享同一 native 实现和不确定结果阻断语义。
DirectProject 的现役 `agc_tools` 目录通过 Windows `cocos-editor-execute` feature 注册 `agc_cocos_execute`,参数只有 `code`。客户端在 blocking worker 内调用插件 native 模块,执行前检查现有项目权限但不获取 `.agent/project.lock`;该入口只通过 Inspector / pipe 操作已打开的 Creator,文件写入工具仍独立使用项目锁。当前 bridge 出现执行结果不确定后拒绝后续 execute。旧 Runtime 的对应工具名为 `cocos.editor.execute`,继续使用它已有的 pending action、权限和恢复语义;插件入口注册的同名命令走宿主 `host.rpc` → `EditorAdapter` 路径,两条路径共享同一 native 实现和不确定结果阻断语义。
注入 payload 在目标 Creator 主进程内监听 `\\.\pipe\genarrative-cocos-editor-{pid}`,使用换行分隔的 JSON。crate 只生成三种操作:
@@ -83,11 +94,11 @@ Rust 客户端在写入前通过 `GetNamedPipeServerProcessId` 验证 pipe 属
- 注入超时不会释放仍可能被远程线程使用的内存,并返回人工核对错误,避免在不确定状态下破坏目标进程。
- 非 Windows、feature 未启用、目标不存在、身份不匹配或 payload 不合规均直接失败,不启动 Cocos、不关闭 Cocos、不修改项目文件。
## 后续接入
## 验收
下一步是在独立 crate 内实现 Inspector 引导并替换 DLL 装载入口,保留 feature 开关、项目/PID 绑定和 `ping/status/execute` 三条命令。进程发现仍只是内部目标校验,不增加客户端扫描服务。隔离验证脚本使用 Node 的 `_debugProcess`;正式 Rust 实现可直接调用同一组 Win32 API,无需附带额外 Node 运行时。源码接入、默认/启用 feature 编译和 AGC 发行包验收仍未完成。
正式引导由 Rust 调用 Win32、HTTP 和 WebSocket 完成,不额外启动 Node 助手。执行 `cargo test --manifest-path plugins/agc-cocos-editor/native/cocos-editor-bridge/Cargo.toml --features windows-bootstrap` 验证身份、路径、状态与协议。追加 `-- --ignored` 实际运行自有 Node 进程的冷启动、保留已有 Inspector 和 pipe 超时回归;fixture 进程由测试独占并回收。
当前验证:crate 全 feature 单元测试、Node bootstrap fixture、Rust 到 Node bootstrap 的真实命名管道回环(含 execute 超时不确定结果)通过;AGC feature 编译使用临时工作树与 Codex 资源替身,只属于编译检查,不代表发布包或真实 Creator 验收。当前工作区完整 AGC 检查受缺失内置 Codex CLI 阻断,TypeScript 契约测试受缺失 Vitest 阻断。
真实 Creator 使用 `cargo run --manifest-path plugins/agc-cocos-editor/native/cocos-editor-bridge/Cargo.toml --features windows-bootstrap --example creator_smoke -- <已打开的项目绝对路径>`。该入口只返回 PID、项目、版本和 Inspector 状态,验证首次执行、复用和 connect/ping,不写项目文件。初始 `before=NotReady` 才证明冷启动;后续只有 warm 成功不能替代冷启动验收。源码编译、真实 Creator smoke、发行包构建与安装包 smoke 分别报告。
## Inspector 注入调研(2026-09-10)
@@ -82,7 +82,7 @@ OpenAI 的标准模型是“Plugin 作为可安装包,组合 Skills、可选 M
宿主以已安装插件目录为 cwd 启动入口;JavaScript 入口使用系统 `node` 执行,其它入口直接执行。环境先清空,再保留 PATH、Windows 系统目录和临时目录等必要变量,并注入插件身份和协议版本;不继承客户端凭据。Windows 复用进程模块的 Job Object,Unix 使用独立进程组,停止/卸载时回收自有进程。
stdin/stdout 使用一行一个 JSON-RPC 2.0 消息,单条消息限制 2 MiB,队列和并发请求有上限;独立消息循环持续处理注册请求、事件和响应。写入与响应共享 10 秒期限,写入阻塞只终止对应运行实例。宿主 API 权限用于约束 `host.*` 调用;Runtime Plugin 是用户主动启动的本地程序,这不是 OS 沙箱。
stdin/stdout 使用一行一个 JSON-RPC 2.0 消息,单条消息限制 2 MiB,队列和并发请求有上限;独立消息循环持续处理注册请求、事件和响应。普通 RPC 写入与响应共享 10 秒期限;声明编辑器适配器的插件允许 90 秒响应期限以覆盖连接引导与编辑器执行,写入仍限 10 秒。写入阻塞只终止对应运行实例。宿主 API 权限用于约束 `host.*` 调用;Runtime Plugin 是用户主动启动的本地程序,这不是 OS 沙箱。
SDK 对插件暴露稳定的通用 API:
@@ -1,5 +1,13 @@
# AI 游戏创作智能体 App 实施计划
## 2026-09-12 已有项目打开响应性
DirectProject 工作区只恢复自身对话,不按专业 Agent 默认任务占位行批量读取旧会话或生成专业 Agent 文本回执。专业 Agent 结果加载 effect 必须以当前 Runtime 模式为边界,并在模式切换时清空旧结果。仍供开发入口使用的 `read_local_conversation` 在 blocking worker 内完整执行权限校验、会话目录解析和历史读取,避免文件访问或锁等待阻塞 Tauri 窗口线程。
DirectProject 自身的 `read_direct_project_conversation` 也必须在 blocking worker 中执行权限校验、JSONL 历史解析和消息投影,不能因为它只读取一份项目历史就保留同步 Tauri command。
验收覆盖实际 Launcher 打开已有项目:恢复 DirectProject 对话且不调用 `read_local_conversation`;后台读取仍遵守项目权限策略。原生客户端重复打开同一已有项目时验证窗口响应,IPC 测量只记录命令名和耗时,不记录会话内容。
## 图片生成恢复与测试边界
已有持久生成账本的 Provider 待执行动作恢复时,若动作省略了旧视觉 Agent 自动补齐的参数,只在 Agent、动作身份、生成种类和冻结提示词均匹配旧合同后补齐缺省参数;显式参数不得被覆盖。新请求继续按当前自由图片合同执行,不能重新引入固定视觉产物门禁。恢复复用原 operation 与幂等账本,不因默认值变化重复提交已受理请求。