@tea-agent/loop-agent 0.42.0-next.9 → 0.42.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 (236) hide show
  1. package/CHANGELOG.md +111 -45
  2. package/dist/application/dag/run-dag.js +8 -2
  3. package/dist/application/evaluation/budget.js +19 -1
  4. package/dist/application/task-lifecycle/advance.js +26 -8
  5. package/dist/application/task-lifecycle/observe.js +43 -29
  6. package/dist/application/task-lifecycle/plan-transitions.js +5 -4
  7. package/dist/build-stamp.json +3 -3
  8. package/dist/cli/program.js +1 -1
  9. package/dist/commands/dag-rerun-task.js +2 -0
  10. package/dist/commands/task-source-prepare.js +3 -1
  11. package/dist/executors/dag-pi-executor.js +2584 -600
  12. package/dist/executors/pi-executor.js +22 -1
  13. package/dist/executors/pi-extension-resolver.js +14 -2
  14. package/dist/executors/pi-sdk-executor.js +140 -39
  15. package/dist/executors/shell-executor.js +135 -55
  16. package/dist/shared/dag-failure-category.js +6 -0
  17. package/dist/shared/frontend-execution-policy.js +23 -0
  18. package/dist/task/config-types.js +4 -0
  19. package/dist/task/contract/apply.js +36 -2
  20. package/dist/task/source-prepare/ledger-reconciliation.js +2 -2
  21. package/dist/task/source-prepare/ledger-review.js +6 -9
  22. package/dist/task/source-prepare/parse-intent.js +7 -0
  23. package/dist/task/source-prepare/semantic-intake.js +16 -26
  24. package/dist/task/source-prepare/source-fidelity-pi.js +28 -9
  25. package/dist/task/source-references.js +48 -23
  26. package/dist/worker/console/chat/assistant-content.js +23 -2
  27. package/dist/worker/console/chat/browser-policy.js +143 -0
  28. package/dist/worker/console/chat/browser-routes.js +148 -0
  29. package/dist/worker/console/chat/chat-event-store.js +4 -2
  30. package/dist/worker/console/chat/explore-tools.js +13 -0
  31. package/dist/worker/console/chat/pi-runtime.js +173 -94
  32. package/dist/worker/console/chat/resource-loader.js +4 -1
  33. package/dist/worker/console/chat/routes.js +208 -66
  34. package/dist/worker/console/chat/scm-routes.js +217 -0
  35. package/dist/worker/console/chat/scm-service.js +283 -0
  36. package/dist/worker/console/chat/scm-tools.js +111 -0
  37. package/dist/worker/console/chat/sdd-data-alignment.js +78 -11
  38. package/dist/worker/console/chat/session-catalog.js +32 -0
  39. package/dist/worker/console/chat/session-mode-view.js +48 -0
  40. package/dist/worker/console/chat/session-mode.js +218 -0
  41. package/dist/worker/console/chat/session-store.js +27 -7
  42. package/dist/worker/console/chat/shortcuts.js +6 -0
  43. package/dist/worker/console/chat/subagents/agent-tool.js +62 -0
  44. package/dist/worker/console/chat/subagents/explore-agent.js +169 -0
  45. package/dist/worker/console/chat/subagents/index.js +5 -0
  46. package/dist/worker/console/chat/subagents/orchestrator.js +273 -0
  47. package/dist/worker/console/chat/subagents/tool-policy.js +53 -0
  48. package/dist/worker/console/chat/subagents/types.js +13 -0
  49. package/dist/worker/console/chat/terminal-routes.js +216 -0
  50. package/dist/worker/console/chat/terminal-sessions.js +284 -0
  51. package/dist/worker/console/chat/terminal-tools.js +199 -0
  52. package/dist/worker/console/chat/tool-preview.js +21 -0
  53. package/dist/worker/console/chat/tools.js +13 -1
  54. package/dist/worker/console/chat/turn-process.js +1 -0
  55. package/dist/worker/console/interview/tools.js +1 -0
  56. package/dist/worker/console/server.js +2 -28
  57. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C6n9_m0P.js → abnfDiagram-N423BO3Z-C9eI7nEo.js} +1 -1
  58. package/dist/worker/console/static/assets/{arc-DQh-IfZ1.js → arc-VJWsxWhB.js} +1 -1
  59. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-54NnrwUC.js → architectureDiagram-T3A2C74G-BGcyiMSo.js} +1 -1
  60. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-pivRALGK.js → blockDiagram-VBNYF7ZC-BScnFwyi.js} +1 -1
  61. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BR7OV2NJ.js → c4Diagram-5PPSVZJV-Bl9_BsLi.js} +1 -1
  62. package/dist/worker/console/static/assets/channel-B6sQYuOE.js +1 -0
  63. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-B1Aq6BcK.js → chunk-2GRJ4B5K-F1uKxiUt.js} +1 -1
  64. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CbdU0rjo.js → chunk-2Q5K7J3B-rSRMynVu.js} +1 -1
  65. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-Dqi2GJeD.js → chunk-5RXB4S5H-DAsJm1WD.js} +1 -1
  66. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BYn1Hu4R.js → chunk-5VM5RSS4-DQIdVI0a.js} +1 -1
  67. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DRLjDL0k.js → chunk-6Q2QTUOP-4A_8rJ-Q.js} +1 -1
  68. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CY9Xx2jV.js → chunk-GF5L2VYU-BHnT-vjh.js} +1 -1
  69. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BNCZs7_z.js → chunk-JWPE2WC7-Rq7QKBkn.js} +1 -1
  70. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DZ8AStLL.js → chunk-KBJHAD2P-BXh-AI2u.js} +1 -1
  71. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DsxjYrzz.js → chunk-RYQCIY6F-BblcLy8m.js} +1 -1
  72. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-Ddx1KC1l.js → chunk-XXDRQBXY-zHZmVnB6.js} +1 -1
  73. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Z6s5QoeI.js +1 -0
  74. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Z6s5QoeI.js +1 -0
  75. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-W9TveCnK.js → cose-bilkent-JH36ORCC-Cmwz0Wi4.js} +1 -1
  76. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-l9j_ztZH.js → cynefin-VYW2F7L2-Dq76MHQU.js} +1 -1
  77. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BMJMKi4G.js → cynefinDiagram-MW4NZA55-zPahV1fM.js} +1 -1
  78. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-Bb4mG9pH.js → dagre-VZM6K2ZE-DQJ3xPc_.js} +1 -1
  79. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BMgL_Qv0.js → diagram-7IWD3JNH-BwX7u6fv.js} +1 -1
  80. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-Bvo2T4OQ.js → diagram-B4RE2ZJO-CodnDCco.js} +1 -1
  81. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-_5kWRN9c.js → diagram-LBJQPF4R-gAjtWkxG.js} +1 -1
  82. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DqdMrltM.js → diagram-Q27KOJAE-CGCqz0cS.js} +1 -1
  83. package/dist/worker/console/static/assets/{diagram-UB23O5K3-CDDYsNkp.js → diagram-UB23O5K3-RHwYEywd.js} +1 -1
  84. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-c4nfnZUV.js → ebnfDiagram-BXEA7PRR-B6seb_p_.js} +1 -1
  85. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DnkUcNMs.js → erDiagram-JOGREHBK-CmwCKYe8.js} +1 -1
  86. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-Dz0KGLZE.js → flowDiagram-UKHOOZJN-BfNsaZ0V.js} +1 -1
  87. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-Cj1t1uka.js → ganttDiagram-PKOTCBZU-zmYgi_Z3.js} +1 -1
  88. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-tp2FrBHd.js → gitGraphDiagram-DS77QQ5N-BDEzzSKF.js} +1 -1
  89. package/dist/worker/console/static/assets/index-DgenUAfc.js +468 -0
  90. package/dist/worker/console/static/assets/index-aF4u-Y__.css +1 -0
  91. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DQwJS8DH.js → infoDiagram-6WML65LV-DeSz8l42.js} +1 -1
  92. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-eimCQWD4.js → ishikawaDiagram-WSZJBQD7-B1LV29aH.js} +1 -1
  93. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-Dd9Gbwgv.js → journeyDiagram-NVQOT4AX-CCw4W2oU.js} +1 -1
  94. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Qve3cyft.js → kanban-definition-27J2QSJJ-BozaMoRJ.js} +1 -1
  95. package/dist/worker/console/static/assets/{linear-UXKSe36Z.js → linear-G1JR40SX.js} +1 -1
  96. package/dist/worker/console/static/assets/{mermaid.core-CWhj4JXN.js → mermaid.core-CCgPF0oA.js} +5 -5
  97. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-yTcwf4SJ.js → mindmap-definition-FAOFIHXS-CEqnCHnD.js} +1 -1
  98. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-_7qToaZP.js → pegDiagram-VL7TDLO6-DpmQPKuI.js} +1 -1
  99. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CXmrKmDm.js → pieDiagram-7S7Q4E2Y-BP501AxR.js} +1 -1
  100. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-hMmrJyaS.js → quadrantDiagram-CIZ2JOQS-D1dBhl_A.js} +1 -1
  101. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BXw8tCBe.js → railroadDiagram-AXF67PYL-DgZDS5pY.js} +1 -1
  102. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BmjgnLZl.js → requirementDiagram-LRYGKXZP-BzB3pyIq.js} +1 -1
  103. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Bj77SPpN.js → sankeyDiagram-W5VNT64P-B9ZprFFP.js} +1 -1
  104. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-B2FDVysL.js → sequenceDiagram-SI44F4Z6-CC2-_XrA.js} +1 -1
  105. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-UChNY9ZZ.js → sizeCapture-X5ZJPWSS-UVtAUqgB.js} +1 -1
  106. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-wbAEkbd7.js → stateDiagram-OKZ733FA-CWcS5JYG.js} +1 -1
  107. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BooX8u1Q.js +1 -0
  108. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DCEkU8HR.js → swimlanes-SLNWSIFB-C4p-dn06.js} +2 -2
  109. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D64_eqqE.js +8 -0
  110. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-BGp7H06U.js → timeline-definition-Z64GVDOM-Dnz52OHX.js} +1 -1
  111. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DsCIQuWR.js → vennDiagram-T6HMQDX7-CzTE0Nfu.js} +1 -1
  112. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-cRZLP4Xe.js → wardleyDiagram-T6FBY63Y-NAR9cjQQ.js} +1 -1
  113. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CP0xLR9Y.js → xychartDiagram-ELKLHX3M-DVMk8413.js} +1 -1
  114. package/dist/worker/console/static/index.html +2 -2
  115. package/dist/worker/console/static-src/chat-view-types.js +1 -1
  116. package/dist/worker/console/static-src/operator-chat/chat-link.js +94 -0
  117. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +142 -7
  118. package/dist/worker/console/static-src/operator-chat/pending-user-message.js +44 -0
  119. package/dist/worker/console/static-src/operator-chat/process-label.js +41 -0
  120. package/dist/worker/console/static-src/operator-chat/tools-catalog.js +21 -2
  121. package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +13 -0
  122. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +2 -0
  123. package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +51 -0
  124. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +33 -18
  125. package/dist/worker/console/static-src/operator-chat/useChatStream.js +48 -16
  126. package/dist/worker/console/static-src/operator-chat/useChatThread.js +170 -7
  127. package/dist/worker/console/static-src/operator-chat/useComposer.js +13 -7
  128. package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +21 -0
  129. package/dist/worker/console/static-src/shell/workspace-route.js +4 -0
  130. package/dist/worker/console/workspace-context.js +15 -1
  131. package/dist/worker/observe/node-transparency.js +81 -72
  132. package/dist/worker/observe/routes.js +20 -1
  133. package/dist/worker/observe/static/constants.js +22 -22
  134. package/dist/worker/observe/static/dag-context-reason-labels.js +19 -0
  135. package/dist/worker/observe/static/dag-history-labels.js +1 -0
  136. package/dist/worker/observe/static/dag-inspector-humanize.d.ts +16 -0
  137. package/dist/worker/observe/static/dag-inspector-humanize.js +342 -0
  138. package/dist/worker/observe/static/dag-node-purpose.js +10 -10
  139. package/dist/worker/observe/static/dom.js +20 -1
  140. package/dist/worker/observe/static/format-pool.d.ts +2 -0
  141. package/dist/worker/observe/static/format-pool.js +6 -0
  142. package/dist/worker/observe/static/format.js +7 -0
  143. package/dist/worker/observe/static/index.html +4 -4
  144. package/dist/worker/observe/static/inspect-workspace.js +34 -7
  145. package/dist/worker/observe/static/inspector-submission.js +32 -0
  146. package/dist/worker/observe/static/kpi.js +1 -0
  147. package/dist/worker/observe/static/prompt-restart-candidates.js +4 -2
  148. package/dist/worker/observe/static/relations.js +7 -5
  149. package/dist/worker/observe/static/router.js +13 -0
  150. package/dist/worker/observe/static/run-processing.js +2 -0
  151. package/dist/worker/observe/static/shell-chrome.js +36 -3
  152. package/dist/worker/observe/static/state.js +35 -2
  153. package/dist/worker/observe/static/styles.css +431 -39
  154. package/dist/worker/observe/static/task-failure-labels.d.ts +4 -0
  155. package/dist/worker/observe/static/task-failure-labels.js +67 -0
  156. package/dist/worker/observe/static/task-history.js +12 -0
  157. package/dist/worker/observe/static/views/batch.js +6 -13
  158. package/dist/worker/observe/static/views/dag-graph.js +51 -4
  159. package/dist/worker/observe/static/views/dag-inspector.js +1069 -426
  160. package/dist/worker/observe/static/views/dag-trajectory.js +3 -0
  161. package/dist/worker/observe/static/views/dag.d.ts +6 -0
  162. package/dist/worker/observe/static/views/dag.js +64 -22
  163. package/dist/worker/observe/static/views/dags.js +2 -0
  164. package/dist/worker/observe/static/views/dashboard.js +21 -12
  165. package/dist/worker/observe/static/views/failures.js +21 -11
  166. package/dist/worker/observe/static/views/feature.js +11 -29
  167. package/dist/worker/observe/static/views/pool.js +37 -28
  168. package/dist/worker/observe/static/views/run.js +48 -5
  169. package/dist/worker/observe/static/views/session-timeline.js +194 -243
  170. package/dist/worker/observe/static/views/task.js +81 -62
  171. package/dist/workflows/dag/backend-test-plan-protocol.js +104 -0
  172. package/dist/workflows/dag/budget-enforcement.js +53 -3
  173. package/dist/workflows/dag/dag-retry-schema.js +3 -0
  174. package/dist/workflows/dag/frontend-capacity.js +9 -0
  175. package/dist/workflows/dag/frontend-contract-facts.js +130 -0
  176. package/dist/workflows/dag/frontend-design-policy.js +103 -17
  177. package/dist/workflows/dag/frontend-durable-tools.js +193 -0
  178. package/dist/workflows/dag/frontend-execution-groups.js +24 -0
  179. package/dist/workflows/dag/frontend-implementation-contract.js +423 -41
  180. package/dist/workflows/dag/frontend-input-projection.js +76 -0
  181. package/dist/workflows/dag/frontend-plan-completeness.js +186 -0
  182. package/dist/workflows/dag/frontend-plan-recovery-policy.js +18 -0
  183. package/dist/workflows/dag/frontend-plan-render.js +21 -3
  184. package/dist/workflows/dag/frontend-prewrite-gate.js +1 -1
  185. package/dist/workflows/dag/frontend-recovery-controller.js +32 -8
  186. package/dist/workflows/dag/frontend-recovery-lineage.js +13 -0
  187. package/dist/workflows/dag/frontend-recovery-plan.js +4 -1
  188. package/dist/workflows/dag/frontend-recovery-run.js +146 -16
  189. package/dist/workflows/dag/frontend-review-scopes.js +139 -0
  190. package/dist/workflows/dag/frontend-risk.js +2 -0
  191. package/dist/workflows/dag/frontend-session-budget.js +249 -0
  192. package/dist/workflows/dag/frontend-shadow-dual-write.js +37 -3
  193. package/dist/workflows/dag/frontend-shape-facts.js +12 -2
  194. package/dist/workflows/dag/frontend-shape.js +46 -7
  195. package/dist/workflows/dag/frontend-test-execution-evidence.js +49 -0
  196. package/dist/workflows/dag/frontend-typed-event-store.js +14 -0
  197. package/dist/workflows/dag/frontend-verification-trace.js +38 -4
  198. package/dist/workflows/dag/frontend-writer-admission.js +2 -2
  199. package/dist/workflows/dag/init-hybrid.js +70 -35
  200. package/dist/workflows/dag/node-execution.js +225 -226
  201. package/dist/workflows/dag/prompt.js +4 -0
  202. package/dist/workflows/dag/recovery-lease.js +106 -16
  203. package/dist/workflows/dag/rerun-feedback.js +1 -0
  204. package/dist/workflows/dag/rerun-plan.js +96 -4
  205. package/dist/workflows/dag/rerun-run.js +28 -6
  206. package/dist/workflows/dag/rerun-task.js +221 -18
  207. package/dist/workflows/dag/retry-policy.js +27 -10
  208. package/dist/workflows/dag/runner-exit-diagnostics.js +125 -0
  209. package/dist/workflows/dag/runner.js +246 -19
  210. package/dist/workflows/dag/structured-output-repair.js +4 -1
  211. package/dist/workflows/dag/types.js +10 -3
  212. package/dist/workflows/dag/validate.js +10 -8
  213. package/dist/workflows/dag/workspace-checkpoint.js +66 -0
  214. package/docs/operations/README.md +2 -0
  215. package/docs/templates/agent-dag.schema.json +2 -2
  216. package/docs/templates/backend-test-dag.json +6 -4
  217. package/docs/templates/frontend-design-contract.md +4 -4
  218. package/docs/templates/frontend-implementation-contract.schema.json +68 -4
  219. package/docs/templates/frontend-implementation-dag.json +5 -5
  220. package/harness.json +1 -1
  221. package/package.json +8 -6
  222. package/skills/frontend-contract/SKILL.md +2 -1
  223. package/skills/frontend-contract/references/contract-protocol.md +19 -3
  224. package/skills/frontend-design-review/SKILL.md +12 -11
  225. package/skills/frontend-plan/SKILL.md +22 -2
  226. package/skills/frontend-plan/references/decision-contract.md +114 -5
  227. package/skills/frontend-plan/references/design-decisions.md +32 -0
  228. package/skills/frontend-review/SKILL.md +10 -11
  229. package/skills/frontend-scout/references/scout-evidence.md +4 -0
  230. package/dist/worker/console/static/assets/channel-DsZxrgqe.js +0 -1
  231. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-CuToPeGV.js +0 -1
  232. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-CuToPeGV.js +0 -1
  233. package/dist/worker/console/static/assets/index-D9Sc0f0y.js +0 -449
  234. package/dist/worker/console/static/assets/index-DDQc5a50.css +0 -1
  235. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-yPoT19ft.js +0 -1
  236. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-VWdarchG.js +0 -8
@@ -183,6 +183,13 @@ body[data-shell="observe-console"] .process-timeline-time,
183
183
  color: var(--muted);
184
184
  font-size: 12px;
185
185
  }
186
+ /* 末级(当前页)窄屏截断,避免长标题/裸 ID 撑换行。 */
187
+ .breadcrumb .breadcrumb-current {
188
+ overflow: hidden;
189
+ min-width: 0;
190
+ text-overflow: ellipsis;
191
+ white-space: nowrap;
192
+ }
186
193
 
187
194
  .breadcrumb[hidden] {
188
195
  display: none;
@@ -274,9 +281,34 @@ body[data-shell="observe-console"] .process-timeline-time,
274
281
 
275
282
  .view-heading {
276
283
  display: grid;
277
- gap: 4px;
284
+ grid-template-columns: auto minmax(0, 1fr) auto;
285
+ align-items: center;
286
+ gap: 4px 10px;
278
287
  margin-bottom: var(--space-6);
279
288
  }
289
+ /* 标题行:kicker + 标题 + 刷新按钮同行(按钮靠右);说明文字独占下一行。
290
+ 用显式 grid 而非 flex-wrap:flex-basis 百分比在部分嵌套下不触发换行。 */
291
+ .view-heading .view-kicker {
292
+ grid-row: 1;
293
+ grid-column: 1;
294
+ }
295
+ /* 无 kicker 的页面标题从第一列开始,避免空列 + 列间距造成缩进。 */
296
+ .view-heading:not(:has(.view-kicker)) > h2 {
297
+ grid-column: 1 / 3;
298
+ }
299
+ .view-heading > h2 {
300
+ grid-row: 1;
301
+ grid-column: 2;
302
+ margin: 0;
303
+ }
304
+ .view-heading .view-manual-refresh {
305
+ grid-row: 1;
306
+ grid-column: 3;
307
+ }
308
+ .view-heading > p:last-of-type {
309
+ grid-row: 2;
310
+ grid-column: 1 / -1;
311
+ }
280
312
 
281
313
  .view-kicker {
282
314
  display: inline-flex;
@@ -301,7 +333,7 @@ body[data-shell="observe-console"] .process-timeline-time,
301
333
  letter-spacing: -0.02em;
302
334
  }
303
335
 
304
- .view-heading > p:last-child {
336
+ .view-heading > p:last-of-type {
305
337
  max-width: 66ch;
306
338
  margin: 0;
307
339
  color: var(--body);
@@ -1321,6 +1353,26 @@ body.is-resizing-dag-graph {
1321
1353
  overscroll-behavior-x: contain;
1322
1354
  scrollbar-width: thin;
1323
1355
  }
1356
+ /* 溢出渐隐:边缘阴影提示还有更多 Tab(类名由 overflow 测量驱动)。 */
1357
+ .dag-inspector-tabs.is-overflow-start,
1358
+ .dag-inspector-tabs.is-overflow-end {
1359
+ background-repeat: no-repeat;
1360
+ background-size: 22px 100%;
1361
+ }
1362
+ .dag-inspector-tabs.is-overflow-start {
1363
+ background-image: linear-gradient(90deg, rgb(38 37 30 / 12%), rgb(38 37 30 / 0));
1364
+ background-position: left center;
1365
+ }
1366
+ .dag-inspector-tabs.is-overflow-end {
1367
+ background-image: linear-gradient(270deg, rgb(38 37 30 / 12%), rgb(38 37 30 / 0));
1368
+ background-position: right center;
1369
+ }
1370
+ .dag-inspector-tabs.is-overflow-start.is-overflow-end {
1371
+ background-image:
1372
+ linear-gradient(90deg, rgb(38 37 30 / 12%), rgb(38 37 30 / 0)),
1373
+ linear-gradient(270deg, rgb(38 37 30 / 12%), rgb(38 37 30 / 0));
1374
+ background-position: left center, right center;
1375
+ }
1324
1376
  .dag-inspector-tab {
1325
1377
  flex: 0 0 auto;
1326
1378
  min-height: 30px;
@@ -1354,6 +1406,76 @@ body.is-resizing-dag-graph {
1354
1406
  padding: var(--space-4);
1355
1407
  overflow: auto;
1356
1408
  overscroll-behavior: contain;
1409
+ container-type: inline-size;
1410
+ }
1411
+ .dag-inspector-content.is-readable-page {
1412
+ display: flex;
1413
+ flex-direction: column;
1414
+ gap: 14px;
1415
+ background: color-mix(in srgb, var(--canvas-soft) 72%, var(--surface));
1416
+ }
1417
+ .inspector-page-lead {
1418
+ position: relative;
1419
+ flex: 0 0 auto;
1420
+ min-width: 0;
1421
+ padding: 13px 15px 14px 20px;
1422
+ border: 1px solid var(--hairline);
1423
+ border-radius: 12px;
1424
+ background: var(--surface);
1425
+ box-shadow: 0 4px 14px rgb(38 37 30 / 4%);
1426
+ overflow: hidden;
1427
+ }
1428
+ .inspector-page-lead::before {
1429
+ position: absolute;
1430
+ top: 0;
1431
+ bottom: 0;
1432
+ left: 0;
1433
+ width: 4px;
1434
+ background: var(--orange);
1435
+ content: "";
1436
+ }
1437
+ .inspector-page-lead h4,
1438
+ .inspector-page-lead p {
1439
+ margin: 0;
1440
+ }
1441
+ .inspector-page-lead h4 {
1442
+ margin-top: 3px;
1443
+ color: var(--ink);
1444
+ font-size: 16px;
1445
+ line-height: 1.35;
1446
+ }
1447
+ .inspector-page-lead p {
1448
+ margin-top: 5px;
1449
+ max-width: 68ch;
1450
+ color: var(--body);
1451
+ font-size: 12px;
1452
+ line-height: 1.55;
1453
+ }
1454
+ .inspector-page-eyebrow {
1455
+ display: block;
1456
+ color: var(--orange-active);
1457
+ font-size: 9px;
1458
+ font-weight: 800;
1459
+ letter-spacing: 0.12em;
1460
+ }
1461
+ .inspector-page-eyebrow-row {
1462
+ display: flex;
1463
+ align-items: center;
1464
+ justify-content: space-between;
1465
+ gap: 8px;
1466
+ }
1467
+ .inspector-page-eyebrow-row .observe-icon-button {
1468
+ flex: 0 0 24px;
1469
+ width: 24px;
1470
+ min-width: 24px;
1471
+ height: 24px;
1472
+ min-height: 24px;
1473
+ font-size: 14px;
1474
+ }
1475
+ /* 收起态只保留 eyebrow 行,点击可再展开(会话级记忆)。 */
1476
+ .inspector-page-lead.is-collapsed h4,
1477
+ .inspector-page-lead.is-collapsed p {
1478
+ display: none;
1357
1479
  }
1358
1480
  .dag-inspector-attempt-bar {
1359
1481
  position: sticky;
@@ -1978,13 +2100,16 @@ body.is-resizing-dag-graph {
1978
2100
  margin: 0 2px;
1979
2101
  pointer-events: none;
1980
2102
  }
2103
+ /* display:flex 会盖过 UA 的 [hidden],贴底/无溢出隐藏 dock 需显式声明。 */
2104
+ .process-timeline-autoscroll-dock[hidden] {
2105
+ display: none;
2106
+ }
1981
2107
  .process-timeline-autoscroll {
1982
2108
  position: relative;
1983
2109
  pointer-events: auto;
1984
2110
  display: inline-flex;
1985
2111
  align-items: center;
1986
2112
  justify-content: center;
1987
- gap: 7px;
1988
2113
  width: 36px;
1989
2114
  height: 36px;
1990
2115
  padding: 0;
@@ -1993,7 +2118,9 @@ body.is-resizing-dag-graph {
1993
2118
  background: color-mix(in srgb, var(--surface) 94%, var(--canvas));
1994
2119
  color: var(--body);
1995
2120
  box-shadow: 0 8px 24px rgb(38 37 30 / 14%);
1996
- font-size: 14px;
2121
+ font-size: 11px;
2122
+ font-weight: 650;
2123
+ white-space: nowrap;
1997
2124
  cursor: pointer;
1998
2125
  backdrop-filter: blur(10px);
1999
2126
  }
@@ -2029,25 +2156,22 @@ body.is-resizing-dag-graph {
2029
2156
  outline: none;
2030
2157
  box-shadow: 0 8px 24px rgb(38 37 30 / 16%), 0 0 0 3px var(--orange-soft);
2031
2158
  }
2032
- .process-timeline-autoscroll.is-active {
2033
- border-color: var(--ink);
2034
- background: var(--ink);
2035
- color: #fff;
2036
- }
2037
- .process-timeline-autoscroll.is-active:hover,
2038
- .process-timeline-autoscroll.is-active:focus-visible {
2159
+ .process-timeline-autoscroll.has-unread {
2039
2160
  border-color: var(--orange);
2040
- background: var(--ink);
2041
- color: #fff;
2161
+ color: var(--orange-active);
2042
2162
  }
2043
2163
  .process-timeline-autoscroll-signal {
2164
+ display: none;
2165
+ position: absolute;
2166
+ top: 5px;
2167
+ right: 5px;
2044
2168
  width: 5px;
2045
2169
  height: 5px;
2046
2170
  border-radius: 50%;
2047
- background: var(--muted-soft);
2048
- }
2049
- .process-timeline-autoscroll.is-active .process-timeline-autoscroll-signal {
2050
2171
  background: var(--orange);
2172
+ }
2173
+ .process-timeline-autoscroll.has-unread .process-timeline-autoscroll-signal {
2174
+ display: block;
2051
2175
  box-shadow: 0 0 0 4px rgb(245 78 0 / 16%);
2052
2176
  animation: process-timeline-live-pulse 1.8s ease-out infinite;
2053
2177
  }
@@ -2056,7 +2180,7 @@ body.is-resizing-dag-graph {
2056
2180
  75% { box-shadow: 0 0 0 7px rgb(245 78 0 / 0%); }
2057
2181
  }
2058
2182
  @media (prefers-reduced-motion: reduce) {
2059
- .process-timeline-autoscroll.is-active .process-timeline-autoscroll-signal {
2183
+ .process-timeline-autoscroll.has-unread .process-timeline-autoscroll-signal {
2060
2184
  animation: none;
2061
2185
  }
2062
2186
  .process-timeline-autoscroll::after {
@@ -2068,28 +2192,6 @@ body.is-resizing-dag-graph {
2068
2192
  flex-wrap: wrap;
2069
2193
  gap: 4px;
2070
2194
  }
2071
- .process-timeline-toggle {
2072
- min-height: 28px;
2073
- padding: 0 10px;
2074
- border: 1px solid var(--hairline-strong);
2075
- border-radius: var(--radius-sm);
2076
- background: var(--surface);
2077
- color: var(--body);
2078
- font-size: 11px;
2079
- font-weight: 600;
2080
- cursor: pointer;
2081
- }
2082
- .process-timeline-toggle:hover,
2083
- .process-timeline-toggle:focus-visible {
2084
- border-color: var(--orange);
2085
- color: var(--orange-active);
2086
- outline: none;
2087
- }
2088
- .process-timeline-toggle[aria-pressed="true"] {
2089
- border-color: color-mix(in srgb, var(--orange) 55%, var(--hairline));
2090
- background: #fff5ed;
2091
- color: var(--orange-active);
2092
- }
2093
2195
  .process-timeline-body {
2094
2196
  min-width: 0;
2095
2197
  padding: 4px 0 8px var(--space-2);
@@ -2343,6 +2445,10 @@ body.is-resizing-dag-graph {
2343
2445
  }
2344
2446
  .node-input-semantics {
2345
2447
  margin: 0;
2448
+ padding: 9px 11px;
2449
+ border: 1px dashed var(--hairline-strong);
2450
+ border-radius: 9px;
2451
+ background: color-mix(in srgb, var(--canvas-soft) 74%, var(--surface));
2346
2452
  font-size: 12px;
2347
2453
  font-weight: 600;
2348
2454
  color: var(--muted);
@@ -2362,6 +2468,31 @@ body.is-resizing-dag-graph {
2362
2468
  font-size: 12px;
2363
2469
  font-weight: 600;
2364
2470
  }
2471
+ .dag-inspector-content.is-readable-page .node-input-section,
2472
+ .dag-inspector-content.is-readable-page .spec-evidence-section,
2473
+ .dag-inspector-content.is-readable-page
2474
+ .node-transparency-root
2475
+ > .node-input-summary {
2476
+ padding: 14px 15px;
2477
+ border: 1px solid var(--hairline);
2478
+ border-radius: 12px;
2479
+ background: var(--surface);
2480
+ box-shadow: 0 3px 12px rgb(38 37 30 / 3%);
2481
+ }
2482
+ .dag-inspector-content.is-readable-page .node-input-section,
2483
+ .dag-inspector-content.is-readable-page .spec-evidence-section {
2484
+ padding-bottom: 14px;
2485
+ }
2486
+ .dag-inspector-content.is-readable-page
2487
+ .spec-evidence-section
2488
+ + .spec-evidence-section {
2489
+ margin-top: 0;
2490
+ }
2491
+ .dag-inspector-content.is-readable-page .node-input-section h4,
2492
+ .dag-inspector-content.is-readable-page .spec-evidence-section h4 {
2493
+ margin-bottom: 10px;
2494
+ font-size: 13px;
2495
+ }
2365
2496
  .node-input-summary {
2366
2497
  display: grid;
2367
2498
  grid-template-columns: max-content 1fr;
@@ -2374,6 +2505,70 @@ body.is-resizing-dag-graph {
2374
2505
  color: var(--muted);
2375
2506
  font-weight: 600;
2376
2507
  }
2508
+ .node-input-summary-help {
2509
+ position: relative;
2510
+ display: inline-grid;
2511
+ place-items: center;
2512
+ width: 13px;
2513
+ height: 13px;
2514
+ margin-left: 4px;
2515
+ border: 1px solid var(--hairline-strong);
2516
+ border-radius: 50%;
2517
+ color: var(--muted);
2518
+ font-size: 9px;
2519
+ font-weight: 800;
2520
+ line-height: 1;
2521
+ vertical-align: 1px;
2522
+ cursor: help;
2523
+ }
2524
+
2525
+ .node-input-summary-help::after {
2526
+ position: absolute;
2527
+ bottom: calc(100% + 8px);
2528
+ left: 0;
2529
+ z-index: 20;
2530
+ width: max-content;
2531
+ min-width: 220px;
2532
+ max-width: min(320px, calc(100vw - 48px));
2533
+ padding: 8px 10px;
2534
+ border: 1px solid var(--hairline-strong);
2535
+ border-radius: var(--radius-sm);
2536
+ background: var(--ink);
2537
+ color: var(--white);
2538
+ box-shadow: 0 8px 24px rgb(38 37 30 / 18%);
2539
+ content: attr(data-tooltip);
2540
+ font-size: 12px;
2541
+ font-weight: 500;
2542
+ line-height: 1.45;
2543
+ white-space: pre-line;
2544
+ opacity: 0;
2545
+ visibility: hidden;
2546
+ transform: translateY(4px);
2547
+ pointer-events: none;
2548
+ transition: opacity 120ms ease, transform 120ms ease, visibility 120ms ease;
2549
+ }
2550
+
2551
+ .node-input-summary-help:hover::after,
2552
+ .node-input-summary-help:focus-visible::after {
2553
+ opacity: 1;
2554
+ visibility: visible;
2555
+ transform: translateY(0);
2556
+ }
2557
+
2558
+ .node-input-summary-help:focus-visible {
2559
+ outline: 2px solid var(--orange);
2560
+ outline-offset: 2px;
2561
+ }
2562
+ .dag-inspector-content.is-readable-page .node-input-summary > dt,
2563
+ .dag-inspector-content.is-readable-page .node-input-summary > dd {
2564
+ padding: 7px 0;
2565
+ border-bottom: 1px solid color-mix(in srgb, var(--hairline) 72%, transparent);
2566
+ }
2567
+ .dag-inspector-content.is-readable-page
2568
+ .node-input-summary
2569
+ > :nth-last-child(-n + 2) {
2570
+ border-bottom: 0;
2571
+ }
2377
2572
  .node-input-summary dd {
2378
2573
  margin: 0;
2379
2574
  color: var(--ink);
@@ -2442,6 +2637,33 @@ body.is-resizing-dag-graph {
2442
2637
  border-radius: var(--radius-md);
2443
2638
  background: var(--surface-2, #f3f1ec);
2444
2639
  }
2640
+
2641
+ @container (max-width: 520px) {
2642
+ .inspector-page-lead {
2643
+ padding: 12px 13px 13px 18px;
2644
+ }
2645
+ .inspector-page-lead h4 {
2646
+ font-size: 15px;
2647
+ }
2648
+ .dag-inspector-content.is-readable-page .node-input-section,
2649
+ .dag-inspector-content.is-readable-page .spec-evidence-section,
2650
+ .dag-inspector-content.is-readable-page
2651
+ .node-transparency-root
2652
+ > .node-input-summary {
2653
+ padding: 12px;
2654
+ }
2655
+ .dag-inspector-content.is-readable-page .node-input-summary {
2656
+ grid-template-columns: minmax(0, 1fr);
2657
+ gap: 0;
2658
+ }
2659
+ .dag-inspector-content.is-readable-page .node-input-summary > dt {
2660
+ padding: 8px 0 2px;
2661
+ border-bottom: 0;
2662
+ }
2663
+ .dag-inspector-content.is-readable-page .node-input-summary > dd {
2664
+ padding: 0 0 8px;
2665
+ }
2666
+ }
2445
2667
  .node-artifact-card.is-consumed {
2446
2668
  border-left: 3px solid var(--blue, #2563eb);
2447
2669
  }
@@ -2824,6 +3046,19 @@ body.is-resizing-dag-graph {
2824
3046
  white-space: pre-wrap;
2825
3047
  overflow-wrap: anywhere;
2826
3048
  }
3049
+ .run-output-shell {
3050
+ position: relative;
3051
+ }
3052
+ .run-output-follow-dock {
3053
+ position: absolute;
3054
+ right: 10px;
3055
+ bottom: 10px;
3056
+ z-index: 3;
3057
+ pointer-events: none;
3058
+ }
3059
+ .run-output-follow-dock[hidden] {
3060
+ display: none;
3061
+ }
2827
3062
 
2828
3063
  .artifact-list {
2829
3064
  display: grid;
@@ -5028,3 +5263,160 @@ button.copy-command:focus-visible {
5028
5263
  .prompt-restart-status.prompt-restart-error {
5029
5264
  color: var(--red);
5030
5265
  }
5266
+
5267
+ /* Reader controls stay within reach while the body scrolls. */
5268
+ .dag-inspector.is-expanded { width: calc(100vw - 48px); }
5269
+ .inspect-workspace-root .dag-inspector.is-expanded { width: calc(100% - 32px); }
5270
+ .dag-inspector-header .dag-inspector-attempt-bar { position: relative; top: auto; grid-column: 1 / -1; margin: 0; padding: 8px 0 0; border-bottom: 0; border-top: 1px solid var(--hairline); }
5271
+ .process-timeline-toolbar { position: sticky; top: -16px; z-index: 5; padding: 8px 0; background: var(--surface); border-bottom: 1px solid var(--hairline); }
5272
+ .process-timeline-search { flex: 1 1 160px; min-width: 100px; padding: 6px 8px; border: 1px solid var(--hairline-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); }
5273
+ .process-timeline-item.is-search-match { background: color-mix(in srgb, var(--amber) 12%, var(--surface)); border-radius: var(--radius-sm); }
5274
+ .dag-inspector.is-expanded .inspector-page-lead { max-width: none; }
5275
+ .dag-inspector-content .process-timeline-code, .dag-inspector-content .process-timeline-thinking-body { max-height: none; overflow-y: visible; }
5276
+ @media (max-width: 700px) {
5277
+ .dag-inspector.is-expanded { width: calc(100vw - 24px); }
5278
+ .dag-inspector-controls { flex-wrap: wrap; }
5279
+ .dag-inspector-header { padding: 12px; }
5280
+ .dag-inspector-purpose, .dag-inspector-attempt-label { display: none; }
5281
+ .dag-inspector-attempt-preview { font-size: 11px; }
5282
+ }
5283
+
5284
+ .dag-action-intents, .node-relation-links { display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
5285
+ .node-relation-links h5 { width:100%; margin:8px 0 0; }
5286
+ .dag-action-intents [aria-pressed="true"] { border-color:var(--orange); color:var(--orange-active); }
5287
+ .dag-action-card[hidden] { display:none; }
5288
+ .context-component { padding:10px 0; border-top:1px solid var(--hairline); }
5289
+ .context-component > summary { cursor:pointer; overflow-wrap:anywhere; }
5290
+ .context-component-body { margin-top:12px; }
5291
+ .context-record-heading { margin:0; color:var(--ink); font-weight:650; }
5292
+ .context-record-meta { margin:0; color:var(--muted); font-size:12px; line-height:1.6; overflow-wrap:anywhere; }
5293
+ .context-component > summary { display:list-item; color:var(--ink); }
5294
+ .context-component-name { font-weight:600; }
5295
+ .context-component-meta { display:block; margin:4px 0 0 16px; color:var(--muted); font-size:11px; font-weight:400; }
5296
+ .context-source-details { margin-top:12px; color:var(--muted); font-size:12px; }
5297
+ .context-source-details > summary { cursor:pointer; }
5298
+ .context-source-details .node-transparency-summary { margin-top:12px; }
5299
+ .inspector-operation { padding:8px 12px; border:1px solid var(--hairline); border-radius:var(--radius-sm); margin-bottom:8px; overflow-wrap:anywhere; }
5300
+ .dag-graph-toolbar { flex-wrap:wrap; gap:8px; }
5301
+ .dag-graph-search, .relation-task-picker { padding:6px 8px; border:1px solid var(--hairline); border-radius:var(--radius-sm); background:var(--surface); max-width:100%; }
5302
+ #view-dashboard { display:flex; flex-direction:column; }
5303
+ #view-dashboard[hidden] { display:none; }
5304
+ #view-dashboard .dashboard-workspace { order:-2; }
5305
+ #dashboard-kpi { padding-top:8px; padding-bottom:8px; }
5306
+ #dashboard-kpi .kpi-card { padding-top:12px; padding-bottom:12px; }
5307
+ #dashboard-kpi .kpi-value { font-size:24px; }
5308
+
5309
+ .attempt-comparison-toolbar { display:flex; gap:12px; padding-bottom:12px; }
5310
+ .attempt-comparison-columns { display:grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap:16px; }
5311
+ .attempt-comparison-columns > p { grid-column:1/-1; }
5312
+ .attempt-comparison-column { min-width:0; overflow-wrap:anywhere; }
5313
+ @media (max-width:700px) { .attempt-comparison-columns { grid-template-columns:minmax(0,1fr); } }
5314
+
5315
+ /* Compact controls share the existing palette and keep names available on focus. */
5316
+ .observe-icon-button,
5317
+ .dag-graph-toolbar .observe-icon-button {
5318
+ display: inline-grid;
5319
+ place-items: center;
5320
+ flex: 0 0 32px;
5321
+ width: 32px;
5322
+ min-width: 32px;
5323
+ height: 32px;
5324
+ min-height: 32px;
5325
+ padding: 0;
5326
+ border: 1px solid transparent;
5327
+ border-radius: 7px;
5328
+ background: transparent;
5329
+ color: var(--body);
5330
+ font-size: 17px;
5331
+ line-height: 1;
5332
+ box-shadow: none;
5333
+ cursor: pointer;
5334
+ }
5335
+ .observe-icon-button:hover:not(:disabled),
5336
+ .observe-icon-button[aria-pressed="true"] {
5337
+ background: var(--surface-muted);
5338
+ color: var(--ink);
5339
+ border-color: var(--hairline);
5340
+ transform: none;
5341
+ }
5342
+ .observe-icon-button:focus-visible,
5343
+ .observe-select:focus-visible {
5344
+ outline: 2px solid var(--orange);
5345
+ outline-offset: 2px;
5346
+ }
5347
+ .observe-icon-button:disabled { opacity: .35; cursor: default; }
5348
+ .observe-select {
5349
+ min-height: 32px;
5350
+ max-width: 100%;
5351
+ padding: 4px 24px 4px 10px;
5352
+ border: 1px solid var(--hairline);
5353
+ border-radius: 7px;
5354
+ background: var(--surface);
5355
+ color: var(--ink);
5356
+ font: inherit;
5357
+ font-size: 12px;
5358
+ cursor: pointer;
5359
+ }
5360
+ .dag-inspector-header { gap: 10px; padding: 12px 16px; }
5361
+ .dag-inspector-title { gap: 3px; }
5362
+ .dag-inspector-purpose { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
5363
+ .dag-inspector-controls { gap: 3px; }
5364
+ .dag-inspector-header .dag-inspector-attempt-bar { gap: 4px; padding-top: 8px; }
5365
+ .dag-inspector-attempt-label { display: none; }
5366
+ .dag-inspector-attempt-preview { flex: 1; gap: 8px; min-width: 0; }
5367
+ .dag-inspector-attempt-category { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
5368
+ .process-timeline-toolbar { gap: 4px; align-items: center; flex-shrink: 0; }
5369
+ .process-timeline-filter-group { flex: 0 0 auto; max-width: 135px; }
5370
+ .process-timeline-search { margin: 0 4px; height: 32px; flex: 1 1 120px; }
5371
+ .process-timeline-toolbar > [role="status"] { font-size: 11px; white-space: nowrap; }
5372
+ .dag-graph-toolbar { gap: 4px; }
5373
+ .dag-graph-toolbar-left { margin-right: auto; }
5374
+ .dag-graph-search { height: 32px; width: 160px; margin-left: 8px; }
5375
+ @media (max-width: 700px) {
5376
+ .dag-inspector-header { padding: 10px 12px; }
5377
+ .dag-inspector-controls { flex-wrap: nowrap; }
5378
+ .dag-inspector-status { padding: 2px 6px; }
5379
+ .dag-inspector-attempt-preview { flex-basis: 100%; padding-left: 36px; }
5380
+ .process-timeline-search { flex-basis: 96px; min-width: 76px; }
5381
+ .dag-graph-toolbar-left { flex: 1 1 100%; }
5382
+ .dag-graph-search { flex: 1; min-width: 96px; }
5383
+ }
5384
+ .observe-icon-button { position: relative; }
5385
+ .observe-icon-button::after {
5386
+ content: attr(data-tooltip);
5387
+ position: absolute;
5388
+ right: 0;
5389
+ top: calc(100% + 6px);
5390
+ z-index: 30;
5391
+ padding: 6px 8px;
5392
+ border-radius: 5px;
5393
+ background: var(--ink);
5394
+ color: var(--surface);
5395
+ font: 11px/1.4 system-ui, sans-serif;
5396
+ white-space: nowrap;
5397
+ opacity: 0;
5398
+ pointer-events: none;
5399
+ }
5400
+ .observe-icon-button:focus-visible::after { opacity: 1; }
5401
+ .risk-dag-items { display: grid; gap: 6px; padding-top: 8px; }
5402
+ /* The hosted Console also has .panel styles; keep the reader shell flush. */
5403
+ #dag-inspector { padding: 0; gap: 0; }
5404
+ .dag-inspector-header .dag-inspector-attempt-bar { flex-wrap: nowrap; background: transparent; }
5405
+ .dag-inspector-header .dag-inspector-attempt-select { min-width: 0; flex: 0 1 126px; }
5406
+ .dag-inspector-header .dag-inspector-attempt-preview { flex: 1 1 auto; flex-wrap: nowrap; padding: 0; }
5407
+ .dag-inspector-header .dag-inspector-attempt-category,
5408
+ .dag-inspector-header .dag-inspector-attempt-duration { display: none; }
5409
+ @container (max-width: 560px) {
5410
+ .process-timeline-toolbar { display: grid; grid-template-columns: minmax(80px, 1fr) 32px 32px 32px; gap: 4px; }
5411
+ .process-timeline-filter-group { grid-row: 1; grid-column: 1 / 3; width: fit-content; }
5412
+ .process-timeline-errors { grid-row: 1; grid-column: 3; }
5413
+ .process-timeline-protocol-toggle { grid-row: 1; grid-column: 4; }
5414
+ .process-timeline-search { grid-row: 2; grid-column: 1 / 3; width: 100%; margin: 0; }
5415
+ .process-search-previous { grid-row: 2; grid-column: 3; }
5416
+ .process-search-next { grid-row: 2; grid-column: 4; }
5417
+ .process-timeline-toolbar > [role="status"] { grid-row: 3; grid-column: 1 / -1; }
5418
+ .process-timeline-toolbar > [role="status"]:empty { display: none; }
5419
+ }
5420
+
5421
+ .process-search-highlight { background: #ffe082; color: #382800; border-radius: 2px; }
5422
+ .process-timeline-item.is-search-current { outline: 2px solid var(--amber); outline-offset: -2px; }
@@ -0,0 +1,4 @@
1
+ export const TASK_FAILURE_UNKNOWN_LABEL: string;
2
+
3
+ export function taskFailureCategoryLabel(category: unknown): string;
4
+ export function followUpLabel(action: unknown): string;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * 异常 Task 页业务文案映射(Observe UI,2026-09-06-observe-reading-and-polish)。
3
+ *
4
+ * 表驱动映射:Task 级 failureCategory(ProductLineFailureCategory)与
5
+ * 建议跟进(FOLLOW_UP_BY_CATEGORY / DAG_RECOVERY_ACTIONS)仅保留 raw token
6
+ * 于 title 等诊断属性,主文案一律中文业务术语。未知或缺失分类 fail-closed
7
+ * 原文透传(异常页是排障入口,未收录 token 比误译更有诊断价值)。
8
+ */
9
+
10
+ /** 表一:Task 失败分类(src/worker/pool/types.ts ProductLineFailureCategory)→ 中文。 */
11
+ const TASK_FAILURE_CATEGORY_LABELS = {
12
+ SpecUnclear: "需求不明确",
13
+ ContractMismatch: "契约不一致",
14
+ ProductBug: "产品缺陷",
15
+ TestBug: "测试缺陷",
16
+ EnvFailure: "环境问题",
17
+ FlakyTest: "测试不稳定",
18
+ RiskyChange: "变更风险",
19
+ DependencyFailure: "依赖阻塞",
20
+ NeedsHuman: "需要人工",
21
+ Unknown: "未分类",
22
+ // run 级补充(read-model:state.json controller-interrupted)。
23
+ "controller-interrupted": "控制器中断",
24
+ };
25
+
26
+ /**
27
+ * 表二:建议跟进/恢复动作 → 中文。并集覆盖
28
+ * src/worker/pool/failure-routing.ts FOLLOW_UP_BY_CATEGORY 与
29
+ * src/workflows/dag/recovery-recommendation.ts DAG_RECOVERY_ACTIONS。
30
+ */
31
+ const FOLLOW_UP_LABELS = {
32
+ "spec-clarification": "澄清需求",
33
+ "architecture-contract-fix": "修订契约",
34
+ "dev-fix": "开发修复",
35
+ "qa-fix-test": "修复测试",
36
+ "env-fix": "修复环境",
37
+ "flaky-test-analysis": "分析不稳定测试",
38
+ "human-review": "人工审查",
39
+ "manual-review": "人工审查",
40
+ "unblock-dependency": "解除依赖阻塞",
41
+ "human-triage": "人工分诊",
42
+ none: "无需处理",
43
+ monitor: "持续观察",
44
+ "retry-node": "重试节点",
45
+ "rerun-after-fix": "修复后重跑",
46
+ "resume-or-reject": "恢复或拒绝",
47
+ "inspect-upstream": "检查上游",
48
+ };
49
+
50
+ export const TASK_FAILURE_UNKNOWN_LABEL = "未分类";
51
+
52
+ /**
53
+ * Task 失败分类 → 中文;未知英文 token 原样透传(title 仍可标注 raw),
54
+ * 空值返回空串由调用方决定占位。
55
+ */
56
+ export function taskFailureCategoryLabel(category) {
57
+ const raw = String(category ?? "").trim();
58
+ if (!raw) return "";
59
+ return TASK_FAILURE_CATEGORY_LABELS[raw] ?? raw;
60
+ }
61
+
62
+ /** 建议跟进/恢复动作 → 中文;未知 token 原样透传,空值返回空串。 */
63
+ export function followUpLabel(action) {
64
+ const raw = String(action ?? "").trim();
65
+ if (!raw) return "";
66
+ return FOLLOW_UP_LABELS[raw] ?? raw;
67
+ }
@@ -0,0 +1,12 @@
1
+ /** Merge poll/older pages without dropping the pages the reader loaded. */
2
+ export function mergeTaskHistoryPage(state, page, older = false) {
3
+ const existing = new Map(state.runs.map((run) => [run.workerRunId, run]));
4
+ for (const run of page.runs ?? []) existing.set(run.workerRunId, run);
5
+ const order = older ? [...state.runs, ...(page.runs ?? [])] : [...(page.runs ?? []), ...state.runs];
6
+ const seen = new Set();
7
+ state.runs = order.filter((run) => { if (seen.has(run.workerRunId)) return false; seen.add(run.workerRunId); return true; }).map((run) => existing.get(run.workerRunId));
8
+ if (older || !state.loadedOlder) state.nextBefore = page.nextBefore ?? null;
9
+ if (older) state.loadedOlder = true;
10
+ state.error = null;
11
+ return state;
12
+ }