@tea-agent/loop-agent 0.40.0-next.2 → 0.40.0-next.4

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 (140) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +9 -2
  3. package/README.md +2 -2
  4. package/dist/application/task-lifecycle/advance.js +12 -0
  5. package/dist/build-stamp.json +3 -3
  6. package/dist/cli/update/runtime-activity.js +1 -29
  7. package/dist/commands/dag-rerun.js +1 -1
  8. package/dist/executors/dag-pi-executor.js +46 -5
  9. package/dist/executors/shell-executor.js +28 -0
  10. package/dist/executors/workspace-write-snapshot.js +68 -0
  11. package/dist/shared/dag-prompt-override.js +4 -5
  12. package/dist/shared/update/npm-client.js +33 -11
  13. package/dist/task/config-types.js +10 -0
  14. package/dist/task/contract/apply.js +11 -1
  15. package/dist/task/contract/constants.js +2 -0
  16. package/dist/task/contract/hash.js +3 -0
  17. package/dist/task/contract/observe.js +25 -4
  18. package/dist/task/contract/paths.js +2 -1
  19. package/dist/task/contract/project.js +15 -1
  20. package/dist/task/contract/schema.js +2 -0
  21. package/dist/task/contract/transaction.js +12 -0
  22. package/dist/task/source-prepare/completeness.js +188 -0
  23. package/dist/task/source-prepare/fragment-inventory.js +474 -0
  24. package/dist/task/source-prepare/index.js +3 -0
  25. package/dist/task/source-prepare/ledger-reconciliation.js +127 -0
  26. package/dist/task/source-prepare/ledger-review.js +214 -0
  27. package/dist/task/source-prepare/ledger.js +545 -0
  28. package/dist/task/source-prepare/prepare.js +262 -1
  29. package/dist/task/source-prepare/semantic-intake.js +19 -3
  30. package/dist/task/source-prepare/source-fidelity-pi.js +384 -0
  31. package/dist/task/source-prepare/types.js +22 -0
  32. package/dist/worker/cli.js +12 -26
  33. package/dist/worker/console/console-handoff.js +82 -0
  34. package/dist/worker/console/console-update-and-init.js +115 -0
  35. package/dist/worker/console/console-update-runtime.js +84 -0
  36. package/dist/worker/console/draft-store.js +49 -0
  37. package/dist/worker/console/operation-store.js +1 -1
  38. package/dist/worker/console/operator-actions.js +129 -4
  39. package/dist/worker/console/operator-surface-health.js +1 -0
  40. package/dist/worker/console/prd-intake-bridge.js +13 -0
  41. package/dist/worker/console/routes.js +3 -0
  42. package/dist/worker/console/server.js +73 -5
  43. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-DLMldIE8.js → abnfDiagram-N423BO3Z-CTx1TrNa.js} +1 -1
  44. package/dist/worker/console/static/assets/{arc-DVOg1dSW.js → arc-B4i9cVxX.js} +1 -1
  45. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-715v7joo.js → architectureDiagram-T3A2C74G-BAXE8_Rl.js} +1 -1
  46. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-BtMEGtAQ.js → blockDiagram-VBNYF7ZC-C5Xh59at.js} +1 -1
  47. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-qUxXsdxu.js → c4Diagram-5PPSVZJV-B_asOzAu.js} +1 -1
  48. package/dist/worker/console/static/assets/channel-Dj_4Moei.js +1 -0
  49. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-BYMag72f.js → chunk-2GRJ4B5K-wRO_iRNc.js} +1 -1
  50. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-C5jt5rtx.js → chunk-2Q5K7J3B-ByOaSh_G.js} +1 -1
  51. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-DvZghfS2.js → chunk-5RXB4S5H-DjLzudan.js} +1 -1
  52. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-CXutxAmY.js → chunk-5VM5RSS4-JCNGkXYT.js} +1 -1
  53. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BkANIDWk.js → chunk-6Q2QTUOP-BhrPXXMZ.js} +1 -1
  54. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-Bwy1wwlr.js → chunk-GF5L2VYU-TJ5JuEBT.js} +1 -1
  55. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-D3pWYVCG.js → chunk-JWPE2WC7-VVthn_mD.js} +1 -1
  56. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DRzjzmFD.js → chunk-KBJHAD2P-D60-Mny4.js} +1 -1
  57. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-C4xXDxXL.js → chunk-RYQCIY6F-zXv7aVye.js} +1 -1
  58. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-BngIZ90b.js → chunk-XXDRQBXY-By9VQoi1.js} +1 -1
  59. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C0YYAyCa.js +1 -0
  60. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C0YYAyCa.js +1 -0
  61. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-B40ACoFn.js → cose-bilkent-JH36ORCC-C4zQLe-M.js} +1 -1
  62. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BE-1ZRAI.js → cynefin-VYW2F7L2-wh5N2ReN.js} +1 -1
  63. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BoYbwVTh.js → cynefinDiagram-MW4NZA55-Dlu5wIqs.js} +1 -1
  64. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-B5-KA0fK.js → dagre-VZM6K2ZE-CrDgthc6.js} +1 -1
  65. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-DJpCToT5.js → diagram-7IWD3JNH-zN1clg27.js} +1 -1
  66. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-De8R04Ng.js → diagram-B4RE2ZJO-BN-o7J7-.js} +1 -1
  67. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-BU1N8DiA.js → diagram-LBJQPF4R-C8SuPt0d.js} +1 -1
  68. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BUUUzSYI.js → diagram-Q27KOJAE-BoizuHbZ.js} +1 -1
  69. package/dist/worker/console/static/assets/{diagram-UB23O5K3-zLoT1RC4.js → diagram-UB23O5K3-BzUzXixG.js} +1 -1
  70. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-_q4-4N8c.js → ebnfDiagram-BXEA7PRR-Ev3lA4Cf.js} +1 -1
  71. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-CTqzoNSL.js → erDiagram-JOGREHBK-GALUzRbs.js} +1 -1
  72. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CMKSYKJM.js → flowDiagram-UKHOOZJN-CZJN65Sb.js} +1 -1
  73. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-Dj6U8Sb7.js → ganttDiagram-PKOTCBZU-JLB9OESl.js} +1 -1
  74. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-BfoxVYky.js → gitGraphDiagram-DS77QQ5N-CcvCr4GD.js} +1 -1
  75. package/dist/worker/console/static/assets/{index-CA0nQEbb.js → index-CW88Fjbw.js} +81 -81
  76. package/dist/worker/console/static/assets/index-DP0ZJl39.css +1 -0
  77. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-T5NfvHGV.js → infoDiagram-6WML65LV-HG5z7aVg.js} +1 -1
  78. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BEhUMkut.js → ishikawaDiagram-WSZJBQD7-BHEu9chR.js} +1 -1
  79. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-B2Ld6nNt.js → journeyDiagram-NVQOT4AX-Cp_Up8-a.js} +1 -1
  80. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-nV9T85yS.js → kanban-definition-27J2QSJJ-DvVeY-em.js} +1 -1
  81. package/dist/worker/console/static/assets/{linear-CIO1zDYh.js → linear-aGmcjgTn.js} +1 -1
  82. package/dist/worker/console/static/assets/{mermaid.core-B_ucAqLq.js → mermaid.core-Biyo-tqA.js} +5 -5
  83. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-BIA3VNcZ.js → mindmap-definition-FAOFIHXS-DyxY2pIb.js} +1 -1
  84. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-CNzLjNV3.js → pegDiagram-VL7TDLO6-CkdGuc50.js} +1 -1
  85. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-PWytzfc_.js → pieDiagram-7S7Q4E2Y-NNQI9xVR.js} +1 -1
  86. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-CS0wGoIq.js → quadrantDiagram-CIZ2JOQS-PAJkuz_G.js} +1 -1
  87. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-C3Wsqph8.js → railroadDiagram-AXF67PYL-ZwrQod0O.js} +1 -1
  88. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DF6FDTYg.js → requirementDiagram-LRYGKXZP-D3ZfrzM2.js} +1 -1
  89. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-BdQUJm6y.js → sankeyDiagram-W5VNT64P-DDGFmWk5.js} +1 -1
  90. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-Bv9rppGg.js → sequenceDiagram-SI44F4Z6-DO6mmXTA.js} +1 -1
  91. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-C3Hpvb_B.js → sizeCapture-X5ZJPWSS-DMbCQiJt.js} +1 -1
  92. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-CZOWLpno.js → stateDiagram-OKZ733FA-Di_YUEfC.js} +1 -1
  93. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DrdDvela.js +1 -0
  94. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CPQRIZx5.js → swimlanes-SLNWSIFB-Bn2PphNJ.js} +2 -2
  95. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DPkEAULl.js +8 -0
  96. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CkwM9BgA.js → timeline-definition-Z64GVDOM-DPh8pRsp.js} +1 -1
  97. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-wGSoDzYc.js → vennDiagram-T6HMQDX7-GMfl26pW.js} +1 -1
  98. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-GNVas2gx.js → wardleyDiagram-T6FBY63Y-DTlmVrmF.js} +1 -1
  99. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-C5USnHw7.js → xychartDiagram-ELKLHX3M-YGBjKAS5.js} +1 -1
  100. package/dist/worker/console/static/index.html +2 -2
  101. package/dist/worker/console/static-src/app/console-types.js +40 -1
  102. package/dist/worker/console/static-src/app/useOperatorActions.js +5 -0
  103. package/dist/worker/console/static-src/app/useTaskWizard.js +73 -1
  104. package/dist/worker/observability/init-runtime-activity.js +26 -0
  105. package/dist/worker/observe/node-input.js +88 -2
  106. package/dist/worker/observe/routes.js +188 -0
  107. package/dist/worker/observe/static/api.js +3 -3
  108. package/dist/worker/observe/static/dag-node-purpose.d.ts +6 -0
  109. package/dist/worker/observe/static/dag-node-purpose.js +203 -0
  110. package/dist/worker/observe/static/format.js +37 -0
  111. package/dist/worker/observe/static/index.html +5 -0
  112. package/dist/worker/observe/static/prompt-restart-candidates.d.ts +18 -0
  113. package/dist/worker/observe/static/prompt-restart-candidates.js +36 -0
  114. package/dist/worker/observe/static/state.js +2 -2
  115. package/dist/worker/observe/static/styles.css +357 -35
  116. package/dist/worker/observe/static/views/dag-graph.js +4 -2
  117. package/dist/worker/observe/static/views/dag-inspector.js +531 -78
  118. package/dist/worker/observe/static/views/dag.d.ts +13 -0
  119. package/dist/worker/observe/static/views/dag.js +4 -3
  120. package/dist/worker/observe/static/views/task.js +55 -0
  121. package/dist/workflows/dag/frontend-implementation-contract.js +88 -2
  122. package/dist/workflows/dag/frontend-plan-render.js +24 -0
  123. package/dist/workflows/dag/frontend-prewrite-gate.js +197 -0
  124. package/dist/workflows/dag/frontend-review-context.js +92 -10
  125. package/dist/workflows/dag/init-hybrid.js +144 -4
  126. package/dist/workflows/dag/node-execution.js +45 -0
  127. package/dist/workflows/dag/types.js +45 -12
  128. package/docs/README.md +1 -0
  129. package/docs/architecture/evolution.md +45 -0
  130. package/docs/init-surface.manifest.json +1 -0
  131. package/docs/templates/README.md +1 -1
  132. package/docs/templates/frontend-implementation-contract.schema.json +681 -24
  133. package/package.json +1 -1
  134. package/skills/loop-agent/references/hybrid-dag.md +7 -0
  135. package/dist/worker/console/static/assets/channel-BG6TLen_.js +0 -1
  136. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-GuyUqs0h.js +0 -1
  137. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-GuyUqs0h.js +0 -1
  138. package/dist/worker/console/static/assets/index-C3GgHg-g.css +0 -1
  139. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Dgsvn63q.js +0 -1
  140. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DaNfG1BJ.js +0 -8
@@ -0,0 +1,36 @@
1
+ export function buildPromptRestartCandidateOptions(
2
+ frozenPrompt,
3
+ failedCandidates,
4
+ ) {
5
+ const options = [
6
+ {
7
+ key: "frozen",
8
+ label: "冻结原始提示词",
9
+ prompt: String(frozenPrompt ?? ""),
10
+ truncated: false,
11
+ },
12
+ ];
13
+ const seen = new Set();
14
+ for (const candidate of [...(failedCandidates ?? [])].sort(
15
+ (a, b) => Number(a?.attempt ?? 0) - Number(b?.attempt ?? 0),
16
+ )) {
17
+ const attempt = Number(candidate?.attempt);
18
+ if (!Number.isSafeInteger(attempt) || attempt < 1 || seen.has(attempt)) {
19
+ continue;
20
+ }
21
+ if (typeof candidate?.prompt !== "string") continue;
22
+ seen.add(attempt);
23
+ const failureCategory =
24
+ typeof candidate.failureCategory === "string" &&
25
+ candidate.failureCategory.trim()
26
+ ? candidate.failureCategory.trim()
27
+ : "unknown";
28
+ options.push({
29
+ key: `attempt-${attempt}`,
30
+ label: `第 ${attempt} 次失败 · ${failureCategory}`,
31
+ prompt: candidate.prompt,
32
+ truncated: candidate.truncated === true,
33
+ });
34
+ }
35
+ return options;
36
+ }
@@ -82,8 +82,8 @@ export const uiState = {
82
82
  dagNodeExecutionOutputLoading: false,
83
83
  dagNodeExecutionOutputError: null,
84
84
  dagNodeExecutionOutputKey: null,
85
- /** When true,「执行过程」展开 message_start/end 原始协议事件。默认展开,用户可点选隐藏。 */
86
- sessionTimelineShowProtocol: true,
85
+ /** When true,「执行过程」展开 message_start/end 原始协议事件。默认隐藏,用户可点选展开。 */
86
+ sessionTimelineShowProtocol: false,
87
87
  /** Open <details> keys restored across timeline re-renders. */
88
88
  sessionTimelineOpenDetails: null,
89
89
  lastSnapshot: null,
@@ -1222,6 +1222,13 @@ body.is-resizing-dag-graph {
1222
1222
  font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
1223
1223
  overflow-wrap: anywhere;
1224
1224
  }
1225
+ .dag-inspector-purpose {
1226
+ margin: 0;
1227
+ color: var(--muted);
1228
+ font-size: 12px;
1229
+ line-height: 1.45;
1230
+ overflow-wrap: anywhere;
1231
+ }
1225
1232
  .dag-inspector-controls {
1226
1233
  display: inline-flex;
1227
1234
  align-items: center;
@@ -3570,71 +3577,386 @@ button.copy-command:focus-visible {
3570
3577
  }
3571
3578
 
3572
3579
  /* Experimental prompt-override rerun tab (only rendered with the mutation token). */
3580
+ #dag-inspector-panel-prompt-restart {
3581
+ display: flex;
3582
+ flex-direction: column;
3583
+ min-height: 0;
3584
+ }
3585
+ #dag-inspector-panel-prompt-restart:has(.prompt-restart-panel.is-readonly) {
3586
+ overflow: hidden;
3587
+ }
3588
+ .prompt-restart-panel,
3573
3589
  .prompt-restart-box {
3574
3590
  display: flex;
3575
3591
  flex-direction: column;
3576
- gap: 0.75rem;
3577
- padding: 0.5rem 0.25rem;
3592
+ gap: var(--space-3);
3593
+ min-width: 0;
3594
+ flex: 1;
3595
+ }
3596
+ .prompt-restart-panel.is-readonly {
3597
+ min-height: 0;
3598
+ overflow: hidden;
3599
+ }
3600
+ .prompt-restart-panel.is-readonly .prompt-restart-prompt-card {
3601
+ flex: 1 1 auto;
3602
+ min-height: 12rem;
3603
+ }
3604
+ .prompt-restart-toolbar {
3605
+ display: grid;
3606
+ grid-template-columns: minmax(0, 1fr) auto;
3607
+ gap: var(--space-3);
3608
+ align-items: start;
3609
+ }
3610
+ .prompt-restart-mode-field {
3611
+ min-width: 12.5rem;
3612
+ }
3613
+ .prompt-restart-banner {
3614
+ display: flex;
3615
+ flex-wrap: wrap;
3616
+ align-items: center;
3617
+ gap: 6px 10px;
3618
+ padding: 10px 12px;
3619
+ border: 1px solid var(--hairline);
3620
+ border-radius: var(--radius-lg);
3621
+ background: var(--canvas-soft);
3622
+ }
3623
+ .prompt-restart-banner.is-edit {
3624
+ border-color: color-mix(in srgb, var(--orange) 28%, var(--hairline));
3625
+ background: color-mix(in srgb, var(--orange-soft) 55%, var(--surface));
3626
+ }
3627
+ .prompt-restart-banner-kicker {
3628
+ width: fit-content;
3629
+ padding: 2px 8px;
3630
+ border-radius: var(--radius-pill);
3631
+ background: var(--surface-muted);
3632
+ color: var(--muted);
3633
+ font-size: 11px;
3634
+ font-weight: 700;
3635
+ letter-spacing: 0.02em;
3636
+ }
3637
+ .prompt-restart-banner.is-edit .prompt-restart-banner-kicker {
3638
+ background: var(--orange-soft);
3639
+ color: var(--orange-active);
3640
+ }
3641
+ .prompt-restart-banner-title,
3642
+ .prompt-restart-banner-body {
3643
+ margin: 0;
3644
+ }
3645
+ .prompt-restart-banner-title {
3646
+ color: var(--ink);
3647
+ font-size: 13px;
3648
+ font-weight: 700;
3649
+ line-height: 1.35;
3650
+ }
3651
+ .prompt-restart-banner-body {
3652
+ flex-basis: 100%;
3653
+ color: var(--body);
3654
+ font-size: 12px;
3655
+ line-height: 1.5;
3578
3656
  }
3579
3657
  .prompt-restart-field {
3580
3658
  display: flex;
3581
3659
  flex-direction: column;
3582
- gap: 0.35rem;
3660
+ gap: 6px;
3661
+ min-width: 0;
3662
+ }
3663
+ .prompt-restart-field.is-hidden,
3664
+ .prompt-restart-prompt-card.is-hidden {
3665
+ display: none;
3666
+ }
3667
+ .prompt-restart-label {
3668
+ color: var(--ink);
3669
+ font-size: 12px;
3670
+ font-weight: 700;
3671
+ letter-spacing: 0.01em;
3672
+ }
3673
+ .prompt-restart-hint {
3674
+ margin: 0;
3675
+ color: var(--muted);
3676
+ font-size: 12px;
3677
+ line-height: 1.45;
3678
+ }
3679
+ .prompt-restart-candidate-select {
3680
+ display: block;
3681
+ width: 100%;
3682
+ min-width: 0;
3683
+ }
3684
+ .prompt-restart-candidate-select .custom-select-trigger {
3685
+ width: 100%;
3686
+ }
3687
+ .prompt-restart-candidate-select .custom-select-menu {
3688
+ z-index: 6;
3689
+ }
3690
+ .prompt-restart-mode-switch {
3691
+ display: flex;
3692
+ width: fit-content;
3693
+ max-width: 100%;
3694
+ gap: 4px;
3695
+ padding: 4px;
3696
+ border: 1px solid var(--hairline);
3697
+ border-radius: var(--radius-pill);
3698
+ background: var(--surface);
3699
+ }
3700
+ #dag-inspector-panel-prompt-restart button.prompt-restart-mode-option,
3701
+ .prompt-restart-mode-option {
3702
+ appearance: none;
3703
+ display: inline-flex;
3704
+ align-items: center;
3705
+ justify-content: center;
3706
+ flex: 0 0 auto;
3707
+ width: auto;
3708
+ min-height: 30px;
3709
+ height: 30px;
3710
+ padding: 0 12px;
3711
+ border: 1px solid transparent;
3712
+ border-radius: var(--radius-pill);
3713
+ background: transparent;
3714
+ color: var(--muted);
3715
+ font-size: 12px;
3716
+ font-weight: 700;
3717
+ line-height: 1;
3718
+ letter-spacing: 0;
3719
+ white-space: nowrap;
3720
+ box-shadow: none;
3721
+ transform: none;
3722
+ cursor: pointer;
3723
+ }
3724
+ #dag-inspector-panel-prompt-restart button.prompt-restart-mode-option:hover,
3725
+ #dag-inspector-panel-prompt-restart button.prompt-restart-mode-option:focus-visible,
3726
+ .prompt-restart-mode-option:hover,
3727
+ .prompt-restart-mode-option:focus-visible {
3728
+ color: var(--ink);
3729
+ background: var(--surface-muted);
3730
+ border-color: transparent;
3731
+ outline: none;
3732
+ box-shadow: none;
3733
+ transform: none;
3734
+ }
3735
+ #dag-inspector-panel-prompt-restart button.prompt-restart-mode-option.is-selected,
3736
+ .prompt-restart-mode-option.is-selected {
3737
+ background: var(--ink);
3738
+ color: #fff;
3739
+ border-color: transparent;
3740
+ }
3741
+ .prompt-restart-prompt-card {
3742
+ display: flex;
3743
+ flex-direction: column;
3744
+ min-width: 0;
3745
+ overflow: hidden;
3746
+ border: 1px solid var(--hairline);
3747
+ border-radius: var(--radius-lg);
3748
+ background: var(--surface);
3749
+ }
3750
+ .prompt-restart-prompt-head {
3751
+ display: flex;
3752
+ align-items: flex-start;
3753
+ justify-content: space-between;
3754
+ gap: var(--space-3);
3755
+ padding: 10px 12px;
3756
+ border-bottom: 1px solid var(--hairline);
3757
+ background: var(--canvas-soft);
3758
+ }
3759
+ .prompt-restart-prompt-titles {
3760
+ display: flex;
3761
+ flex-wrap: wrap;
3762
+ align-items: center;
3763
+ gap: 6px 8px;
3764
+ min-width: 0;
3765
+ }
3766
+ .prompt-restart-prompt-title {
3767
+ color: var(--ink);
3768
+ font-size: 13px;
3769
+ font-weight: 700;
3770
+ line-height: 1.3;
3771
+ }
3772
+ .prompt-restart-prompt-badge {
3773
+ padding: 2px 8px;
3774
+ border-radius: var(--radius-pill);
3775
+ background: var(--surface-muted);
3776
+ color: var(--muted);
3777
+ font-size: 11px;
3778
+ font-weight: 700;
3779
+ }
3780
+ .prompt-restart-prompt-meta {
3781
+ flex-basis: 100%;
3782
+ color: var(--muted);
3783
+ font-size: 11px;
3784
+ line-height: 1.3;
3785
+ }
3786
+ .prompt-restart-copy-icon {
3787
+ flex: 0 0 auto;
3788
+ margin-top: 1px;
3789
+ }
3790
+ .prompt-restart-prompt-actions {
3791
+ display: flex;
3792
+ align-items: center;
3793
+ gap: 6px;
3794
+ flex: 0 0 auto;
3795
+ }
3796
+ #dag-inspector-panel-prompt-restart button.prompt-restart-prompt-fold,
3797
+ .prompt-restart-prompt-fold {
3798
+ appearance: none;
3799
+ display: inline-flex;
3800
+ align-items: center;
3801
+ justify-content: center;
3802
+ min-height: 30px;
3803
+ height: 30px;
3804
+ padding: 0 10px;
3805
+ border: 1px solid var(--hairline);
3806
+ border-radius: var(--radius-pill);
3807
+ background: var(--surface);
3808
+ color: var(--body);
3809
+ font-size: 12px;
3810
+ font-weight: 700;
3811
+ line-height: 1;
3812
+ box-shadow: none;
3813
+ transform: none;
3814
+ cursor: pointer;
3815
+ }
3816
+ #dag-inspector-panel-prompt-restart button.prompt-restart-prompt-fold:hover,
3817
+ .prompt-restart-prompt-fold:hover {
3818
+ border-color: var(--hairline-strong);
3819
+ background: var(--surface-muted);
3820
+ color: var(--ink);
3821
+ transform: none;
3822
+ }
3823
+ .prompt-restart-prompt-card.is-collapsed .prompt-restart-readonly {
3824
+ display: none;
3825
+ }
3826
+ .prompt-restart-readonly {
3827
+ margin: 0;
3828
+ padding: 14px 16px;
3829
+ overflow: auto;
3830
+ background: var(--canvas-soft);
3831
+ color: var(--ink);
3832
+ font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
3833
+ font-size: 12px;
3834
+ line-height: 1.65;
3835
+ white-space: pre-wrap;
3836
+ overflow-wrap: anywhere;
3837
+ tab-size: 2;
3838
+ }
3839
+ .prompt-restart-panel.is-readonly .prompt-restart-readonly {
3840
+ flex: 1 1 auto;
3841
+ min-height: 0;
3842
+ max-height: none;
3843
+ }
3844
+ .prompt-restart-panel.is-edit .prompt-restart-readonly {
3845
+ max-height: min(36vh, 18rem);
3583
3846
  }
3584
3847
  .prompt-restart-textarea {
3585
3848
  width: 100%;
3586
3849
  min-height: 8rem;
3587
3850
  resize: vertical;
3588
3851
  box-sizing: border-box;
3589
- font-family: var(--mono-font, ui-monospace, SFMono-Regular, Menlo, monospace);
3590
- font-size: 12.5px;
3591
- line-height: 1.5;
3592
- white-space: pre;
3593
- overflow-wrap: normal;
3852
+ padding: 12px 14px;
3853
+ border: 1px solid var(--hairline);
3854
+ border-radius: var(--radius-lg);
3855
+ background: var(--canvas-soft);
3856
+ color: var(--ink);
3857
+ font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
3858
+ font-size: 12px;
3859
+ line-height: 1.65;
3860
+ white-space: pre-wrap;
3861
+ overflow-wrap: anywhere;
3594
3862
  overflow-x: auto;
3595
3863
  }
3596
- .prompt-restart-actions {
3864
+ .prompt-restart-textarea-work {
3865
+ min-height: 10rem;
3866
+ }
3867
+ .prompt-restart-textarea:hover {
3868
+ border-color: var(--hairline-strong);
3869
+ }
3870
+ .prompt-restart-textarea:focus-visible {
3871
+ outline: 2px solid color-mix(in srgb, var(--orange) 55%, transparent);
3872
+ outline-offset: 1px;
3873
+ border-color: color-mix(in srgb, var(--orange) 35%, var(--hairline));
3874
+ }
3875
+ .prompt-restart-textarea-compact {
3876
+ min-height: 4.5rem;
3877
+ }
3878
+ .prompt-restart-actions,
3879
+ .prompt-restart-footer {
3597
3880
  display: flex;
3598
- gap: 0.5rem;
3881
+ flex-wrap: wrap;
3882
+ gap: var(--space-2);
3599
3883
  align-items: center;
3884
+ justify-content: flex-end;
3600
3885
  }
3886
+ .prompt-restart-footer {
3887
+ position: sticky;
3888
+ bottom: calc(-1 * var(--space-4));
3889
+ z-index: 2;
3890
+ margin-top: auto;
3891
+ padding: 10px 0 2px;
3892
+ border-top: 1px solid var(--hairline);
3893
+ background: var(--surface);
3894
+ }
3895
+ .prompt-restart-footer .prompt-restart-status {
3896
+ flex: 1 1 12rem;
3897
+ min-width: 0;
3898
+ margin-right: auto;
3899
+ }
3900
+ #dag-inspector-panel-prompt-restart button.prompt-restart-submit,
3601
3901
  .prompt-restart-submit {
3602
- padding: 0.35rem 0.9rem;
3603
- font-size: 13.5px;
3902
+ appearance: none;
3903
+ display: inline-flex;
3904
+ align-items: center;
3905
+ justify-content: center;
3906
+ min-height: 34px;
3907
+ height: 34px;
3908
+ padding: 0 16px;
3909
+ border: 1px solid var(--orange);
3910
+ border-radius: var(--radius-pill);
3911
+ background: var(--orange);
3912
+ color: #fff;
3913
+ font-size: 13px;
3914
+ font-weight: 700;
3915
+ line-height: 1;
3916
+ letter-spacing: 0.01em;
3917
+ box-shadow: none;
3918
+ transform: none;
3604
3919
  cursor: pointer;
3605
3920
  }
3921
+ #dag-inspector-panel-prompt-restart button.prompt-restart-submit:hover,
3922
+ #dag-inspector-panel-prompt-restart button.prompt-restart-submit:focus-visible,
3923
+ .prompt-restart-submit:hover,
3924
+ .prompt-restart-submit:focus-visible {
3925
+ background: var(--orange-active);
3926
+ border-color: var(--orange-active);
3927
+ color: #fff;
3928
+ outline: none;
3929
+ box-shadow: none;
3930
+ transform: none;
3931
+ }
3932
+ #dag-inspector-panel-prompt-restart button.prompt-restart-submit.is-secondary,
3933
+ .prompt-restart-submit.is-secondary {
3934
+ border-color: var(--hairline);
3935
+ background: var(--surface);
3936
+ color: var(--ink);
3937
+ }
3938
+ #dag-inspector-panel-prompt-restart button.prompt-restart-submit.is-secondary:hover,
3939
+ #dag-inspector-panel-prompt-restart button.prompt-restart-submit.is-secondary:focus-visible,
3940
+ .prompt-restart-submit.is-secondary:hover,
3941
+ .prompt-restart-submit.is-secondary:focus-visible {
3942
+ border-color: var(--orange);
3943
+ background: var(--orange-soft);
3944
+ color: var(--orange-active);
3945
+ }
3946
+ #dag-inspector-panel-prompt-restart button.prompt-restart-submit:disabled,
3606
3947
  .prompt-restart-submit:disabled {
3607
3948
  opacity: 0.55;
3608
3949
  cursor: wait;
3950
+ transform: none;
3609
3951
  }
3610
3952
  .prompt-restart-status {
3611
3953
  margin: 0;
3612
- font-size: 13px;
3613
3954
  min-height: 1.2em;
3955
+ color: var(--body);
3956
+ font-size: 13px;
3614
3957
  white-space: pre-wrap;
3615
3958
  word-break: break-word;
3616
3959
  }
3617
3960
  .prompt-restart-status.prompt-restart-error {
3618
- color: var(--red, #c0392b);
3619
- }
3620
- .prompt-restart-readonly {
3621
- margin: 0;
3622
- padding: 0.5rem 0.6rem;
3623
- font-family: var(--mono-font, ui-monospace, SFMono-Regular, Menlo, monospace);
3624
- font-size: 12.5px;
3625
- line-height: 1.5;
3626
- white-space: pre;
3627
- overflow: auto;
3628
- border: 1px solid var(--border-color, rgba(125, 125, 125, 0.35));
3629
- border-radius: 6px;
3630
- max-height: 60vh;
3631
- }
3632
- .prompt-restart-mode {
3633
- display: flex;
3634
- align-items: center;
3635
- gap: 0.5rem;
3636
- }
3637
- .prompt-restart-mode-select {
3638
- max-width: 100%;
3639
- font-size: 13px;
3961
+ color: var(--red);
3640
3962
  }
@@ -22,6 +22,7 @@ import {
22
22
  setDagGraphViewMode,
23
23
  currentDagGraphViewMode,
24
24
  } from "../state.js";
25
+ import { describeDagNodePurpose } from "../dag-node-purpose.js";
25
26
  import { selectDagNode } from "./dag-inspector.js";
26
27
  import { renderTrajectoryStoryboard } from "./dag-trajectory.js";
27
28
 
@@ -335,12 +336,13 @@ export function renderDagGraph(dag, dagRunId, existingWrap = null) {
335
336
  const statusLine = `${statusSymbol(status)} ${statusLabel(node.status)} · ${formatMs(node.durationMs)}`;
336
337
  // 节点宽 216、左右 padding≈14:按显示列宽截断(CJK 双宽)。
337
338
  const maxDisplayWidth = Math.max(10, Math.floor((position.width - 28) / 7));
339
+ const purpose = describeDagNodePurpose(node.nodeId, node);
338
340
  const group = svgEl("g", {
339
341
  transform: `translate(${position.x} ${position.y})`,
340
342
  class: `dag-graph-node status-${status}${node.nodeId === uiState.selectedDagNodeId ? " selected" : ""}${uiState.selectedDagNodeId && !related.has(node.nodeId) ? " dag-dimmed" : ""}`,
341
343
  tabindex: 0,
342
344
  role: "button",
343
- "aria-label": `${node.nodeId},状态 ${status}${historyLabel ? `,执行历史 ${historyLabel}` : ""}`,
345
+ "aria-label": `${node.nodeId},${purpose ? `${purpose},` : ""}状态 ${status}${historyLabel ? `,执行历史 ${historyLabel}` : ""}`,
344
346
  });
345
347
  group.appendChild(
346
348
  svgEl("rect", { width: position.width, height: position.height, rx: 10 }),
@@ -352,7 +354,7 @@ export function renderDagGraph(dag, dagRunId, existingWrap = null) {
352
354
  : "";
353
355
  const attemptHint =
354
356
  node.attemptCount > 0 ? `\nattempts: ${node.attemptCount}` : "";
355
- title.textContent = `${node.nodeId}\n${node.executor ?? "未知执行器"}\n${status}${historyLabel ? `\n执行历史:${historyLabel}` : ""}${passHint}${attemptHint}`;
357
+ title.textContent = `${node.nodeId}${purpose ? `\n${purpose}` : ""}\n${node.executor ?? "未知执行器"}\n${status}${historyLabel ? `\n执行历史:${historyLabel}` : ""}${passHint}${attemptHint}`;
356
358
  group.appendChild(title);
357
359
  const label = svgEl("text", {
358
360
  x: 14,