# agc-cocos-editor Cocos Creator 编辑器桥接插件。用户侧看到的是一个普通 AGC 插件:插件生命周期、UI、 RPC、权限和能力注册全部由通用宿主负责,只有“如何连接 Cocos Creator”属于本插件。 它同时是 AGC 的**内置插件**:随客户端分发、不能卸载。只有当前受控目录被识别为 Cocos Creator 项目时才会暴露插件、面板和工具;切换到其它项目会立即停止插件实例并隐藏对应能力。 用户在运行时设置里只能切换“是否可用”,禁用后插件不能启动,`agc_cocos_execute` 与全部 `cocos_*` Agent 工具也会从 Agent 工具列表、工具策略快照和上下文里消失;重新启用后仍需 满足当前项目是 Cocos 的门禁。 Cocos Creator 项目目录中的 `extensions/`、`package.json` 插件声明或第三方 MCP 包不属于 AGC Cocos 桥接来源。Agent 处理 Cocos 请求时只使用客户端登记的 `agc-cocos-editor` 内置插件;内置工具不可用时报告客户端插件状态,不扫描或要求用户启动项目内 MCP 扩展。 ```text plugin.json Agent Plugins 清单 + AGC Runtime 扩展 src/entry.mjs 运行时入口(注册命令 / 能力 / 面板,转发 host.rpc) src/cocos-editor-adapter.mjs 通用请求 → Cocos 适配器请求的翻译与入参校验 src/operations/ 36 个操作的 schema、主进程/场景/预览实现 src/cocos-editor-operations.mjs 插件侧构造器,与 native 编译内置代码一致 panels/cocos-editor.html 自包含面板 native/cocos-editor-bridge/ 插件自带 native 模块(进程发现、pipe 协议、注入) ``` ## Runtime 契约 | 项 | 值 | | --------- | ---------------------------------------------------------------------------------- | | 协议 | `agc.plugin.v1`(stdio 行分隔 JSON-RPC 2.0) | | 适配器 id | `cocos-editor` | | 命令 | `cocos.editor.execute`(`{ code }`) | | 操作命令 | `cocos.editor.operation`(`{ operation: "cocos_*", args: {...} }`) | | Agent MCP | `agc_cocos_execute` + `catalog.json` 的全部 36 个 `cocos_*` 工具 | | 能力 | `cocos.editor.connection`(`{ operation, processId?, projectPath?, timeoutMs? }`) | | 面板 | `cocos-editor`(`panels/cocos-editor.html`,sidebar) | `operation` 取值为 `detect`、`connect`、`disconnect`、`prepare`、`ping`、`status`、 `execute`、`inject`,与 native 适配器的 `COCOS_EDITOR_RPC_METHODS` 一一对应; `src/entry.test.mjs` 会校验两边不会漂移。 ## Agent 能力与 JavaScript 用法 Agent 通过 `agc_cocos_execute` 注入 JavaScript 函数体;插件只负责把代码安全地送进 已校验的 Creator 主进程,不在项目目录写入扩展。常用的 Creator 3.8.8 操作如下: 客户端还注册了 `cocos.editor.operation` 操作命令。它把第三方 MCP 的 36 个稳定操作名 暴露给宿主;DirectProject 的 `agc_tools` 同时从该目录注册 36 个独立工具。两者使用相同 schema 和内置 JS,并在执行时走同一个受控 `editor.execute` 通道: ```text cocos_ping / cocos_get_capabilities / cocos_get_project_info cocos_get_current_scene_meta / cocos_get_log_tail / cocos_diagnose cocos_get_build_diagnostics / cocos_list_assets / cocos_get_prefab_info cocos_get_hierarchy / cocos_search_nodes / cocos_inspect_node cocos_set_node_active / cocos_set_node_transform / cocos_set_node_name cocos_create_node / cocos_delete_node / cocos_reparent_node cocos_set_node_sibling_index / cocos_duplicate_node / cocos_instantiate_prefab cocos_set_component_property / cocos_add_component / cocos_remove_component cocos_create_ui_shape / cocos_create_ui_label / cocos_create_ui_sprite cocos_create_ui_button / cocos_apply_ui_spec cocos_preview_debug_start / cocos_preview_debug_read / cocos_preview_debug_capture cocos_preview_debug_stop / cocos_save_scene / cocos_editor_undo / cocos_mcp_undo_last ``` 场景操作由主进程定位唯一 Scene WebView,将随包 JS 加载到该运行时,调用 Creator 场景管理器 与 `require('cc')` 的引擎 API;保存和资源导入使用官方 `Editor.Message`。不安装项目扩展。 `cocos_get_hierarchy` 返回 `{ sceneUuid, tree, truncated }`,节点含 `nid/uuid`;写工具的 `nid/parentNid/childNid` 均支持查询得到的 NID 或 UUID。`cocos_inspect_node` 返回带真实索引的 组件属性。场景切换后旧 NID 不复用,需重新查询。 批量 UI 支持 container/shape/label/sprite/button、Layout、Widget、九宫格,限制为 64 个节点和 12 层(按钮文字计入节点数)。Shape 使用 AssetDB 导入的 `assets/agc-ui-shapes/` PNG 模板; 它是可复用资产缓存,撤销节点不会删除模板。`save` 缺省 true,运行态回读和保存失败都会明确报告。 首次保存缺省创建 `assets/Main.scene`,也可通过 `cocos_save_scene { path }` 指定新路径。 编辑事务保留前后序列化快照(单份 2 MiB、最多 32 次、合计 16 MiB)。MCP 撤销只在当前场景仍 等于对应后状态时恢复,已保存事务的撤销同步保存。代码更新、Creator 重启和切换场景不保留撤销历史。 `cocos_editor_undo` 使用官方 undo;最近操作属于本插件时额外核对恢复结果。 预览在插件自有、无 Node 权限的独立 Chromium 窗口运行,只接收当前 Creator 项目预览端口的 loopback URL。采集 console、JS 异常、网络失败及 HTTP 错误,截图作为 MCP PNG image 返回; stop 只关闭该窗口。日志只读项目 `temp/logs/`、`temp/builder/`、`build/` 下的日志文件。 所有操作仍受项目身份校验、单执行队列和不确定结果禁止重放约束。实现按 Creator 3.8.8 核验; 其它 3.x 版本中缺少对应运行时 API 时会报告错误,不虚报能力已执行。 | 目的 | 示例 | | --- | --- | | 读取场景树 | `return await Editor.Message.request('scene', 'query-node-tree');` | | 读取节点 | `return await Editor.Message.request('scene', 'query-node', uuid);` | | 修改属性 | 优先 `cocos_set_component_property`;原始 `scene/set-property` 需要从 query-node 克隆并修改属性 dump | | 添加组件 | `return await Editor.Message.request('scene', 'create-component', { uuid, component });` | | 执行场景脚本 | `return await Editor.Message.request('scene', 'execute-scene-script', { name, method, args });` | | 查询资源 | `return await Editor.Message.request('asset-db', 'query-asset-info', uuid);` | 先执行只读查询取得真实节点 UUID、组件标识和属性路径,再执行单个修改并回读校验。 不要猜 UUID、组件 CID 或属性路径;需要保存、删除或批量修改时,先确认对应 Creator 消息协议,再通过同一入口逐步执行。 execute 不接受并发积压。结果不确定时返回 `needs-reconciliation` 与 `retryAllowed: false` 并阻止后续发送;native 适配器的阻断不会被 disconnect 或插件进程重载清除。请先核对编辑器状态,再重启客户端恢复。 ## 项目上下文 插件从宿主获得当前受控项目路径: - 注册 `host.events.subscribe { type: 'project.changed' }` 时,宿主在响应里返回当前 `projectPath`。 - 之后宿主设置项目时推送 `project.changed` 事件,payload 带 `projectPath`。 插件不缓存凭据;资源与日志只在当前受控项目内有界读取。编辑器操作经 `host.rpc` 交给 native 适配器, 由适配器做 PID / 项目 / 版本校验。 ## Native 模块 `native/cocos-editor-bridge` 是从 AGC 服务端源码树移入本插件包的独立 crate,实现 `editor-adapter-api::EditorAdapter`: - `process-discovery`:只把 `CocosCreator.exe` 主进程的 PID、`--project` 和 Creator 版本绑定起来,排除 Electron 子进程。 - `windows-transport`:注入后通过 named pipe 提供 `ping/status/execute`,执行结果 不确定时返回 `ExecutionUncertain` 并禁止自动重放。 - `windows-injection`:随包 DLL 的 Windows 注入实现,默认关闭。 - `windows-bootstrap`:在首次 connect/execute 前经目标 PID 的 Node Inspector 安装内置 bootstrap,验证 pipe 握手并关闭本次开启的 Inspector;保留已有调试会话。 AGC 客户端当前在编译期链接本 crate(Cargo path 依赖),由通用宿主按 manifest 的 `adapter` 字段注册;宿主源码里没有 Cocos 进程名、注入或 Editor.Message 逻辑。 ## 本地验证 ```bash cargo test --manifest-path plugins/agc-cocos-editor/native/cocos-editor-bridge/Cargo.toml cargo test --manifest-path plugins/agc-cocos-editor/native/cocos-editor-bridge/Cargo.toml --features windows-bootstrap -- --include-ignored npm test --prefix plugins/agc-cocos-editor ``` 真实 Creator 验收(注入、Inspector 引导、非空场景读写)仍按 `docs/technical/【技术方案】AGC Cocos Creator 编辑器桥接模块-2026-09-09.md` 单独执行。