@tea-agent/loop-agent 0.42.0-next.9 → 0.43.0-next.1

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.
Files changed (157) hide show
  1. package/CHANGELOG.md +65 -59
  2. package/dist/application/dag/run-dag.js +3 -2
  3. package/dist/application/task-lifecycle/advance.js +9 -4
  4. package/dist/build-stamp.json +3 -3
  5. package/dist/cli/program.js +1 -1
  6. package/dist/commands/dag-rerun-task.js +2 -0
  7. package/dist/commands/task-source-prepare.js +3 -1
  8. package/dist/executors/dag-pi-executor.js +1514 -175
  9. package/dist/executors/pi-extension-resolver.js +14 -2
  10. package/dist/executors/shell-executor.js +131 -54
  11. package/dist/shared/dag-failure-category.js +6 -0
  12. package/dist/task/contract/apply.js +36 -2
  13. package/dist/task/source-prepare/parse-intent.js +7 -0
  14. package/dist/worker/console/chat/chat-event-store.js +4 -2
  15. package/dist/worker/console/chat/pi-runtime.js +45 -2
  16. package/dist/worker/console/chat/resource-loader.js +4 -1
  17. package/dist/worker/console/chat/routes.js +28 -12
  18. package/dist/worker/console/chat/sdd-data-alignment.js +13 -2
  19. package/dist/worker/console/chat/session-store.js +5 -1
  20. package/dist/worker/console/chat/subagents/agent-tool.js +62 -0
  21. package/dist/worker/console/chat/subagents/explore-agent.js +169 -0
  22. package/dist/worker/console/chat/subagents/index.js +5 -0
  23. package/dist/worker/console/chat/subagents/orchestrator.js +273 -0
  24. package/dist/worker/console/chat/subagents/tool-policy.js +53 -0
  25. package/dist/worker/console/chat/subagents/types.js +13 -0
  26. package/dist/worker/console/chat/tool-preview.js +10 -0
  27. package/dist/worker/console/chat/tools.js +11 -1
  28. package/dist/worker/console/chat/turn-process.js +1 -0
  29. package/dist/worker/console/interview/tools.js +1 -0
  30. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C6n9_m0P.js → abnfDiagram-N423BO3Z-B0Q0nClf.js} +1 -1
  31. package/dist/worker/console/static/assets/{arc-DQh-IfZ1.js → arc-DCPjC19G.js} +1 -1
  32. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-54NnrwUC.js → architectureDiagram-T3A2C74G-CP5n9jmG.js} +1 -1
  33. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-pivRALGK.js → blockDiagram-VBNYF7ZC-CmaWi_Wg.js} +1 -1
  34. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BR7OV2NJ.js → c4Diagram-5PPSVZJV-Ct5tcMfZ.js} +1 -1
  35. package/dist/worker/console/static/assets/channel-DAS07MdS.js +1 -0
  36. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-B1Aq6BcK.js → chunk-2GRJ4B5K-C0osm1Zf.js} +1 -1
  37. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CbdU0rjo.js → chunk-2Q5K7J3B-CDWviED7.js} +1 -1
  38. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-Dqi2GJeD.js → chunk-5RXB4S5H-mtSk1-j7.js} +1 -1
  39. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BYn1Hu4R.js → chunk-5VM5RSS4-D5J9PHC7.js} +1 -1
  40. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DRLjDL0k.js → chunk-6Q2QTUOP-Begg4WAa.js} +1 -1
  41. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CY9Xx2jV.js → chunk-GF5L2VYU-sF1AEy7T.js} +1 -1
  42. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BNCZs7_z.js → chunk-JWPE2WC7-BqbsWXZb.js} +1 -1
  43. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DZ8AStLL.js → chunk-KBJHAD2P-BKJrPcJ6.js} +1 -1
  44. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DsxjYrzz.js → chunk-RYQCIY6F-CcwNMRho.js} +1 -1
  45. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-Ddx1KC1l.js → chunk-XXDRQBXY-BEJi3iIs.js} +1 -1
  46. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Cwk-5jiW.js +1 -0
  47. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Cwk-5jiW.js +1 -0
  48. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-W9TveCnK.js → cose-bilkent-JH36ORCC-DRLgTvVu.js} +1 -1
  49. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-l9j_ztZH.js → cynefin-VYW2F7L2-BoAVG3cs.js} +1 -1
  50. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BMJMKi4G.js → cynefinDiagram-MW4NZA55-Bzol06hR.js} +1 -1
  51. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-Bb4mG9pH.js → dagre-VZM6K2ZE-UmliJM77.js} +1 -1
  52. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BMgL_Qv0.js → diagram-7IWD3JNH-BWLcJkFo.js} +1 -1
  53. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-Bvo2T4OQ.js → diagram-B4RE2ZJO-CgApOm-O.js} +1 -1
  54. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-_5kWRN9c.js → diagram-LBJQPF4R-Bh3RgTLs.js} +1 -1
  55. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DqdMrltM.js → diagram-Q27KOJAE-Dsh-D5nE.js} +1 -1
  56. package/dist/worker/console/static/assets/{diagram-UB23O5K3-CDDYsNkp.js → diagram-UB23O5K3-Dkbbpcpb.js} +1 -1
  57. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-c4nfnZUV.js → ebnfDiagram-BXEA7PRR-3EBaA3t3.js} +1 -1
  58. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DnkUcNMs.js → erDiagram-JOGREHBK-Bq2Dc5ok.js} +1 -1
  59. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-Dz0KGLZE.js → flowDiagram-UKHOOZJN-De7y55ha.js} +1 -1
  60. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-Cj1t1uka.js → ganttDiagram-PKOTCBZU-fLiDbQRh.js} +1 -1
  61. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-tp2FrBHd.js → gitGraphDiagram-DS77QQ5N-Du617mp1.js} +1 -1
  62. package/dist/worker/console/static/assets/index-C0O48S_P.js +449 -0
  63. package/dist/worker/console/static/assets/index-CzKf4U8P.css +1 -0
  64. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DQwJS8DH.js → infoDiagram-6WML65LV-BwmlF-XP.js} +1 -1
  65. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-eimCQWD4.js → ishikawaDiagram-WSZJBQD7-zsGtS59u.js} +1 -1
  66. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-Dd9Gbwgv.js → journeyDiagram-NVQOT4AX-DTTPTe3f.js} +1 -1
  67. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Qve3cyft.js → kanban-definition-27J2QSJJ-BkXg9aP-.js} +1 -1
  68. package/dist/worker/console/static/assets/{linear-UXKSe36Z.js → linear-7U2ue5IE.js} +1 -1
  69. package/dist/worker/console/static/assets/{mermaid.core-CWhj4JXN.js → mermaid.core-BUuGHmWO.js} +5 -5
  70. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-yTcwf4SJ.js → mindmap-definition-FAOFIHXS-7q6fX0Sv.js} +1 -1
  71. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-_7qToaZP.js → pegDiagram-VL7TDLO6-CkQPJN55.js} +1 -1
  72. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CXmrKmDm.js → pieDiagram-7S7Q4E2Y-CCal_tfX.js} +1 -1
  73. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-hMmrJyaS.js → quadrantDiagram-CIZ2JOQS-B7bpxyAZ.js} +1 -1
  74. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BXw8tCBe.js → railroadDiagram-AXF67PYL-CJmww7D-.js} +1 -1
  75. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BmjgnLZl.js → requirementDiagram-LRYGKXZP-D6ldWJEv.js} +1 -1
  76. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Bj77SPpN.js → sankeyDiagram-W5VNT64P-VGh33I9e.js} +1 -1
  77. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-B2FDVysL.js → sequenceDiagram-SI44F4Z6-CCkDrIjU.js} +1 -1
  78. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-UChNY9ZZ.js → sizeCapture-X5ZJPWSS-NC8f5Otb.js} +1 -1
  79. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-wbAEkbd7.js → stateDiagram-OKZ733FA-_92ezZdF.js} +1 -1
  80. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DyJg5gzW.js +1 -0
  81. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DCEkU8HR.js → swimlanes-SLNWSIFB-BdUCGtbP.js} +2 -2
  82. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-B1cw_0Uy.js +8 -0
  83. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-BGp7H06U.js → timeline-definition-Z64GVDOM-CdD1H8ia.js} +1 -1
  84. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DsCIQuWR.js → vennDiagram-T6HMQDX7-Dkdk3oFo.js} +1 -1
  85. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-cRZLP4Xe.js → wardleyDiagram-T6FBY63Y-CKu2uPPY.js} +1 -1
  86. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CP0xLR9Y.js → xychartDiagram-ELKLHX3M-ClqAnuG8.js} +1 -1
  87. package/dist/worker/console/static/index.html +2 -2
  88. package/dist/worker/console/static-src/chat-view-types.js +1 -1
  89. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +23 -0
  90. package/dist/worker/console/static-src/operator-chat/pending-user-message.js +32 -0
  91. package/dist/worker/console/static-src/operator-chat/tools-catalog.js +21 -2
  92. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +2 -0
  93. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +2 -0
  94. package/dist/worker/console/static-src/operator-chat/useChatStream.js +30 -14
  95. package/dist/worker/console/static-src/operator-chat/useChatThread.js +133 -5
  96. package/dist/worker/console/static-src/shell/workspace-route.js +4 -0
  97. package/dist/worker/observe/static/constants.js +22 -22
  98. package/dist/worker/observe/static/dag-context-reason-labels.js +19 -0
  99. package/dist/worker/observe/static/dag-history-labels.js +1 -0
  100. package/dist/worker/observe/static/dag-inspector-humanize.d.ts +16 -0
  101. package/dist/worker/observe/static/dag-inspector-humanize.js +339 -0
  102. package/dist/worker/observe/static/dag-node-purpose.js +10 -10
  103. package/dist/worker/observe/static/index.html +4 -4
  104. package/dist/worker/observe/static/prompt-restart-candidates.js +4 -2
  105. package/dist/worker/observe/static/relations.js +5 -5
  106. package/dist/worker/observe/static/styles.css +171 -0
  107. package/dist/worker/observe/static/views/dag-graph.js +1 -1
  108. package/dist/worker/observe/static/views/dag-inspector.js +329 -174
  109. package/dist/worker/observe/static/views/dag.js +16 -12
  110. package/dist/worker/observe/static/views/session-timeline.js +5 -3
  111. package/dist/workflows/dag/backend-test-plan-protocol.js +104 -0
  112. package/dist/workflows/dag/dag-retry-schema.js +3 -0
  113. package/dist/workflows/dag/frontend-contract-facts.js +130 -0
  114. package/dist/workflows/dag/frontend-design-policy.js +101 -16
  115. package/dist/workflows/dag/frontend-implementation-contract.js +410 -41
  116. package/dist/workflows/dag/frontend-plan-render.js +13 -2
  117. package/dist/workflows/dag/frontend-prewrite-gate.js +1 -1
  118. package/dist/workflows/dag/frontend-recovery-controller.js +25 -1
  119. package/dist/workflows/dag/frontend-recovery-plan.js +4 -1
  120. package/dist/workflows/dag/frontend-recovery-run.js +142 -16
  121. package/dist/workflows/dag/frontend-risk.js +2 -0
  122. package/dist/workflows/dag/frontend-shadow-dual-write.js +17 -1
  123. package/dist/workflows/dag/frontend-shape.js +16 -6
  124. package/dist/workflows/dag/frontend-test-execution-evidence.js +48 -0
  125. package/dist/workflows/dag/frontend-typed-event-store.js +3 -0
  126. package/dist/workflows/dag/frontend-verification-trace.js +38 -4
  127. package/dist/workflows/dag/frontend-writer-admission.js +2 -2
  128. package/dist/workflows/dag/init-hybrid.js +57 -28
  129. package/dist/workflows/dag/node-execution.js +201 -85
  130. package/dist/workflows/dag/recovery-lease.js +106 -16
  131. package/dist/workflows/dag/rerun-feedback.js +1 -0
  132. package/dist/workflows/dag/rerun-plan.js +90 -4
  133. package/dist/workflows/dag/rerun-run.js +28 -6
  134. package/dist/workflows/dag/rerun-task.js +221 -18
  135. package/dist/workflows/dag/retry-policy.js +27 -10
  136. package/dist/workflows/dag/runner-exit-diagnostics.js +125 -0
  137. package/dist/workflows/dag/runner.js +220 -18
  138. package/dist/workflows/dag/structured-output-repair.js +4 -1
  139. package/dist/workflows/dag/types.js +4 -3
  140. package/dist/workflows/dag/validate.js +10 -8
  141. package/dist/workflows/dag/workspace-checkpoint.js +66 -0
  142. package/docs/operations/README.md +1 -0
  143. package/docs/templates/agent-dag.schema.json +2 -2
  144. package/docs/templates/backend-test-dag.json +6 -4
  145. package/docs/templates/frontend-implementation-contract.schema.json +34 -2
  146. package/harness.json +1 -1
  147. package/package.json +4 -5
  148. package/skills/frontend-plan/SKILL.md +14 -1
  149. package/skills/frontend-plan/references/decision-contract.md +101 -5
  150. package/skills/frontend-plan/references/design-decisions.md +32 -0
  151. package/dist/worker/console/static/assets/channel-DsZxrgqe.js +0 -1
  152. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-CuToPeGV.js +0 -1
  153. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-CuToPeGV.js +0 -1
  154. package/dist/worker/console/static/assets/index-D9Sc0f0y.js +0 -449
  155. package/dist/worker/console/static/assets/index-DDQc5a50.css +0 -1
  156. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-yPoT19ft.js +0 -1
  157. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-VWdarchG.js +0 -8
@@ -0,0 +1,339 @@
1
+ /**
2
+ * Human-readable copy for the DAG node inspector.
3
+ *
4
+ * API payloads keep their stable machine fields and enum values. The inspector
5
+ * uses these maps only at render time and preserves the raw terms in titles so
6
+ * diagnostics remain available without making them the primary UI language.
7
+ */
8
+
9
+ const FIELD_LABELS = Object.freeze({
10
+ executor: "执行方式",
11
+ role: "节点职责",
12
+ complexity: "任务复杂度",
13
+ writePolicy: "写入权限",
14
+ toolProfile: "可用工具范围",
15
+ depends_on: "需要先完成的节点",
16
+ dependsPolicy: "前置节点要求",
17
+ failureAwareDependsOn: "失败时仍可读取的前置节点",
18
+ runIf: "什么情况下执行",
19
+ kind: "执行类型",
20
+ modelHint: "建议使用的模型",
21
+ preset: "预设处理流程",
22
+ cwd: "执行目录",
23
+ timeoutMs: "超时时间(毫秒)",
24
+ nonZeroExitPolicy: "命令失败时如何处理",
25
+ gates: "执行前后检查",
26
+ handlers: "内部处理器",
27
+ status: "当前状态",
28
+ outputMode: "输出形式",
29
+ firstProtocolLine: "首行格式要求",
30
+ resolved: "成功加载的扩展",
31
+ requested: "计划加载的扩展",
32
+ sha256: "内容校验码",
33
+ lengthChars: "字符数",
34
+ artifact: "记录文件",
35
+ run: "运行编号",
36
+ node: "节点编号",
37
+ model: "使用模型",
38
+ rank: "执行顺序",
39
+ origin: "结果来源",
40
+ duration: "耗时",
41
+ attempt: "第几次执行",
42
+ declared: "是否找到运行前设置",
43
+ dispatched: "是否已把任务交给执行器",
44
+ "node status": "节点状态",
45
+ "context digest": "本次上下文校验码",
46
+ "captured at": "记录时间",
47
+ components: "上下文组成项数量",
48
+ truncations: "被截断的内容数量",
49
+ skills: "加载的技能数量",
50
+ extensions: "加载的扩展数量",
51
+ tools: "可用工具数量",
52
+ parent: "来源运行",
53
+ "graph sha256": "文件关系校验码",
54
+ path: "文件位置",
55
+ media: "文件类型",
56
+ schema: "数据格式",
57
+ materialization: "文件生成状态",
58
+ bytes: "文件大小(字节)",
59
+ revision: "是否可以替换",
60
+ supersedes: "替换前版本校验码",
61
+ producer: "由哪个节点生成",
62
+ required: "是否必须使用",
63
+ "Direct consumers": "会直接使用此文件的节点",
64
+ "运行类型": "运行类型",
65
+ "来源运行": "来源运行",
66
+ "发起方式": "为什么创建这次运行",
67
+ "人工选择节点": "人工选择的起点",
68
+ "从此节点重新执行": "实际重新执行的起点",
69
+ "重跑计划哈希": "重跑计划校验码",
70
+ });
71
+
72
+ const FIELD_HELP = Object.freeze({
73
+ executor: "这一步是由 AI、命令,还是系统规则来完成。",
74
+ role: "这个节点在整条流程里负责规划、修改、审查还是验证。",
75
+ complexity: "系统对这一步工作量和推理难度的预估。",
76
+ writePolicy: "这一步是否能修改文件,以及能修改到什么程度。",
77
+ toolProfile: "这一步被允许使用哪一类工具。",
78
+ depends_on: "这些节点完成后,这一步才能开始。",
79
+ dependsPolicy: "前置节点出现失败或跳过时,这一步是否还能继续。",
80
+ failureAwareDependsOn: "即使这些前置节点失败,本节点仍可读取它们留下的信息。",
81
+ runIf: "只有预设条件成立时,这一步才会执行。",
82
+ kind: "系统实际采用的执行方法。",
83
+ modelHint: "配置建议使用的 AI 模型,实际模型以执行记录为准。",
84
+ preset: "系统预先定义好的一套处理步骤。",
85
+ cwd: "命令从哪个文件夹开始运行。",
86
+ timeoutMs: "执行超过这段时间后会被判定为超时。",
87
+ nonZeroExitPolicy: "命令返回失败时,是立即停止还是仅记录结果。",
88
+ gates: "开始或结束前必须通过的检查。",
89
+ handlers: "这个节点内部会依次调用的处理步骤。",
90
+ status: "这一步目前进行到什么状态。",
91
+ outputMode: "结果需要按普通文本还是固定结构返回。",
92
+ firstProtocolLine: "结果第一行必须遵守的格式。",
93
+ resolved: "实际成功加载并可供节点使用的扩展。",
94
+ requested: "运行计划原本要求加载的扩展。",
95
+ sha256: "用于确认内容有没有变化的一串校验值。",
96
+ lengthChars: "保存内容包含多少个字符。",
97
+ artifact: "这条记录在工作区中的保存位置。",
98
+ run: "这次完整运行的唯一编号。",
99
+ node: "当前步骤的唯一编号。",
100
+ model: "这一步实际使用的 AI 模型。",
101
+ rank: "这一步位于依赖流程的第几层,不等同于执行次数。",
102
+ origin: "当前结果是本次生成、沿用旧结果,还是人工替换而来。",
103
+ duration: "这一步从开始到结束花费的时间。",
104
+ attempt: "当前查看的是第几次执行尝试。",
105
+ declared: "运行开始前是否保存了这一步的设置。",
106
+ dispatched: "任务是否已经真正交给执行器。",
107
+ "node status": "交给执行器之后,这一步最终处于什么状态。",
108
+ "context digest": "用于确认节点实际收到的整组内容是否变化。",
109
+ "captured at": "系统记录节点实际上下文的时间。",
110
+ components: "节点实际收到的上下文由多少部分组成。",
111
+ truncations: "有多少部分因为过长而只提供了节选。",
112
+ skills: "本次执行实际提供了多少项技能。",
113
+ extensions: "本次执行实际加载了多少个扩展。",
114
+ tools: "本次执行允许调用多少种工具。",
115
+ parent: "当前运行是从哪一次旧运行继续而来。",
116
+ "graph sha256": "用于确认文件生产和使用关系没有变化。",
117
+ path: "文件在工作区中的相对位置。",
118
+ media: "文件的内容类型,例如 JSON 或纯文本。",
119
+ schema: "结构化文件必须符合的数据规则。",
120
+ materialization: "登记的文件是否已经真实生成,并且与记录一致。",
121
+ bytes: "文件占用的存储大小。",
122
+ revision: "这个文件是否允许上传新版本并从后续节点继续。",
123
+ supersedes: "被当前版本替换掉的旧文件校验值。",
124
+ producer: "最初生成这个文件的节点。",
125
+ required: "后续节点是否必须使用这个文件。",
126
+ "Direct consumers": "会直接读取这个文件的下一批节点。",
127
+ "运行类型": "这是首次运行,还是从旧运行继续创建的新运行。",
128
+ "来源运行": "新运行所依据的旧运行编号。",
129
+ "发起方式": "为什么会从旧运行创建这次新运行。",
130
+ "人工选择节点": "操作者希望从哪个节点开始重新执行。",
131
+ "从此节点重新执行": "系统检查依赖后,最终决定从哪个节点开始。",
132
+ "重跑计划哈希": "用于确认预览计划和真正执行时的计划完全一致。",
133
+ });
134
+
135
+ const FIELD_VALUE_LABELS = Object.freeze({
136
+ executor: {
137
+ pi: "AI 执行",
138
+ shell: "命令执行",
139
+ static: "系统直接生成",
140
+ },
141
+ kind: {
142
+ pi: "AI 执行",
143
+ shell: "命令执行",
144
+ static: "系统直接生成",
145
+ },
146
+ complexity: {
147
+ LOW: "较简单",
148
+ MED: "中等",
149
+ HIGH: "较复杂",
150
+ },
151
+ role: {
152
+ planner: "任务规划",
153
+ implementer: "执行修改",
154
+ reviewer: "结果审查",
155
+ verifier: "验证结果",
156
+ closeout: "收尾确认",
157
+ scout: "信息收集",
158
+ supervisor: "流程监督",
159
+ },
160
+ writePolicy: {
161
+ "read-only": "只读,不修改文件",
162
+ exclusive: "仅此节点可以修改指定文件",
163
+ "docs-only": "只允许修改文档",
164
+ },
165
+ toolProfile: {
166
+ "read-only": "只读工具",
167
+ write: "可修改文件的工具",
168
+ },
169
+ status: {
170
+ PENDING: "等待执行",
171
+ RUNNING: "正在执行",
172
+ FINISHED: "已完成",
173
+ ERROR: "执行失败",
174
+ SKIPPED: "已跳过",
175
+ pending: "等待执行",
176
+ running: "正在执行",
177
+ finished: "已完成",
178
+ completed: "已完成",
179
+ succeeded: "成功",
180
+ failed: "失败",
181
+ error: "执行失败",
182
+ skipped: "已跳过",
183
+ captured: "已记录",
184
+ missing: "没有记录",
185
+ invalid: "记录不可用",
186
+ available: "可用",
187
+ unavailable: "不可用",
188
+ },
189
+ declared: {
190
+ available: "已保存",
191
+ missing: "未保存",
192
+ invalid: "记录不可用",
193
+ },
194
+ dispatched: {
195
+ dispatched: "已下发",
196
+ pending: "尚未下发",
197
+ missing: "没有下发记录",
198
+ },
199
+ dependsPolicy: {
200
+ all: "所有前置节点成功后才执行",
201
+ "all-or-condition-skip": "前置节点成功,或按条件允许跳过后执行",
202
+ },
203
+ nonZeroExitPolicy: {
204
+ fail: "命令失败就停止",
205
+ record: "记录失败结果后继续",
206
+ },
207
+ outputMode: {
208
+ "structured-required": "必须按固定结构输出",
209
+ text: "普通文本",
210
+ },
211
+ "node status": {
212
+ PENDING: "等待执行",
213
+ RUNNING: "正在执行",
214
+ FINISHED: "已完成",
215
+ ERROR: "执行失败",
216
+ SKIPPED: "已跳过",
217
+ },
218
+ materialization: {
219
+ materialized: "文件已生成",
220
+ missing: "文件缺失",
221
+ mismatch: "文件与登记信息不一致",
222
+ "not-recorded": "没有生成记录",
223
+ },
224
+ revision: {
225
+ eligible: "可以替换",
226
+ blocked: "不能替换",
227
+ },
228
+ origin: {
229
+ executed: "本次运行生成",
230
+ imported: "沿用上一次运行的结果",
231
+ overridden: "使用了人工替换的新文件",
232
+ unknown: "暂时无法确定",
233
+ },
234
+ required: {
235
+ yes: "必须使用",
236
+ no: "可选",
237
+ true: "必须使用",
238
+ false: "可选",
239
+ },
240
+ "发起方式": {
241
+ "artifact-override": "替换产出后继续",
242
+ "prompt-override": "修改提示词后重跑",
243
+ "node-rerun": "从指定节点重跑",
244
+ },
245
+ "运行类型": {
246
+ root: "首次运行",
247
+ continuation: "从旧运行继续的新运行",
248
+ },
249
+ "差异类型": {
250
+ text: "文本文件",
251
+ json: "结构化数据文件(JSON)",
252
+ binary: "二进制文件",
253
+ },
254
+ "风险级别": {
255
+ low: "较低",
256
+ medium: "中等",
257
+ high: "较高",
258
+ },
259
+ });
260
+
261
+ const LIST_LABELS = Object.freeze({
262
+ skills: "可用技能",
263
+ "piExtensions(声明)": "计划加载的 AI 扩展",
264
+ requested: "计划加载的扩展",
265
+ allowedPaths: "允许读取或修改的范围",
266
+ forbiddenPaths: "禁止访问或修改的范围",
267
+ writeSet: "本节点实际可以修改的范围",
268
+ "Direct consumers": "会直接使用此文件的节点",
269
+ });
270
+
271
+ const COMMON_VALUE_LABELS = Object.freeze({
272
+ unknown: "暂时无法确定",
273
+ "(none)": "无",
274
+ "(parse failed)": "无法解析",
275
+ pass: "通过",
276
+ fail: "失败",
277
+ warning: "有提醒",
278
+ true: "是",
279
+ false: "否",
280
+ "system-prompt": "系统说明",
281
+ "developer-prompt": "开发约束",
282
+ "user-prompt": "用户要求",
283
+ "task-contract": "任务约定",
284
+ "execution-constraint": "执行限制",
285
+ "context-file": "补充资料",
286
+ "upstream-artifact": "上游文件",
287
+ "tool-contract": "工具使用规则",
288
+ "runtime-fact": "运行信息",
289
+ full: "完整包含",
290
+ excerpt: "只包含节选",
291
+ summary: "只包含摘要",
292
+ "reference-only": "只提供引用位置",
293
+ omitted: "未包含",
294
+ });
295
+
296
+ export function inspectorFieldLabel(field) {
297
+ const raw = String(field ?? "");
298
+ return FIELD_LABELS[raw] ?? LIST_LABELS[raw] ?? raw;
299
+ }
300
+
301
+ export function inspectorValueLabel(field, value) {
302
+ const rawField = String(field ?? "");
303
+ const rawValue = String(value ?? "");
304
+ if (rawField === "runIf" && rawValue) return "满足预设条件时执行";
305
+ return (
306
+ FIELD_VALUE_LABELS[rawField]?.[rawValue] ??
307
+ COMMON_VALUE_LABELS[rawValue] ??
308
+ rawValue
309
+ );
310
+ }
311
+
312
+ export function inspectorFieldHelp(field) {
313
+ return FIELD_HELP[String(field ?? "")] ?? null;
314
+ }
315
+
316
+ export function inspectorListValueLabel(value) {
317
+ const raw = String(value ?? "");
318
+ const separator = raw.indexOf(":");
319
+ if (separator > 0) {
320
+ const token = raw.slice(0, separator);
321
+ const humanToken = COMMON_VALUE_LABELS[token];
322
+ if (humanToken) return `${humanToken}${raw.slice(separator)}`;
323
+ }
324
+ return COMMON_VALUE_LABELS[raw] ?? raw;
325
+ }
326
+
327
+ export function describeInspectorMeta(field, value) {
328
+ const rawLabel = String(field ?? "");
329
+ const rawValueText = String(value ?? "");
330
+ const label = inspectorFieldLabel(rawLabel);
331
+ const humanValue = inspectorValueLabel(rawLabel, rawValueText);
332
+ return {
333
+ label,
334
+ value: humanValue,
335
+ help: inspectorFieldHelp(rawLabel),
336
+ rawLabel: label === rawLabel ? null : rawLabel,
337
+ rawValue: humanValue === rawValueText ? null : rawValueText,
338
+ };
339
+ }
@@ -12,7 +12,7 @@ const NODE_PURPOSE_BY_ID = {
12
12
  "implement-pi": "在允许路径内按计划改代码,完成本轮主实现。",
13
13
  "implement-core": "在允许路径内完成核心实现,不越出约定写入范围。",
14
14
  "repair-pi": "只修验证暴露出的可修复问题,不重开需求、不扩大 writeSet。",
15
- "verify-shell": "跑冻结的验证命令,用退出码证明实现是否达标。",
15
+ "verify-shell": "运行预先确定的验证命令,用命令结果判断是否达标。",
16
16
  "soft-verify-shell": "先做软验证,留下证据供过程监督,不立刻判整单失败。",
17
17
  "hard-verify-shell": "硬验证:命令必须通过,作为后续审查与收口的事实。",
18
18
  "review-pi": "对照需求与 diff 做只读审查,给出通过或需修订。",
@@ -35,14 +35,14 @@ const NODE_PURPOSE_BY_ID = {
35
35
  "static-invariant-shell": "跑静态不变量检查,确认约定结构与约束仍成立。",
36
36
  "changeset-impact-shell": "评估本轮 diff 的影响面,标出高风险改动。",
37
37
  "closeout-artifact-shell": "收集收口所需的确定性产物与证据路径。",
38
- "final-verify-shell": "收口前最后一轮冻结验证,作为完成权威。",
38
+ "final-verify-shell": "收尾前运行最后一轮固定验证,作为完成依据。",
39
39
  "closeout-summary-pi": "把验证与交付事实写成简短交接摘要。",
40
40
 
41
41
  "frontend-contract-pi": "把前端需求整理成可追踪契约:页面、状态、验收与边界。",
42
42
  "frontend-contract-import-shell": "导入并固化前端实现契约,供后续设计、写入与验证节点使用。",
43
43
  "frontend-scout-pi": "只读侦察前端结构、组件与接口用法,不改文件。",
44
44
  "frontend-plan-pi": "选定实现与 Mock/API 策略,输出可执行的前端实现契约补丁。",
45
- "frontend-design-policy-shell": "确定前端设计与 Mock/API 策略,冻结后续实现必须遵守的规则。",
45
+ "frontend-design-policy-shell": "确定前端设计和数据对接方案,并保存后续实现必须遵守的规则。",
46
46
  "frontend-design-review-pi": "审查前端计划是否可写:通过则沿用原计划,否则要求修订。",
47
47
  "frontend-plan-revision-pi": "按设计审查意见修订前端契约,不扩大范围。",
48
48
  "frontend-final-design-review-pi": "复核修订后的前端计划,只有通过才能授权写入。",
@@ -51,9 +51,9 @@ const NODE_PURPOSE_BY_ID = {
51
51
  "frontend-lint-baseline-shell": "记录写入前的 lint 基线,供实现后对比,不阻断写入。",
52
52
  "frontend-implement-pi": "按已批准契约改前端代码、状态与交互,留在 writeSet 内。",
53
53
  "frontend-verify-assess-shell": "跑静态/行为/Mock 验证并评估能否有界修复。",
54
- "frontend-verify-shell": "执行冻结的前端验证命令,产出可复查的通过或失败证据。",
54
+ "frontend-verify-shell": "运行预先确定的前端检查,留下可复查的通过或失败结果。",
55
55
  "frontend-repair-pi": "只修评估为可修复的前端失败,不重开需求。",
56
- "frontend-reverify-shell": "修复后用同一套冻结命令复验。",
56
+ "frontend-reverify-shell": "修复后用同一套检查再次验证。",
57
57
  "frontend-review-context-shell": "打包真实 diff 与有效验证证据,供审查节点使用。",
58
58
  "frontend-review-pi": "对照契约审查前端实现与证据,给出通过或需修订。",
59
59
  "frontend-review-gate-shell": "前端审查门禁:结论为通过才进入收口。",
@@ -85,7 +85,7 @@ const NODE_PURPOSE_BY_ID = {
85
85
  "validate-backend-test-environment-shell": "检查 Python/pytest 与测试布局是否可跑,失败则不消耗模型。",
86
86
  "backend-test-analysis-contract-shell": "固化后端测试分析契约与布局。",
87
87
  "backend-test-environment-scout-pi": "侦察后端测试环境与入口,不改业务代码。",
88
- "backend-test-execution-contract-shell": "冻结后端测试如何执行、产物写到哪里。",
88
+ "backend-test-execution-contract-shell": "确定后端测试如何执行、结果保存到哪里。",
89
89
  "generate-backend-md-plan-pi": "生成中文模块索引与用例卡片计划。",
90
90
  "materialize-backend-md-module-manifest-shell": "把 Markdown 模块清单落到磁盘。",
91
91
  "review-and-revise-backend-md-cases-pi": "独立审查并修订 Markdown 用例。",
@@ -145,7 +145,7 @@ function describeFromPattern(nodeId) {
145
145
  return "确定性门禁:核验上游结论,通过才放行后续节点。";
146
146
  }
147
147
  if (id.endsWith("-shell") && id.includes("verify")) {
148
- return "跑冻结验证命令,留下可复查的通过/失败证据。";
148
+ return "运行预先确定的验证命令,留下可复查的通过或失败结果。";
149
149
  }
150
150
  if (id.endsWith("-shell") && (id.includes("report") || id.includes("manifest"))) {
151
151
  return "把本轮证据整理成报告或清单,不改业务代码。";
@@ -181,9 +181,9 @@ function describeFromPattern(nodeId) {
181
181
  }
182
182
 
183
183
  function describeFromExecutor(executor) {
184
- if (executor === "shell") return "运行确定性命令并留下证据。";
185
- if (executor === "pi") return "由模型执行该步骤,范围受节点契约约束。";
186
- if (executor === "static") return "按冻结规则直接给出结果,不调用模型。";
184
+ if (executor === "shell") return "由系统运行预先设置的命令,并保存执行结果。";
185
+ if (executor === "pi") return "由 AI 完成这一步,能做的事情受运行设置限制。";
186
+ if (executor === "static") return "按预先确定的规则直接给出结果,不调用 AI。";
187
187
  return "";
188
188
  }
189
189
 
@@ -132,8 +132,8 @@
132
132
 
133
133
  <section data-view="dag" id="view-dag" class="view" hidden>
134
134
  <div class="view-heading">
135
- <p class="view-kicker">Agent DAG</p>
136
- <h2>DAG 详情</h2>
135
+ <p class="view-kicker">自动执行流程</p>
136
+ <h2>运行详情</h2>
137
137
  </div>
138
138
  <section
139
139
  id="dag-relations"
@@ -240,11 +240,11 @@
240
240
  <section data-view="failures" id="view-failures" class="view" hidden>
241
241
  <div class="view-heading">
242
242
  <p class="view-kicker">Attention Queue</p>
243
- <h2>异常 Task</h2>
243
+ <h2>异常任务</h2>
244
244
  <p>按运行状态和建议跟进项集中处理需要人工介入的 Task。</p>
245
245
  </div>
246
246
  <div id="failures-empty" class="panel empty-state" hidden>
247
- 当前没有异常 Task
247
+ 当前没有异常任务
248
248
  </div>
249
249
  <section id="failures-list" class="panel panel-table"></section>
250
250
  </section>
@@ -1,3 +1,5 @@
1
+ import { attemptFailureLabel } from "./dag-history-labels.js";
2
+
1
3
  export function buildPromptRestartCandidateOptions(
2
4
  frozenPrompt,
3
5
  failedCandidates,
@@ -5,7 +7,7 @@ export function buildPromptRestartCandidateOptions(
5
7
  const options = [
6
8
  {
7
9
  key: "frozen",
8
- label: "冻结原始提示词",
10
+ label: "运行开始时的提示词",
9
11
  prompt: String(frozenPrompt ?? ""),
10
12
  truncated: false,
11
13
  },
@@ -27,7 +29,7 @@ export function buildPromptRestartCandidateOptions(
27
29
  : "unknown";
28
30
  options.push({
29
31
  key: `attempt-${attempt}`,
30
- label: `第 ${attempt} 次失败 · ${failureCategory}`,
32
+ label: `第 ${attempt} 次失败 · ${attemptFailureLabel(failureCategory)}`,
31
33
  prompt: candidate.prompt,
32
34
  truncated: candidate.truncated === true,
33
35
  });
@@ -70,11 +70,11 @@ export function featureLookupState(snapshot, featureId) {
70
70
 
71
71
  export const RELATION_KIND_ORDER = ["feature", "task", "batch", "run", "dag"];
72
72
  export const RELATION_LABELS = {
73
- feature: "Feature",
74
- task: "Task",
75
- batch: "Batch",
76
- run: "Run",
77
- dag: "DAG",
73
+ feature: "需求",
74
+ task: "任务",
75
+ batch: "任务批次",
76
+ run: "执行实例",
77
+ dag: "运行流程",
78
78
  };
79
79
 
80
80
  /**
@@ -1354,6 +1354,57 @@ body.is-resizing-dag-graph {
1354
1354
  padding: var(--space-4);
1355
1355
  overflow: auto;
1356
1356
  overscroll-behavior: contain;
1357
+ container-type: inline-size;
1358
+ }
1359
+ .dag-inspector-content.is-readable-page {
1360
+ display: flex;
1361
+ flex-direction: column;
1362
+ gap: 14px;
1363
+ background: color-mix(in srgb, var(--canvas-soft) 72%, var(--surface));
1364
+ }
1365
+ .inspector-page-lead {
1366
+ position: relative;
1367
+ flex: 0 0 auto;
1368
+ min-width: 0;
1369
+ padding: 13px 15px 14px 20px;
1370
+ border: 1px solid var(--hairline);
1371
+ border-radius: 12px;
1372
+ background: var(--surface);
1373
+ box-shadow: 0 4px 14px rgb(38 37 30 / 4%);
1374
+ overflow: hidden;
1375
+ }
1376
+ .inspector-page-lead::before {
1377
+ position: absolute;
1378
+ top: 0;
1379
+ bottom: 0;
1380
+ left: 0;
1381
+ width: 4px;
1382
+ background: var(--orange);
1383
+ content: "";
1384
+ }
1385
+ .inspector-page-lead h4,
1386
+ .inspector-page-lead p {
1387
+ margin: 0;
1388
+ }
1389
+ .inspector-page-lead h4 {
1390
+ margin-top: 3px;
1391
+ color: var(--ink);
1392
+ font-size: 16px;
1393
+ line-height: 1.35;
1394
+ }
1395
+ .inspector-page-lead p {
1396
+ margin-top: 5px;
1397
+ max-width: 68ch;
1398
+ color: var(--body);
1399
+ font-size: 12px;
1400
+ line-height: 1.55;
1401
+ }
1402
+ .inspector-page-eyebrow {
1403
+ display: block;
1404
+ color: var(--orange-active);
1405
+ font-size: 9px;
1406
+ font-weight: 800;
1407
+ letter-spacing: 0.12em;
1357
1408
  }
1358
1409
  .dag-inspector-attempt-bar {
1359
1410
  position: sticky;
@@ -2343,6 +2394,10 @@ body.is-resizing-dag-graph {
2343
2394
  }
2344
2395
  .node-input-semantics {
2345
2396
  margin: 0;
2397
+ padding: 9px 11px;
2398
+ border: 1px dashed var(--hairline-strong);
2399
+ border-radius: 9px;
2400
+ background: color-mix(in srgb, var(--canvas-soft) 74%, var(--surface));
2346
2401
  font-size: 12px;
2347
2402
  font-weight: 600;
2348
2403
  color: var(--muted);
@@ -2362,6 +2417,31 @@ body.is-resizing-dag-graph {
2362
2417
  font-size: 12px;
2363
2418
  font-weight: 600;
2364
2419
  }
2420
+ .dag-inspector-content.is-readable-page .node-input-section,
2421
+ .dag-inspector-content.is-readable-page .spec-evidence-section,
2422
+ .dag-inspector-content.is-readable-page
2423
+ .node-transparency-root
2424
+ > .node-input-summary {
2425
+ padding: 14px 15px;
2426
+ border: 1px solid var(--hairline);
2427
+ border-radius: 12px;
2428
+ background: var(--surface);
2429
+ box-shadow: 0 3px 12px rgb(38 37 30 / 3%);
2430
+ }
2431
+ .dag-inspector-content.is-readable-page .node-input-section,
2432
+ .dag-inspector-content.is-readable-page .spec-evidence-section {
2433
+ padding-bottom: 14px;
2434
+ }
2435
+ .dag-inspector-content.is-readable-page
2436
+ .spec-evidence-section
2437
+ + .spec-evidence-section {
2438
+ margin-top: 0;
2439
+ }
2440
+ .dag-inspector-content.is-readable-page .node-input-section h4,
2441
+ .dag-inspector-content.is-readable-page .spec-evidence-section h4 {
2442
+ margin-bottom: 10px;
2443
+ font-size: 13px;
2444
+ }
2365
2445
  .node-input-summary {
2366
2446
  display: grid;
2367
2447
  grid-template-columns: max-content 1fr;
@@ -2374,6 +2454,70 @@ body.is-resizing-dag-graph {
2374
2454
  color: var(--muted);
2375
2455
  font-weight: 600;
2376
2456
  }
2457
+ .node-input-summary-help {
2458
+ position: relative;
2459
+ display: inline-grid;
2460
+ place-items: center;
2461
+ width: 13px;
2462
+ height: 13px;
2463
+ margin-left: 4px;
2464
+ border: 1px solid var(--hairline-strong);
2465
+ border-radius: 50%;
2466
+ color: var(--muted);
2467
+ font-size: 9px;
2468
+ font-weight: 800;
2469
+ line-height: 1;
2470
+ vertical-align: 1px;
2471
+ cursor: help;
2472
+ }
2473
+
2474
+ .node-input-summary-help::after {
2475
+ position: absolute;
2476
+ bottom: calc(100% + 8px);
2477
+ left: 0;
2478
+ z-index: 20;
2479
+ width: max-content;
2480
+ min-width: 220px;
2481
+ max-width: min(320px, calc(100vw - 48px));
2482
+ padding: 8px 10px;
2483
+ border: 1px solid var(--hairline-strong);
2484
+ border-radius: var(--radius-sm);
2485
+ background: var(--ink);
2486
+ color: var(--white);
2487
+ box-shadow: 0 8px 24px rgb(38 37 30 / 18%);
2488
+ content: attr(data-tooltip);
2489
+ font-size: 12px;
2490
+ font-weight: 500;
2491
+ line-height: 1.45;
2492
+ white-space: pre-line;
2493
+ opacity: 0;
2494
+ visibility: hidden;
2495
+ transform: translateY(4px);
2496
+ pointer-events: none;
2497
+ transition: opacity 120ms ease, transform 120ms ease, visibility 120ms ease;
2498
+ }
2499
+
2500
+ .node-input-summary-help:hover::after,
2501
+ .node-input-summary-help:focus-visible::after {
2502
+ opacity: 1;
2503
+ visibility: visible;
2504
+ transform: translateY(0);
2505
+ }
2506
+
2507
+ .node-input-summary-help:focus-visible {
2508
+ outline: 2px solid var(--orange);
2509
+ outline-offset: 2px;
2510
+ }
2511
+ .dag-inspector-content.is-readable-page .node-input-summary > dt,
2512
+ .dag-inspector-content.is-readable-page .node-input-summary > dd {
2513
+ padding: 7px 0;
2514
+ border-bottom: 1px solid color-mix(in srgb, var(--hairline) 72%, transparent);
2515
+ }
2516
+ .dag-inspector-content.is-readable-page
2517
+ .node-input-summary
2518
+ > :nth-last-child(-n + 2) {
2519
+ border-bottom: 0;
2520
+ }
2377
2521
  .node-input-summary dd {
2378
2522
  margin: 0;
2379
2523
  color: var(--ink);
@@ -2442,6 +2586,33 @@ body.is-resizing-dag-graph {
2442
2586
  border-radius: var(--radius-md);
2443
2587
  background: var(--surface-2, #f3f1ec);
2444
2588
  }
2589
+
2590
+ @container (max-width: 520px) {
2591
+ .inspector-page-lead {
2592
+ padding: 12px 13px 13px 18px;
2593
+ }
2594
+ .inspector-page-lead h4 {
2595
+ font-size: 15px;
2596
+ }
2597
+ .dag-inspector-content.is-readable-page .node-input-section,
2598
+ .dag-inspector-content.is-readable-page .spec-evidence-section,
2599
+ .dag-inspector-content.is-readable-page
2600
+ .node-transparency-root
2601
+ > .node-input-summary {
2602
+ padding: 12px;
2603
+ }
2604
+ .dag-inspector-content.is-readable-page .node-input-summary {
2605
+ grid-template-columns: minmax(0, 1fr);
2606
+ gap: 0;
2607
+ }
2608
+ .dag-inspector-content.is-readable-page .node-input-summary > dt {
2609
+ padding: 8px 0 2px;
2610
+ border-bottom: 0;
2611
+ }
2612
+ .dag-inspector-content.is-readable-page .node-input-summary > dd {
2613
+ padding: 0 0 8px;
2614
+ }
2615
+ }
2445
2616
  .node-artifact-card.is-consumed {
2446
2617
  border-left: 3px solid var(--blue, #2563eb);
2447
2618
  }
@@ -202,7 +202,7 @@ export function renderDagGraph(dag, dagRunId, existingWrap = null) {
202
202
  width: layout.width,
203
203
  height: layout.height,
204
204
  role: "img",
205
- "aria-label": `DAG 依赖图,共 ${nodes.length} 个节点`,
205
+ "aria-label": `执行步骤关系,共 ${nodes.length} 个步骤`,
206
206
  });
207
207
  const defs = svgEl("defs");
208
208
  const marker = svgEl("marker", {