Skip to content

feat(workflow-editor): add real WorkflowRun canvas - #190

Merged
nighca merged 18 commits into
mainfrom
feat/120-workflow-editor-real-runtime
Aug 11, 2026
Merged

feat(workflow-editor): add real WorkflowRun canvas#190
nighca merged 18 commits into
mainfrom
feat/120-workflow-editor-real-runtime

Conversation

@huyanxius

@huyanxius huyanxius commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

将 Workflow Editor 从占位页面切换到真实 WorkflowRun / WorkflowController 会话,并提供六类卡片画布、角色设定表单、多动作分支与审核后的 Character 资产发布。

Why

main 中 Workflow Editor 仍是占位页面,无法从真实 WorkflowRun 恢复。继续依赖临时演示数据会掩盖角色归属、节点恢复、错误重试和接口边界问题;仅通过审核而不落入 Character 资产树,也会让流程状态与资产库失去一致性。

Changes

  • 接入真实 WorkflowRun、Project、Character 与 WorkflowController 会话。
  • 使用 workflow_run_id 绑定单角色画布,避免按项目角色顺序猜测。
  • 使用统一 React Flow renderer 投影六类节点和多动作分支。
  • 在角色设定卡片填写角色描述,由 Controller 持久化后固定输入。
  • 审核通过时把完整动画幂等写入现有 Character / Outfit / Action / Frames,成功后再推进审核节点。
  • 补齐路由切换竞态、生成结果读取错误、失败节点重做和恢复中任务的处理。
  • 将 Workflow Editor 路由改为懒加载。

Implementation

  • 页面只订阅 Controller 的 WorkflowRun;流程推进仍由 WorkflowController 持久化。
  • React Flow 只负责拖动、缩放、布局与卡片渲染,禁用自由连线、重连和删除。
  • Character 通过 workflow_run_id 读取唯一绑定;重复绑定会明确失败。
  • 资产发布由既有 features/export 边界调用 Character API,页面不直接写 Character,Controller 继续保持不包含发布逻辑。
  • Action 使用首帧节点 ID 作为稳定 ID;发布重试替换同 ID 动作,不重复追加,并校验 Generation 的项目、类型、任务与结果归属。
  • Generation 后端适配器不在本 PR 实现;当前明确 fail-closed,不使用临时数据回退。

Verification

  • Character 资产发布定向回归:npm test -- --run src/features/export/index.test.ts src/pages/workflow-editor/runtime.test.ts src/pages/workflow-editor/index.test.tsx:3 files / 26 tests 通过
  • npm run typecheck:通过
  • 最终相关文件:oxfmt --check 通过
  • 最终相关文件:oxlint 通过
  • git diff --check 通过
  • 角色设定表单提交前,分支全量门禁通过:format、lint、typecheck、29 files / 209 tests、build(271 modules)

Screenshots

Desktop Mobile
Workflow Editor desktop Workflow Editor mobile

截图使用临时六节点会话展示当前 renderer;图片区域为空白占位,临时预览代码未提交。

Scope

  • 本 PR 不包含 Generation 后端适配器、参考图上传、角色名称自动提取、导出节点与 Playtest 跳转。
  • Generation task type 对齐、workflow_run_id 后端唯一性与导出节点语义留待后续讨论。

Related Issues

Closes #120

The workflow editor needs a maintained graph renderer for its controlled canvas.

Add @xyflow/react and record its exact dependency closure in the lockfile.

The frontend can build the editor without loading graph code on unrelated routes.
The backend binds every Character to the WorkflowRun that produced it.

Map and serialize workflow_run_id, then update typed fixtures that consume Character.

Editors can select the correct character without guessing from project order.
The existing contract text omitted the backend ownership field and described a missing run property.

Document workflow_run_id and the action outfit lookup through the bound Character.

Future adapters have an accurate source of truth for character and outfit identity.
The editor must recover one persisted WorkflowRun through the main repository interfaces.

Compose the controller with project context, the run-bound Character, and an explicit Generation failure boundary.

Production routes no longer depend on demo data or a second workflow state machine.
The production editor needs to project persisted workflow state without owning business transitions.

Render six system node types and parallel action branches through one controlled React Flow canvas.

Commands, recovery paths, and transient UI state remain bounded by WorkflowController and the active run.
React Flow should not increase the initial bundle cost of unrelated application routes.

Load the editor behind Suspense while preserving both protected WorkflowRun route forms.

Authenticated deep links keep their existing behavior and load the canvas only when requested.
Manual editor submissions need to persist the configured prompt before generation.

Allow configuring nodes to override their input while keeping completed nodes immutable.

Generation receives only canonical fields from the persisted setup snapshot.
Manual WorkflowRun entry needs an editable prompt before the setup node is fixed.

Render a controlled description field and submit its value through WorkflowController.

The form becomes read-only after persistence and keeps the existing visual system.
The manual setup path must persist edited input without changing the generation payload shape.

Exercise the real page and controller from form entry through the fixed setup state.

Exact payload assertions prevent UI-only success and accidental nested fields.
The UI change needs reviewer-visible desktop and mobile evidence.

Add screenshots from the current canvas renderer with blank image placeholders.

Reviewers can verify the six-node layout without shipping screenshot mock code.
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
windup Ready Ready Preview Aug 11, 2026 2:52am

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

发现 1 个会让新一轮生成误用旧候选的状态一致性问题,已在 diff 中内联标注。

验证:52 个相关测试通过,npm run typecheck 通过,git diff --check 通过。

Comment thread frontend/src/pages/workflow-editor/index.tsx
@huyanxius
huyanxius requested a review from nighca August 10, 2026 16:23
Approved animations must become durable Character assets before review state advances.

Upsert the reviewed branch into its existing Outfit through the Character API boundary.

Retries keep one stable Action ID and reject mismatched Generation results.
Character publication needs contract coverage for the nested asset tree.

Exercise action mapping, retry replacement, and Generation ownership guards.

The tests prevent duplicate or cross-workflow assets from being persisted.
Review approval must not advance before the Character asset is durable.

Exercise the session orchestration and the page command boundary.

The tests keep publication failures from producing a passed review node.
Character publication should not rely on unrelated WorkflowRun or busy-state renders.

Return the published Character to page state and limit action updates to the asset tree.

The editor preserves character metadata and removes the unused export surface.
Asset publication needs regression coverage independent of review persistence.

Exercise preserved character metadata and page state after an approval failure.

The tests prevent getter-based refresh coupling from returning.
Generation results were keyed by node id alone, so a node holding two tasks silently kept only the last one. Deleted nodes still issued reads, every command reset the viewport, and a single busy slot let a second branch unlock the first mid-flight.

Key generation reads by node and role, skip deleted nodes, refit the view only when the node set changes, and hold busy branches in a set. Four ad-hoc race guards collapse into one AbortController per session and one per read.

Regression tests cover each case, including two parallel branches keeping their own locks. Pass-through wrappers and swapped variable names are gone.
The editor shipped the only page-level stylesheet in the frontend, while index.css states that everything outside it goes through Tailwind utilities. It also carried its own palette of near-identical greens spread across the sheet and the node data.

Move layout, card, menu and boundary styles onto the elements as utility classes. The stylesheet keeps only what utilities cannot express: the shared colour variables, React Flow internal overrides, edge states and keyframes.

The sheet drops from 487 to 76 lines with no visual change, verified by comparing rendered screenshots before and after. Nested main landmarks become plain containers.
…dates

The controller emits on every persist, and the page answered each emit by re-reading every generation the run refers to. With four action branches a single click issued a dozen GETs for results that had not changed.

Keep settled results in a map keyed by task id and serve them from there. Tasks still pending or running are read again, since their status is what the canvas is waiting on, and the map is dropped when the run changes.

A probe over one main line plus three action branches drops from seven reads per command to zero, while the first load still costs seven.
Comment thread frontend/src/features/export/index.ts
Comment thread frontend/src/entities/character/index.ts
@nighca
nighca merged commit f0828f4 into main Aug 11, 2026
9 checks passed
@huyanxius
huyanxius deleted the feat/120-workflow-editor-real-runtime branch August 11, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 实现单角色 Workflow Editor 卡片画布

3 participants