Initial TrueGrowth source import

This commit is contained in:
2026-07-07 09:36:36 +08:00
commit 3b6781d695
2283 changed files with 691996 additions and 0 deletions

View File

@@ -0,0 +1,733 @@
## Context
当前生图反馈主要依赖 `WorkZone`
- 提交时在画布中插入固定尺寸的卡片
- 卡片内部展示标题、状态、步骤列表与删除/隐藏按钮
- 自动插入完成后再删除卡片
这种设计适合表达工作流存在,但不适合表达“图片对象即将落入画布”的过程。问题主要有:
- 过程对象抢占画布注意力,打断创作空间
- 固定卡片高度在单图场景下留白过多
- 生图反馈的核心不是步骤明细,而是“会落在哪、会长成什么比例、现在到了哪个阶段”
- 当前状态同步分散在 `AIInputBar``useWorkflowSubmission``useTaskWorkflowSync``useAutoInsertToCanvas` 中,后续继续在 `WorkZone` 上叠交互会进一步放大复杂度
## Goals
- 让生图过程在画布中表现为“对象正在诞生”,而非“任务卡片正在执行”
- 优先利用提交时即可获得的几何信息,建立可信的一致性反馈
- 在结果未返回前,通过锚点表达位置、比例与状态,而不伪装已知内容
- 保留失败重试、详情追踪和恢复能力
- 首版只覆盖 `image` 类型任务,不改造其他任务类型
## Non-Goals
- 不在首版统一视频、音频、文本、流程图等其他任务反馈
- 不在首版默认引入强品牌化的传送门或粒子特效
- 不依赖结果侧稳定返回 `width/height` 元数据来决定首版锚点几何
## Decision
### 1. 生图改为 `Generation Anchor`
生图提交后,系统在预期插入位置创建轻量锚点,而不是默认创建大面积 `WorkZone` 卡片。
锚点的职责只有四类:
- 表达“已受理”
- 表达“预期落点”
- 表达“预期几何外壳”
- 表达“当前阶段 + 主动作”
步骤详情、历史记录、错误细节默认不在画布中展开。
### 2. 三档几何策略
#### `Frame-first`
若提交时已存在:
- `targetFrameId`
- `targetFrameDimensions`
则锚点直接继承 Frame 外壳,在该容器内部完成生成、显影与结果接管。
#### `Size-first`
若不存在 Frame但已存在明确的 `size`,则使用 `size` 作为锚点外壳的比例来源。该策略与当前插入逻辑一致,因为首版插入已经依赖 `parseSizeToPixels(size)` 进行几何推导。
#### `Ghost-anchor`
若既无 Frame 又无稳定比例信息,则仅创建轻量出生点锚点,不伪装为完整图片框。待结果返回后,再从出生点平滑 morph 为真实图片。
### 3. 用户态状态机
生图锚点统一使用以下用户态:
- `submitted`
- `queued`
- `generating`
- `developing`
- `inserting`
- `completed`
- `failed`
状态解释:
- `submitted`: 用户点击后,任务已创建,输入条需要立即确认
- `queued`: 请求已受理但尚未进入明显执行
- `generating`: 模型正在生成结果
- `developing`: 结果已返回,正在准备插入或执行轻显影
- `inserting`: 正在把真实图片插入画布并与锚点连续过渡
- `completed`: 图片已稳定落位,锚点将短暂停留后淡出
- `failed`: 保留失败节点,允许重试或查看详情
#### 用户态文案规范
首版默认文案应保持“对象正在诞生”的语义,而不是暴露底层工作流术语:
- `submitted`: 已提交,等待执行
- `queued`: 请求已受理,等待执行
- `generating`: 图片正在生成,请稍候
- `developing`: 结果已返回,正在准备显影
- `inserting`: 正在放入画布
- `completed`: 图片已稳定落位
- `failed`: 生成失败,请重试
允许在特定交互瞬间使用更细的提示文案,例如:
- 主线程回退时:请求已受理,正在转入本地执行
- 用户点击重试时:正在重新触发,请稍候
但这些文案必须仍然映射回上述统一用户态,不允许新增平行状态名。
### 4. 详情层收敛
锚点默认只展示:
- 当前阶段文案
- 轻进度
- 一个主动作
详细步骤、错误明细、历史版本应进入任务详情层,而不是在画布中展开完整 `WorkZone`
#### 职责边界
`Generation Anchor` 负责:
- 受理确认
- 预期落点
- 预期几何外壳
- 当前阶段
- 轻进度
- 当前上下文中的恢复动作
任务详情层负责:
- 完整步骤列表
- 错误详情与调试信息
- 历史记录与重试历史
- 批量结果管理
- 非画布主路径的任务追踪
画布中的锚点不应默认展开完整步骤列表,也不应承载需要持续滚动阅读的信息。
### 5. 渐进迁移
首版仅对 `image` 类型启用 `Generation Anchor`
- `image`:默认启用 Anchor
- 其他类型:继续使用现有 `WorkZone` 或现有任务反馈
这样能避免一次性改造所有任务语义,也能降低对现有任务同步链路的影响。
## State Mapping
首版建议由一个统一的 view model 负责把现有信号映射成锚点状态:
- 提交态信号:
- `expectedInsertPosition`
- `targetFrameId`
- `targetFrameDimensions`
- `size`
- 任务执行信号:
- `Task.status`
- `Task.progress`
- `Task.executionPhase`
- 后处理信号:
- `workflowCompletionService`
- 自动插入开始/完成事件
映射规则示例:
- 任务创建后但未进入稳定进度更新:`submitted`
- `TaskExecutionPhase.SUBMITTING`: `queued`
- `Task.progress` 持续推进:`generating`
- 任务已成功但后处理未完成:`developing`
- 图片正在落入画布:`inserting`
- 后处理完成并已插入:`completed`
- 任意执行或插入失败:`failed`
## UI Model
建议新增面向 UI 的锚点模型:
- `anchorType`: `frame | ratio | ghost | stack`
- `phase`
- `position`
- `dimensions`
- `progress`
- `title`
- `subtitle`
- `primaryAction`
- `secondaryAction`
- `transitionMode`
该模型只表达画布中锚点需要展示什么,不直接持有完整工作流对象。
## Integration Notes
- 输入条负责第一层反馈:点击后立即显示“已提交”
- 画布锚点负责第二层反馈:表达位置、比例、阶段
- 任务详情层负责第三层反馈:步骤明细、失败原因、历史记录
- 现有 `WorkZone` 首版可作为非生图路径保留,不与生图锚点混用
## Architecture Alignment
### Runtime Topology
首版推荐的运行时拓扑如下:
1. `AIInputBar`
- 负责生图提交入口
- 产出提交期几何上下文
- 调用 `ImageGenerationAnchorTransforms.insertAnchor`
- 触发输入条“已提交”反馈
2. `with-image-generation-anchor`
- 负责 `generation-anchor` 元素的画布承载与渲染
- 管理 anchor 元素的插入、更新、删除与命中
3. `useImageGenerationAnchorController`
- 负责把原始信号映射为 UI model
- 不直接写画布,只输出“应该显示什么”
4. `useImageGenerationAnchorSync`
- 负责监听任务与后处理事件
- 负责按 `taskId / workflowId` 找到 anchor
- 负责把 controller 产出的状态回写到画布元素
5. `useAutoInsertToCanvas`
- 负责真实图片落图
- 负责驱动 `developing -> inserting -> completed`
- 负责在插入完成后让 anchor 收口
6. `WorkZone`
- 生图首版不再作为默认反馈
- 仅保留给非生图任务与旧路径兼容
### Ownership Matrix
#### `AIInputBar`
拥有:
- `generationType === 'image'` 分流决策
- `expectedInsertPosition`
- `targetFrameId`
- `targetFrameDimensions`
- `requestedSize`
- `currentImageAnchorIdRef`
- 输入条首段反馈
不拥有:
- anchor 运行中阶段推进
- 刷新恢复
- 自动插入后的收口
- 全局任务同步
#### `Drawnix`
拥有:
- 注册 `with-image-generation-anchor`
- 挂载 `useImageGenerationAnchorSync`
- 在 board ready / task storage ready 后进行恢复协调
不拥有:
- 提交期几何推导
- 真实插入行为本身
#### `useImageGenerationAnchorSync`
拥有:
-`taskQueueService``workflowCompletionService`、插入事件读取状态
- 根据 `taskId / workflowId` 查找 anchor
- 调用 transforms 更新 anchor 元素
不拥有:
- 具体 JSX 渲染
- 业务提交入口
#### `useAutoInsertToCanvas`
拥有:
- 结果 URL 到画布对象的真实插入
- 插入前后的 anchor 状态推进
- 插入失败到失败态的回写
不拥有:
- anchor 初次创建
- 输入条即时反馈
### Data Contracts
#### Submission Context
建议定义一个单独的提交期上下文对象,避免多个模块重复各自取值:
- `workflowId`
- `taskIds`
- `expectedInsertPosition`
- `targetFrameId`
- `targetFrameDimensions`
- `requestedSize`
- `prompt`
- `count`
- `createdAt`
来源:
- `AIInputBar`
用途:
- 创建 anchor
- 恢复定位
- 插入时兜底寻找几何上下文
#### Anchor View Model
建议定义一个稳定的 UI model避免 JSX 直接依赖任务/工作流对象:
- `anchorType`
- `phase`
- `progressMode: 'indeterminate' | 'percent' | 'steps'`
- `progressValue`
- `title`
- `subtitle`
- `showFrameShell`
- `showRatioShell`
- `showGhostPulse`
- `canRetry`
- `canOpenDetails`
- `transitionMode: 'fade' | 'morph' | 'frame-fill' | 'stack-expand'`
### Runtime Sequence
#### 提交阶段
1. `AIInputBar` 解析生图请求
2. 推导 `expectedInsertPosition / Frame / size`
3. 构造 submission context
4. 创建 `generation-anchor`
5. 提交任务到工作流 / 任务队列
#### 执行阶段
1. `taskQueueService` 发出 `taskCreated / taskUpdated`
2. `useImageGenerationAnchorSync` 读取任务状态
3. `useImageGenerationAnchorController``Task.status / progress / executionPhase` 映射为 `submitted / queued / generating`
4. transforms 更新 anchor 元素
#### 后处理阶段
1. 任务成功返回结果 URL
2. `workflowCompletionService` 发出后处理开始
3. anchor 切到 `developing`
4. `useAutoInsertToCanvas` 开始插入
5. anchor 切到 `inserting`
6. 图片落图成功后anchor 切到 `completed` 并收口
#### 失败阶段
1. 任务失败或插入失败
2. `useImageGenerationAnchorSync` / `useAutoInsertToCanvas` 写回失败态
3. anchor 保留失败节点
4. 用户可原位重试或打开详情
## Implementation Breakdown
### 1. 元素层拆分
首版不建议在现有 `workzone` 元素上继续追加“生图锚点”模式,而是新增独立的画布元素类型:
- `generation-anchor`
原因:
- `workzone` 语义是“工作流过程面板”
- `generation-anchor` 语义是“结果出生点”
- 两者在几何、交互密度、恢复逻辑和删除时机上都不同
- 生图首版需要与非生图路径并行存在,独立元素类型更利于渐进迁移
插件实现建议优先参考现有的轻元素模式,而不是继续沿用 `with-workzone` 的重型编排模式:
- 参考 `withCard` / `CardGenerator``foreignObject + React root + generator` 范式
- 参考 `withAudioNode` / `AudioNodeGenerator` 的“轻元素 + 实时状态渲染”模式
- 若后续需要手动缩放,再单独增加 resize companion plugin参考 `with-card-resize` / `with-audio-node-resize`
不建议参考 `withTool` 的消息桥式重型模式,因为 anchor 不是一个 iframe 工具,也不应承担任务编排职责。
### 2. 建议新增文件
#### 类型层
- `packages/drawnix/src/types/image-generation-anchor.types.ts`
职责:
- 定义 `PlaitImageGenerationAnchor`
- 定义 `anchorType`
- 定义用户态 `phase`
- 定义提交期几何上下文与主动作字段
建议字段:
- `workflowId`
- `taskIds`
- `anchorType: 'frame' | 'ratio' | 'ghost' | 'stack'`
- `phase`
- `progress`
- `requestedSize`
- `expectedInsertPosition`
- `targetFrameId`
- `targetFrameDimensions`
- `resultUrl`
- `error`
- `zoom`
#### 渲染层
- `packages/drawnix/src/components/image-generation-anchor/ImageGenerationAnchorContent.tsx`
- `packages/drawnix/src/components/image-generation-anchor/image-generation-anchor.scss`
- `packages/drawnix/src/components/image-generation-anchor/index.ts`
职责:
- 渲染 `Frame Anchor`
- 渲染 `Ratio Anchor`
- 渲染 `Ghost-anchor`
- 渲染失败态与主动作
约束:
- 只做展示,不直接 claim / resume / 查询任务状态
- 不持有工作流恢复逻辑
#### 插件层
- `packages/drawnix/src/plugins/with-image-generation-anchor.ts`
职责:
- 注册 `generation-anchor` 元素
- 创建 `foreignObject`
- 管理激活态边框与点击命中
- 提供 transforms
- `insertAnchor`
- `updateAnchorState`
- `updateGeometry`
- `removeAnchor`
- `getById`
- `getAnchorByTaskId`
- `getAnchorByWorkflowId`
- `getAllAnchors`
边界约束:
- 插件层只提供元素能力
- 不直接订阅 `taskQueueService`
- 不直接处理 workflow 恢复
- 不直接决定 anchor 何时完成或消失
#### 状态映射层
- `packages/drawnix/src/hooks/useImageGenerationAnchorController.ts`
- `packages/drawnix/src/utils/image-generation-anchor-view-model.ts`
职责:
- 将提交期几何信号 + 任务状态 + 后处理状态映射为 anchor UI model
- 统一决定:
- `anchorType`
- `phase`
- `progress`
- `title/subtitle`
- `primaryAction`
- `transitionMode`
关键原则:
- UI 不直接认 `taskQueueService``workflowSubmissionService``workflowCompletionService` 的原始对象
- UI 只认 `ImageGenerationAnchorController` 产出的 anchor view model
- controller 是 image anchor 的单一状态源
建议保持该层为纯映射或轻控制器,不直接操作 DOM。
#### 同步层
- `packages/drawnix/src/hooks/useImageGenerationAnchorSync.ts`
职责:
- 在 board 级别监听 `taskQueueService`
- 在 board 级别监听后处理 / 自动插入事件
- 在刷新恢复后重新同步 anchor 状态
- 将更新写回 `ImageGenerationAnchorTransforms`
边界约束:
- `sync` 只负责订阅和归一化原始事件
- `sync` 不直接做业务判断
- `sync` 允许重复事件、乱序事件和恢复事件
- `controller` 负责幂等推进和去重
该 hook 应由 `Drawnix` 持有,而不是由 `AIInputBar` 或单个 anchor 组件持有。
### 3. 现有文件改动范围
#### `AIInputBar.tsx`
保留职责:
- 判断当前是否是 `image` 类型提交
- 计算 `expectedInsertPosition`
- 解析 `targetFrameId / targetFrameDimensions`
- 计算 `requestedSize`
- 在提交时创建首个 anchor
- 提供输入条“已提交”即时反馈
移出职责:
- 不再负责生图默认大 `WorkZone` 创建
- 不再通过 `currentWorkZoneIdRef` 驱动生图的完整生命周期
- 不再直接订阅 `taskQueueService.observeTaskUpdates()`
- 不再直接订阅 `workflowCompletionService.observeCompletionEvents()`
- 不再直接基于 image 路径写 `WorkZoneTransforms.update/remove`
建议新增:
- `currentImageAnchorIdRef`
并保留现有:
- `currentWorkZoneIdRef`
作为非生图路径兼容。
#### `useAutoInsertToCanvas.ts`
新增职责:
- 根据 `taskId` 查找 image anchor
- 在“结果已返回但未插入”时切换到 `developing`
- 在“开始插入”时切换到 `inserting`
- 在“插入完成”时执行 anchor → image 的收口
- 在失败时更新为失败节点
需要替换的当前耦合:
- 现有 `findWorkZoneForTask`
- 现有基于 WorkZone 的 `expectedInsertPosition / targetFrameDimensions` 读取
- 现有生图完成后直接删除 WorkZone 的逻辑
- 现有依赖 `ai-generation-complete` 解锁输入条的生图路径
#### `drawnix.tsx`
新增职责:
- 注册 `with-image-generation-anchor`
- 挂载 `useImageGenerationAnchorSync`
保留职责:
- 现有 `WorkZone` 恢复与同步先只服务非生图路径
建议调整:
-`Drawnix` 成为 image anchor 的全局恢复入口
- 不再让 `AIInputBar` 持有刷新恢复或跨任务同步逻辑
- 现有 `restoreWorkZones`、workflow sync、task queue sync 中的 image 逻辑应迁移到 anchor sync而不是继续直接写 WorkZone
#### `useWorkflowSubmission.ts`
建议调整:
- 将 image 类型从“默认 WorkZone 同步路径”中分流出来
- 保持文本、Agent、非生图任务继续复用现有逻辑
说明:
生图首版的主要状态源更应该是:
- 提交期几何上下文
- `taskQueueService`
- 后处理 / 插入事件
而不是完整 `workflow` 步骤列表。
需要重点清理的耦合:
- 当前把 workflow 事件直接同步到 WorkZone 的分支
- 当前把 image 路径当成默认 workflow 面板处理的分支
#### `with-workzone.ts` / `WorkZoneContent.tsx`
首版策略:
- 保留
- 不扩展生图主路径
- 仅服务非生图任务与兜底流程
后续可选策略:
- 当 image anchor 稳定后,再把生图相关分支从 WorkZone 中逐步收缩或删除
### 4. 状态层职责划分
建议把状态划成三层:
#### 提交期几何状态
来源:
- `AIInputBar`
- 选区 / Frame
- `size`
职责:
- 决定 anchor 初始位置与外壳类型
-`AIInputBar` 唯一应长期保有的 image 特有语义
#### 任务执行状态
来源:
- `taskQueueService`
- `Task.progress`
- `Task.executionPhase`
职责:
- 决定 `submitted / queued / generating`
- 是任务生命周期的唯一执行真相,不直接决定最终收口
#### 后处理 / 插入状态
来源:
- `workflowCompletionService`
- `useAutoInsertToCanvas`
职责:
- 决定 `developing / inserting / completed / failed`
- 用于避免“任务已完成但图片尚未真正落图”时提前收口
### 5. 单一状态源约束
对于 image anchor必须明确以下 ownership 约束:
- `AIInputBar` 只拥有提交瞬间快照,不拥有持续运行态
- `WorkflowContext` / `workflowSubmissionService` 只拥有 workflow 计划真相,不拥有 anchor UI 真相
- `taskQueueService` 只拥有任务执行真相
- `workflowCompletionService` 只拥有后处理真相
- `ImageGenerationAnchorController` 拥有唯一的 anchor 运行态
任何直接绕过 controller 写入 anchor UI 状态的路径,都视为架构违规。
### 6. 迁移顺序
推荐按以下顺序推进,避免双系统互相打架:
1. 新增 anchor 类型、plugin 与 view model
2.`AIInputBar` 中仅对 `image` 路径创建 anchor
3.`useAutoInsertToCanvas` 中接入 anchor 查找与完成态收口
4.`Drawnix` 中增加 anchor 同步 / 恢复 hook
5. 将 image 路径从默认 `WorkZone` 更新链中分流
6. 手工验证稳定后,再考虑清理 WorkZone 中的 image 分支
### 7. 为什么不复用 `WorkZone`
不推荐直接把 `WorkZoneContent` 改成“生图锚点样式”的主要原因:
- 仍会保留错误的元素语义
- 仍会把大量工作流字段塞进画布元素
- 仍会让生图依赖当前分散的 WorkZone 同步链
- 会增加“单组件承担展示 + 恢复 + 兜底编排”的复杂度
独立元素类型虽然首版工作量更高,但长期边界更清晰。
## Audit And Review Plan
### 代码层重点审计
- 是否仍有 image 路径写入 `WorkZoneTransforms`
- 是否存在 anchor 与 WorkZone 对同一 image 任务双写
- 是否有组件直接读取 `taskQueueService` 并绕过 controller
- 是否把恢复逻辑重新塞回展示组件
- 是否在未知比例场景下错误创建完整比例框
- 是否仍沿用 `ai-generation-complete` 作为 image 路径的唯一解锁信号
### 迁移层重点审计
- `AIInputBar` 创建 image anchor 后,是否仍然默认创建 WorkZone
- `useAutoInsertToCanvas` 是否还依赖 `findWorkZoneForTask`
- `drawnix.tsx` 的 WorkZone 恢复逻辑是否误处理 image anchor
- `useWorkflowSubmission` 是否仍将 image 事件同步到 WorkZone
- `useTaskWorkflowSync` 是否仍把 image 任务 fallback 到 WorkZone
- 是否仍存在多个 `setTimeout(1500)` 竞争删除同一 image 反馈对象
### 手工验证重点
- 选中 Frame 的单图生图
- 指定 `size` 的单图生图
- 不指定 `size` 的单图生图
- 同 prompt 多图生成
- 失败后原位重试
- 刷新页面后的锚点恢复
- 自动插入完成后的收口行为
### Code Review 必查文件
- `packages/drawnix/src/components/ai-input-bar/AIInputBar.tsx`
- `packages/drawnix/src/hooks/useAutoInsertToCanvas.ts`
- `packages/drawnix/src/drawnix.tsx`
- `packages/drawnix/src/hooks/useWorkflowSubmission.ts`
- `packages/drawnix/src/hooks/useTaskWorkflowSync.ts`
- `packages/drawnix/src/plugins/with-workzone.ts`
- `packages/drawnix/src/plugins/with-image-generation-anchor.ts`
- `packages/drawnix/src/services/workflow-completion-service.ts`
- `packages/drawnix/src/services/task-queue-service.ts`
## Risks
- 若锚点状态映射继续分散在多个 hook 与组件中,会重新产生“多处同步”的维护问题
- 若在未知比例时仍强制生成完整图片框,会造成锚点与最终结果不一致
- 若首版同时覆盖多任务类型,会让锚点语义被稀释,增加复杂度
## Mitigations
- 首版限制在 `image` 类型
- 将状态映射收敛到单一 view model / controller
- 将几何策略明确为 `Frame-first / Size-first / Ghost-anchor`
- 保留现有 `WorkZone` 给非生图路径,降低迁移风险

View File

@@ -0,0 +1,26 @@
# Change: update image generation anchor feedback
## Why
当前生图提交后默认在画布内创建 `WorkZone` 进度卡。该反馈方式能够表达“系统正在执行”,但不符合无限画布的创作语义:用户希望看到的是“图片对象正在诞生”,而不是“任务卡片正在运行”。
同时生图与文本、分析、Agent 工具调用不同,结果天然会落入画布,因此其过程反馈也应优先围绕“落点、比例、对象连续性”设计,而不是围绕“工作流步骤列表”设计。
## What Changes
- 为 AI 生图引入新的 `Generation Anchor` 反馈对象,替代默认的大面积 `WorkZone` 卡片
- 按提交时可获得的几何信息,定义三档锚点策略:
- `Frame-first`
- `Size-first`
- `Ghost-anchor`
- 为生图定义统一的用户态状态机:`submitted``queued``generating``developing``inserting``completed``failed`
- 将生图的详细执行信息收敛到任务详情层,不再默认在画布中展示完整步骤卡片
- 保留失败重试、历史可追踪和刷新恢复能力,但以锚点节点而非过程卡片的形式呈现
## Impact
- Affected specs: `image-generation-feedback`
- Affected code:
- `packages/drawnix/src/components/ai-input-bar/AIInputBar.tsx`
- `packages/drawnix/src/hooks/useAutoInsertToCanvas.ts`
- `packages/drawnix/src/plugins/with-workzone.ts`
- `packages/drawnix/src/components/workzone-element/WorkZoneContent.tsx`
- `packages/drawnix/src/services/task-queue-service.ts`
- `packages/drawnix/src/services/canvas-operations/canvas-insertion.ts`

View File

@@ -0,0 +1,78 @@
## ADDED Requirements
### Requirement: Image Generation SHALL Use Canvas Anchors Instead Of Default Progress Cards
The system SHALL represent image-generation progress in the canvas through lightweight generation anchors instead of default large workflow cards.
#### Scenario: User submits a single image generation request
- **WHEN** the user submits an `image` generation request from the AI input bar
- **THEN** the canvas SHALL show a lightweight generation anchor near the expected insertion location
- **AND** SHALL NOT default to a large progress card for that image request
#### Scenario: Non-image tasks keep existing feedback behavior
- **WHEN** the user submits a non-image generation request
- **THEN** the system MAY continue to use the existing task feedback behavior
- **AND** SHALL NOT be forced into the image anchor presentation model
### Requirement: Image Generation Anchors SHALL Derive Geometry From Submission-Time Signals
The system SHALL determine the image anchor geometry from the strongest available submission-time signals before the final image result is returned.
#### Scenario: Anchor inherits frame geometry
- **GIVEN** the user submits image generation while a target frame is selected
- **AND** the request contains `targetFrameId` and `targetFrameDimensions`
- **WHEN** the anchor is created
- **THEN** the anchor SHALL use the frame geometry as its primary outer shell
#### Scenario: Anchor inherits requested aspect ratio
- **GIVEN** the request has no target frame
- **AND** the request contains a valid `size` ratio
- **WHEN** the anchor is created
- **THEN** the anchor SHALL derive its aspect ratio from that requested size
#### Scenario: Anchor falls back to a ghost anchor
- **GIVEN** the request has no target frame
- **AND** the request has no stable ratio signal
- **WHEN** the anchor is created
- **THEN** the system SHALL create a lightweight ghost anchor instead of a full image frame placeholder
### Requirement: Image Generation SHALL Expose User-Centered Lifecycle States
The system SHALL map image generation into user-centered lifecycle states that prioritize creation continuity over raw workflow details.
#### Scenario: User sees lifecycle progression
- **WHEN** an image generation task progresses from submission to insertion
- **THEN** the UI SHALL express the lifecycle using user-facing states such as `submitted`, `queued`, `generating`, `developing`, `inserting`, `completed`, and `failed`
- **AND** SHALL allow those states to be rendered without exposing the full internal workflow step list in the canvas by default
### Requirement: Completed Images SHALL Replace Anchors With Spatial Continuity
The system SHALL transition from anchor to final image with spatial continuity so the result appears to emerge from the same canvas location.
#### Scenario: Image result is inserted into the canvas
- **WHEN** the image generation result is ready and the insertion flow begins
- **THEN** the final image SHALL take over the anchor location with a continuous visual transition
- **AND** the anchor SHALL fade out after the image is stably inserted
### Requirement: Failed Image Generation SHALL Preserve Contextual Recovery
The system SHALL preserve a contextual recovery point when image generation fails.
#### Scenario: Image generation fails before insertion
- **WHEN** an image generation task fails
- **THEN** the anchor SHALL remain in place as a failure node
- **AND** SHALL expose a retry path without requiring the user to rediscover the original insertion context
### Requirement: Image Generation Anchors SHALL Defer Detailed Execution History To Task Details
The system SHALL keep canvas anchors lightweight and defer detailed execution history to the task detail layer.
#### Scenario: Canvas anchor shows only concise progress context
- **WHEN** an image generation anchor is rendered in the canvas
- **THEN** it SHALL prioritize stage, lightweight progress, and direct recovery actions
- **AND** SHALL NOT default to rendering the full workflow step list inside the canvas object
#### Scenario: Users need detailed failure or history information
- **WHEN** the user requests more detail about an image generation task
- **THEN** the system SHALL provide that information through the task detail layer
- **AND** the anchor MAY offer a navigation affordance without becoming the primary detail container

View File

@@ -0,0 +1,40 @@
## 1. Product Rules
- [x] 1.1 定义生图锚点的用户态状态机与文案规范
- [x] 1.2 定义 `Frame-first / Size-first / Ghost-anchor` 三档几何策略
- [x] 1.3 明确生图锚点与任务详情层的职责边界
## 2. State Model
- [x] 2.1 新增 `image-generation-anchor.types.ts`,定义 anchor 元素、用户态与几何上下文
- [x] 2.2 新增 anchor view model / controller统一映射任务状态、进度与后处理阶段
- [x] 2.3 收敛生图反馈所需的提交期几何信号插入点、Frame、size
- [x] 2.4 为失败重试与刷新恢复定义统一的锚点状态转换
- [x] 2.5 定义 submission context 与 anchor view model 的字段契约,避免多模块各自拼装
- [x] 2.6 明确 controller 为 image anchor 的单一状态源,禁止其他模块直接双写 UI 状态
## 3. UI Implementation
- [x] 3.1 新增 `with-image-generation-anchor.ts`,注册 `generation-anchor` 元素与 transforms
- [x] 3.2 新增 `ImageGenerationAnchorContent.tsx` 与样式文件,替代生图默认大卡片
- [x] 3.3 实现 `Frame Anchor``Ratio Anchor` 的首版渲染
- [x] 3.4 实现 `Ghost-anchor` 兜底渲染
- [x] 3.5 实现锚点到真实图片的完成态过渡
- [x] 3.6 实现失败态节点与重试入口
## 4. Workflow Integration
- [x] 4.1 在 `AIInputBar` 中为 `image` 类型接入“已提交”即时反馈,并创建首个 anchor
- [x] 4.2 在 `useAutoInsertToCanvas` 中基于 `taskId` 查找 anchor驱动 `developing / inserting / completed / failed`
- [x] 4.3 在 `Drawnix` 中挂载 image anchor 的同步 / 恢复 hook
- [x] 4.4 为生图路径分流现有 `WorkZone`,避免默认展示大卡片
- [x] 4.5 保留非生图任务对现有 `WorkZone` 的兼容
- [x] 4.6 调整 `useWorkflowSubmission`,避免 image 路径继续走默认 WorkZone 同步
- [x] 4.7 调整 `useTaskWorkflowSync`,避免 image 任务 fallback 到 WorkZone
- [x] 4.8 清理 image 路径中的重复 `setTimeout` 删除与 `ai-generation-complete` 双写依赖
## 5. Validation
- [x] 5.1 验证选中 Frame 生图时的锚点几何一致性
- [x] 5.2 验证指定 `size` 生图时的比例一致性
- [x] 5.3 验证无 Frame / 无稳定比例时的 `Ghost-anchor` 降级体验
- [x] 5.4 验证生图路径不再默认创建大 `WorkZone` 卡片
- [x] 5.5 验证失败、重试、刷新恢复与自动插入完成后的收口行为
- [x] 5.6 Code review 审计 image 路径是否仍残留 `WorkZoneTransforms` 双写
- [x] 5.7 验证非图片任务仍保持旧 WorkZone 路径不受影响
- [x] 5.8 手工审计 `AIInputBar``Drawnix``useAutoInsertToCanvas``useWorkflowSubmission``useTaskWorkflowSync` 的 image 路径 ownership