From 6ef64c3bcf0daa73d0147ad2ecf2a4abf77c7ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 24 Sep 2026 13:05:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=20design=5Fdoc=20=E7=9A=84=E5=88=87?= =?UTF-8?q?=E5=88=86=E6=A8=A1=E5=9D=97=E6=8F=90=E5=8D=87=E4=B8=BA=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E6=A8=A1=E5=9D=97=20=E6=8A=8A=20steps/separate.rs=20?= =?UTF-8?q?=E6=8F=90=E5=8D=87=E4=B8=BA=20steps/separate/mod.rs=EF=BC=8C?= =?UTF-8?q?=E5=8F=AA=E4=BF=9D=E7=95=99=E7=BA=AF=20State=20=E5=8F=98?= =?UTF-8?q?=E6=8D=A2=20=E6=8A=8A=20design=5Fdoc/cut=5Fimages.rs=20?= =?UTF-8?q?=E7=A7=BB=E5=88=B0=20steps/separate/cut=5Fimages.rs=EF=BC=8C?= =?UTF-8?q?=E4=B8=8E=E5=AE=83=E6=9C=8D=E5=8A=A1=E7=9A=84=E5=88=87=E5=88=86?= =?UTF-8?q?=E6=AD=A5=E9=AA=A4=E5=90=8C=E5=B1=82=20=E6=8A=8A=20normalize=5F?= =?UTF-8?q?cut=5Fimage=5Fpath=20=E4=BB=8E=20steps/mod.rs=20=E4=B8=8B?= =?UTF-8?q?=E6=B2=89=E5=88=B0=20steps/separate/mod.rs=EF=BC=8C=E7=B4=A7?= =?UTF-8?q?=E9=82=BB=E4=B8=A4=E4=B8=AA=E4=BD=BF=E7=94=A8=E7=82=B9=20run=5F?= =?UTF-8?q?workflow.rs=20=E6=94=B9=E4=BB=8E=20steps::separate=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=AF=BC=E5=85=A5=E5=88=87=E5=88=86=E5=85=A5=E5=8F=A3?= =?UTF-8?q?=E4=B8=8E=E7=99=BB=E8=AE=B0=E5=85=A5=E5=8F=A3=20=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E4=B8=A4=E4=BB=BD=20UI=20=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E6=8A=80=E6=9C=AF=E6=96=B9=E6=A1=88=E7=9A=84=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E4=B8=8E=E4=BB=A3=E7=A0=81=E5=9C=B0=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src-tauri/src/ui_editor/design_doc/mod.rs | 1 - .../src/ui_editor/design_doc/run_workflow.rs | 3 +-- .../src/ui_editor/design_doc/steps/mod.rs | 5 ---- .../{ => steps/separate}/cut_images.rs | 7 +++--- .../steps/{separate.rs => separate/mod.rs} | 23 ++++++++++++++----- ...œ¯方案】UI编辑器Agent工具化重写-2026-09-23.md | 7 +++--- ...–¹案】UI编辑器代码地图与模块职责-2026-09-23.md | 2 +- 7 files changed, 27 insertions(+), 21 deletions(-) rename apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/{ => steps/separate}/cut_images.rs (95%) rename apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/{separate.rs => separate/mod.rs} (94%) diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/mod.rs index e65f7d914..bc1a69b82 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/mod.rs @@ -1,6 +1,5 @@ mod checkpoint; mod creation; -mod cut_images; mod run_workflow; mod steps; diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/run_workflow.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/run_workflow.rs index d2d003667..b698e4c7f 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/run_workflow.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/run_workflow.rs @@ -9,9 +9,8 @@ use super::checkpoint::{ checkpoint_timestamp, CheckpointDocument, CheckpointLine, RoundOutcome, WorkflowLog, WorkflowRound, }; -use super::cut_images::register_cut_image_sprites; use super::steps::recognize::apply_recognition; -use super::steps::separate::{add_sprite_assets, apply_separation}; +use super::steps::separate::{add_sprite_assets, apply_separation, register_cut_image_sprites}; use crate::enforce_project_permission_policy; use crate::ui_editor::commands::separation::finalize_separation; use crate::ui_editor::commands::{ diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/mod.rs index 6525ad603..7ef20d8a8 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/mod.rs @@ -1,7 +1,2 @@ pub(crate) mod recognize; pub(crate) mod separate; - -/// 镜像前端 `normalizeProjectRelativePath`:只做分隔符与根斜杠归一,不做路径校验。 -pub(crate) fn normalize_cut_image_path(path: &str) -> String { - path.replace('\\', "/").trim_start_matches('/').to_string() -} diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/cut_images.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/cut_images.rs similarity index 95% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/cut_images.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/cut_images.rs index af64b1f9a..28997580e 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/cut_images.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/cut_images.rs @@ -1,10 +1,11 @@ -//! 登记自动切分产出的图片并构造切分素材。镜像前端 `useUiEditorPage.ts` 的 -//! `import_local_project_image_assets` → `prepareSpriteAssetBatch` 两段。 +//! `separate` sub-step 的资源侧:登记自动切分产出的图片并构造切分素材。镜像前端 +//! `useUiEditorPage.ts` 的 `import_local_project_image_assets` → +//! `prepareSpriteAssetBatch` 两段。 //! //! 登记按路径复用已有 manifest 条目,所以重放不会重复登记;登记失败的路径只回报 //! 说明,不回滚已经登记成功的资源。 -use super::steps::normalize_cut_image_path; +use super::normalize_cut_image_path; use crate::import_local_project_assets_for_agent; use crate::ui_editor::commands::SeparationDTO; use crate::ui_editor::resource::sprite::SpriteAsset; diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/mod.rs similarity index 94% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/mod.rs index 8eaebffad..bde0c7631 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/mod.rs @@ -1,9 +1,15 @@ -//! 自动切分结果落到 State。镜像前端 `useUiEditorPage.ts` 的切分回填循环、 -//! `features/ui-editor/useUiEditorState.ts` 的 `addSpriteAssetsToState` 与 -//! `features/ui-editor/separationStatus.ts` 的问题状态写回。 +//! `separate` sub-step 的全部落地逻辑,按有无副作用分两个文件: //! -//! 切分图片的登记不是这里的事:调用方先按 `bound_nodes` 的路径登记资源并构造 -//! `SpriteAsset`,本模块只做纯 State 变换。 +//! - `cut_images`:按 `bound_nodes` 的路径登记图片并构造 `SpriteAsset`,带项目 +//! manifest 副作用。 +//! - 本文件:登记结果与 `SeparationDTO` 到 State 的纯变换,镜像前端 +//! `useUiEditorPage.ts` 的切分回填循环、`features/ui-editor/useUiEditorState.ts` +//! 的 `addSpriteAssetsToState` 与 `features/ui-editor/separationStatus.ts` 的问题 +//! 状态写回。 + +mod cut_images; + +pub(crate) use cut_images::{register_cut_image_sprites, CutImageSprites}; use crate::ui_editor::commands::separation::{BoundNode, ProblematicNode}; use crate::ui_editor::commands::SeparationDTO; @@ -14,6 +20,11 @@ use crate::ui_editor::state::State; use crate::ui_editor::utils::SpriteAssetId; use std::collections::HashMap; +/// 镜像前端 `normalizeProjectRelativePath`:只做分隔符与根斜杠归一,不做路径校验。 +pub(crate) fn normalize_cut_image_path(path: &str) -> String { + path.replace('\\', "/").trim_start_matches('/').to_string() +} + /// 把切分产出的素材合入 State。同一 id 已有不同内容时报错,镜像 /// `addSpriteAssetsToState` 的 `duplicate` 与资源校验。 pub(crate) fn add_sprite_assets(state: &State, sprites: &[SpriteAsset]) -> Result { @@ -121,7 +132,7 @@ fn backfill_bound_node( sprite_by_path: &HashMap, errors: &mut Vec, ) { - let path = super::normalize_cut_image_path(&bound.cut_image_path); + let path = normalize_cut_image_path(&bound.cut_image_path); let Some(sprite) = sprite_by_path.get(&path) else { errors.push(format!( "节点 {} 缺少已登记的自动切分素材图片:{path}", diff --git a/docs/technical/【技术方案】UI编辑器Agent工具化重写-2026-09-23.md b/docs/technical/【技术方案】UI编辑器Agent工具化重写-2026-09-23.md index bba8d71b0..c7111cdfc 100644 --- a/docs/technical/【技术方案】UI编辑器Agent工具化重写-2026-09-23.md +++ b/docs/technical/【技术方案】UI编辑器Agent工具化重写-2026-09-23.md @@ -69,11 +69,12 @@ src/ui_editor/design_doc/ ├─ mod.rs 模块声明与三个工具的对外导出 ├─ creation.rs from-images:登记图片、建文档、manifest 注册、命名取号 ├─ checkpoint.rs JSONL 追加、读取、轮次判定 -├─ cut_images.rs 切图图片登记与 SpriteAsset 构造 ├─ run_workflow.rs recognize → separate → write-back 编排与恢复 ├─ steps/ │ ├─ recognize.rs 识别 DTO 落 State -│ └─ separate.rs 切分 DTO 落 State(回填、清状态、写 NeedReview) +│ └─ separate/ +│ ├─ mod.rs 切分 DTO 落 State(回填、清状态、写 NeedReview) +│ └─ cut_images.rs 切图图片登记与 SpriteAsset 构造 └─ test_support.rs design_doc 单测共用夹具 src/agent/runtime_tools/ui_design_doc.rs 工具参数解析与 Runtime 侧调用 ``` @@ -97,7 +98,7 @@ src/agent/runtime_tools/ui_design_doc.rs 工具参数解析与 Runtime 侧调 2. 术语与 ADR:`CONTEXT.md` 四个词条、检查点 ADR。 3. 本文档。 4. 提示词目录模块 + 两个无状态工具(`from-images`、`into-js`)。 -5. `run-workflow` 与 JSONL 检查点(`design_doc/{checkpoint,cut_images,run_workflow}.rs` + `steps/`)。 +5. `run-workflow` 与 JSONL 检查点(`design_doc/{checkpoint,run_workflow}.rs` + `steps/separate/`)。 6. 前端收口:删 `uiDesignResourceBridge` 的 `ui-workflow.*` 优先级与 `project-development` 的自动打开分支。 7. 三个工具注册进 Runtime(`agent_native_tools`、`runtime_tools/ui_design_doc.rs`、可执行工具目录、并行账本映射、design-foundation 白名单)。 diff --git a/docs/technical/【技术方案】UI编辑器代码地图与模块职责-2026-09-23.md b/docs/technical/【技术方案】UI编辑器代码地图与模块职责-2026-09-23.md index 8373cd104..98241f0d0 100644 --- a/docs/technical/【技术方案】UI编辑器代码地图与模块职责-2026-09-23.md +++ b/docs/technical/【技术方案】UI编辑器代码地图与模块职责-2026-09-23.md @@ -27,7 +27,7 @@ view/ui-editor (页面/组件) | `component/` | 组件枚举 `Component::{Image, Text}`、`NodeComponent`(LLM 工具载荷的 `PureNode`/`WithComponent` 判别式) | | `resource/` | 界面图(`path` / `pixel_size` / `pixels_per_unit`)、sprite(含 `SpriteBorder` 九宫格)、字体(格式/媒体类型/CSS format)资源描述 | | `persistence.rs` | 文档读写、`revision` 乐观并发保存、领域校验(重复 ID、树/资源引用、组件状态)、代码生成写盘 | -| `design_doc/` | Agent 工具链路:`creation.rs` 用一至四张设计图新建文档(登记未登记图片、按 `ui/UI 设计 N.json` 取号、持项目写锁装 revision 0、失败回滚)、`checkpoint.rs` JSONL 检查点日志、`cut_images.rs` 切图登记与 `SpriteAsset` 构造、`run_workflow.rs` 三步编排与崩溃恢复、`steps/` 纯 State 镜像步骤 | +| `design_doc/` | Agent 工具链路:`creation.rs` 用一至四张设计图新建文档(登记未登记图片、按 `ui/UI 设计 N.json` 取号、持项目写锁装 revision 0、失败回滚)、`checkpoint.rs` JSONL 检查点日志、`run_workflow.rs` 三步编排与崩溃恢复、`steps/` 逐步落 State(`recognize.rs` 识别、`separate/` 切分:`cut_images.rs` 登记切图与 `SpriteAsset` 构造、`mod.rs` 回填与问题状态) | | `html_renderer/` | 由 State 生成 HTML 片段与 JS(maud + 布局/组件 CSS 映射),供预览与 `ui/generated-*.js` | | `commands/` | LLM 工具链:`recognition`(结构识别)、`separation/`(自动切分素材)、`utils.rs`(LLM 请求、重试、`required_tool_arguments`) | | `commands/separation/` | 切分批处理、截图/预切、sidecar 恢复(inspect / finalize / discard)、patch 回写 |