@tea-agent/loop-agent 0.39.0-next.9 → 0.39.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 (288) hide show
  1. package/AGENTS.md +4 -1
  2. package/CHANGELOG.md +269 -69
  3. package/README.md +11 -5
  4. package/bin/loop-agent.js +7 -3
  5. package/dist/application/dag/generate-task-dag.js +9 -0
  6. package/dist/application/task-lifecycle/advance.js +16 -0
  7. package/dist/build-stamp.json +3 -3
  8. package/dist/cli/command-definitions.js +16 -5
  9. package/dist/cli/program.js +16 -2
  10. package/dist/cli/update/notifier.js +2 -2
  11. package/dist/cli/update/runtime-activity.js +1 -29
  12. package/dist/cli.js +2 -1
  13. package/dist/commands/dag-rerun.js +55 -1
  14. package/dist/commands/init-model-catalog.js +464 -0
  15. package/dist/commands/init-upgrade.js +265 -97
  16. package/dist/commands/init.js +428 -27
  17. package/dist/commands/inspect-next.js +8 -0
  18. package/dist/commands/task-advance.js +31 -0
  19. package/dist/executors/dag-pi-executor.js +124 -18
  20. package/dist/executors/pi-event-serializer.js +42 -1
  21. package/dist/executors/pi-executor.js +51 -0
  22. package/dist/executors/pi-extension-resolver.js +233 -0
  23. package/dist/executors/pi-playwright-cli-tool.js +74 -28
  24. package/dist/executors/pi-sdk-executor.js +187 -59
  25. package/dist/executors/shell-executor.js +555 -34
  26. package/dist/executors/shell-write-guard.js +7 -0
  27. package/dist/shared/dag-failure-category.js +138 -0
  28. package/dist/shared/dag-prompt-override.js +27 -0
  29. package/dist/shared/operator/capabilities.js +181 -27
  30. package/dist/shared/playwright-cli-command-policy.js +15 -0
  31. package/dist/shared/update/console-notifier.js +100 -0
  32. package/dist/{cli → shared}/update/npm-client.js +70 -15
  33. package/dist/{cli → shared}/update/state.js +41 -13
  34. package/dist/task/config-types.js +28 -0
  35. package/dist/task/contract/apply.js +11 -1
  36. package/dist/task/contract/constants.js +3 -0
  37. package/dist/task/contract/diff.js +26 -0
  38. package/dist/task/contract/hash.js +3 -0
  39. package/dist/task/contract/observe.js +25 -4
  40. package/dist/task/contract/paths.js +2 -1
  41. package/dist/task/contract/project.js +20 -1
  42. package/dist/task/contract/schema.js +8 -1
  43. package/dist/task/contract/transaction.js +12 -0
  44. package/dist/task/source-prepare/build-draft.js +15 -0
  45. package/dist/task/source-prepare/completeness.js +188 -0
  46. package/dist/task/source-prepare/fragment-inventory.js +474 -0
  47. package/dist/task/source-prepare/index.js +3 -0
  48. package/dist/task/source-prepare/ledger-reconciliation.js +127 -0
  49. package/dist/task/source-prepare/ledger-review.js +214 -0
  50. package/dist/task/source-prepare/ledger.js +545 -0
  51. package/dist/task/source-prepare/parse-intent.js +24 -4
  52. package/dist/task/source-prepare/prepare.js +262 -1
  53. package/dist/task/source-prepare/semantic-intake.js +19 -3
  54. package/dist/task/source-prepare/source-fidelity-pi.js +384 -0
  55. package/dist/task/source-prepare/types.js +22 -0
  56. package/dist/worker/cli.js +18 -2
  57. package/dist/worker/console/chat/deferred-turn.js +91 -0
  58. package/dist/worker/console/chat/mcp-inventory.js +221 -0
  59. package/dist/worker/console/chat/operation-card.js +8 -1
  60. package/dist/worker/console/chat/pi-console-config.js +81 -10
  61. package/dist/worker/console/chat/pi-runtime.js +165 -83
  62. package/dist/worker/console/chat/repo-walk.js +10 -1
  63. package/dist/worker/console/chat/routes.js +480 -55
  64. package/dist/worker/console/chat/semantic-activity.js +20 -8
  65. package/dist/worker/console/chat/session-store.js +146 -2
  66. package/dist/worker/console/chat/turn-process.js +10 -10
  67. package/dist/worker/console/console-handoff.js +82 -0
  68. package/dist/worker/console/console-update-and-init.js +115 -0
  69. package/dist/worker/console/console-update-runtime.js +84 -0
  70. package/dist/worker/console/dag-execution-receipt.js +33 -0
  71. package/dist/worker/console/draft-store.js +49 -0
  72. package/dist/worker/console/inspect-split.js +18 -0
  73. package/dist/worker/console/operation-run-facts.js +19 -3
  74. package/dist/worker/console/operation-store.js +1 -1
  75. package/dist/worker/console/operator-actions.js +320 -4
  76. package/dist/worker/console/operator-surface-health.js +1 -0
  77. package/dist/worker/console/operator-user-error.js +2 -2
  78. package/dist/worker/console/pi-readiness.js +5 -4
  79. package/dist/worker/console/prd-intake-bridge.js +13 -0
  80. package/dist/worker/console/recovery-cta.js +4 -4
  81. package/dist/worker/console/recovery-error-copy.js +4 -4
  82. package/dist/worker/console/routes.js +46 -2
  83. package/dist/worker/console/security.js +63 -9
  84. package/dist/worker/console/server.js +111 -7
  85. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-BLXFe4qI.js → abnfDiagram-N423BO3Z-CTx1TrNa.js} +1 -1
  86. package/dist/worker/console/static/assets/{arc-7iOJeqho.js → arc-B4i9cVxX.js} +1 -1
  87. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CYoyj5K7.js → architectureDiagram-T3A2C74G-BAXE8_Rl.js} +1 -1
  88. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-fK01JNlR.js → blockDiagram-VBNYF7ZC-C5Xh59at.js} +1 -1
  89. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-bzbw5D_Z.js → c4Diagram-5PPSVZJV-B_asOzAu.js} +1 -1
  90. package/dist/worker/console/static/assets/channel-Dj_4Moei.js +1 -0
  91. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-Cf6hJFFG.js → chunk-2GRJ4B5K-wRO_iRNc.js} +1 -1
  92. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DSFXR-et.js → chunk-2Q5K7J3B-ByOaSh_G.js} +1 -1
  93. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BagJechl.js → chunk-5RXB4S5H-DjLzudan.js} +1 -1
  94. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-E7QNMFaW.js → chunk-5VM5RSS4-JCNGkXYT.js} +1 -1
  95. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BG_eOBrC.js → chunk-6Q2QTUOP-BhrPXXMZ.js} +1 -1
  96. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-Bo42dqol.js → chunk-GF5L2VYU-TJ5JuEBT.js} +1 -1
  97. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-dibM-87v.js → chunk-JWPE2WC7-VVthn_mD.js} +1 -1
  98. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-Bytrp3Oe.js → chunk-KBJHAD2P-D60-Mny4.js} +1 -1
  99. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DBABILrr.js → chunk-RYQCIY6F-zXv7aVye.js} +1 -1
  100. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DCUk5Pf9.js → chunk-XXDRQBXY-By9VQoi1.js} +1 -1
  101. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C0YYAyCa.js +1 -0
  102. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C0YYAyCa.js +1 -0
  103. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BlGE9v6E.js → cose-bilkent-JH36ORCC-C4zQLe-M.js} +1 -1
  104. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-DGl5ewph.js → cynefin-VYW2F7L2-wh5N2ReN.js} +1 -1
  105. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-DsJ_SVH_.js → cynefinDiagram-MW4NZA55-Dlu5wIqs.js} +1 -1
  106. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-BIhjFdzv.js → dagre-VZM6K2ZE-CrDgthc6.js} +1 -1
  107. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-Dmy1ctTb.js → diagram-7IWD3JNH-zN1clg27.js} +1 -1
  108. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-DYCtWUF3.js → diagram-B4RE2ZJO-BN-o7J7-.js} +1 -1
  109. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-BMZFHVd2.js → diagram-LBJQPF4R-C8SuPt0d.js} +1 -1
  110. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-b_U8gfaO.js → diagram-Q27KOJAE-BoizuHbZ.js} +1 -1
  111. package/dist/worker/console/static/assets/{diagram-UB23O5K3-Dzy_bn-I.js → diagram-UB23O5K3-BzUzXixG.js} +1 -1
  112. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-DJCiMNEI.js → ebnfDiagram-BXEA7PRR-Ev3lA4Cf.js} +1 -1
  113. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-28lD016B.js → erDiagram-JOGREHBK-GALUzRbs.js} +1 -1
  114. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-DGyHJmIw.js → flowDiagram-UKHOOZJN-CZJN65Sb.js} +1 -1
  115. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-CzdwUjrO.js → ganttDiagram-PKOTCBZU-JLB9OESl.js} +1 -1
  116. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-D9bGwuo8.js → gitGraphDiagram-DS77QQ5N-CcvCr4GD.js} +1 -1
  117. package/dist/worker/console/static/assets/index-CW88Fjbw.js +406 -0
  118. package/dist/worker/console/static/assets/index-DP0ZJl39.css +1 -0
  119. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-LJgJUQFC.js → infoDiagram-6WML65LV-HG5z7aVg.js} +1 -1
  120. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-98LaB8zb.js → ishikawaDiagram-WSZJBQD7-BHEu9chR.js} +1 -1
  121. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-D-ISzwlQ.js → journeyDiagram-NVQOT4AX-Cp_Up8-a.js} +1 -1
  122. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-gfYOI-EL.js → kanban-definition-27J2QSJJ-DvVeY-em.js} +1 -1
  123. package/dist/worker/console/static/assets/{linear-CyntZgKV.js → linear-aGmcjgTn.js} +1 -1
  124. package/dist/worker/console/static/assets/{mermaid.core-BBOR7dg0.js → mermaid.core-Biyo-tqA.js} +5 -5
  125. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-CQAgwPMk.js → mindmap-definition-FAOFIHXS-DyxY2pIb.js} +1 -1
  126. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DkMiZFuV.js → pegDiagram-VL7TDLO6-CkdGuc50.js} +1 -1
  127. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-DLNXa_0J.js → pieDiagram-7S7Q4E2Y-NNQI9xVR.js} +1 -1
  128. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Dc7bdzjm.js → quadrantDiagram-CIZ2JOQS-PAJkuz_G.js} +1 -1
  129. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BxMB0QqW.js → railroadDiagram-AXF67PYL-ZwrQod0O.js} +1 -1
  130. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-FjumoKn4.js → requirementDiagram-LRYGKXZP-D3ZfrzM2.js} +1 -1
  131. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-CkhKc_E3.js → sankeyDiagram-W5VNT64P-DDGFmWk5.js} +1 -1
  132. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-DoBWqTTH.js → sequenceDiagram-SI44F4Z6-DO6mmXTA.js} +1 -1
  133. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-CQeh_YeE.js → sizeCapture-X5ZJPWSS-DMbCQiJt.js} +1 -1
  134. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-LuHmFW-I.js → stateDiagram-OKZ733FA-Di_YUEfC.js} +1 -1
  135. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DrdDvela.js +1 -0
  136. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CHwbDctY.js → swimlanes-SLNWSIFB-Bn2PphNJ.js} +2 -2
  137. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DPkEAULl.js +8 -0
  138. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CoMngk0X.js → timeline-definition-Z64GVDOM-DPh8pRsp.js} +1 -1
  139. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-CURYbtbO.js → vennDiagram-T6HMQDX7-GMfl26pW.js} +1 -1
  140. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-BdqSECjU.js → wardleyDiagram-T6FBY63Y-DTlmVrmF.js} +1 -1
  141. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-DbMUYuAg.js → xychartDiagram-ELKLHX3M-YGBjKAS5.js} +1 -1
  142. package/dist/worker/console/static/index.html +2 -2
  143. package/dist/worker/console/static-src/app/console-types.js +40 -1
  144. package/dist/worker/console/static-src/app/useOperatorActions.js +6 -1
  145. package/dist/worker/console/static-src/app/useRecoveryActions.js +2 -2
  146. package/dist/worker/console/static-src/app/useRecoveryConsole.js +38 -2
  147. package/dist/worker/console/static-src/app/useRunProgress.js +46 -0
  148. package/dist/worker/console/static-src/app/useTaskWizard.js +73 -1
  149. package/dist/worker/console/static-src/operator-chat/cards/failure-category-advice.js +25 -0
  150. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +74 -26
  151. package/dist/worker/console/static-src/operator-chat/input-history.js +76 -0
  152. package/dist/worker/console/static-src/operator-chat/mutation-gate.js +1 -1
  153. package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +328 -0
  154. package/dist/worker/console/static-src/operator-chat/resource-diagnostics.js +204 -0
  155. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +8 -1
  156. package/dist/worker/console/static-src/operator-chat/turn-submission.js +54 -0
  157. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +3 -0
  158. package/dist/worker/console/static-src/operator-chat/useChatStream.js +237 -11
  159. package/dist/worker/console/static-src/operator-chat/useChatThread.js +50 -22
  160. package/dist/worker/console/static-src/operator-chat/useComposer.js +32 -0
  161. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +26 -1
  162. package/dist/worker/console/static-src/pages/tasks/run-id-resolution.js +79 -0
  163. package/dist/worker/console/static-src/pages/tasks/run-ownership-verify.js +23 -0
  164. package/dist/worker/console/static-src/pages/tasks/run-panel-progress.js +110 -0
  165. package/dist/worker/loop-agent/loop-agent-client.js +7 -3
  166. package/dist/worker/materialize/harness-task-lineage.js +5 -2
  167. package/dist/worker/observability/init-runtime-activity.js +26 -0
  168. package/dist/worker/observability/read-model.js +22 -0
  169. package/dist/worker/observe/node-input.js +160 -3
  170. package/dist/worker/observe/node-process.js +377 -0
  171. package/dist/worker/observe/routes.js +224 -3
  172. package/dist/worker/observe/shell-handler-keys.js +34 -0
  173. package/dist/worker/observe/static/api.js +67 -1
  174. package/dist/worker/observe/static/constants.js +8 -1
  175. package/dist/worker/observe/static/dag-history-labels.js +4 -0
  176. package/dist/worker/observe/static/format.js +60 -0
  177. package/dist/worker/observe/static/index.html +5 -0
  178. package/dist/worker/observe/static/markdown-render.js +20 -1
  179. package/dist/worker/observe/static/operator-chrome.js +4 -0
  180. package/dist/worker/observe/static/prompt-restart-candidates.d.ts +18 -0
  181. package/dist/worker/observe/static/prompt-restart-candidates.js +36 -0
  182. package/dist/worker/observe/static/state.js +13 -2
  183. package/dist/worker/observe/static/styles.css +85 -0
  184. package/dist/worker/observe/static/views/dag-inspector.js +912 -8
  185. package/dist/worker/observe/static/views/dag.js +8 -1
  186. package/dist/worker/observe/static/views/failures.js +5 -2
  187. package/dist/worker/observe/static/views/session-timeline.js +78 -9
  188. package/dist/worker/observe/static/views/task.js +55 -0
  189. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +856 -54
  190. package/dist/workflows/dag/backend-test-case-manifest.js +4 -0
  191. package/dist/workflows/dag/backend-test-execution-contract.js +18 -9
  192. package/dist/workflows/dag/backend-test-gap-fill.js +205 -0
  193. package/dist/workflows/dag/backend-test-intake-context.js +32 -0
  194. package/dist/workflows/dag/backend-test-layout.js +133 -0
  195. package/dist/workflows/dag/backend-test-markdown-workflow.js +343 -33
  196. package/dist/workflows/dag/backend-test-module-stem.js +5 -0
  197. package/dist/workflows/dag/backend-test-pytest-collection.js +454 -36
  198. package/dist/workflows/dag/backend-test-result-contract.js +1 -1
  199. package/dist/workflows/dag/backend-test-scenario-param.js +884 -140
  200. package/dist/workflows/dag/backend-test-scenario-partitions.js +321 -0
  201. package/dist/workflows/dag/backend-test-writer-completeness.js +110 -61
  202. package/dist/workflows/dag/contract-output-registry.js +15 -0
  203. package/dist/workflows/dag/contract-validator-registrations.js +3 -1
  204. package/dist/workflows/dag/convergence/controller.js +141 -0
  205. package/dist/workflows/dag/dynamic-runtime/loop-until.js +1 -1
  206. package/dist/workflows/dag/dynamic-runtime/map.js +25 -9
  207. package/dist/workflows/dag/dynamic-runtime/shared.js +1 -1
  208. package/dist/workflows/dag/failure-category.js +7 -116
  209. package/dist/workflows/dag/frontend-implementation-contract.js +465 -6
  210. package/dist/workflows/dag/frontend-plan-render.js +24 -0
  211. package/dist/workflows/dag/frontend-prewrite-gate.js +293 -84
  212. package/dist/workflows/dag/frontend-repair.js +14 -0
  213. package/dist/workflows/dag/frontend-review-context.js +92 -10
  214. package/dist/workflows/dag/frontend-risk.js +15 -2
  215. package/dist/workflows/dag/frontend-test-case-checklist.js +30 -4
  216. package/dist/workflows/dag/frontend-test-case-manifest.js +11 -4
  217. package/dist/workflows/dag/frontend-test-case-quality.js +11 -16
  218. package/dist/workflows/dag/frontend-test-environment-probe.js +230 -0
  219. package/dist/workflows/dag/frontend-test-html-report.js +3 -1
  220. package/dist/workflows/dag/frontend-test-l5-report.js +3 -1
  221. package/dist/workflows/dag/frontend-test-layout.js +159 -0
  222. package/dist/workflows/dag/frontend-test-markdown.js +61 -0
  223. package/dist/workflows/dag/frontend-test-result-contract.js +188 -42
  224. package/dist/workflows/dag/frontend-test-standard-scenarios.js +70 -0
  225. package/dist/workflows/dag/frontend-verification-trace.js +29 -4
  226. package/dist/workflows/dag/init-hybrid.js +1019 -209
  227. package/dist/workflows/dag/node-execution.js +228 -15
  228. package/dist/workflows/dag/prompt.js +60 -1
  229. package/dist/workflows/dag/rerun-feedback.js +212 -0
  230. package/dist/workflows/dag/rerun-plan.js +224 -27
  231. package/dist/workflows/dag/rerun-run.js +61 -6
  232. package/dist/workflows/dag/rerun-task.js +61 -2
  233. package/dist/workflows/dag/retry-policy.js +109 -0
  234. package/dist/workflows/dag/structured-output-repair.js +712 -0
  235. package/dist/workflows/dag/types.js +185 -12
  236. package/dist/workflows/dag/validate.js +64 -20
  237. package/docs/README.md +1 -0
  238. package/docs/architecture/evolution.md +45 -0
  239. package/docs/init-surface.manifest.json +6 -0
  240. package/docs/operations/README.md +1 -1
  241. package/docs/operations/local-development-environment.md +1 -5
  242. package/docs/skills/vetted-skill-registry.md +14 -0
  243. package/docs/templates/README.md +2 -2
  244. package/docs/templates/agent-dag.schema.json +44 -0
  245. package/docs/templates/backend-test-dag.json +60 -35
  246. package/docs/templates/frontend-implementation-contract.schema.json +681 -24
  247. package/docs/templates/frontend-test-case-checklist.md +2 -2
  248. package/docs/templates/frontend-test-dag.json +8 -10
  249. package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +1 -1
  250. package/docs/templates/init-managed-agents.md +13 -3
  251. package/harness.json +6 -4
  252. package/package.json +12 -4
  253. package/scripts/next-info.mjs +356 -0
  254. package/scripts/next-publish-gate.mjs +238 -0
  255. package/scripts/release-source-binding.mjs +251 -0
  256. package/skills/analyze-product-requirements/SKILL.md +8 -5
  257. package/skills/analyze-product-requirements/references/acceptance-criteria.md +1 -1
  258. package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +10 -6
  259. package/skills/analyze-product-requirements/references/example.md +50 -0
  260. package/skills/analyze-product-requirements/references/forward-test-cases.md +11 -7
  261. package/skills/analyze-product-requirements/references/kb-integration.md +5 -5
  262. package/skills/analyze-product-requirements/references/product-analysis-schema.md +8 -4
  263. package/skills/analyze-product-requirements/references/product-requirement-schema.md +2 -2
  264. package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +1 -1
  265. package/skills/analyze-product-requirements/scripts/test-validators.mjs +11 -1
  266. package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +20 -1
  267. package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +9 -0
  268. package/skills/codebase-scout/SKILL.md +1 -1
  269. package/skills/fe-test-ui-scout/SKILL.md +65 -0
  270. package/skills/fe-test-ui-scout/references/ledger-schema.md +62 -0
  271. package/skills/fe-test-ui-scout/references/recon-protocol.md +54 -0
  272. package/skills/frontend-implementation/references/node-contracts.md +2 -2
  273. package/skills/improve-codebase-architecture/SKILL.md +81 -0
  274. package/skills/improve-codebase-architecture/deepening.md +37 -0
  275. package/skills/improve-codebase-architecture/html-report.md +123 -0
  276. package/skills/improve-codebase-architecture/interface-design.md +44 -0
  277. package/skills/improve-codebase-architecture/language.md +53 -0
  278. package/skills/loop-agent/references/command-reference.md +11 -4
  279. package/skills/loop-agent/references/hybrid-dag.md +7 -0
  280. package/skills/playwright-cli/SKILL.md +23 -1
  281. package/skills/playwright-cli-case-generator/SKILL.md +29 -8
  282. package/dist/worker/console/static/assets/channel-BBOTJHvD.js +0 -1
  283. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Cm8Yf8tD.js +0 -1
  284. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Cm8Yf8tD.js +0 -1
  285. package/dist/worker/console/static/assets/index-B-qWGThd.js +0 -325
  286. package/dist/worker/console/static/assets/index-C-xRgY_0.css +0 -1
  287. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DZihfdKc.js +0 -1
  288. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-CKnXCjHX.js +0 -8
@@ -13,6 +13,7 @@
13
13
  * - A run summary is a projection only: it can never change the terminal
14
14
  * operation state decided by the command envelope/exit facts.
15
15
  */
16
+ import { normalizeDagFailureCategory } from "../../shared/dag-failure-category.js";
16
17
  import { scrubSecrets } from "./chat/explore-tools.js";
17
18
  const RUN_SUMMARY_MAX_NODES = 20;
18
19
  const RUN_SUMMARY_MAX_TEXT_CHARS = 600;
@@ -72,7 +73,13 @@ function safeNode(value) {
72
73
  const status = boundedRedactedText(rec.status, 100);
73
74
  if (!id || !status)
74
75
  return undefined;
75
- return { id, status };
76
+ const rawCategory = boundedRedactedText(rec.failureCategory, 200);
77
+ if (!rawCategory)
78
+ return { id, status };
79
+ const category = normalizeDagFailureCategory(rawCategory, status);
80
+ if (category === "success" || category === "skipped")
81
+ return { id, status };
82
+ return { id, status, failureCategory: category };
76
83
  }
77
84
  /** Independent allowlist projection of a structured run summary. */
78
85
  export function safeRunSummaryForProjection(value) {
@@ -117,13 +124,22 @@ export function safeRunSummaryForProjection(value) {
117
124
  }
118
125
  }
119
126
  const verdict = boundedRedactedText(rec.verdict);
120
- const failureCategory = boundedRedactedText(rec.failureCategory);
127
+ const rawFailureCategory = boundedRedactedText(rec.failureCategory, 200);
128
+ // Normalize the run-level category too (2026-08-23): raw codes like
129
+ // missing-api-key / nonzero-exit never matched the browser advice table.
130
+ const failureCategory = rawFailureCategory !== undefined
131
+ ? normalizeDagFailureCategory(rawFailureCategory, status)
132
+ : undefined;
121
133
  return {
122
134
  runId,
123
135
  status,
124
136
  nodes,
125
137
  ...(verdict !== undefined ? { verdict } : {}),
126
- ...(failureCategory !== undefined ? { failureCategory } : {}),
138
+ ...(failureCategory !== undefined &&
139
+ failureCategory !== "success" &&
140
+ failureCategory !== "skipped"
141
+ ? { failureCategory }
142
+ : {}),
127
143
  ...(outOfBounds.length > 0 ? { outOfBounds } : {}),
128
144
  ...(next ? { next } : {}),
129
145
  };
@@ -1,7 +1,7 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import path from "node:path";
3
3
  import { listJsonFiles, readJsonIfExists, sha256Json, writeSecureJson, } from "./app-data.js";
4
- export const TERMINAL_OPERATION_STATES = new Set(["succeeded", "failed", "timed-out"]);
4
+ export const TERMINAL_OPERATION_STATES = new Set(["succeeded", "failed", "timed-out", "restarting"]);
5
5
  function operationFile(appData, operationId) {
6
6
  return path.join(appData.operations, `${operationId}.json`);
7
7
  }
@@ -1,5 +1,6 @@
1
1
  import { access, readFile } from "node:fs/promises";
2
- import { buildOperatorCapabilitiesDocument } from "../../shared/operator/capabilities.js";
2
+ import { buildOperatorCapabilitiesDocument, OFFICIAL_TAIL_ACTION_IDS, } from "../../shared/operator/capabilities.js";
3
+ import { DAG_RERUN_PROMPT_OVERRIDE_ENV, isDagRerunPromptOverrideEnabled, MAX_DAG_RERUN_PROMPT_OVERRIDE_CHARS, } from "../../shared/dag-prompt-override.js";
3
4
  import { buildOperatorResult, operatorFailed, operatorSucceeded, } from "../../shared/operator/envelope.js";
4
5
  import { CANONICAL_TASK_ID_PATTERN, formatLocalBusinessDate, getTaskPaths, loadTaskConfig, } from "../../task/runtime.js";
5
6
  import { diffTaskContract, validateDraftForTask, } from "../../task/contract/index.js";
@@ -401,6 +402,85 @@ async function runReadCli(ctx, args, command) {
401
402
  });
402
403
  }
403
404
  }
405
+ /**
406
+ * Parse and bound the experimental promptOverrides action param. The env
407
+ * switch is checked separately so disabled deployments fail closed before any
408
+ * staging happens. `mode` defaults to "replace"; "append" keeps the frozen
409
+ * base prompt and only appends the operator text as a marked addendum.
410
+ */
411
+ function parsePromptOverrideParams(raw) {
412
+ if (raw === undefined || raw === null)
413
+ return { kind: "ok", overrides: [] };
414
+ if (!Array.isArray(raw)) {
415
+ return {
416
+ kind: "error",
417
+ message: "promptOverrides must be an array of {nodeId, prompt, mode?}",
418
+ };
419
+ }
420
+ if (raw.length === 0)
421
+ return { kind: "ok", overrides: [] };
422
+ if (raw.length > 8) {
423
+ return { kind: "error", message: "promptOverrides supports at most 8 nodes" };
424
+ }
425
+ const overrides = [];
426
+ const seen = new Set();
427
+ for (const item of raw) {
428
+ if (!item || typeof item !== "object") {
429
+ return {
430
+ kind: "error",
431
+ message: "promptOverrides entries must be objects {nodeId, prompt, mode?}",
432
+ };
433
+ }
434
+ const record = item;
435
+ const nodeId = typeof record.nodeId === "string" ? record.nodeId.trim() : "";
436
+ const prompt = typeof record.prompt === "string" ? record.prompt : "";
437
+ const mode = record.mode === undefined || record.mode === null
438
+ ? undefined
439
+ : typeof record.mode === "string"
440
+ ? record.mode
441
+ : "invalid";
442
+ if (!nodeId) {
443
+ return { kind: "error", message: "promptOverrides nodeId is required" };
444
+ }
445
+ if (seen.has(nodeId)) {
446
+ return {
447
+ kind: "error",
448
+ message: `promptOverrides contains duplicate nodeId: ${nodeId}`,
449
+ };
450
+ }
451
+ seen.add(nodeId);
452
+ if (mode !== undefined && mode !== "append" && mode !== "replace") {
453
+ return {
454
+ kind: "error",
455
+ message: `promptOverrides mode for ${nodeId} must be append or replace`,
456
+ };
457
+ }
458
+ if (!prompt.trim() || prompt.length > MAX_DAG_RERUN_PROMPT_OVERRIDE_CHARS) {
459
+ return {
460
+ kind: "error",
461
+ message: `promptOverrides prompt for ${nodeId} must be 1-${MAX_DAG_RERUN_PROMPT_OVERRIDE_CHARS} characters`,
462
+ };
463
+ }
464
+ overrides.push(mode === undefined ? { nodeId, prompt } : { nodeId, prompt, mode });
465
+ }
466
+ return { kind: "ok", overrides };
467
+ }
468
+ /** Stage override bodies under app-data and build `--prompt-override` CLI
469
+ * args. The flag carries the mode: `--prompt-override-append` for append. */
470
+ async function buildPromptOverrideCliArgs(ctx, overrides) {
471
+ const args = [];
472
+ for (const override of overrides) {
473
+ const staged = await stageUtf8Text(ctx.appData, override.prompt, {
474
+ extension: ".md",
475
+ label: `prompt-override-${override.nodeId}`,
476
+ });
477
+ const flag = override.mode === "append"
478
+ ? "--prompt-override-append"
479
+ : "--prompt-override";
480
+ args.push(flag, `${override.nodeId}@${staged.path}`);
481
+ }
482
+ return args;
483
+ }
404
484
  async function acceptOperation(ctx, input) {
405
485
  const created = await ctx.operations.create({
406
486
  clientRequestId: input.clientRequestId,
@@ -456,6 +536,106 @@ async function acceptOperation(ctx, input) {
456
536
  },
457
537
  };
458
538
  }
539
+ async function acceptConsoleUpdateAndInit(ctx, clientRequestId, channel) {
540
+ if (!ctx.consoleUpdateExecutor) {
541
+ return {
542
+ kind: "error",
543
+ status: 503,
544
+ body: operatorFailed({
545
+ command: "consoleUpdateAndInit",
546
+ outcome: "blocked",
547
+ code: "CONSOLE_UPDATE_UNAVAILABLE",
548
+ message: "Console update runtime is unavailable",
549
+ }),
550
+ };
551
+ }
552
+ const created = await ctx.operations.create({
553
+ clientRequestId,
554
+ action: "consoleUpdateAndInit",
555
+ actionParams: { channel },
556
+ });
557
+ if (created.kind === "conflict") {
558
+ return {
559
+ kind: "error",
560
+ status: 409,
561
+ body: operatorFailed({
562
+ command: "consoleUpdateAndInit",
563
+ outcome: "conflict",
564
+ code: "REQUEST_ID_REUSE_CONFLICT",
565
+ message: created.message,
566
+ }),
567
+ };
568
+ }
569
+ if (created.kind === "idempotent") {
570
+ return {
571
+ kind: "accepted",
572
+ status: 202,
573
+ body: {
574
+ operationId: created.operation.operationId,
575
+ state: created.operation.state,
576
+ clientRequestId: created.operation.clientRequestId,
577
+ action: created.operation.action,
578
+ },
579
+ };
580
+ }
581
+ queueMicrotask(() => {
582
+ void (async () => {
583
+ const operationId = created.operation.operationId;
584
+ await ctx.operations.update(operationId, {
585
+ state: "running",
586
+ startedAt: new Date().toISOString(),
587
+ });
588
+ ctx.events.append(operationId, {
589
+ at: new Date().toISOString(),
590
+ kind: "state",
591
+ state: "running",
592
+ message: `checking runtime, npm ${channel}, and safe initialization`,
593
+ });
594
+ try {
595
+ const result = await ctx.consoleUpdateExecutor(channel);
596
+ const state = result.state;
597
+ const next = await ctx.operations.update(operationId, {
598
+ state,
599
+ finishedAt: new Date().toISOString(),
600
+ result: result,
601
+ ...(result.errorCode ? { errorCode: result.errorCode } : {}),
602
+ ...(result.errorMessage ? { errorMessage: result.errorMessage } : {}),
603
+ });
604
+ ctx.events.append(operationId, {
605
+ at: new Date().toISOString(),
606
+ kind: "state",
607
+ state: next.state,
608
+ message: result.errorMessage ?? `console maintenance ${next.state}`,
609
+ });
610
+ }
611
+ catch (error) {
612
+ const message = error instanceof Error ? error.message : String(error);
613
+ const next = await ctx.operations.update(operationId, {
614
+ state: "needs-reconcile",
615
+ finishedAt: new Date().toISOString(),
616
+ errorCode: "CONSOLE_UPDATE_EXCEPTION",
617
+ errorMessage: message,
618
+ });
619
+ ctx.events.append(operationId, {
620
+ at: new Date().toISOString(),
621
+ kind: "error",
622
+ state: next.state,
623
+ message,
624
+ });
625
+ }
626
+ })();
627
+ });
628
+ return {
629
+ kind: "accepted",
630
+ status: 202,
631
+ body: {
632
+ operationId: created.operation.operationId,
633
+ state: created.operation.state,
634
+ clientRequestId: created.operation.clientRequestId,
635
+ action: created.operation.action,
636
+ },
637
+ };
638
+ }
459
639
  export async function dispatchOperatorAction(ctx, req) {
460
640
  const action = req.action?.trim();
461
641
  if (!action) {
@@ -486,6 +666,31 @@ export async function dispatchOperatorAction(ctx, req) {
486
666
  };
487
667
  }
488
668
  const p = paramsOf(req);
669
+ if (action === "consoleUpdateAndInit") {
670
+ if (req.source !== "human-ui") {
671
+ return {
672
+ kind: "error",
673
+ status: 403,
674
+ body: operatorFailed({
675
+ command: action,
676
+ outcome: "blocked",
677
+ code: "HUMAN_UI_REQUIRED",
678
+ message: "consoleUpdateAndInit is available only from the Operate UI",
679
+ }),
680
+ };
681
+ }
682
+ if (!req.clientRequestId?.trim()) {
683
+ return invalid(action, "clientRequestId is required");
684
+ }
685
+ if (Object.keys(p).some((key) => key !== "channel")) {
686
+ return invalid(action, "only channel may be provided");
687
+ }
688
+ const channel = p.channel ?? "latest";
689
+ if (channel !== "latest" && channel !== "next") {
690
+ return invalid(action, "channel must be latest or next");
691
+ }
692
+ return acceptConsoleUpdateAndInit(ctx, req.clientRequestId, channel);
693
+ }
489
694
  switch (action) {
490
695
  case "operatorCapabilities": {
491
696
  const doc = buildOperatorCapabilitiesDocument();
@@ -672,6 +877,80 @@ export async function dispatchOperatorAction(ctx, req) {
672
877
  const body = await runReadCli(ctx, ["dag", "report", "--run-id", runId, "--json"], "dag report");
673
878
  return { kind: "sync", status: body.ok ? 200 : 400, body };
674
879
  }
880
+ case "dagDoctor": {
881
+ const runId = str(p.runId) ?? str(p.dagRunId);
882
+ const args = ["dag", "doctor"];
883
+ if (runId)
884
+ args.push("--run-id", runId);
885
+ const body = await runReadCli(ctx, args, "dag doctor");
886
+ return { kind: "sync", status: body.ok ? 200 : 400, body };
887
+ }
888
+ case "dagStatus": {
889
+ const runId = str(p.runId) ?? str(p.dagRunId);
890
+ if (!runId)
891
+ return invalid(action, "runId is required");
892
+ const body = await runReadCli(ctx, ["dag", "status", "--run-id", runId], "dag status");
893
+ return { kind: "sync", status: body.ok ? 200 : 400, body };
894
+ }
895
+ case "workerPoolDoctor": {
896
+ const taskId = str(p.taskId);
897
+ const run = ctx.runCommand ??
898
+ ((args, options) => ctx.client.runExternal
899
+ ? ctx.client.runExternal(resolveSiblingAgentWorkerBin(), args, options)
900
+ : ctx.client.run(args, options));
901
+ let result;
902
+ try {
903
+ result = await run(["pool", "doctor", "--repo", ctx.repoRoot, "--json"], {
904
+ cwd: ctx.repoRoot,
905
+ artifactName: "read-pool-doctor",
906
+ expectJson: true,
907
+ });
908
+ }
909
+ catch (error) {
910
+ return {
911
+ kind: "error",
912
+ status: 400,
913
+ body: operatorFailed({
914
+ command: action,
915
+ outcome: "invalid",
916
+ code: "INVALID_INPUT",
917
+ message: `cannot read pool doctor facts: ${error instanceof Error ? error.message : String(error)}`,
918
+ }),
919
+ };
920
+ }
921
+ if (!result.ok || result.exitCode !== 0 || !result.json) {
922
+ return {
923
+ kind: "error",
924
+ status: 400,
925
+ body: operatorFailed({
926
+ command: action,
927
+ outcome: "invalid",
928
+ code: "INVALID_INPUT",
929
+ message: summarizeReadCliFailure(result),
930
+ }),
931
+ };
932
+ }
933
+ const inventory = result.json;
934
+ if (!taskId) {
935
+ return {
936
+ kind: "sync",
937
+ status: 200,
938
+ body: operatorSucceeded(action, inventory),
939
+ };
940
+ }
941
+ const v2 = (inventory.v2 ?? []).filter((entry) => entry.taskId === taskId);
942
+ const legacy = (inventory.legacy ?? []).filter((entry) => entry.taskId === taskId);
943
+ return {
944
+ kind: "sync",
945
+ status: 200,
946
+ body: operatorSucceeded(action, {
947
+ ...inventory,
948
+ v2,
949
+ legacy,
950
+ focusedTaskId: taskId,
951
+ }),
952
+ };
953
+ }
675
954
  case "status": {
676
955
  const taskId = str(p.taskId);
677
956
  if (!taskId) {
@@ -986,7 +1265,7 @@ export async function dispatchOperatorAction(ctx, req) {
986
1265
  }
987
1266
  if (operatorAction) {
988
1267
  const target = buildOperatorCapabilitiesDocument().actions.find((entry) => entry.action === operatorAction &&
989
- entry.description.startsWith("Official CLI action coverage") &&
1268
+ OFFICIAL_TAIL_ACTION_IDS.has(entry.action) &&
990
1269
  entry.humanConfirmation === "required");
991
1270
  if (!target)
992
1271
  return invalid(action, "operatorAction must name a required official action");
@@ -2004,12 +2283,35 @@ export async function dispatchOperatorAction(ctx, req) {
2004
2283
  }
2005
2284
  return accepted;
2006
2285
  }
2286
+ case "dagPromptOverrideConfig": {
2287
+ // The prompt-edit entry is visible by default. The internal environment
2288
+ // switch remains an emergency kill switch and is reflected here.
2289
+ return {
2290
+ kind: "sync",
2291
+ status: 200,
2292
+ body: operatorSucceeded(action, {
2293
+ enabled: isDagRerunPromptOverrideEnabled(),
2294
+ envVar: DAG_RERUN_PROMPT_OVERRIDE_ENV,
2295
+ }),
2296
+ };
2297
+ }
2007
2298
  case "dagRerunPlan": {
2008
2299
  const runId = str(p.runId);
2009
2300
  const fromNode = str(p.fromNode);
2010
2301
  if (!runId || !fromNode) {
2011
2302
  return invalid(action, "runId and fromNode are required");
2012
2303
  }
2304
+ const parsedOverrides = parsePromptOverrideParams(p.promptOverrides);
2305
+ if (parsedOverrides.kind === "error") {
2306
+ return invalid(action, parsedOverrides.message);
2307
+ }
2308
+ if (parsedOverrides.overrides.length > 0 &&
2309
+ !isDagRerunPromptOverrideEnabled()) {
2310
+ return invalid(action, `prompt override rerun is disabled by ${DAG_RERUN_PROMPT_OVERRIDE_ENV}; unset it or use a value other than 0, false, or off to enable this experimental capability`);
2311
+ }
2312
+ const overrideArgs = parsedOverrides.overrides.length > 0
2313
+ ? await buildPromptOverrideCliArgs(ctx, parsedOverrides.overrides)
2314
+ : [];
2013
2315
  const body = await runReadCli(ctx, [
2014
2316
  "dag",
2015
2317
  "rerun",
@@ -2018,6 +2320,7 @@ export async function dispatchOperatorAction(ctx, req) {
2018
2320
  "--from-node",
2019
2321
  fromNode,
2020
2322
  "--plan",
2323
+ ...overrideArgs,
2021
2324
  "--json",
2022
2325
  ], "dag rerun plan");
2023
2326
  return { kind: "sync", status: body.ok ? 200 : 400, body };
@@ -2031,6 +2334,17 @@ export async function dispatchOperatorAction(ctx, req) {
2031
2334
  if (!runId || !fromNode || !planHash || !reason || !clientRequestId) {
2032
2335
  return invalid(action, "runId, fromNode, planHash, reason, and clientRequestId are required");
2033
2336
  }
2337
+ const parsedOverrides = parsePromptOverrideParams(p.promptOverrides);
2338
+ if (parsedOverrides.kind === "error") {
2339
+ return invalid(action, parsedOverrides.message);
2340
+ }
2341
+ if (parsedOverrides.overrides.length > 0 &&
2342
+ !isDagRerunPromptOverrideEnabled()) {
2343
+ return invalid(action, `prompt override rerun is disabled by ${DAG_RERUN_PROMPT_OVERRIDE_ENV}; unset it or use a value other than 0, false, or off to enable this experimental capability`);
2344
+ }
2345
+ const overrideArgs = parsedOverrides.overrides.length > 0
2346
+ ? await buildPromptOverrideCliArgs(ctx, parsedOverrides.overrides)
2347
+ : [];
2034
2348
  return acceptOperation(ctx, {
2035
2349
  action,
2036
2350
  actionParams: p,
@@ -2048,6 +2362,7 @@ export async function dispatchOperatorAction(ctx, req) {
2048
2362
  clientRequestId,
2049
2363
  "--reason",
2050
2364
  reason,
2365
+ ...overrideArgs,
2051
2366
  "--json",
2052
2367
  ],
2053
2368
  });
@@ -2536,8 +2851,9 @@ export async function dispatchOperatorAction(ctx, req) {
2536
2851
  // M5 official-command coverage uses one generic tail for newly registered
2537
2852
  // CLI actions. It remains inside dispatchOperatorAction (the sole dispatch
2538
2853
  // surface) and only accepts argv arrays declared by the capability schema.
2539
- const capability = buildOperatorCapabilitiesDocument().actions.find((entry) => entry.action === action &&
2540
- entry.description.startsWith("Official CLI action coverage"));
2854
+ // 2026-08-18: high-frequency entries got real descriptions; membership is
2855
+ // now derived from OFFICIAL_TAIL_ACTION_IDS, not description prefixes.
2856
+ const capability = buildOperatorCapabilitiesDocument().actions.find((entry) => entry.action === action && OFFICIAL_TAIL_ACTION_IDS.has(entry.action));
2541
2857
  if (capability) {
2542
2858
  const rawArgs = p.args;
2543
2859
  if (rawArgs !== undefined &&
@@ -12,6 +12,7 @@ export function buildOperatorSurfaceHealthV1(input) {
12
12
  repoName: input.repoRoot.split(/[\\/]/).filter(Boolean).pop() ?? "repository",
13
13
  packageName,
14
14
  packageVersion,
15
+ consoleInstanceId: input.consoleInstanceId,
15
16
  piReadiness: input.piReadiness,
16
17
  inspect: {
17
18
  ready: input.inspectReady,
@@ -3,7 +3,7 @@ import { rewriteRecoveryOperatorError } from "./recovery-error-copy.js";
3
3
  const MUTATION_GATE_COPY = [
4
4
  {
5
5
  pattern: /invalid (boot capability|confirmation header) token/i,
6
- copy: "页面已过期(控制台已重启),请刷新页面(F5)后重试。",
6
+ copy: "页面凭证已失效(控制台可能已重启),请刷新页面(F5)后重试。",
7
7
  },
8
8
  {
9
9
  pattern: /mutation requires boot capability cookie|mutation requires confirmation header token/i,
@@ -23,7 +23,7 @@ export function formatOperatorUserError(message) {
23
23
  if (recovery)
24
24
  return recovery;
25
25
  if (/controller identity changed|package fingerprint changed|entry binary sha256 changed/i.test(raw)) {
26
- return "控制器版本已变更(Console 启动后代码被重新编译)。请重启 Console 后再试,一次会话中途不要升级/重建控制器。";
26
+ return "控制器版本已变更(Console 启动后代码被重新编译,或提交了 package.json / bin / dist / skills 等指纹范围文件)。请重启 Console 进程使其重新加载当前构建后再重试本操作;一次会话中途不要重建控制器。";
27
27
  }
28
28
  if (/Pi session file missing or not openable|cannot reopen chat session .* no persisted Pi session file/i.test(raw)) {
29
29
  return "该对话的 Pi 会话文件已丢失,无法恢复上下文。请新建对话继续(历史记录无法重开)。";
@@ -85,7 +85,7 @@ function hasProviderConfig(snapshot) {
85
85
  /**
86
86
  * Discover live Pi SDK / auth / model readiness via ModelRuntime.
87
87
  * Kept inside worker/console (dynamic import) so Worker does not depend on
88
- * executors; contract matches pi-sdk-executor 0.80.10.
88
+ * executors; contract matches pi-sdk-executor 0.83.0.
89
89
  */
90
90
  export async function discoverPiReadinessProbe(options) {
91
91
  const repoRoot = options?.repoRoot ?? process.cwd();
@@ -118,7 +118,7 @@ export async function discoverPiReadinessProbe(options) {
118
118
  modelsAvailable: false,
119
119
  interviewSessionOk: false,
120
120
  details: {
121
- sdkMessage: "Pi SDK incompatible: requires createAgentSession, getAgentDir, and ModelRuntime.create (0.80.10)",
121
+ sdkMessage: "Pi SDK incompatible: requires createAgentSession, getAgentDir, and ModelRuntime.create (0.83.0)",
122
122
  authMessage: "skipped (sdk incompatible)",
123
123
  modelsMessage: "skipped (sdk incompatible)",
124
124
  sessionMessage: "skipped (sdk incompatible)",
@@ -159,7 +159,7 @@ export async function discoverPiReadinessProbe(options) {
159
159
  modelsAvailable: false,
160
160
  interviewSessionOk: false,
161
161
  details: {
162
- sdkMessage: "Pi SDK 0.80.10 contract available",
162
+ sdkMessage: "Pi SDK 0.83.0 contract available",
163
163
  authMessage: `ModelRuntime.create failed: ${message}`,
164
164
  modelsMessage: "skipped (runtime init failed)",
165
165
  sessionMessage: "skipped (runtime init failed)",
@@ -222,8 +222,9 @@ export async function discoverPiReadinessProbe(options) {
222
222
  authReady,
223
223
  modelsAvailable,
224
224
  interviewSessionOk,
225
+ piAvailableModels: availableModels,
225
226
  details: {
226
- sdkMessage: `Pi SDK 0.80.10 contract available (agentDir=${agentDir})`,
227
+ sdkMessage: `Pi SDK 0.83.0 contract available (agentDir=${agentDir})`,
227
228
  authMessage: authReady
228
229
  ? `credentials/providers ready (available=${availableCount}, providerConfig=${providerConfigured})`
229
230
  : "no available models and no stored/configured provider credentials (set Pi auth or provider API keys)",
@@ -9,6 +9,7 @@ import { getTaskPaths } from "../../task/runtime.js";
9
9
  import { SEMANTIC_INTAKE_ARTIFACT_REL, } from "../../task/source-prepare/semantic-intake.js";
10
10
  import { extractRequirementFactsFromMarkdown } from "../../task/source-prepare/parse-intent.js";
11
11
  import { filterPlaceholderPaths, isNonPlaceholderPath, } from "../../task/source-prepare/placeholder-paths.js";
12
+ import { summarizeLedgerPayload, } from "./draft-store.js";
12
13
  import { emptyDraft } from "./interview/grill-me.js";
13
14
  import { normalizeConsoleWorkflowKind } from "./workflow-kinds.js";
14
15
  function asStringList(value) {
@@ -219,6 +220,15 @@ export async function buildDraftFromTaskIntake(input) {
219
220
  const paths = getTaskPaths(input.repoRoot, input.taskId);
220
221
  const warnings = warningList(input.advanceJson);
221
222
  const lifecycleState = lifecycleFromAdvanceJson(input.advanceJson);
223
+ // Source fidelity ledger 安全摘要透传(AC-009):来自 advance/prepare 结果,
224
+ // 未知形状安全丢弃,绝不携带未截断原文。
225
+ const advanceRoot = input.advanceJson && typeof input.advanceJson === "object"
226
+ ? input.advanceJson
227
+ : {};
228
+ const ledgerSummary = summarizeLedgerPayload(advanceRoot.ledgerSummary) ??
229
+ summarizeLedgerPayload(advanceRoot.result && typeof advanceRoot.result === "object"
230
+ ? advanceRoot.result.ledgerSummary
231
+ : undefined);
222
232
  const semanticApplied = warnings.some((w) => w.code === "SEMANTIC_INTAKE_APPLIED");
223
233
  const semanticFailed = warnings.find((w) => w.code === "SEMANTIC_INTAKE_PI_FAILED" ||
224
234
  w.code === "SEMANTIC_INTAKE_INVALID_OUTPUT" ||
@@ -427,11 +437,14 @@ export async function buildDraftFromTaskIntake(input) {
427
437
  if (input.engineering) {
428
438
  draft = applyEngineeringBoundaryToDraft(draft, input.engineering);
429
439
  }
440
+ // AC-BLOCK-002:摘要仅经响应返回 UI 视图模型,不写入 draft(防止 strict
441
+ // taskContractDraftSchema 因未知 ledgerSummary 键拒绝 canonical draft)。
430
442
  return {
431
443
  draft,
432
444
  parseStatus,
433
445
  semanticIntake,
434
446
  gaps,
447
+ ...(ledgerSummary ? { ledgerSummary } : {}),
435
448
  lifecycleState,
436
449
  };
437
450
  }
@@ -59,20 +59,20 @@ const CTA = {
59
59
  },
60
60
  dagRerun: {
61
61
  id: "dagRerun",
62
- label: "从节点重跑",
62
+ label: "从失败节点恢复",
63
63
  requiresReason: true,
64
64
  action: "dagRerun",
65
65
  lane: "dag",
66
- guide: "终端失败默认首选:先 dagRerunPlan,plan 合格后直接执行(无需 Human Gate)。Worker 持有的 run、workspace/controller 漂移或含 unsafe shell 时不要强跑子图",
66
+ guide: "Provider、网络、限流或超时等非代码问题的首选:先评估安全子图,合格后创建 continuation run 从有效节点恢复(无需 Human Gate)。Worker 持有的 run、workspace/controller 漂移或含 unsafe shell 时不要强跑子图",
67
67
  commandHint: "loop-agent dag rerun --run-id <run-id> --from-node <node-id> --plan",
68
68
  },
69
69
  standaloneTaskRerun: {
70
70
  id: "standaloneTaskRerun",
71
- label: "完整重跑任务",
71
+ label: "带反馈重新执行任务",
72
72
  requiresReason: true,
73
73
  action: "standaloneTaskRerun",
74
74
  lane: "dag",
75
- guide: "独立 DAG run 整单重跑:仅当 from-node plan 不合格时直调执行,服务端校验 run facts,无需 Human Gate。Worker 持有的 run 请用下方「重新排队 Worker Task」",
75
+ guide: "独立 DAG run 无法安全从节点恢复时,重新生成完整 DAG,并带入上一轮仍未解决的 verify/review 反馈;没有可继承反馈时会明确说明(无需 Human Gate)。Worker 持有的 run 请用下方「重新排队 Worker Task」",
76
76
  commandHint: "loop-agent dag rerun-task --run-id <run-id> --reason <text> --json",
77
77
  },
78
78
  workerTaskRetry: {
@@ -107,7 +107,7 @@ export function nextActionForIneligibleRerun(reasons) {
107
107
  "worker-managed-rerun-unsupported")) {
108
108
  return "下一步:请点下方「重新排队 Worker Task」,从头完整执行。";
109
109
  }
110
- return "下一步:请改用「完整重跑任务」,从头完整执行。";
110
+ return "下一步:请改用「带反馈重新执行任务」,重新生成完整 DAG。";
111
111
  }
112
112
  export function formatIneligibleRerunMessage(input) {
113
113
  const fallback = input.fallbackMessage?.trim();
@@ -141,16 +141,16 @@ export function rewriteRecoveryOperatorError(raw) {
141
141
  return formatIneligibleRerunMessage({ fallbackMessage: text });
142
142
  }
143
143
  if (/action must be a mutation-gate target/i.test(text)) {
144
- return "这个操作不能再走确认门。Worker 启动的任务请直接点「重新排队 Worker Task」;独立运行请点「完整重跑任务」。";
144
+ return "这个操作不能再走确认门。Worker 启动的任务请直接点「重新排队 Worker Task」;独立运行请点「带反馈重新执行任务」。";
145
145
  }
146
146
  if (/cannot read dagReport run facts/i.test(text)) {
147
147
  return "读不到这次运行的失败报告,不能完整重跑。请先点「查看报告」或「Doctor 诊断」。";
148
148
  }
149
149
  if (/dagRerunPlan run facts unavailable/i.test(text)) {
150
- return "读不到从节点续跑的资格结果,不能改走完整重跑。请先点「从节点重跑」查看资格,或先「查看报告」。";
150
+ return "读不到节点恢复资格,不能直接改走完整重跑。请先点「从失败节点恢复」查看资格,或先「查看报告」。";
151
151
  }
152
152
  if (/node rerun plan is eligible/i.test(text)) {
153
- return "从节点续跑是安全的,请改用「从节点重跑」,不必完整重跑整单。";
153
+ return "节点恢复是安全的,请改用「从失败节点恢复」,不必重新执行完整任务。";
154
154
  }
155
155
  if (/does not support autonomous standaloneTaskRerun/i.test(text)) {
156
156
  return "当前失败不适合自动完整重跑。请先点「查看报告」,按建议操作。";