@siming-org/cli 0.7.1 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3682,9 +3682,26 @@ import { Command as Command5 } from "commander";
3682
3682
  function createDagCommand() {
3683
3683
  const dag = new Command5("dag").description("DAG template & instance management");
3684
3684
  const tpl = dag.command("template").description("DAG template management");
3685
- withCommonOpts(tpl.command("list"), "table").option("--project <id>", "filter by projectId").description("List DAG templates (summary projection: node labels only, no prompts \u2014 use `show` for full detail)").action(async (opts) => {
3685
+ withCommonOpts(tpl.command("list"), "table").option("--project <key|id>", "filter by project (key or id; defaults to workspace defaultProject)").description("List DAG templates (summary projection: node labels only, no prompts \u2014 use `show` for full detail)").action(async (opts) => {
3686
3686
  const client = createClient(opts.url);
3687
- const result = await handleListTemplates(client, opts.project);
3687
+ const projectOpt = opts.project ?? readWorkspaceConfig()?.defaultProject;
3688
+ let projectId;
3689
+ if (projectOpt !== void 0) {
3690
+ const r = await resolveProjectId(client, projectOpt);
3691
+ if (!r.success) {
3692
+ if (opts.project === void 0) {
3693
+ renderResult(opts.format, fail({
3694
+ ...r.error,
3695
+ hint: `workspace defaultProject "${projectOpt}" \u89E3\u6790\u5931\u8D25\u2014\u2014siming config unset defaultProject \u540E\u91CD\u8BD5\uFF0C\u6216\u663E\u5F0F --project <key|id>`
3696
+ }));
3697
+ } else {
3698
+ renderResult(opts.format, r);
3699
+ }
3700
+ return;
3701
+ }
3702
+ projectId = r.data;
3703
+ }
3704
+ const result = await handleListTemplates(client, projectId);
3688
3705
  if (!result.success) {
3689
3706
  renderResult(opts.format, result);
3690
3707
  return;
@@ -4775,7 +4792,7 @@ function createFlowCommand() {
4775
4792
  });
4776
4793
  flow.command("install <pkg-spec>").description(
4777
4794
  "Install a node library package from npm \u2014 validate 1.1 manifest \u2192 plan complete assets \u2192 confirm \u2192 apply dependencies \u2192 nodes \u2192 library"
4778
- ).option("--url <url>", "server base URL").option("--scope <scope>", "install scope: global|project", "global").option("--project <key|id>", "target project (required when scope=project)").option("--registry <url>", "npm registry for pack (e.g. private mirror; default npm config)").option("--yes", "skip interactive confirmation").option("--force", "allow version downgrade; admin may also replace a conflicting model alias").action(async (pkgSpec, opts) => {
4795
+ ).option("--url <url>", "server base URL").option("--scope <scope>", "install scope: global|project", "global").option("--project <key|id>", "target project (required when scope=project)").option("--registry <url>", "npm registry for pack (e.g. private mirror; default npm config)").option("--yes", "skip interactive confirmation").option("--force", "allow version downgrade; admin may also sync a conflicting model alias display name (realModel is never overwritten)").action(async (pkgSpec, opts) => {
4779
4796
  const scopeResult = parseEnum(opts.scope, SkillScopeSchema3, "scope");
4780
4797
  if (!scopeResult.success) {
4781
4798
  renderResult("json", scopeResult);
@@ -4817,7 +4834,7 @@ function createFlowCommand() {
4817
4834
  ${conflicts.map((item) => ` ${item.kind}:${item.key} \u2014 ${item.reason ?? "\u5185\u5BB9\u51B2\u7A81"}`).join("\n")}`,
4818
4835
  httpStatus: 0,
4819
4836
  bizCode: conflicts.some((item) => item.conflictKind === "model-alias") ? "FLOW_MODEL_ALIAS_CONFLICT" : "FLOW_ASSET_SCOPE_CONFLICT",
4820
- hint: "\u6309\u6761\u76EE\u4FEE\u590D\u76EE\u6807\u73AF\u5883\u6216\u5305\u5185\u5BB9\u540E\u91CD\u65B0\u6267\u884C\uFF1B--force \u53EA\u653E\u884C\u7248\u672C\u964D\u7EA7\u53CA admin \u7684 Model Alias \u8986\u76D6"
4837
+ hint: "\u6309\u6761\u76EE\u4FEE\u590D\u76EE\u6807\u73AF\u5883\u6216\u5305\u5185\u5BB9\u540E\u91CD\u65B0\u6267\u884C\uFF1B--force \u53EA\u653E\u884C\u7248\u672C\u964D\u7EA7\u53CA admin \u5BF9 Model Alias \u5C55\u793A\u540D\u7684\u540C\u6B65\uFF08realModel \u6C38\u4E0D\u8986\u76D6\uFF09"
4821
4838
  }));
4822
4839
  return;
4823
4840
  }
@@ -5085,14 +5102,14 @@ function planModelAlias(payload, existing, access, force) {
5085
5102
  ...base,
5086
5103
  action: "conflict",
5087
5104
  conflictKind: "model-alias",
5088
- reason: `Model Alias \u5185\u5BB9\u4E0D\u540C\uFF08${diffs.join(", ")}\uFF09\uFF1B\u4EC5 admin \u663E\u5F0F --force \u53EF\u8986\u76D6`,
5105
+ reason: `Model Alias \u5C55\u793A\u540D\u4E0D\u540C\uFF08${diffs.join(", ")}\uFF09\uFF1B\u4EC5 admin \u663E\u5F0F --force \u53EF\u540C\u6B65\u5C55\u793A\u540D\uFF08realModel \u6C38\u4E0D\u8986\u76D6\uFF09`,
5089
5106
  expectedState: snapshotModelAlias(existing)
5090
5107
  };
5091
5108
  }
5092
5109
  return {
5093
5110
  ...base,
5094
5111
  action: "update",
5095
- reason: `admin --force \u8986\u76D6\u5DEE\u5F02\u5B57\u6BB5\uFF1A${diffs.join(", ")}`,
5112
+ reason: `admin --force \u540C\u6B65\u5C55\u793A\u540D\uFF1A${diffs.join(", ")}\uFF08realModel \u4E0D\u5199\u5165\uFF09`,
5096
5113
  expectedState: snapshotModelAlias(existing)
5097
5114
  };
5098
5115
  }
@@ -5300,7 +5317,6 @@ function diffAgent(payload, entity) {
5300
5317
  function diffModelAlias(payload, entity) {
5301
5318
  const diffs = [];
5302
5319
  if (entity.name !== payload.name) diffs.push("name");
5303
- if (entity.realModel !== payload.realModel) diffs.push("realModel");
5304
5320
  return diffs;
5305
5321
  }
5306
5322
  function diffNode(payload, entity, packageName) {
@@ -5354,7 +5370,7 @@ function snapshotAgent(entity) {
5354
5370
  };
5355
5371
  }
5356
5372
  function snapshotModelAlias(entity) {
5357
- return { code: entity.code, name: entity.name, realModel: entity.realModel };
5373
+ return { code: entity.code, name: entity.name };
5358
5374
  }
5359
5375
  function snapshotNode(entity) {
5360
5376
  return {
@@ -5517,7 +5533,7 @@ async function writeAsset(client, manifest, plan, item) {
5517
5533
  const input = { code: payload2.code, name: payload2.name, realModel: payload2.realModel };
5518
5534
  return client.postJson("/api/model-aliases", input);
5519
5535
  }
5520
- const patch2 = { name: payload2.name, realModel: payload2.realModel };
5536
+ const patch2 = { name: payload2.name };
5521
5537
  return client.putJson(`/api/model-aliases/${encodeURIComponent(payload2.code)}`, patch2);
5522
5538
  }
5523
5539
  if (item.kind === "skill") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siming-org/cli",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "license": "MIT",
5
5
  "author": "Wuchao",
6
6
  "engines": {
@@ -27,8 +27,8 @@
27
27
  "picocolors": "^1.1.1",
28
28
  "yaml": "^2.6.0",
29
29
  "zod": "^4.4.3",
30
- "@siming-org/core": "0.7.1",
31
- "@siming-org/server": "0.7.1"
30
+ "@siming-org/core": "0.7.3",
31
+ "@siming-org/server": "0.7.3"
32
32
  },
33
33
  "devDependencies": {
34
34
  "tsup": "^8.3.5",
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "exportFormatVersion": "1.0",
3
- "exportedAt": "2026-09-15T08:13:01.500Z",
3
+ "exportedAt": "2026-09-17T14:14:30.449Z",
4
4
  "warnings": [],
5
5
  "template": {
6
6
  "name": "full_workflow",
7
- "description": "通用软件开发全流程:PRD 设计与确认、分支对齐、完整技术方案双审,界面任务经交互设计节点产出可核对交互契约(含人工确认),按任务轨道进入后端或前端实现与验证,完成单元测试和项目适用的端到端测试,经最终集成验证、发布验收与架构信息归档后收敛。feature 使用完整路径;bugfix 和界面微调可按任务配置跳过 PRD。混合任务先完成后端测试链,再进入前端实现与视觉验证。",
7
+ "description": "通用软件开发全流程:PRD 设计与确认、分支对齐、完整技术方案双审,界面任务经交互设计节点产出可核对交互契约(含人工确认),按任务轨道进入后端或前端实现——后端轨完成单元测试、前端轨完成前端单元测试与界面呈现验证后汇合到端到端测试,经最终集成验证、发布验收与架构信息归档后收敛。feature 使用完整路径;bugfix 和界面微调可按任务配置跳过 PRD",
8
8
  "nodes": [
9
9
  {
10
10
  "id": "PRD",
@@ -138,7 +138,7 @@
138
138
  "label": "视觉验证",
139
139
  "phase": "track",
140
140
  "track": "ui",
141
- "prompt": "# 视觉验证\n\n## 节点职责\n\n运行当前界面并通过浏览器完成验收路径,验证功能结果、采集视觉证据,再根据独立 `visual-reviewer` 的评审结果完成修复和回归。本节点负责运行、操作、采证和流程收敛,不代替 Agent 判断视觉质量。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、前端实现记录,以及项目和所属模块的提示词。存在交互契约产物时,读取契约并将其自检清单与验收点作为验证清单的底座;无契约时以验收标准为底座。加载 `workflow-discipline`,调用独立 `visual-reviewer` 评审视觉证据。\n\n根据需求整理待验证页面、用户路径、需要呈现的状态和代表性视口。缺少运行方式、访问地址、认证或数据准备信息时,先从项目脚本、配置和现有环境中查找;仍无法运行当前实现时,说明缺失信息并暂停。\n\n## 执行流程\n\n1. 按项目声明启动当前实现及其依赖服务,确认页面对应本次代码。\n2. 使用浏览器自动化能力执行需求涉及的真实用户路径,验证操作后的页面结果、请求结果、反馈、错误处理和持久化后的重新加载结果。\n3. 检查浏览器控制台中的新增错误、失败请求和其他运行异常。\n4. 按验收范围触发适用的加载、空、错误、成功和关键交互状态,并在代表性视口采集截图、视频或等价原始证据;有交互契约时按契约条款逐项触发与核对,证据覆盖契约验收点;不在本节点预判视觉结论。\n5. 将需求、设计规范、场景说明、视口信息和原始证据交给 `visual-reviewer`;交互契约(如有)随需求与设计规范一并作为评审材料移交,不提供实现者结论或预期缺陷。\n6. 修复功能验证失败项以及 `visual-reviewer` 报告的 BLOCKER、HIGH Findings,然后重新执行受影响路径、采集同场景证据并再次评审,直至功能验证通过且视觉评审为 PASS。MEDIUM、LOW 逐项处理或记录保留理由。\n7. 清理本次创建的临时数据和运行资源,不删除非本次创建的数据。\n\n## 产出与检查\n\n推进前确认:\n\n- 需求涉及的用户路径已通过真实浏览器操作验证,并观察到最终结果;\n- 页面结果、请求、反馈、错误处理、持久化和控制台均无未解决的严重问题;\n- 验收所需状态与视口已呈现,原始证据对应当前实现且可追溯;\n- `visual-reviewer` 最终结论为 PASS,所有 Findings 均已处理或说明;\n- 修复后的受影响路径已重新验证并重新采证;\n- 临时数据和运行资源已按项目规则清理。\n\n## 任务差异处理\n\n根据需求和页面能力选择用户路径、状态、视口与证据,不套用固定 CRUD 或截图数量。某项不适用时说明理由,不得静默跳过。完全无法运行当前实现,或修复需要改变已确认需求、设计方向、公开契约或引入新依赖时,说明影响并暂停;验证与修订轮次按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将功能验证结论、已覆盖的用户路径、状态与视口、请求和控制台结果、原始证据引用、缺陷修复、未适用项及理由、`visual-reviewer` 结论与 Findings 处理情况写入当前节点记录。完成上述检查后推进下一节点。",
141
+ "prompt": "# 视觉验证\n\n## 节点职责\n\n运行当前界面,通过浏览器到达需求要求的视觉状态,采集原始证据,并依据独立 `visual-reviewer` 的评审结果完成修复与回归。本节点只建立**呈现断言**(页面是否按需求呈现:布局、还原度、色系、文案呈现、代表性视口观感、加载/空/错误等状态的视觉呈现);功能结果、请求结果、字段语义、状态推导与持久化结果等**行为语义断言归端到端验证**,不在本节点建立。本节点负责运行、操作、采证与流程收敛,不代替 Agent 判断视觉质量。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、前端实现记录,以及项目和所属模块的提示词。存在交互契约产物时,读取契约并将其自检清单与验收点作为呈现断言的锚点底座;无契约时以验收标准为底座。加载 `workflow-discipline`,调用独立 `visual-reviewer` 评审视觉证据。\n\n根据需求整理待验证页面、目标视觉状态与代表性视口。缺少运行方式、访问地址、认证或数据准备信息时,先从项目脚本、配置和现有环境中查找;仍无法运行当前实现时,说明缺失信息并暂停。\n\n## 执行流程\n\n1. 按项目声明启动当前实现及其依赖服务,确认页面对应本次代码,并检查页面可达性与控制台未捕获错误——该检查只用于判定证据是否可用,不作为行为结论。\n2. 产出场景清单:每条为“场景 × 呈现断言 × 锚点”三要素,锚点为交互契约条款(有契约时)或验收标准条款(无契约时)。**无锚点的呈现断言不得进入清单**;确有需求依据而契约缺条款时,登记契约缺口交回,不自行补写需求;既无锚点又无需求依据的呈现断言删除并记录原因。\n3. 清单形成后逐条执行:用浏览器自动化操作到达目标视觉状态(交互动作在本节点的唯一目的是到达目标状态),按清单逐项核对呈现,并在代表性视口采集截图、视频或等价原始证据,证据需覆盖清单中的每条锚点。\n4. 采证中发现明显行为异常(如目标状态无法到达)时,按缺陷记录并交回修复,不在本节点沉淀为行为断言。\n5. 将需求、设计规范、场景清单、视口信息和原始证据交给 `visual-reviewer`;交互契约(如有)随需求与设计规范一并作为评审材料移交,不提供实现者结论或预期缺陷。\n6. 修复呈现缺陷以及 `visual-reviewer` 报告的 BLOCKER、HIGH Findings,然后重新采集同场景证据并再次评审,直至呈现验证通过且视觉评审为 PASS。MEDIUM、LOW 逐项处理或记录保留理由。\n7. 同一场景连续 2 轮采证失败即停止重跑,人工检查页面结构、选择器与运行轨迹定位根因,禁止继续盲改重跑。\n8. 将本节点观察到的、应由端到端覆盖而设计未纳入的行为场景,通过节点记录交接给端到端设计/开发节点;该交接走节点记录,不进问题池。\n9. 清理本次创建的临时数据和运行资源,不删除非本次创建的数据。\n\n## 产出与检查\n\n推进前确认:\n\n- 场景清单每条含“场景 × 呈现断言 × 锚点”三要素,无锚点断言已按规则处置;\n- 页面可达性与运行时异常检查已执行,证据可用且对应当前实现;\n- 清单中每条呈现断言均有对应原始证据,代表性视口与关键状态(加载、空、错误、成功、关键交互)已覆盖或说明不适用理由;\n- 未在本节点建立行为语义断言,越界观察已记录并归回对应节点;\n- `visual-reviewer` 最终结论为 PASS,所有 Findings 均已处理或说明;\n- 修复后的受影响场景已重新验证并重新采证;\n- 同一场景未连续超过 2 轮盲改重跑,触发停手时已人工定位根因并记录结论;\n- 行为场景交接与临时数据、运行资源清理已完成。\n\n## 任务差异处理\n\n根据需求和页面能力选择目标状态、视口与证据,不套用固定 CRUD 或截图数量。某项不适用时说明理由,不得静默跳过。完全无法运行当前实现,或修复需要改变已确认需求、设计方向、公开契约或引入新依赖时,说明影响并暂停;验证与修订轮次按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将场景清单、呈现断言与锚点、已到达的目标状态与视口、页面可达与控制台结果、原始证据引用、缺陷修复、越界观察与行为场景交接、未适用项及理由、`visual-reviewer` 结论与 Findings 处理情况写入当前节点记录。完成上述检查后推进下一节点。",
142
142
  "skills": [
143
143
  "workflow-discipline"
144
144
  ],
@@ -147,8 +147,8 @@
147
147
  ],
148
148
  "sourcePreset": {
149
149
  "code": "verify-visual",
150
- "version": "1.4.1",
151
- "contentHash": "a959a6617abf83fb",
150
+ "version": "1.5.0",
151
+ "contentHash": "b3addf5a54976ba8",
152
152
  "agents": [
153
153
  "visual-reviewer"
154
154
  ]
@@ -199,12 +199,57 @@
199
199
  ]
200
200
  }
201
201
  },
202
+ {
203
+ "id": "UI_UT_DESIGN",
204
+ "label": "前端单元测试设计",
205
+ "phase": "test",
206
+ "track": "ui",
207
+ "prompt": "# 前端单元测试设计\n\n## 节点职责\n\n为本次界面改动设计可执行的单元测试计划,覆盖界面渲染输出、状态与分支、交互回调以及加载、空、错误等界面状态的呈现与行为,明确测什么、为什么测以及预期什么。本节点只产出测试设计,不编写或执行测试代码,并通过独立 `test-reviewer` 评审设计质量。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、非目标、技术方案、前端实现变更、交互契约(如有)与编码决策,以及项目和所属模块的前端测试约束(测试框架与命令、目录与命名约定、覆盖率门)。加载 `workflow-discipline`;调用独立 `test-reviewer` 评审测试设计。\n\n读取现有前端测试目录、配置与用例,确认框架、渲染方式、模拟边界与覆盖要求。信息缺失时先从仓库现状推导;仍无法确定关键行为、契约锚点或测试边界时,说明缺失信息并暂停。用例清单的锚点底座:有交互契约时以契约条款与验收标准为锚点,无契约时以验收标准为锚点——无锚点的用例不得进入清单。\n\n## 执行流程\n\n1. 界定测试对象:列出本次界面改动涉及的界面元素与状态——渲染输出、条件分支、交互回调、加载中、空数据、错误态;从需求与前端变更逐项对应,不按文件或函数罗列。\n2. 组织用例清单:按用户可见行为组织,每条含“场景 → 期望结果 → 锚点(验收标准或契约条款)”,并写明前置条件、数据准备(使用贴近真实使用形态的数据,不因实现便利而简化)、操作步骤、观察点(按用户可感知方式定位界面元素:可见文案、可访问名称、角色,不绑死实现结构)、预期结果,使后续实现者无需猜测测试意图。\n3. 覆盖维度:显式覆盖边界与异常(非法输入、空或超长内容、加载中、失败态、禁用或权限态);确认项按界面实际能力选取,不适用项说明理由,不制造无行为意义的用例。\n4. 分层与断言对象:以组件或界面级行为测试为主;断言对象限定为用户可见输出与可访问信息(可见性、文案、可访问名称、角色)及交互结果,不设计断言组件实例、内部状态或私有实现的用例。\n5. 替身边界:明确哪些依赖使用真实实现、替身或受控环境(网络请求、时钟、路由等),避免过度替换掩盖被测行为,也避免把跨系统路径误当单元测试。\n6. 覆盖目标:对应项目声明的覆盖率门,说明本次改动的覆盖范围、预计缺口与风险(含只统计被导入文件导致覆盖虚高的风险)。\n7. 逐项核对现有测试:标记复用、调整或新增,并指出具体用例及其覆盖的本次行为,不用“已有覆盖”笼统跳过。\n8. 形成最终测试设计:包含范围与策略、用例清单、覆盖目标、层级边界、风险与不适用说明、锚点→用例映射表(每条验收标准或契约条款至少对应一个用例 ID);不得包含可执行测试函数、断言代码或完整 fixture。\n9. 将测试设计连同映射表交给 `test-reviewer`,不提供设计者结论或预期结果。委派材料按「契约 + 路标 + 已验锚点」组装:项目前端测试约束以节选直接置入委派 prompt;需求、前端变更、现有测试给路径路标;非首轮重审随附上轮已验锚点清单。\n10. 修复 BLOCKER、HIGH Findings 后重新评审:reviewer 只重验本轮修订触及的条目与受影响锚点,未触及项沿用上轮结论,但每轮报告保持全量 Findings 快照——已解决的标记关闭,不静默丢弃,是否处理由主会话决策;评审至多 3 轮,第 3 轮仍未 PASS 时保留在当前节点并请用户裁定,附双方分歧清单。MEDIUM、LOW 逐项处理或记录保留理由。Findings 处理记录写入节点记录,禁止回写被评审文档——测试设计文档只保留设计本体。\n\n## 产出与检查\n\n推进前确认:\n\n- 本次界面改动的行为与状态已逐项对应到用例,无遗漏的改动面;\n- 每条用例有场景、锚点、观察点与预期结果,锚点可追溯到验收标准或契约条款;\n- 边界、异常与界面状态(加载、空、错误)已覆盖或说明不适用理由;\n- 断言对象均为用户可见输出与可访问信息,未见断言内部状态或私有实现的用例;\n- 替身、数据准备与测试层级边界合理,未新增测试工具链;\n- 覆盖目标对应项目声明的覆盖率门,缺口与风险已说明;\n- 锚点→用例映射表完整;\n- 现有测试的复用、调整与新增判断均有具体依据;\n- 最终设计不含可执行测试代码,也不含评审处理记录;\n- `test-reviewer` 最终结论为 PASS(或按 3 轮上界经用户裁定通过),所有 Findings 均已处理或说明;\n- 测试设计已形成完整产物,登记值携带全文(超限时为路径引用且已说明理由)。\n\n## 任务差异处理\n\n根据被测界面选择覆盖维度,不机械套用固定模板或为不适用场景制造用例。无行为逻辑的纯样式调整,说明判断依据与其适用的验证层级(如视觉验证),不得静默产出空设计。测试设计文档超过约 400 行时先按界面单元拆分再送审。评审修订与执行障碍按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将测试设计结论、用例清单与锚点映射、覆盖目标与缺口、替身边界、现有测试复用判断、不适用项及理由、设计产物(登记携带全文,超限时为路径引用且已说明理由)、`test-reviewer` 结论与各轮 Findings 处理记录写入当前节点记录——处理记录只进节点记录,被评审文档保持设计本体。完成上述检查后推进下一节点。",
208
+ "skills": [
209
+ "workflow-discipline"
210
+ ],
211
+ "agents": [
212
+ "test-reviewer"
213
+ ],
214
+ "sourcePreset": {
215
+ "code": "test-ui-unit-design",
216
+ "version": "1.0.0",
217
+ "contentHash": "a32ddb2ba79630dc",
218
+ "agents": [
219
+ "test-reviewer"
220
+ ]
221
+ }
222
+ },
223
+ {
224
+ "id": "UI_UT_DEV",
225
+ "label": "前端单元测试开发",
226
+ "phase": "test",
227
+ "track": "ui",
228
+ "prompt": "# 前端单元测试开发\n\n## 节点职责\n\n依据已确认的前端单元测试设计编写或调整测试代码,验证界面呈现与交互行为符合需求。测试代码和必要的前端实现修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、前端实现变更、前端单元测试设计、前序决策,以及项目和所属模块的前端测试约束(框架与命令、覆盖率门)。加载 `coding-standards`、`workflow-discipline`;出现测试失败且根因不明确时加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取现有前端测试、配置与项目命令,确认框架、渲染方式、定位与断言惯例、替身与数据准备、覆盖率统计范围。缺少关键信息时先从仓库现状补齐;仍无法确定测试语义时说明缺失信息并暂停。\n\n## 执行流程\n\n1. 建立“测试设计用例 → 测试实现或已有用例”的逐项映射,明确新增、调整和复用范围。\n2. 按项目惯例实现测试:Arrange-Act-Assert 结构、描述性命名说明场景与预期、相关用例分组;断言渲染输出、用户可见状态与交互结果,不断言内部状态或私有实现。\n3. 定位界面元素使用用户可感知的方式(可访问角色、标签文本、可见文本),不使用样式类名或内部选择器绑死实现结构。\n4. 替身只隔离单元边界:网络请求、时钟、路由等外部依赖用替身,不替换被测行为本身;用例之间相互独立、可任意顺序执行,禁止真实计时等待与顺序依赖。\n5. 完成一个测试文件或紧密相关的一组用例后,将明确的命令、范围和通过标准交给 `test-executor` 执行,并依据事实报告判断结果。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按 `bugfix-root-cause-verification` 复现、提出并验证假设,确认根因后再修改测试、前端实现或环境。\n7. 修复后重新执行原失败范围及受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常、修改数据避开问题或硬编码结果制造通过;不得通过调整覆盖率阈值、排除文件、缩小统计范围或屏蔽统计使覆盖率门通过。\n8. 覆盖率门不满足时按缺口补充用例;确属无法覆盖的代码说明原因并写入节点记录。\n9. 所有设计用例实现后,先根据前端改动与依赖关系判定回归范围,无法可靠判断时扩大范围;范围判定完成后必须调用 `test-executor` 执行该回归范围(含项目声明的覆盖率命令)。\n10. 检查设计映射、测试删除、skip/only、无效观察点、隔离性、独立性与覆盖率统计,确认测试变更完整。\n11. 将需求、测试设计、项目约束和全部代码变更位置交给 `code-reviewer`,不提供实现者结论或预期结果。修复 BLOCKER、HIGH Findings 后重新执行受影响测试并复审,直至测试通过且评审为 PASS;MEDIUM、LOW 逐项处理或记录保留理由。\n\n## 产出与检查\n\n推进前确认:\n\n- 每个适用的测试设计用例都有对应实现或明确的已有测试;\n- 测试具有用户可感知的观察点,断言行为与呈现而非实现细节;\n- 用例相互独立、可任意顺序执行,替身与数据准备符合项目约束;\n- 所有测试失败均在根因明确后修复,没有制造假绿;\n- `test-executor` 报告适用范围全部通过,失败为 0,未授权跳过为 0,覆盖率门满足,日志可追溯;\n- 覆盖率缺口或无法覆盖项已说明,未调整阈值、排除文件、缩小统计范围或屏蔽统计;\n- 完整性检查通过,没有删除有效测试或遗漏设计用例;\n- `code-reviewer` 最终结论为 PASS,所有 Findings 均已处理或说明;\n- 测试代码、必要的前端修复和执行报告已形成可引用产物。\n\n## 任务差异处理\n\n根据项目前端测试框架和变更范围选择实现与回归方式,不套用固定命令或覆盖率指标。测试设计中的用例确实不适用或已被等价测试覆盖时,说明具体依据。失败修复涉及破坏性契约、新依赖或真实范围扩张时先说明影响并暂停;同一问题多轮仍不收敛时按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将设计到实现的映射、测试代码变更、实际执行命令与范围、通过/失败/跳过统计与覆盖率结果、日志与报告引用、根因和修复、无法覆盖项及说明、完整性结论、未适用项及理由、`code-reviewer` 结论与 Findings 处理情况写入当前节点记录。完成上述检查后推进下一节点。",
229
+ "skills": [
230
+ "coding-standards",
231
+ "workflow-discipline"
232
+ ],
233
+ "agents": [
234
+ "test-executor",
235
+ "code-reviewer"
236
+ ],
237
+ "sourcePreset": {
238
+ "code": "test-ui-unit-implement",
239
+ "version": "1.0.0",
240
+ "contentHash": "c8ceaf5f205a7574",
241
+ "agents": [
242
+ "test-executor",
243
+ "code-reviewer"
244
+ ]
245
+ }
246
+ },
202
247
  {
203
248
  "id": "E2E_DESIGN",
204
249
  "label": "端到端测试设计",
205
250
  "phase": "test",
206
- "track": "backend",
207
- "prompt": "# 端到端测试设计\n\n## 节点职责\n\n判断项目是否存在适用的端到端测试体系;适用时为本次变更设计跨真实系统边界的可执行场景,不适用时记录依据。本节点只产出测试设计,不编写或执行测试代码,并通过独立 `test-reviewer` 评审设计质量。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、非目标、技术方案、生产代码与单元测试变更、前序决策,以及项目和所属模块的测试约束。加载 `workflow-discipline`,调用独立 `test-reviewer` 评审测试设计或不适用判断。\n\n读取项目提示词、测试说明、E2E 目录、配置、执行入口和现有用例,确认项目是否定义了 E2E 对象、边界、框架、环境和数据规则。缺少信息时先从仓库现状补齐,不凭通用惯例新建测试体系。\n\n## 执行流程\n\n1. 记录已检索的项目声明、目录、配置和现有用例,判断项目是否存在可用的 E2E 体系。\n2. 项目未定义 E2E 时,说明检索范围、判断依据及不引入新体系的结论,形成 N/A 产物后进入独立评审。\n3. 项目已定义 E2E 时,从需求和变更中识别必须跨真实边界验证的用户或系统路径,结合风险、现有覆盖和低层测试确定纳入与排除范围。\n4. 为每个场景写明标识、目标、优先级、前置条件、步骤、观察点、预期结果、数据准备、隔离和清理要求。场景应验证最终可观察结果,不只验证请求成功或调用发生。\n5. 覆盖正常、失败、权限、恢复、状态或兼容场景中的适用部分,并说明哪些行为已由单元或其他测试层级可靠覆盖,避免重复和遗漏;形成跨边界行为→场景映射表(每条须跨边界验证的行为对应至少一个场景 ID)。\n6. 形成最终设计,不包含测试函数、可执行 fixture、请求代码或浏览器操作代码。\n7. 将测试设计连同映射表交给 `test-reviewer`,不提供设计者结论或预期结果。委派材料按「契约 + 路标 + 已验锚点」组装:项目 E2E 约束以节选直接置入委派 prompt;需求、生产变更、现有用例给路径路标;非首轮重审随附上轮已验锚点清单。N/A 判断评审时提供检索范围与证据路标。\n8. 适用时修复 BLOCKER、HIGH Findings 后重新评审:reviewer 只重验本轮修订触及的条目与受影响锚点,未触及项沿用上轮结论,但每轮报告保持全量 Findings 快照——已解决的标记关闭,不允许静默丢弃,是否处理由主会话决策;评审至多 3 轮,第 3 轮仍未 PASS 时保留在当前节点并请用户裁定,附双方分歧清单。MEDIUM、LOW 逐项处理或记录保留理由。Findings 处理记录写入节点记录,禁止回写被评审文档——测试设计文档只保留设计本体。\n\n## 产出与检查\n\n推进前确认:\n\n- 项目 E2E 体系的适用性已有仓库证据;\n- N/A 时已记录检索范围和判断依据,未擅自新建框架、目录或入口;\n- 适用时,覆盖范围与本次跨边界行为逐项对应,纳入和排除均有理由;跨边界行为→场景映射表完整;\n- 每个场景的前置条件、步骤、观察点、预期结果和数据清理可供后续实现;\n- 与其他测试层级的边界明确,设计不含可执行测试代码,也不含评审处理记录;\n- `test-reviewer` 最终结论为 PASS(或按 3 轮上界经用户裁定通过),所有 Findings 均已处理或说明;\n- E2E 设计或 N/A 结论已形成完整产物,登记值携带全文(超限时为路径引用且已说明理由)。\n\n## 任务差异处理\n\n不默认逐接口覆盖,也不默认只测关键旅程;根据项目现有 E2E 体系、需求风险和低层覆盖确定范围。项目未定义 E2E 时不把本节点变成测试基础设施建设;若任务明确要求新建 E2E 体系,应将其作为范围与技术决策单独确认。E2E 设计文档超过约 400 行时先按场景分组拆分再送审。执行障碍和评审修订按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将 E2E 适用性、检索范围与依据、覆盖范围、场景设计、测试层级边界、数据与清理策略、不适用项及理由、设计产物(登记携带全文,超限时为路径引用且已说明理由)、`test-reviewer` 结论与各轮 Findings 处理记录写入当前节点记录——处理记录只进节点记录,被评审文档保持设计本体。完成上述检查后推进下一节点。",
251
+ "track": "all",
252
+ "prompt": "# 端到端测试设计\n\n## 节点职责\n\n判断项目是否存在适用的端到端测试体系;适用时为本次变更设计跨真实系统边界的可执行场景,不适用时记录依据;本节点对后端、界面与混合三类任务均生效。设计环节判定某场景本期做不了时,必须把该场景落成问题池 issue,不允许只留在设计文档里。本节点只产出测试设计,不编写或执行测试代码,并通过独立 `test-reviewer` 评审设计质量。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、非目标、技术方案、生产代码与低层测试变更(后端单元测试与/或前端单元测试,按任务轨道)、前序决策与节点记录中的行为场景交接建议(如视觉验证环节发现应覆盖而设计未纳入的行为),以及项目和所属模块的测试约束。加载 `workflow-discipline`,调用独立 `test-reviewer` 评审测试设计或不适用判断。\n\n读取项目提示词、测试说明、E2E 目录、配置、执行入口和现有用例,确认项目是否定义了 E2E 对象、边界、框架、环境和数据规则。缺少信息时先从仓库现状补齐,不凭通用惯例新建测试体系。\n\n## 执行流程\n\n1. 记录已检索的项目声明、目录、配置和现有用例,判断项目是否存在可用的 E2E 体系。\n2. 项目未定义 E2E 时,说明检索范围、判断依据及不引入新体系的结论,形成 N/A 产物后进入独立评审。\n3. 项目已定义 E2E 时,从需求和变更中识别必须跨真实边界验证的用户或系统路径,结合前序节点交接的行为场景、风险、现有覆盖和低层测试确定纳入与排除范围。\n4. 为每个场景写明标识、目标、优先级、前置条件、步骤、观察点、预期结果、数据准备、隔离和清理要求。场景应验证最终可观察结果,不只验证请求成功或调用发生。\n5. 覆盖正常、失败、权限、恢复、状态或兼容场景中的适用部分,并说明哪些行为已由单元测试或其他低层测试可靠覆盖,避免重复和遗漏;形成跨边界行为→场景映射表(每条须跨边界验证的行为对应至少一个场景 ID)。\n6. 逐条判定场景本次是否可做:外部条件不具备、依赖未就绪或数据准备不可行时,把该场景落成一条问题池 issue——标题写明场景,描述写清需求依据与延期理由,登记到当前任务所属项目;节点记录中写明已登记的 issue 编号。禁止只在设计文档里写“延期”而不落库;该场景何时补、是否转任务由问题池既有机制决定,本节点不另设清偿环节。\n7. 形成最终设计,不包含测试函数、可执行 fixture、请求代码或浏览器操作代码;延期场景在设计文档中保留排除状态与其 issue 编号。\n8. 将测试设计连同映射表交给 `test-reviewer`,不提供设计者结论或预期结果。委派材料按「契约 + 路标 + 已验锚点」组装:项目 E2E 约束以节选直接置入委派 prompt;需求、生产变更、现有用例给路径路标;非首轮重审随附上轮已验锚点清单。N/A 判断评审时提供检索范围与证据路标。\n9. 适用时修复 BLOCKER、HIGH Findings 后重新评审:reviewer 只重验本轮修订触及的条目与受影响锚点,未触及项沿用上轮结论,但每轮报告保持全量 Findings 快照——已解决的标记关闭,不静默丢弃,是否处理由主会话决策;评审至多 3 轮,第 3 轮仍未 PASS 时保留在当前节点并请用户裁定,附双方分歧清单。MEDIUM、LOW 逐项处理或记录保留理由。Findings 处理记录写入节点记录,禁止回写被评审文档——测试设计文档只保留设计本体。\n\n## 产出与检查\n\n推进前确认:\n\n- 项目 E2E 体系的适用性已有仓库证据;\n- N/A 时已记录检索范围和判断依据,未擅自新建框架、目录或入口;\n- 适用时,覆盖范围与本次跨边界行为逐项对应,纳入和排除均有理由;跨边界行为→场景映射表完整;\n- 每个场景的前置条件、步骤、观察点、预期结果和数据清理可供后续实现;\n- 延期场景已落成问题池 issue(标题、需求依据、延期理由、归属当前任务所属项目齐备),节点记录含 issue 编号;确无延期场景时已说明判定依据;\n- 与其他测试层级的边界明确,设计不含可执行测试代码,也不含评审处理记录;\n- `test-reviewer` 最终结论为 PASS(或按 3 轮上界经用户裁定通过),所有 Findings 均已处理或说明;\n- E2E 设计或 N/A 结论已形成完整产物,登记值携带全文(超限时为路径引用且已说明理由)。\n\n## 任务差异处理\n\n不默认逐接口覆盖,也不默认只测关键旅程;根据项目现有 E2E 体系、需求风险与低层覆盖确定范围。项目未定义 E2E 时不把本节点变成测试基础设施建设;若任务明确要求新建 E2E 体系,应将其作为范围与技术决策单独确认。场景确实无法执行时按执行流程第 6 条落问题池,不得静默删除或只在设计文档标注延期。E2E 设计文档超过约 400 行时先按场景分组拆分再送审。执行障碍和评审修订按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将 E2E 适用性、检索范围与依据、覆盖范围、场景设计、测试层级边界、数据与清理策略、延期场景的 issue 编号、前序行为场景交接的处理结果、不适用项及理由、设计产物(登记携带全文,超限时为路径引用且已说明理由)、`test-reviewer` 结论与各轮 Findings 处理记录写入当前节点记录——处理记录只进节点记录,被评审文档保持设计本体。完成上述检查后推进下一节点。",
208
253
  "skills": [
209
254
  "workflow-discipline"
210
255
  ],
@@ -213,8 +258,8 @@
213
258
  ],
214
259
  "sourcePreset": {
215
260
  "code": "test-e2e-design",
216
- "version": "1.5.0",
217
- "contentHash": "f1d0e86615f305a3",
261
+ "version": "1.6.0",
262
+ "contentHash": "8061e58e3641a86c",
218
263
  "agents": [
219
264
  "test-reviewer"
220
265
  ]
@@ -224,8 +269,8 @@
224
269
  "id": "E2E_DEV",
225
270
  "label": "端到端测试开发",
226
271
  "phase": "test",
227
- "track": "backend",
228
- "prompt": "# 端到端测试开发\n\n## 节点职责\n\n依据已确认的 E2E 设计实现并验证跨真实系统边界的测试场景;设计结论为 N/A 时复核依据并记录结果。测试代码和必要的生产代码修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、生产代码、E2E 设计、单元测试结果、前序决策,以及项目和所属模块的测试约束。加载 `coding-standards`、`workflow-discipline`;测试失败且根因不明确时,再加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取项目的 E2E 目录、配置、执行入口、邻近用例和环境规则。缺少关键信息时先从仓库现状补齐,不擅自引入项目未定义的测试体系。\n\n## 执行流程\n\n1. 读取 E2E 适用性结论并建立“设计场景 → 测试实现或已有用例”的逐项映射。\n2. 设计结论为 N/A 时,复核项目仍未定义适用的 E2E 体系;依据成立则记录 N/A,发现依据不成立则返回设计范围判断,不直接越过设计补写测试。\n3. 适用时,按项目现有框架和唯一执行入口实现测试,落实前置条件、操作步骤、观察点、预期结果、数据隔离和清理。测试必须经过项目定义的真实边界,并验证最终可观察结果。\n4. 完成一个场景或紧密相关的一组场景后,将明确的命令、范围和通过标准交给 `test-executor` 执行。\n5. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按需加载 `bugfix-root-cause-verification`,确认根因后再修改测试、生产代码或环境。\n6. 修复后重新执行原失败场景及受影响回归。不得通过删除有效测试、skip/only、绕开真实边界、缩小应执行范围、放宽正确断言、吞异常或硬编码结果制造通过。\n7. 全部场景实现后,以证据链确定 E2E 回归范围:列出本节点的测试与生产代码变更,映射到受影响场景(同一入口、同一链路、共享前置数据的用例),逐项给出执行或排除的依据。E2E 全量是须举证的主动决策而非兜底——仅当证据表明改动横切多个入口或共享基础设施时执行;未完成受影响分析就宣称无法判断、或以「保险起见」直接全量,均判定为范围决策失败。生产代码发生修复时,同样按证据链确定并执行受影响的低层测试。\n8. 检查设计映射、测试删除、skip/only、断言有效性、真实边界、数据隔离、清理和环境可重复性。\n9. 将需求、E2E 设计、项目约束和全部代码变更位置交给 `code-reviewer`,不提供实现者结论或预期结果。修复 BLOCKER、HIGH Findings 后重新执行受影响测试并复审,直至测试通过且评审为 PASS;MEDIUM、LOW 逐项处理或记录保留理由。\n\n## 产出与检查\n\n推进前确认:\n\n- N/A 结论已有复核证据,或每个适用设计场景都有对应实现或明确的已有测试;\n- 测试遵循项目现有 E2E 体系并经过真实系统边界;\n- 观察点、数据隔离、清理和环境准备符合项目约束;\n- 所有失败均在根因明确后修复,没有制造假绿;\n- `test-executor` 报告适用 E2E 和必要的低层回归全部通过,失败为 0,未授权跳过为 0;\n- 完整性检查通过,日志和报告可追溯;\n- `code-reviewer` 最终结论为 PASS,所有 Findings 均已处理或说明;\n- 测试代码、必要的生产修复和执行报告已形成可引用产物。\n\n## 任务差异处理\n\n项目没有适用的 E2E 体系时不新建框架、目录或执行入口。根据项目能力和设计范围选择测试、环境和回归方式,不套用固定浏览器、协议、命令或覆盖指标。失败修复涉及破坏性契约、新依赖或真实范围扩张时先说明影响并暂停;同一问题多轮仍不收敛时按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将 E2E 适用性复核、设计到实现的映射、测试代码变更、真实边界、数据与清理、实际执行命令、范围及判断依据、通过/失败/跳过统计、低层回归、日志与报告引用、根因和修复、完整性结论、`code-reviewer` 结论与 Findings 处理情况写入当前节点记录。完成上述检查后推进下一节点。",
272
+ "track": "all",
273
+ "prompt": "# 端到端测试开发\n\n## 节点职责\n\n依据已确认的 E2E 设计实现并验证跨真实系统边界的测试场景;设计结论为 N/A 时复核依据并记录结果;本节点对后端、界面与混合三类任务均生效。实现环节发现某场景本期确实不可执行时,必须把该场景落成问题池 issue,不允许只留在记录里当作已完成。测试代码和必要的生产代码修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、生产代码、E2E 设计(含延期场景的 issue 编号)、低层测试结果(后端单元测试与/或前端单元测试,按任务轨道)、前序决策与节点记录中的行为场景交接建议,以及项目和所属模块的测试约束。加载 `coding-standards`、`workflow-discipline`;测试失败且根因不明确时,再加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取项目的 E2E 目录、配置、执行入口、邻近用例和环境规则。缺少关键信息时先从仓库现状补齐,不擅自引入项目未定义的测试体系。\n\n## 执行流程\n\n1. 读取 E2E 适用性结论并建立“设计场景 → 测试实现或已有用例”的逐项映射;设计中标为延期的场景按其 issue 编号核对,不重复实现或重复登记。\n2. 设计结论为 N/A 时,复核项目仍未定义适用的 E2E 体系;依据成立则记录 N/A,发现依据不成立则返回设计范围判断,不直接越过设计补写测试。\n3. 适用时,按项目现有框架和唯一执行入口实现测试,落实前置条件、操作步骤、观察点、预期结果、数据隔离和清理。测试必须经过项目定义的真实边界,并验证最终可观察结果。\n4. 实现中发现某场景本期确实不可执行时,把该场景落成一条问题池 issue——标题写明场景,描述写清需求依据与延期理由(本期不可执行原因),登记到当前任务所属项目,并将 issue 编号写入节点记录;不得通过删除测试、跳过标记或缩水断言代替登记。\n5. 完成一个场景或紧密相关的一组场景后,将明确的命令、范围和通过标准交给 `test-executor` 执行。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按需加载 `bugfix-root-cause-verification`,确认根因后再修改测试、生产代码或环境。\n7. 修复后重新执行原失败场景及受影响回归。不得通过删除有效测试、skip/only、绕开真实边界、缩小应执行范围、放宽正确断言、吞异常或硬编码结果制造通过。\n8. 全部场景实现后,以证据链确定 E2E 回归范围:列出本节点的测试与生产代码变更,映射到受影响场景(同一入口、同一链路、共享前置数据的用例),逐项给出执行或排除的依据。E2E 全量是须举证的主动决策而非兜底——仅当证据表明改动横切多个入口或共享基础设施时执行;未完成受影响分析就宣称无法判断、或以“保险起见”直接全量,均判定为范围决策失败。生产代码发生修复时,同样按证据链确定并执行受影响的低层测试(含前端单测,按任务轨道)。\n9. 检查设计映射(含延期场景的 issue 编号)、测试删除、skip/only、断言有效性、真实边界、数据隔离、清理和环境可重复性。\n10. 将需求、E2E 设计、项目约束和全部代码变更位置交给 `code-reviewer`,不提供实现者结论或预期结果。修复 BLOCKER、HIGH Findings 后重新执行受影响测试并复审,直至测试通过且评审为 PASS;MEDIUM、LOW 逐项处理或记录保留理由。\n\n## 产出与检查\n\n推进前确认:\n\n- N/A 结论已有复核证据,或每个适用设计场景都有对应实现、明确的已有测试,或已落问题池 issue 并在节点记录留有编号;\n- 测试遵循项目现有 E2E 体系并经过真实系统边界;\n- 观察点、数据隔离、清理和环境准备符合项目约束;\n- 所有失败均在根因明确后修复,没有制造假绿;\n- `test-executor` 报告适用 E2E 和必要的低层回归全部通过,失败为 0,未授权跳过为 0;\n- 延期登记未被删除测试、跳过标记或缩水断言替代;\n- 完整性检查通过,日志和报告可追溯;\n- `code-reviewer` 最终结论为 PASS,所有 Findings 均已处理或说明;\n- 测试代码、必要的生产修复和执行报告已形成可引用产物。\n\n## 任务差异处理\n\n项目没有适用的 E2E 体系时不新建框架、目录或执行入口。根据项目能力和设计范围选择测试、环境和回归方式,不套用固定浏览器、协议、命令或覆盖指标。失败修复涉及破坏性契约、新依赖或真实范围扩张时先说明影响并暂停;同一问题多轮仍不收敛时按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将 E2E 适用性复核、设计到实现的映射、测试代码变更、真实边界、数据与清理、实际执行命令、范围及判断依据、通过/失败/跳过统计、延期场景的 issue 编号、低层回归(含前端单测,按任务轨道)、日志与报告引用、根因和修复、完整性结论、`code-reviewer` 结论与 Findings 处理情况写入当前节点记录。完成上述检查后推进下一节点。",
229
274
  "skills": [
230
275
  "coding-standards",
231
276
  "workflow-discipline"
@@ -236,8 +281,8 @@
236
281
  ],
237
282
  "sourcePreset": {
238
283
  "code": "test-e2e-implement",
239
- "version": "1.3.1",
240
- "contentHash": "4c0b71a785fe001a",
284
+ "version": "1.4.0",
285
+ "contentHash": "8b98aa2366937442",
241
286
  "agents": [
242
287
  "test-executor",
243
288
  "code-reviewer"
@@ -347,10 +392,6 @@
347
392
  "autoResume": false
348
393
  }
349
394
  },
350
- {
351
- "from": "CODE_UI",
352
- "to": "UI_VISUAL"
353
- },
354
395
  {
355
396
  "from": "CODE_BACKEND",
356
397
  "to": "UT_DESIGN"
@@ -369,19 +410,36 @@
369
410
  }
370
411
  },
371
412
  {
372
- "from": "E2E_DESIGN",
373
- "to": "E2E_DEV"
413
+ "from": "UT_DEV",
414
+ "to": "CODE_UI"
374
415
  },
375
416
  {
376
- "from": "E2E_DEV",
377
- "to": "CODE_UI"
417
+ "from": "CODE_UI",
418
+ "to": "UI_UT_DESIGN"
378
419
  },
379
420
  {
380
- "from": "E2E_DEV",
381
- "to": "INTEGRATE"
421
+ "from": "UI_UT_DESIGN",
422
+ "to": "UI_UT_DEV"
423
+ },
424
+ {
425
+ "from": "UI_UT_DEV",
426
+ "to": "UI_VISUAL"
382
427
  },
383
428
  {
384
429
  "from": "UI_VISUAL",
430
+ "to": "E2E_DESIGN",
431
+ "pausePoint": {
432
+ "type": "checkpoint",
433
+ "description": "代码检查点提交 + 节点归档(视觉验证 → E2E 设计;git commit + 记录归档,无需用户决策)",
434
+ "autoResume": true
435
+ }
436
+ },
437
+ {
438
+ "from": "E2E_DESIGN",
439
+ "to": "E2E_DEV"
440
+ },
441
+ {
442
+ "from": "E2E_DEV",
385
443
  "to": "INTEGRATE"
386
444
  },
387
445
  {
@@ -400,64 +458,72 @@
400
458
  ],
401
459
  "layout": {
402
460
  "PRD": {
403
- "x": 170,
461
+ "x": 110,
404
462
  "y": 40
405
463
  },
406
464
  "ALIGN": {
407
- "x": 170,
465
+ "x": 110,
408
466
  "y": 184
409
467
  },
410
468
  "DESIGN": {
411
- "x": 170,
469
+ "x": 110,
412
470
  "y": 328
413
471
  },
414
472
  "INTERACTION": {
415
- "x": 170,
473
+ "x": 110,
416
474
  "y": 472
417
475
  },
418
476
  "CODE_BACKEND": {
419
- "x": 300,
420
- "y": 616
477
+ "x": 178.71533661918517,
478
+ "y": 618.5693267616297
479
+ },
480
+ "CODE_UI": {
481
+ "x": -150.13018036059404,
482
+ "y": 622.7764209502931
483
+ },
484
+ "UI_VISUAL": {
485
+ "x": -150.130180360594,
486
+ "y": 1041.9297871421447
421
487
  },
422
488
  "UT_DESIGN": {
423
- "x": 300,
489
+ "x": 180,
424
490
  "y": 760
425
491
  },
426
492
  "UT_DEV": {
427
- "x": 300,
493
+ "x": 180,
428
494
  "y": 904
429
495
  },
430
- "E2E_DESIGN": {
431
- "x": 300,
432
- "y": 1048
496
+ "UI_UT_DESIGN": {
497
+ "x": -150.130180360594,
498
+ "y": 759.0684406654042
433
499
  },
434
- "E2E_DEV": {
435
- "x": 300,
436
- "y": 1192
500
+ "UI_UT_DEV": {
501
+ "x": -150.130180360594,
502
+ "y": 905.6377674270339
437
503
  },
438
- "CODE_UI": {
439
- "x": 40,
440
- "y": 616
504
+ "E2E_DESIGN": {
505
+ "x": 110,
506
+ "y": 1191.0684406654043
441
507
  },
442
- "UI_VISUAL": {
443
- "x": 40,
444
- "y": 760
508
+ "E2E_DEV": {
509
+ "x": 110,
510
+ "y": 1319.6524800956263
445
511
  },
446
512
  "INTEGRATE": {
447
- "x": 170,
448
- "y": 1336
513
+ "x": 110,
514
+ "y": 1462.3678167148114
449
515
  },
450
516
  "ACCEPT": {
451
- "x": 170,
452
- "y": 1480
517
+ "x": 111.28466338081483,
518
+ "y": 1599.9444998107372
453
519
  },
454
520
  "ARCHIVE": {
455
- "x": 170,
456
- "y": 1624
521
+ "x": 110,
522
+ "y": 1745.229163191552
457
523
  }
458
524
  },
459
525
  "isDefault": false,
460
- "version": "3.5.2"
526
+ "version": "3.6.1"
461
527
  },
462
528
  "dependencies": {
463
529
  "skills": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "exportFormatVersion": "1.0",
3
- "exportedAt": "2026-09-15T08:13:01.507Z",
3
+ "exportedAt": "2026-09-17T14:14:30.455Z",
4
4
  "warnings": [],
5
5
  "template": {
6
6
  "name": "quick_workflow",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "exportFormatVersion": "1.0",
3
- "exportedAt": "2026-09-15T08:13:01.505Z",
3
+ "exportedAt": "2026-09-17T14:14:30.453Z",
4
4
  "warnings": [],
5
5
  "template": {
6
6
  "name": "research_workflow",