@tea-agent/loop-agent 0.43.0-next.1 → 0.43.0-next.11
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/CHANGELOG.md +144 -9
- package/dist/application/dag/run-dag.js +5 -0
- package/dist/application/evaluation/budget.js +19 -1
- package/dist/application/task-lifecycle/advance.js +17 -4
- package/dist/application/task-lifecycle/observe.js +43 -29
- package/dist/application/task-lifecycle/plan-transitions.js +5 -4
- package/dist/build-stamp.json +3 -3
- package/dist/executors/dag-pi-executor.js +1237 -586
- package/dist/executors/pi-executor.js +22 -1
- package/dist/executors/pi-sdk-executor.js +140 -39
- package/dist/executors/shell-executor.js +8 -4
- package/dist/shared/frontend-execution-policy.js +23 -0
- package/dist/task/config-types.js +4 -0
- package/dist/task/source-prepare/ledger-reconciliation.js +2 -2
- package/dist/task/source-prepare/ledger-review.js +6 -9
- package/dist/task/source-prepare/semantic-intake.js +16 -26
- package/dist/task/source-prepare/source-fidelity-pi.js +28 -9
- package/dist/task/source-references.js +48 -23
- package/dist/worker/console/chat/assistant-content.js +23 -2
- package/dist/worker/console/chat/browser-policy.js +113 -0
- package/dist/worker/console/chat/browser-routes.js +140 -0
- package/dist/worker/console/chat/explore-tools.js +13 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +44 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +202 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +79 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +86 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +38 -0
- package/dist/worker/console/chat/pi-runtime/inspection-types.js +28 -0
- package/dist/worker/console/chat/pi-runtime/inspection.js +439 -0
- package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +153 -0
- package/dist/worker/console/chat/pi-runtime/sdk-session.js +5 -0
- package/dist/worker/console/chat/pi-runtime.js +207 -1178
- package/dist/worker/console/chat/routes.js +208 -71
- package/dist/worker/console/chat/scm-routes.js +217 -0
- package/dist/worker/console/chat/scm-service.js +283 -0
- package/dist/worker/console/chat/scm-tools.js +111 -0
- package/dist/worker/console/chat/sdd-data-alignment.js +65 -9
- package/dist/worker/console/chat/session-catalog.js +32 -0
- package/dist/worker/console/chat/session-mode-view.js +49 -0
- package/dist/worker/console/chat/session-mode.js +219 -0
- package/dist/worker/console/chat/session-store.js +22 -6
- package/dist/worker/console/chat/shortcuts.js +6 -0
- package/dist/worker/console/chat/terminal-routes.js +216 -0
- package/dist/worker/console/chat/terminal-sessions.js +348 -0
- package/dist/worker/console/chat/terminal-tools.js +211 -0
- package/dist/worker/console/chat/tool-preview.js +11 -0
- package/dist/worker/console/chat/tools.js +2 -0
- package/dist/worker/console/server.js +2 -28
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-B0Q0nClf.js → abnfDiagram-N423BO3Z-CTSK0xbU.js} +1 -1
- package/dist/worker/console/static/assets/{arc-DCPjC19G.js → arc-_2MfctFP.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CP5n9jmG.js → architectureDiagram-T3A2C74G-DsDe2wTg.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CmaWi_Wg.js → blockDiagram-VBNYF7ZC-Dtz_779U.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-Ct5tcMfZ.js → c4Diagram-5PPSVZJV-LaULi-gw.js} +1 -1
- package/dist/worker/console/static/assets/channel-CqS4yBWT.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-C0osm1Zf.js → chunk-2GRJ4B5K-DuHBqqX8.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CDWviED7.js → chunk-2Q5K7J3B-BZgZs1dn.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-mtSk1-j7.js → chunk-5RXB4S5H-tzwmlIO_.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-D5J9PHC7.js → chunk-5VM5RSS4-CeYrLkSn.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Begg4WAa.js → chunk-6Q2QTUOP-C92cgilm.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-sF1AEy7T.js → chunk-GF5L2VYU-XOXpGC0F.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BqbsWXZb.js → chunk-JWPE2WC7-CGHbJyCH.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BKJrPcJ6.js → chunk-KBJHAD2P-Bs2-LTzf.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CcwNMRho.js → chunk-RYQCIY6F-rN7up7E4.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-BEJi3iIs.js → chunk-XXDRQBXY-B_fWjKpR.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DVOxNOq0.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DVOxNOq0.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-DRLgTvVu.js → cose-bilkent-JH36ORCC-DE3SdJvB.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BoAVG3cs.js → cynefin-VYW2F7L2-B-4yuRAX.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Bzol06hR.js → cynefinDiagram-MW4NZA55-TiCPFuO8.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-UmliJM77.js → dagre-VZM6K2ZE-7crzLMzA.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BWLcJkFo.js → diagram-7IWD3JNH-Cvr-x6Fd.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-CgApOm-O.js → diagram-B4RE2ZJO-BzcRHUjH.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-Bh3RgTLs.js → diagram-LBJQPF4R-BjkAXilh.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-Dsh-D5nE.js → diagram-Q27KOJAE-BkzyATK7.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-Dkbbpcpb.js → diagram-UB23O5K3-rZuTarYP.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-3EBaA3t3.js → ebnfDiagram-BXEA7PRR-CAYENaN1.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Bq2Dc5ok.js → erDiagram-JOGREHBK-DCEam0Uq.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-De7y55ha.js → flowDiagram-UKHOOZJN-e_dH4wVO.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-fLiDbQRh.js → ganttDiagram-PKOTCBZU-CvZa2zOK.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Du617mp1.js → gitGraphDiagram-DS77QQ5N-CbT5TuKp.js} +1 -1
- package/dist/worker/console/static/assets/index-CUPeoE8W.js +468 -0
- package/dist/worker/console/static/assets/index-SAANIK8g.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-BwmlF-XP.js → infoDiagram-6WML65LV-BWzHQa_Z.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-zsGtS59u.js → ishikawaDiagram-WSZJBQD7-BTjlovtU.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DTTPTe3f.js → journeyDiagram-NVQOT4AX-DkvQoCc1.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BkXg9aP-.js → kanban-definition-27J2QSJJ-CHSzGi3W.js} +1 -1
- package/dist/worker/console/static/assets/{linear-7U2ue5IE.js → linear-DZMkTCWH.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BUuGHmWO.js → mermaid.core-BIMhty7A.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-7q6fX0Sv.js → mindmap-definition-FAOFIHXS-Dx-tyMl3.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-CkQPJN55.js → pegDiagram-VL7TDLO6-C6G34rbY.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CCal_tfX.js → pieDiagram-7S7Q4E2Y-CHK9XOfm.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-B7bpxyAZ.js → quadrantDiagram-CIZ2JOQS-CDARkI0w.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CJmww7D-.js → railroadDiagram-AXF67PYL-DiuUe0ZQ.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-D6ldWJEv.js → requirementDiagram-LRYGKXZP-RE61UR56.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-VGh33I9e.js → sankeyDiagram-W5VNT64P-KDNLHMEG.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CCkDrIjU.js → sequenceDiagram-SI44F4Z6-CeVgXnD9.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-NC8f5Otb.js → sizeCapture-X5ZJPWSS-CXwGyjjG.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-_92ezZdF.js → stateDiagram-OKZ733FA-BjTfozab.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BXoYsyr2.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BdUCGtbP.js → swimlanes-SLNWSIFB-BaXOB8GT.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DfKliS4e.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CdD1H8ia.js → timeline-definition-Z64GVDOM-C3r2hqUU.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-Dkdk3oFo.js → vennDiagram-T6HMQDX7-MWKgl1S9.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CKu2uPPY.js → wardleyDiagram-T6FBY63Y-C9iFcZPk.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-ClqAnuG8.js → xychartDiagram-ELKLHX3M-DqnM24Jp.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/active-turn-tail.js +10 -0
- package/dist/worker/console/static-src/operator-chat/chat-link.js +94 -0
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +122 -10
- package/dist/worker/console/static-src/operator-chat/compaction-message.js +7 -0
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +27 -15
- package/dist/worker/console/static-src/operator-chat/process-label.js +41 -0
- package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +13 -0
- package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +10 -0
- package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +51 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +44 -24
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +18 -2
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +41 -8
- package/dist/worker/console/static-src/operator-chat/useComposer.js +26 -11
- package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +21 -0
- package/dist/worker/console/workspace-context.js +15 -1
- package/dist/worker/observe/node-transparency.js +81 -72
- package/dist/worker/observe/routes.js +20 -1
- package/dist/worker/observe/static/dag-inspector-humanize.js +3 -0
- package/dist/worker/observe/static/dom.js +20 -1
- package/dist/worker/observe/static/format-pool.d.ts +2 -0
- package/dist/worker/observe/static/format-pool.js +6 -0
- package/dist/worker/observe/static/format.js +7 -0
- package/dist/worker/observe/static/inspect-workspace.js +34 -7
- package/dist/worker/observe/static/inspector-submission.js +32 -0
- package/dist/worker/observe/static/kpi.js +1 -0
- package/dist/worker/observe/static/relations.js +2 -0
- package/dist/worker/observe/static/router.js +13 -0
- package/dist/worker/observe/static/run-processing.js +2 -0
- package/dist/worker/observe/static/shell-chrome.js +36 -3
- package/dist/worker/observe/static/state.js +35 -2
- package/dist/worker/observe/static/styles.css +263 -39
- package/dist/worker/observe/static/task-failure-labels.d.ts +4 -0
- package/dist/worker/observe/static/task-failure-labels.js +67 -0
- package/dist/worker/observe/static/task-history.js +12 -0
- package/dist/worker/observe/static/views/batch.js +6 -13
- package/dist/worker/observe/static/views/dag-graph.js +50 -3
- package/dist/worker/observe/static/views/dag-inspector.js +742 -268
- package/dist/worker/observe/static/views/dag-trajectory.js +3 -0
- package/dist/worker/observe/static/views/dag.d.ts +6 -0
- package/dist/worker/observe/static/views/dag.js +49 -11
- package/dist/worker/observe/static/views/dags.js +2 -0
- package/dist/worker/observe/static/views/dashboard.js +21 -12
- package/dist/worker/observe/static/views/failures.js +21 -11
- package/dist/worker/observe/static/views/feature.js +11 -29
- package/dist/worker/observe/static/views/pool.js +37 -28
- package/dist/worker/observe/static/views/run.js +48 -5
- package/dist/worker/observe/static/views/session-timeline.js +189 -240
- package/dist/worker/observe/static/views/task.js +81 -62
- package/dist/workflows/dag/budget-enforcement.js +53 -3
- package/dist/workflows/dag/frontend-capacity.js +9 -0
- package/dist/workflows/dag/frontend-closeout.js +1 -1
- package/dist/workflows/dag/frontend-design-policy.js +2 -1
- package/dist/workflows/dag/frontend-durable-tools.js +193 -0
- package/dist/workflows/dag/frontend-execution-groups.js +24 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +13 -0
- package/dist/workflows/dag/frontend-input-projection.js +76 -0
- package/dist/workflows/dag/frontend-plan-completeness.js +186 -0
- package/dist/workflows/dag/frontend-plan-recovery-policy.js +18 -0
- package/dist/workflows/dag/frontend-plan-render.js +10 -3
- package/dist/workflows/dag/frontend-prewrite-gate.js +3 -3
- package/dist/workflows/dag/frontend-recovery-controller.js +7 -7
- package/dist/workflows/dag/frontend-recovery-lineage.js +13 -0
- package/dist/workflows/dag/frontend-recovery-run.js +4 -0
- package/dist/workflows/dag/frontend-review-context.js +2 -1
- package/dist/workflows/dag/frontend-review-scopes.js +139 -0
- package/dist/workflows/dag/frontend-session-budget.js +249 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +20 -2
- package/dist/workflows/dag/frontend-shape-facts.js +12 -2
- package/dist/workflows/dag/frontend-shape.js +30 -1
- package/dist/workflows/dag/frontend-test-execution-evidence.js +3 -2
- package/dist/workflows/dag/frontend-typed-event-store.js +11 -0
- package/dist/workflows/dag/frontend-verification-trace.js +1 -1
- package/dist/workflows/dag/init-hybrid.js +65 -167
- package/dist/workflows/dag/node-execution.js +38 -155
- package/dist/workflows/dag/prompt.js +4 -0
- package/dist/workflows/dag/rerun-plan.js +7 -1
- package/dist/workflows/dag/runner.js +26 -1
- package/dist/workflows/dag/types.js +6 -0
- package/docs/operations/README.md +1 -0
- package/docs/templates/frontend-design-contract.md +4 -4
- package/docs/templates/frontend-implementation-contract.schema.json +34 -2
- package/docs/templates/frontend-implementation-dag.json +14 -13
- package/package.json +6 -3
- package/skills/frontend-bounded-implement/SKILL.md +3 -3
- package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
- package/skills/frontend-contract/SKILL.md +2 -1
- package/skills/frontend-contract/references/contract-protocol.md +22 -4
- package/skills/frontend-design-review/SKILL.md +22 -16
- package/skills/frontend-design-review/references/review-checklist.md +7 -7
- package/skills/frontend-plan/SKILL.md +21 -2
- package/skills/frontend-plan/references/decision-contract.md +42 -23
- package/skills/frontend-review/SKILL.md +22 -29
- package/skills/frontend-review/references/review-findings.md +24 -43
- package/skills/frontend-scout/references/scout-evidence.md +4 -0
- package/dist/worker/console/static/assets/channel-DAS07MdS.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Cwk-5jiW.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Cwk-5jiW.js +0 -1
- package/dist/worker/console/static/assets/index-C0O48S_P.js +0 -449
- package/dist/worker/console/static/assets/index-CzKf4U8P.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DyJg5gzW.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-B1cw_0Uy.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
|
-
|
|
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-
|
|
336
|
+
.view-heading > p:last-of-type {
|
|
305
337
|
max-width: 66ch;
|
|
306
338
|
margin: 0;
|
|
307
339
|
color: var(--body);
|
|
@@ -1249,6 +1281,9 @@ body.is-resizing-dag-graph {
|
|
|
1249
1281
|
user-select: none;
|
|
1250
1282
|
}
|
|
1251
1283
|
.dag-inspector-header {
|
|
1284
|
+
/* Keep the attempt menu above the content's sticky timeline toolbar. */
|
|
1285
|
+
position: relative;
|
|
1286
|
+
z-index: 6;
|
|
1252
1287
|
display: grid;
|
|
1253
1288
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
1254
1289
|
gap: var(--space-3);
|
|
@@ -1321,6 +1356,26 @@ body.is-resizing-dag-graph {
|
|
|
1321
1356
|
overscroll-behavior-x: contain;
|
|
1322
1357
|
scrollbar-width: thin;
|
|
1323
1358
|
}
|
|
1359
|
+
/* 溢出渐隐:边缘阴影提示还有更多 Tab(类名由 overflow 测量驱动)。 */
|
|
1360
|
+
.dag-inspector-tabs.is-overflow-start,
|
|
1361
|
+
.dag-inspector-tabs.is-overflow-end {
|
|
1362
|
+
background-repeat: no-repeat;
|
|
1363
|
+
background-size: 22px 100%;
|
|
1364
|
+
}
|
|
1365
|
+
.dag-inspector-tabs.is-overflow-start {
|
|
1366
|
+
background-image: linear-gradient(90deg, rgb(38 37 30 / 12%), rgb(38 37 30 / 0));
|
|
1367
|
+
background-position: left center;
|
|
1368
|
+
}
|
|
1369
|
+
.dag-inspector-tabs.is-overflow-end {
|
|
1370
|
+
background-image: linear-gradient(270deg, rgb(38 37 30 / 12%), rgb(38 37 30 / 0));
|
|
1371
|
+
background-position: right center;
|
|
1372
|
+
}
|
|
1373
|
+
.dag-inspector-tabs.is-overflow-start.is-overflow-end {
|
|
1374
|
+
background-image:
|
|
1375
|
+
linear-gradient(90deg, rgb(38 37 30 / 12%), rgb(38 37 30 / 0)),
|
|
1376
|
+
linear-gradient(270deg, rgb(38 37 30 / 12%), rgb(38 37 30 / 0));
|
|
1377
|
+
background-position: left center, right center;
|
|
1378
|
+
}
|
|
1324
1379
|
.dag-inspector-tab {
|
|
1325
1380
|
flex: 0 0 auto;
|
|
1326
1381
|
min-height: 30px;
|
|
@@ -1406,6 +1461,25 @@ body.is-resizing-dag-graph {
|
|
|
1406
1461
|
font-weight: 800;
|
|
1407
1462
|
letter-spacing: 0.12em;
|
|
1408
1463
|
}
|
|
1464
|
+
.inspector-page-eyebrow-row {
|
|
1465
|
+
display: flex;
|
|
1466
|
+
align-items: center;
|
|
1467
|
+
justify-content: space-between;
|
|
1468
|
+
gap: 8px;
|
|
1469
|
+
}
|
|
1470
|
+
.inspector-page-eyebrow-row .observe-icon-button {
|
|
1471
|
+
flex: 0 0 24px;
|
|
1472
|
+
width: 24px;
|
|
1473
|
+
min-width: 24px;
|
|
1474
|
+
height: 24px;
|
|
1475
|
+
min-height: 24px;
|
|
1476
|
+
font-size: 14px;
|
|
1477
|
+
}
|
|
1478
|
+
/* 收起态只保留 eyebrow 行,点击可再展开(会话级记忆)。 */
|
|
1479
|
+
.inspector-page-lead.is-collapsed h4,
|
|
1480
|
+
.inspector-page-lead.is-collapsed p {
|
|
1481
|
+
display: none;
|
|
1482
|
+
}
|
|
1409
1483
|
.dag-inspector-attempt-bar {
|
|
1410
1484
|
position: sticky;
|
|
1411
1485
|
top: calc(-1 * var(--space-4));
|
|
@@ -2029,13 +2103,16 @@ body.is-resizing-dag-graph {
|
|
|
2029
2103
|
margin: 0 2px;
|
|
2030
2104
|
pointer-events: none;
|
|
2031
2105
|
}
|
|
2106
|
+
/* display:flex 会盖过 UA 的 [hidden],贴底/无溢出隐藏 dock 需显式声明。 */
|
|
2107
|
+
.process-timeline-autoscroll-dock[hidden] {
|
|
2108
|
+
display: none;
|
|
2109
|
+
}
|
|
2032
2110
|
.process-timeline-autoscroll {
|
|
2033
2111
|
position: relative;
|
|
2034
2112
|
pointer-events: auto;
|
|
2035
2113
|
display: inline-flex;
|
|
2036
2114
|
align-items: center;
|
|
2037
2115
|
justify-content: center;
|
|
2038
|
-
gap: 7px;
|
|
2039
2116
|
width: 36px;
|
|
2040
2117
|
height: 36px;
|
|
2041
2118
|
padding: 0;
|
|
@@ -2044,7 +2121,9 @@ body.is-resizing-dag-graph {
|
|
|
2044
2121
|
background: color-mix(in srgb, var(--surface) 94%, var(--canvas));
|
|
2045
2122
|
color: var(--body);
|
|
2046
2123
|
box-shadow: 0 8px 24px rgb(38 37 30 / 14%);
|
|
2047
|
-
font-size:
|
|
2124
|
+
font-size: 11px;
|
|
2125
|
+
font-weight: 650;
|
|
2126
|
+
white-space: nowrap;
|
|
2048
2127
|
cursor: pointer;
|
|
2049
2128
|
backdrop-filter: blur(10px);
|
|
2050
2129
|
}
|
|
@@ -2080,25 +2159,22 @@ body.is-resizing-dag-graph {
|
|
|
2080
2159
|
outline: none;
|
|
2081
2160
|
box-shadow: 0 8px 24px rgb(38 37 30 / 16%), 0 0 0 3px var(--orange-soft);
|
|
2082
2161
|
}
|
|
2083
|
-
.process-timeline-autoscroll.
|
|
2084
|
-
border-color: var(--ink);
|
|
2085
|
-
background: var(--ink);
|
|
2086
|
-
color: #fff;
|
|
2087
|
-
}
|
|
2088
|
-
.process-timeline-autoscroll.is-active:hover,
|
|
2089
|
-
.process-timeline-autoscroll.is-active:focus-visible {
|
|
2162
|
+
.process-timeline-autoscroll.has-unread {
|
|
2090
2163
|
border-color: var(--orange);
|
|
2091
|
-
|
|
2092
|
-
color: #fff;
|
|
2164
|
+
color: var(--orange-active);
|
|
2093
2165
|
}
|
|
2094
2166
|
.process-timeline-autoscroll-signal {
|
|
2167
|
+
display: none;
|
|
2168
|
+
position: absolute;
|
|
2169
|
+
top: 5px;
|
|
2170
|
+
right: 5px;
|
|
2095
2171
|
width: 5px;
|
|
2096
2172
|
height: 5px;
|
|
2097
2173
|
border-radius: 50%;
|
|
2098
|
-
background: var(--muted-soft);
|
|
2099
|
-
}
|
|
2100
|
-
.process-timeline-autoscroll.is-active .process-timeline-autoscroll-signal {
|
|
2101
2174
|
background: var(--orange);
|
|
2175
|
+
}
|
|
2176
|
+
.process-timeline-autoscroll.has-unread .process-timeline-autoscroll-signal {
|
|
2177
|
+
display: block;
|
|
2102
2178
|
box-shadow: 0 0 0 4px rgb(245 78 0 / 16%);
|
|
2103
2179
|
animation: process-timeline-live-pulse 1.8s ease-out infinite;
|
|
2104
2180
|
}
|
|
@@ -2107,7 +2183,7 @@ body.is-resizing-dag-graph {
|
|
|
2107
2183
|
75% { box-shadow: 0 0 0 7px rgb(245 78 0 / 0%); }
|
|
2108
2184
|
}
|
|
2109
2185
|
@media (prefers-reduced-motion: reduce) {
|
|
2110
|
-
.process-timeline-autoscroll.
|
|
2186
|
+
.process-timeline-autoscroll.has-unread .process-timeline-autoscroll-signal {
|
|
2111
2187
|
animation: none;
|
|
2112
2188
|
}
|
|
2113
2189
|
.process-timeline-autoscroll::after {
|
|
@@ -2119,28 +2195,6 @@ body.is-resizing-dag-graph {
|
|
|
2119
2195
|
flex-wrap: wrap;
|
|
2120
2196
|
gap: 4px;
|
|
2121
2197
|
}
|
|
2122
|
-
.process-timeline-toggle {
|
|
2123
|
-
min-height: 28px;
|
|
2124
|
-
padding: 0 10px;
|
|
2125
|
-
border: 1px solid var(--hairline-strong);
|
|
2126
|
-
border-radius: var(--radius-sm);
|
|
2127
|
-
background: var(--surface);
|
|
2128
|
-
color: var(--body);
|
|
2129
|
-
font-size: 11px;
|
|
2130
|
-
font-weight: 600;
|
|
2131
|
-
cursor: pointer;
|
|
2132
|
-
}
|
|
2133
|
-
.process-timeline-toggle:hover,
|
|
2134
|
-
.process-timeline-toggle:focus-visible {
|
|
2135
|
-
border-color: var(--orange);
|
|
2136
|
-
color: var(--orange-active);
|
|
2137
|
-
outline: none;
|
|
2138
|
-
}
|
|
2139
|
-
.process-timeline-toggle[aria-pressed="true"] {
|
|
2140
|
-
border-color: color-mix(in srgb, var(--orange) 55%, var(--hairline));
|
|
2141
|
-
background: #fff5ed;
|
|
2142
|
-
color: var(--orange-active);
|
|
2143
|
-
}
|
|
2144
2198
|
.process-timeline-body {
|
|
2145
2199
|
min-width: 0;
|
|
2146
2200
|
padding: 4px 0 8px var(--space-2);
|
|
@@ -2995,6 +3049,19 @@ body.is-resizing-dag-graph {
|
|
|
2995
3049
|
white-space: pre-wrap;
|
|
2996
3050
|
overflow-wrap: anywhere;
|
|
2997
3051
|
}
|
|
3052
|
+
.run-output-shell {
|
|
3053
|
+
position: relative;
|
|
3054
|
+
}
|
|
3055
|
+
.run-output-follow-dock {
|
|
3056
|
+
position: absolute;
|
|
3057
|
+
right: 10px;
|
|
3058
|
+
bottom: 10px;
|
|
3059
|
+
z-index: 3;
|
|
3060
|
+
pointer-events: none;
|
|
3061
|
+
}
|
|
3062
|
+
.run-output-follow-dock[hidden] {
|
|
3063
|
+
display: none;
|
|
3064
|
+
}
|
|
2998
3065
|
|
|
2999
3066
|
.artifact-list {
|
|
3000
3067
|
display: grid;
|
|
@@ -5199,3 +5266,160 @@ button.copy-command:focus-visible {
|
|
|
5199
5266
|
.prompt-restart-status.prompt-restart-error {
|
|
5200
5267
|
color: var(--red);
|
|
5201
5268
|
}
|
|
5269
|
+
|
|
5270
|
+
/* Reader controls stay within reach while the body scrolls. */
|
|
5271
|
+
.dag-inspector.is-expanded { width: calc(100vw - 48px); }
|
|
5272
|
+
.inspect-workspace-root .dag-inspector.is-expanded { width: calc(100% - 32px); }
|
|
5273
|
+
.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); }
|
|
5274
|
+
.process-timeline-toolbar { position: sticky; top: -16px; z-index: 5; padding: 8px 0; background: var(--surface); border-bottom: 1px solid var(--hairline); }
|
|
5275
|
+
.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); }
|
|
5276
|
+
.process-timeline-item.is-search-match { background: color-mix(in srgb, var(--amber) 12%, var(--surface)); border-radius: var(--radius-sm); }
|
|
5277
|
+
.dag-inspector.is-expanded .inspector-page-lead { max-width: none; }
|
|
5278
|
+
.dag-inspector-content .process-timeline-code, .dag-inspector-content .process-timeline-thinking-body { max-height: none; overflow-y: visible; }
|
|
5279
|
+
@media (max-width: 700px) {
|
|
5280
|
+
.dag-inspector.is-expanded { width: calc(100vw - 24px); }
|
|
5281
|
+
.dag-inspector-controls { flex-wrap: wrap; }
|
|
5282
|
+
.dag-inspector-header { padding: 12px; }
|
|
5283
|
+
.dag-inspector-purpose, .dag-inspector-attempt-label { display: none; }
|
|
5284
|
+
.dag-inspector-attempt-preview { font-size: 11px; }
|
|
5285
|
+
}
|
|
5286
|
+
|
|
5287
|
+
.dag-action-intents, .node-relation-links { display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
|
|
5288
|
+
.node-relation-links h5 { width:100%; margin:8px 0 0; }
|
|
5289
|
+
.dag-action-intents [aria-pressed="true"] { border-color:var(--orange); color:var(--orange-active); }
|
|
5290
|
+
.dag-action-card[hidden] { display:none; }
|
|
5291
|
+
.context-component { padding:10px 0; border-top:1px solid var(--hairline); }
|
|
5292
|
+
.context-component > summary { cursor:pointer; overflow-wrap:anywhere; }
|
|
5293
|
+
.context-component-body { margin-top:12px; }
|
|
5294
|
+
.context-record-heading { margin:0; color:var(--ink); font-weight:650; }
|
|
5295
|
+
.context-record-meta { margin:0; color:var(--muted); font-size:12px; line-height:1.6; overflow-wrap:anywhere; }
|
|
5296
|
+
.context-component > summary { display:list-item; color:var(--ink); }
|
|
5297
|
+
.context-component-name { font-weight:600; }
|
|
5298
|
+
.context-component-meta { display:block; margin:4px 0 0 16px; color:var(--muted); font-size:11px; font-weight:400; }
|
|
5299
|
+
.context-source-details { margin-top:12px; color:var(--muted); font-size:12px; }
|
|
5300
|
+
.context-source-details > summary { cursor:pointer; }
|
|
5301
|
+
.context-source-details .node-transparency-summary { margin-top:12px; }
|
|
5302
|
+
.inspector-operation { padding:8px 12px; border:1px solid var(--hairline); border-radius:var(--radius-sm); margin-bottom:8px; overflow-wrap:anywhere; }
|
|
5303
|
+
.dag-graph-toolbar { flex-wrap:wrap; gap:8px; }
|
|
5304
|
+
.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%; }
|
|
5305
|
+
#view-dashboard { display:flex; flex-direction:column; }
|
|
5306
|
+
#view-dashboard[hidden] { display:none; }
|
|
5307
|
+
#view-dashboard .dashboard-workspace { order:-2; }
|
|
5308
|
+
#dashboard-kpi { padding-top:8px; padding-bottom:8px; }
|
|
5309
|
+
#dashboard-kpi .kpi-card { padding-top:12px; padding-bottom:12px; }
|
|
5310
|
+
#dashboard-kpi .kpi-value { font-size:24px; }
|
|
5311
|
+
|
|
5312
|
+
.attempt-comparison-toolbar { display:flex; gap:12px; padding-bottom:12px; }
|
|
5313
|
+
.attempt-comparison-columns { display:grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap:16px; }
|
|
5314
|
+
.attempt-comparison-columns > p { grid-column:1/-1; }
|
|
5315
|
+
.attempt-comparison-column { min-width:0; overflow-wrap:anywhere; }
|
|
5316
|
+
@media (max-width:700px) { .attempt-comparison-columns { grid-template-columns:minmax(0,1fr); } }
|
|
5317
|
+
|
|
5318
|
+
/* Compact controls share the existing palette and keep names available on focus. */
|
|
5319
|
+
.observe-icon-button,
|
|
5320
|
+
.dag-graph-toolbar .observe-icon-button {
|
|
5321
|
+
display: inline-grid;
|
|
5322
|
+
place-items: center;
|
|
5323
|
+
flex: 0 0 32px;
|
|
5324
|
+
width: 32px;
|
|
5325
|
+
min-width: 32px;
|
|
5326
|
+
height: 32px;
|
|
5327
|
+
min-height: 32px;
|
|
5328
|
+
padding: 0;
|
|
5329
|
+
border: 1px solid transparent;
|
|
5330
|
+
border-radius: 7px;
|
|
5331
|
+
background: transparent;
|
|
5332
|
+
color: var(--body);
|
|
5333
|
+
font-size: 17px;
|
|
5334
|
+
line-height: 1;
|
|
5335
|
+
box-shadow: none;
|
|
5336
|
+
cursor: pointer;
|
|
5337
|
+
}
|
|
5338
|
+
.observe-icon-button:hover:not(:disabled),
|
|
5339
|
+
.observe-icon-button[aria-pressed="true"] {
|
|
5340
|
+
background: var(--surface-muted);
|
|
5341
|
+
color: var(--ink);
|
|
5342
|
+
border-color: var(--hairline);
|
|
5343
|
+
transform: none;
|
|
5344
|
+
}
|
|
5345
|
+
.observe-icon-button:focus-visible,
|
|
5346
|
+
.observe-select:focus-visible {
|
|
5347
|
+
outline: 2px solid var(--orange);
|
|
5348
|
+
outline-offset: 2px;
|
|
5349
|
+
}
|
|
5350
|
+
.observe-icon-button:disabled { opacity: .35; cursor: default; }
|
|
5351
|
+
.observe-select {
|
|
5352
|
+
min-height: 32px;
|
|
5353
|
+
max-width: 100%;
|
|
5354
|
+
padding: 4px 24px 4px 10px;
|
|
5355
|
+
border: 1px solid var(--hairline);
|
|
5356
|
+
border-radius: 7px;
|
|
5357
|
+
background: var(--surface);
|
|
5358
|
+
color: var(--ink);
|
|
5359
|
+
font: inherit;
|
|
5360
|
+
font-size: 12px;
|
|
5361
|
+
cursor: pointer;
|
|
5362
|
+
}
|
|
5363
|
+
.dag-inspector-header { gap: 10px; padding: 12px 16px; }
|
|
5364
|
+
.dag-inspector-title { gap: 3px; }
|
|
5365
|
+
.dag-inspector-purpose { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
5366
|
+
.dag-inspector-controls { gap: 3px; }
|
|
5367
|
+
.dag-inspector-header .dag-inspector-attempt-bar { gap: 4px; padding-top: 8px; }
|
|
5368
|
+
.dag-inspector-attempt-label { display: none; }
|
|
5369
|
+
.dag-inspector-attempt-preview { flex: 1; gap: 8px; min-width: 0; }
|
|
5370
|
+
.dag-inspector-attempt-category { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
|
5371
|
+
.process-timeline-toolbar { gap: 4px; align-items: center; flex-shrink: 0; }
|
|
5372
|
+
.process-timeline-filter-group { flex: 0 0 auto; max-width: 135px; }
|
|
5373
|
+
.process-timeline-search { margin: 0 4px; height: 32px; flex: 1 1 120px; }
|
|
5374
|
+
.process-timeline-toolbar > [role="status"] { font-size: 11px; white-space: nowrap; }
|
|
5375
|
+
.dag-graph-toolbar { gap: 4px; }
|
|
5376
|
+
.dag-graph-toolbar-left { margin-right: auto; }
|
|
5377
|
+
.dag-graph-search { height: 32px; width: 160px; margin-left: 8px; }
|
|
5378
|
+
@media (max-width: 700px) {
|
|
5379
|
+
.dag-inspector-header { padding: 10px 12px; }
|
|
5380
|
+
.dag-inspector-controls { flex-wrap: nowrap; }
|
|
5381
|
+
.dag-inspector-status { padding: 2px 6px; }
|
|
5382
|
+
.dag-inspector-attempt-preview { flex-basis: 100%; padding-left: 36px; }
|
|
5383
|
+
.process-timeline-search { flex-basis: 96px; min-width: 76px; }
|
|
5384
|
+
.dag-graph-toolbar-left { flex: 1 1 100%; }
|
|
5385
|
+
.dag-graph-search { flex: 1; min-width: 96px; }
|
|
5386
|
+
}
|
|
5387
|
+
.observe-icon-button { position: relative; }
|
|
5388
|
+
.observe-icon-button::after {
|
|
5389
|
+
content: attr(data-tooltip);
|
|
5390
|
+
position: absolute;
|
|
5391
|
+
right: 0;
|
|
5392
|
+
top: calc(100% + 6px);
|
|
5393
|
+
z-index: 30;
|
|
5394
|
+
padding: 6px 8px;
|
|
5395
|
+
border-radius: 5px;
|
|
5396
|
+
background: var(--ink);
|
|
5397
|
+
color: var(--surface);
|
|
5398
|
+
font: 11px/1.4 system-ui, sans-serif;
|
|
5399
|
+
white-space: nowrap;
|
|
5400
|
+
opacity: 0;
|
|
5401
|
+
pointer-events: none;
|
|
5402
|
+
}
|
|
5403
|
+
.observe-icon-button:focus-visible::after { opacity: 1; }
|
|
5404
|
+
.risk-dag-items { display: grid; gap: 6px; padding-top: 8px; }
|
|
5405
|
+
/* The hosted Console also has .panel styles; keep the reader shell flush. */
|
|
5406
|
+
#dag-inspector { padding: 0; gap: 0; }
|
|
5407
|
+
.dag-inspector-header .dag-inspector-attempt-bar { flex-wrap: wrap; gap: 8px; background: transparent; }
|
|
5408
|
+
.dag-inspector-header .dag-inspector-attempt-select { min-width: 112px; flex: 0 0 126px; }
|
|
5409
|
+
.dag-inspector-header .dag-inspector-attempt-preview { flex: 1 1 100px; flex-wrap: wrap; padding: 0; }
|
|
5410
|
+
.dag-inspector-header .dag-inspector-attempt-category { display: inline; white-space: normal; overflow-wrap: anywhere; }
|
|
5411
|
+
.dag-inspector-header .dag-inspector-attempt-duration { display: none; }
|
|
5412
|
+
@container (max-width: 560px) {
|
|
5413
|
+
.process-timeline-toolbar { display: grid; grid-template-columns: minmax(80px, 1fr) 32px 32px 32px; gap: 4px; }
|
|
5414
|
+
.process-timeline-filter-group { grid-row: 1; grid-column: 1 / 3; width: fit-content; }
|
|
5415
|
+
.process-timeline-errors { grid-row: 1; grid-column: 3; }
|
|
5416
|
+
.process-timeline-protocol-toggle { grid-row: 1; grid-column: 4; }
|
|
5417
|
+
.process-timeline-search { grid-row: 2; grid-column: 1 / 3; width: 100%; margin: 0; }
|
|
5418
|
+
.process-search-previous { grid-row: 2; grid-column: 3; }
|
|
5419
|
+
.process-search-next { grid-row: 2; grid-column: 4; }
|
|
5420
|
+
.process-timeline-toolbar > [role="status"] { grid-row: 3; grid-column: 1 / -1; }
|
|
5421
|
+
.process-timeline-toolbar > [role="status"]:empty { display: none; }
|
|
5422
|
+
}
|
|
5423
|
+
|
|
5424
|
+
.process-search-highlight { background: #ffe082; color: #382800; border-radius: 2px; }
|
|
5425
|
+
.process-timeline-item.is-search-current { outline: 2px solid var(--amber); outline-offset: -2px; }
|
|
@@ -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
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { bindManualViewRefresh, mountTaskRelationPicker } from "../shell-chrome.js";
|
|
1
2
|
/** Observe UI view module (R5). */
|
|
2
3
|
import {
|
|
3
4
|
UI_TEXT,
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
import { clearNode, el, metaGrid, buildTable } from "../dom.js";
|
|
20
21
|
import {
|
|
21
22
|
badge,
|
|
23
|
+
batchStatusBadge,
|
|
22
24
|
badgeClass,
|
|
23
25
|
statusLabel,
|
|
24
26
|
formatTs,
|
|
@@ -71,6 +73,7 @@ import { mountBoundedEventTimeline } from "./timeline.js";
|
|
|
71
73
|
|
|
72
74
|
export async function renderBatch(batchRunId) {
|
|
73
75
|
showView("batch");
|
|
76
|
+
bindManualViewRefresh("batch", () => renderBatch(batchRunId));
|
|
74
77
|
setBreadcrumb([
|
|
75
78
|
{ label: UI_TEXT.dashboard, href: "#/" },
|
|
76
79
|
{ label: batchRunId },
|
|
@@ -88,7 +91,7 @@ export async function renderBatch(batchRunId) {
|
|
|
88
91
|
]);
|
|
89
92
|
if (snapshot) {
|
|
90
93
|
uiState.lastSnapshot = snapshot;
|
|
91
|
-
updateHeaderRefresh(snapshot.generatedAt);
|
|
94
|
+
updateHeaderRefresh(snapshot.generatedAt, { mode: "manual" });
|
|
92
95
|
}
|
|
93
96
|
if (!batch) {
|
|
94
97
|
clearNode(metaEl);
|
|
@@ -100,17 +103,7 @@ export async function renderBatch(batchRunId) {
|
|
|
100
103
|
return;
|
|
101
104
|
}
|
|
102
105
|
|
|
103
|
-
|
|
104
|
-
"batch-relations",
|
|
105
|
-
{
|
|
106
|
-
featureId: batch.featureId,
|
|
107
|
-
batchRunId: batch.batchRunId,
|
|
108
|
-
taskId: batch.tasks?.[0]?.taskId,
|
|
109
|
-
workerRunId: batch.tasks?.[0]?.workerRunId,
|
|
110
|
-
dagRunId: batch.tasks?.[0]?.dagRunId,
|
|
111
|
-
},
|
|
112
|
-
snapshot,
|
|
113
|
-
);
|
|
106
|
+
mountTaskRelationPicker("batch-relations", { featureId: batch.featureId, batchRunId: batch.batchRunId }, (batch.tasks ?? []).map((task) => ({ ...task, featureId: task.featureId ?? batch.featureId })), snapshot);
|
|
114
107
|
|
|
115
108
|
const totalDerived = derivedDurationMs(batch.startedAt, batch.finishedAt);
|
|
116
109
|
clearNode(metaEl);
|
|
@@ -123,7 +116,7 @@ export async function renderBatch(batchRunId) {
|
|
|
123
116
|
? objectRouteLink("feature", batch.featureId, snapshot)
|
|
124
117
|
: el("span", "muted", "—"),
|
|
125
118
|
],
|
|
126
|
-
["状态",
|
|
119
|
+
["状态", batchStatusBadge(batch)],
|
|
127
120
|
["开始时间", formatTs(batch.startedAt)],
|
|
128
121
|
["结束时间", formatTs(batch.finishedAt)],
|
|
129
122
|
["总耗时", formatDuration(totalDerived)],
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
edgeCollidesNonEndpointNodes,
|
|
7
7
|
routeControlEdge,
|
|
8
8
|
} from "../dag-edge-routing.js";
|
|
9
|
-
import { el } from "../dom.js";
|
|
9
|
+
import { el, iconButton } from "../dom.js";
|
|
10
10
|
import {
|
|
11
11
|
statusLabel,
|
|
12
12
|
statusSymbol,
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
currentDagGraphViewMode,
|
|
24
24
|
} from "../state.js";
|
|
25
25
|
import { describeDagNodePurpose } from "../dag-node-purpose.js";
|
|
26
|
-
import { selectDagNode } from "./dag-inspector.js";
|
|
26
|
+
import { selectDagNode, selectDagExecution } from "./dag-inspector.js";
|
|
27
27
|
import { renderTrajectoryStoryboard } from "./dag-trajectory.js";
|
|
28
28
|
|
|
29
29
|
export function svgEl(tag, attrs = {}) {
|
|
@@ -138,6 +138,10 @@ export function renderDagGraph(dag, dagRunId, existingWrap = null) {
|
|
|
138
138
|
controlLaneCount,
|
|
139
139
|
});
|
|
140
140
|
const wrap = existingWrap ?? el("div", "dag-graph-wrap");
|
|
141
|
+
const active = document.activeElement;
|
|
142
|
+
const focusedNodeId = existingWrap?.contains?.(active) ? active?.getAttribute?.("data-node-id") : null;
|
|
143
|
+
const focusedAction = existingWrap?.contains?.(active) ? active?.dataset?.graphAction : null;
|
|
144
|
+
const previousSearch = existingWrap?.querySelector(".dag-graph-search")?.value ?? "";
|
|
141
145
|
// Preserve .dag-graph-viewport DOM identity across poll refreshes so the
|
|
142
146
|
// user's active scroll/pointer target is not destroyed mid-gesture.
|
|
143
147
|
let viewport =
|
|
@@ -169,7 +173,7 @@ export function renderDagGraph(dag, dagRunId, existingWrap = null) {
|
|
|
169
173
|
}
|
|
170
174
|
toolbarLeft.appendChild(el("span", "dag-graph-summary", summaryText));
|
|
171
175
|
toolbar.appendChild(toolbarLeft);
|
|
172
|
-
const reset =
|
|
176
|
+
const reset = iconButton("重置视图", "ri-restart-line", "dag-graph-reset");
|
|
173
177
|
toolbar.appendChild(reset);
|
|
174
178
|
const appendBeforeViewport = (child) => {
|
|
175
179
|
if (viewport?.parentNode === wrap) wrap.insertBefore(child, viewport);
|
|
@@ -339,6 +343,7 @@ export function renderDagGraph(dag, dagRunId, existingWrap = null) {
|
|
|
339
343
|
const purpose = describeDagNodePurpose(node.nodeId, node);
|
|
340
344
|
const group = svgEl("g", {
|
|
341
345
|
transform: `translate(${position.x} ${position.y})`,
|
|
346
|
+
"data-node-id": node.nodeId,
|
|
342
347
|
class: `dag-graph-node status-${status}${node.nodeId === uiState.selectedDagNodeId ? " selected" : ""}${uiState.selectedDagNodeId && !related.has(node.nodeId) ? " dag-dimmed" : ""}`,
|
|
343
348
|
tabindex: 0,
|
|
344
349
|
role: "button",
|
|
@@ -402,6 +407,9 @@ export function renderDagGraph(dag, dagRunId, existingWrap = null) {
|
|
|
402
407
|
});
|
|
403
408
|
svg.appendChild(group);
|
|
404
409
|
}
|
|
410
|
+
const scale = Number(viewport.dataset.scale) || 1;
|
|
411
|
+
svg.style.width = `${Number(svg.getAttribute("width")) * scale}px`;
|
|
412
|
+
svg.style.height = `${Number(svg.getAttribute("height")) * scale}px`;
|
|
405
413
|
viewport.appendChild(svg);
|
|
406
414
|
}
|
|
407
415
|
if (viewport.parentNode !== wrap) wrap.appendChild(viewport);
|
|
@@ -476,9 +484,48 @@ export function renderDagGraph(dag, dagRunId, existingWrap = null) {
|
|
|
476
484
|
}
|
|
477
485
|
}
|
|
478
486
|
}
|
|
487
|
+
const findNode = (id) => {
|
|
488
|
+
const matches = [...viewport.querySelectorAll("[data-node-id]")].filter((element) => element.getAttribute("data-node-id") === id);
|
|
489
|
+
const key = uiState.dagInspectorAttempt?.nodeId === id ? uiState.dagInspectorAttempt.key : null;
|
|
490
|
+
return matches.find((element) => key && element.getAttribute("data-execution-key") === key) ?? matches.at(-1);
|
|
491
|
+
};
|
|
492
|
+
const center = (id, executionId = null) => {
|
|
493
|
+
const target = executionId ? [...viewport.querySelectorAll("[data-execution-id]")].find((item) => item.getAttribute("data-execution-id") === executionId) : findNode(id);
|
|
494
|
+
if (!target) return;
|
|
495
|
+
const rect = target.getBoundingClientRect(), container = viewport.getBoundingClientRect();
|
|
496
|
+
viewport.scrollTo({ left: viewport.scrollLeft + rect.left - container.left - (container.width - rect.width) / 2, top: viewport.scrollTop + rect.top - container.top - (container.height - rect.height) / 2, behavior: "smooth" });
|
|
497
|
+
};
|
|
498
|
+
const addAction = (id, label, action) => { const icons = { selected: "ri-focus-3-line", running: "ri-play-circle-line", failed: "ri-error-warning-line", fit: "ri-fullscreen-line" }; const button = iconButton(label, icons[id], "dag-graph-reset"); button.type = "button"; button.dataset.graphAction = id; button.addEventListener("click", action); toolbar.appendChild(button); return button; };
|
|
499
|
+
addAction("selected", "定位选中", () => center(uiState.selectedDagNodeId)).disabled = !findNode(uiState.selectedDagNodeId);
|
|
500
|
+
addAction("running", "定位运行中", () => { const node = nodes.find((item) => String(item.status).toLowerCase() === "running"); if (node) center(node.nodeId); }).disabled = !nodes.some((item) => String(item.status).toLowerCase() === "running");
|
|
501
|
+
const failedNodes = (mode === "trajectory" ? dag.executionTrajectory?.occurrences ?? [] : nodes).filter((item) => ["error", "failed"].includes(String(item.status).toLowerCase()));
|
|
502
|
+
const failed = addAction("failed", `下个失败 (${failedNodes.length})`, () => {
|
|
503
|
+
if (!failedNodes.length) return;
|
|
504
|
+
const index = failedNodes.findIndex((item) => item.nodeId === uiState.selectedDagNodeId && (mode !== "trajectory" || (item.pass ? `pass-${item.pass}` : null) === (uiState.dagInspectorAttempt?.key ?? null)));
|
|
505
|
+
const node = failedNodes[(index + 1) % failedNodes.length];
|
|
506
|
+
if (mode === "trajectory") selectDagExecution(dagRunId, node.nodeId, node.pass ? `pass-${node.pass}` : null);
|
|
507
|
+
else selectDagNode(dagRunId, node.nodeId);
|
|
508
|
+
requestAnimationFrame(() => center(node.nodeId, node.executionId));
|
|
509
|
+
});
|
|
510
|
+
failed.disabled = !failedNodes.some((node) => findNode(node.nodeId));
|
|
511
|
+
const fit = addAction("fit", "适应画布", () => {
|
|
512
|
+
const svg = viewport.querySelector("svg.dag-graph"); if (!svg) return;
|
|
513
|
+
const width = Number(svg.getAttribute("width")), height = Number(svg.getAttribute("height"));
|
|
514
|
+
const scale = Math.min(1, (viewport.clientWidth - 24) / width, (viewport.clientHeight - 24) / height);
|
|
515
|
+
if (!(scale > 0)) return;
|
|
516
|
+
viewport.dataset.scale = String(scale); svg.style.width = `${width * scale}px`; svg.style.height = `${height * scale}px`; viewport.scrollTo({ left: 0, top: 0 });
|
|
517
|
+
});
|
|
518
|
+
fit.disabled = mode !== "topology";
|
|
519
|
+
const search = el("input", "dag-graph-search"); search.type = "search"; search.placeholder = "查找节点…"; search.value = previousSearch; search.setAttribute("aria-label", "查找流程节点"); search.dataset.graphAction = "search";
|
|
520
|
+
search.addEventListener("keydown", (event) => { if (event.key !== "Enter" || event.isComposing) return; event.preventDefault(); const matches = nodes.filter((item) => `${item.nodeId} ${describeDagNodePurpose(item.nodeId, item)}`.toLocaleLowerCase().includes(search.value.trim().toLocaleLowerCase())); if (!matches.length) return; const index = matches.findIndex((item) => item.nodeId === uiState.selectedDagNodeId); const node = matches[(index + 1) % matches.length]; center(node.nodeId); selectDagNode(dagRunId, node.nodeId); }); toolbar.appendChild(search);
|
|
521
|
+
if (focusedNodeId) findNode(focusedNodeId)?.focus?.({ preventScroll: true });
|
|
522
|
+
else if (focusedAction) [...toolbar.querySelectorAll("[data-graph-action]")].find((item) => item.dataset.graphAction === focusedAction)?.focus?.({ preventScroll: true });
|
|
479
523
|
// Toolbar is rebuilt each paint; bind reset to the current viewport/dagRunId.
|
|
480
524
|
// 重置视图只重置当前模式的 viewport:不切换模式、不重置另一模式、不关闭 Inspector。
|
|
481
525
|
reset.addEventListener("click", () => {
|
|
526
|
+
viewport.dataset.scale = "1";
|
|
527
|
+
const svg = viewport.querySelector("svg.dag-graph");
|
|
528
|
+
if (svg) { svg.style.width = `${svg.getAttribute("width")}px`; svg.style.height = `${svg.getAttribute("height")}px`; }
|
|
482
529
|
if (mode === "trajectory") {
|
|
483
530
|
uiState.dagTrajectoryViewportState = updateDagTrajectoryViewportState(
|
|
484
531
|
uiState.dagTrajectoryViewportState,
|