@winspan/claude-forge 9.2.0 → 9.12.0

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 (591) hide show
  1. package/DEVELOPMENT.md +80 -19
  2. package/README.md +13 -6
  3. package/dist/catalogs/agents.json +19 -24
  4. package/dist/catalogs/skills.json +139 -27
  5. package/dist/claudemd/templates/swarm-protocol.md +1 -1
  6. package/dist/cli/commands/agent.d.ts +169 -0
  7. package/dist/cli/commands/agent.d.ts.map +1 -0
  8. package/dist/cli/commands/agent.js +690 -0
  9. package/dist/cli/commands/agent.js.map +1 -0
  10. package/dist/cli/commands/codegraph.d.ts +17 -0
  11. package/dist/cli/commands/codegraph.d.ts.map +1 -0
  12. package/dist/cli/commands/codegraph.js +263 -0
  13. package/dist/cli/commands/codegraph.js.map +1 -0
  14. package/dist/cli/commands/decisions.d.ts.map +1 -1
  15. package/dist/cli/commands/decisions.js +46 -9
  16. package/dist/cli/commands/decisions.js.map +1 -1
  17. package/dist/cli/commands/executions.d.ts.map +1 -1
  18. package/dist/cli/commands/executions.js +2 -1
  19. package/dist/cli/commands/executions.js.map +1 -1
  20. package/dist/cli/commands/insights-goal-check.d.ts +5 -1
  21. package/dist/cli/commands/insights-goal-check.d.ts.map +1 -1
  22. package/dist/cli/commands/insights-goal-check.js +15 -15
  23. package/dist/cli/commands/insights-goal-check.js.map +1 -1
  24. package/dist/cli/commands/knowledge.d.ts +51 -0
  25. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  26. package/dist/cli/commands/knowledge.js +202 -29
  27. package/dist/cli/commands/knowledge.js.map +1 -1
  28. package/dist/cli/commands/loop.d.ts +95 -0
  29. package/dist/cli/commands/loop.d.ts.map +1 -0
  30. package/dist/cli/commands/loop.js +408 -0
  31. package/dist/cli/commands/loop.js.map +1 -0
  32. package/dist/cli/commands/maintenance.d.ts +33 -0
  33. package/dist/cli/commands/maintenance.d.ts.map +1 -0
  34. package/dist/cli/commands/maintenance.js +75 -0
  35. package/dist/cli/commands/maintenance.js.map +1 -0
  36. package/dist/cli/commands/mcp.d.ts +23 -0
  37. package/dist/cli/commands/mcp.d.ts.map +1 -1
  38. package/dist/cli/commands/mcp.js +82 -0
  39. package/dist/cli/commands/mcp.js.map +1 -1
  40. package/dist/cli/commands/skills.d.ts +131 -0
  41. package/dist/cli/commands/skills.d.ts.map +1 -1
  42. package/dist/cli/commands/skills.js +409 -9
  43. package/dist/cli/commands/skills.js.map +1 -1
  44. package/dist/cli/commands/stats.d.ts.map +1 -1
  45. package/dist/cli/commands/stats.js +9 -2
  46. package/dist/cli/commands/stats.js.map +1 -1
  47. package/dist/cli/index.js +8 -0
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/core/constants.d.ts +37 -0
  50. package/dist/core/constants.d.ts.map +1 -1
  51. package/dist/core/constants.js +43 -0
  52. package/dist/core/constants.js.map +1 -1
  53. package/dist/core/diagnostics/checks.d.ts.map +1 -1
  54. package/dist/core/diagnostics/checks.js +2 -1
  55. package/dist/core/diagnostics/checks.js.map +1 -1
  56. package/dist/core/diagnostics/daemon-status.d.ts +1 -1
  57. package/dist/core/diagnostics/daemon-status.d.ts.map +1 -1
  58. package/dist/core/diagnostics/daemon-status.js +1 -1
  59. package/dist/core/diagnostics/daemon-status.js.map +1 -1
  60. package/dist/core/diagnostics/entropy-checks.d.ts +3 -2
  61. package/dist/core/diagnostics/entropy-checks.d.ts.map +1 -1
  62. package/dist/core/diagnostics/entropy-checks.js +10 -5
  63. package/dist/core/diagnostics/entropy-checks.js.map +1 -1
  64. package/dist/core/diagnostics/heartbeat-reader.d.ts +28 -0
  65. package/dist/core/diagnostics/heartbeat-reader.d.ts.map +1 -0
  66. package/dist/core/diagnostics/heartbeat-reader.js +50 -0
  67. package/dist/core/diagnostics/heartbeat-reader.js.map +1 -0
  68. package/dist/core/event-fields.d.ts +27 -0
  69. package/dist/core/event-fields.d.ts.map +1 -1
  70. package/dist/core/event-fields.js +43 -0
  71. package/dist/core/event-fields.js.map +1 -1
  72. package/dist/core/governance/global-inject.d.ts +34 -4
  73. package/dist/core/governance/global-inject.d.ts.map +1 -1
  74. package/dist/core/governance/global-inject.js +80 -25
  75. package/dist/core/governance/global-inject.js.map +1 -1
  76. package/dist/core/insights/agent-anchor-guard.d.ts +77 -0
  77. package/dist/core/insights/agent-anchor-guard.d.ts.map +1 -0
  78. package/dist/core/insights/agent-anchor-guard.js +119 -0
  79. package/dist/core/insights/agent-anchor-guard.js.map +1 -0
  80. package/dist/core/insights/agent-distill-context.d.ts +55 -0
  81. package/dist/core/insights/agent-distill-context.d.ts.map +1 -0
  82. package/dist/core/insights/agent-distill-context.js +146 -0
  83. package/dist/core/insights/agent-distill-context.js.map +1 -0
  84. package/dist/core/insights/agent-distill-spawn.d.ts +56 -0
  85. package/dist/core/insights/agent-distill-spawn.d.ts.map +1 -0
  86. package/dist/core/insights/agent-distill-spawn.js +179 -0
  87. package/dist/core/insights/agent-distill-spawn.js.map +1 -0
  88. package/dist/core/insights/agent-drift.d.ts +66 -0
  89. package/dist/core/insights/agent-drift.d.ts.map +1 -0
  90. package/dist/core/insights/agent-drift.js +109 -0
  91. package/dist/core/insights/agent-drift.js.map +1 -0
  92. package/dist/core/insights/agent-evolution-sources.d.ts +21 -0
  93. package/dist/core/insights/agent-evolution-sources.d.ts.map +1 -0
  94. package/dist/core/insights/agent-evolution-sources.js +36 -0
  95. package/dist/core/insights/agent-evolution-sources.js.map +1 -0
  96. package/dist/core/insights/agent-health.d.ts +142 -0
  97. package/dist/core/insights/agent-health.d.ts.map +1 -0
  98. package/dist/core/insights/agent-health.js +296 -0
  99. package/dist/core/insights/agent-health.js.map +1 -0
  100. package/dist/core/insights/agent-patch-apply.d.ts +45 -0
  101. package/dist/core/insights/agent-patch-apply.d.ts.map +1 -0
  102. package/dist/core/insights/agent-patch-apply.js +165 -0
  103. package/dist/core/insights/agent-patch-apply.js.map +1 -0
  104. package/dist/core/insights/agent-suggest.d.ts +128 -0
  105. package/dist/core/insights/agent-suggest.d.ts.map +1 -0
  106. package/dist/core/insights/agent-suggest.js +284 -0
  107. package/dist/core/insights/agent-suggest.js.map +1 -0
  108. package/dist/core/insights/coverage-tiers.d.ts +46 -0
  109. package/dist/core/insights/coverage-tiers.d.ts.map +1 -0
  110. package/dist/core/insights/coverage-tiers.js +95 -0
  111. package/dist/core/insights/coverage-tiers.js.map +1 -0
  112. package/dist/{daemon/services → core/insights}/experience-extractor.d.ts +0 -7
  113. package/dist/core/insights/experience-extractor.d.ts.map +1 -0
  114. package/dist/{daemon/services → core/insights}/experience-extractor.js +5 -9
  115. package/dist/core/insights/experience-extractor.js.map +1 -0
  116. package/dist/{daemon/services → core/insights}/violation-reporter.d.ts +20 -1
  117. package/dist/core/insights/violation-reporter.d.ts.map +1 -0
  118. package/dist/{daemon/services → core/insights}/violation-reporter.js +56 -4
  119. package/dist/core/insights/violation-reporter.js.map +1 -0
  120. package/dist/core/loop/loop-engine.d.ts +140 -0
  121. package/dist/core/loop/loop-engine.d.ts.map +1 -0
  122. package/dist/core/loop/loop-engine.js +266 -0
  123. package/dist/core/loop/loop-engine.js.map +1 -0
  124. package/dist/core/queue/index.d.ts.map +1 -1
  125. package/dist/core/queue/index.js +2 -1
  126. package/dist/core/queue/index.js.map +1 -1
  127. package/dist/core/storage/base.d.ts +159 -0
  128. package/dist/core/storage/base.d.ts.map +1 -1
  129. package/dist/core/storage/base.js +523 -0
  130. package/dist/core/storage/base.js.map +1 -1
  131. package/dist/core/storage/codegraph-types.d.ts +79 -0
  132. package/dist/core/storage/codegraph-types.d.ts.map +1 -0
  133. package/dist/core/storage/codegraph-types.js +14 -0
  134. package/dist/core/storage/codegraph-types.js.map +1 -0
  135. package/dist/core/storage/codegraph.d.ts +186 -0
  136. package/dist/core/storage/codegraph.d.ts.map +1 -0
  137. package/dist/core/storage/codegraph.js +452 -0
  138. package/dist/core/storage/codegraph.js.map +1 -0
  139. package/dist/core/storage/decisions.d.ts +30 -5
  140. package/dist/core/storage/decisions.d.ts.map +1 -1
  141. package/dist/core/storage/decisions.js +45 -13
  142. package/dist/core/storage/decisions.js.map +1 -1
  143. package/dist/core/storage/events.d.ts +127 -0
  144. package/dist/core/storage/events.d.ts.map +1 -1
  145. package/dist/core/storage/events.js +318 -3
  146. package/dist/core/storage/events.js.map +1 -1
  147. package/dist/core/storage/feedback.d.ts +3 -23
  148. package/dist/core/storage/feedback.d.ts.map +1 -1
  149. package/dist/core/storage/feedback.js +37 -38
  150. package/dist/core/storage/feedback.js.map +1 -1
  151. package/dist/core/storage/injections.d.ts +40 -0
  152. package/dist/core/storage/injections.d.ts.map +1 -1
  153. package/dist/core/storage/injections.js +69 -0
  154. package/dist/core/storage/injections.js.map +1 -1
  155. package/dist/core/storage/knowledge.d.ts +226 -0
  156. package/dist/core/storage/knowledge.d.ts.map +1 -1
  157. package/dist/core/storage/knowledge.js +391 -4
  158. package/dist/core/storage/knowledge.js.map +1 -1
  159. package/dist/core/storage/pipeline-rollup.d.ts +1 -7
  160. package/dist/core/storage/pipeline-rollup.d.ts.map +1 -1
  161. package/dist/core/storage/pipeline-rollup.js +18 -57
  162. package/dist/core/storage/pipeline-rollup.js.map +1 -1
  163. package/dist/core/storage/routing.d.ts +34 -0
  164. package/dist/core/storage/routing.d.ts.map +1 -1
  165. package/dist/core/storage/routing.js +92 -2
  166. package/dist/core/storage/routing.js.map +1 -1
  167. package/dist/core/storage/rows.d.ts +5 -25
  168. package/dist/core/storage/rows.d.ts.map +1 -1
  169. package/dist/core/storage/schema.sql +92 -27
  170. package/dist/core/storage/sessions.d.ts.map +1 -1
  171. package/dist/core/storage/sessions.js +2 -1
  172. package/dist/core/storage/sessions.js.map +1 -1
  173. package/dist/core/storage/skills.d.ts +159 -0
  174. package/dist/core/storage/skills.d.ts.map +1 -1
  175. package/dist/core/storage/skills.js +350 -4
  176. package/dist/core/storage/skills.js.map +1 -1
  177. package/dist/core/storage/sqlite.d.ts +81 -25
  178. package/dist/core/storage/sqlite.d.ts.map +1 -1
  179. package/dist/core/storage/sqlite.js +143 -45
  180. package/dist/core/storage/sqlite.js.map +1 -1
  181. package/dist/core/storage/tasks.d.ts +270 -0
  182. package/dist/core/storage/tasks.d.ts.map +1 -1
  183. package/dist/core/storage/tasks.js +495 -16
  184. package/dist/core/storage/tasks.js.map +1 -1
  185. package/dist/core/storage/tool-intercepts.d.ts +1 -1
  186. package/dist/core/storage/tool-intercepts.js +1 -1
  187. package/dist/core/types.d.ts +26 -3
  188. package/dist/core/types.d.ts.map +1 -1
  189. package/dist/core/types.js +1 -3
  190. package/dist/core/types.js.map +1 -1
  191. package/dist/core/utils/binary-paths.d.ts +32 -0
  192. package/dist/core/utils/binary-paths.d.ts.map +1 -1
  193. package/dist/core/utils/binary-paths.js +52 -0
  194. package/dist/core/utils/binary-paths.js.map +1 -1
  195. package/dist/core/utils/claude-cli-resolver.d.ts.map +1 -0
  196. package/dist/{skills/distill → core/utils}/claude-cli-resolver.js +1 -1
  197. package/dist/core/utils/claude-cli-resolver.js.map +1 -0
  198. package/dist/core/utils/claude-cli-spawn.d.ts +1 -1
  199. package/dist/core/utils/claude-cli-spawn.js +2 -2
  200. package/dist/core/utils/claude-cli-spawn.js.map +1 -1
  201. package/dist/core/utils/noise-prompt.d.ts +1 -1
  202. package/dist/core/utils/noise-prompt.js +1 -1
  203. package/dist/core/utils/time.d.ts +26 -0
  204. package/dist/core/utils/time.d.ts.map +1 -1
  205. package/dist/core/utils/time.js +33 -0
  206. package/dist/core/utils/time.js.map +1 -1
  207. package/dist/daemon/config-store.d.ts.map +1 -1
  208. package/dist/daemon/config-store.js +14 -5
  209. package/dist/daemon/config-store.js.map +1 -1
  210. package/dist/daemon/event-parser.d.ts.map +1 -1
  211. package/dist/daemon/event-parser.js +5 -0
  212. package/dist/daemon/event-parser.js.map +1 -1
  213. package/dist/daemon/handlers/post-tool-use.d.ts +24 -16
  214. package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
  215. package/dist/daemon/handlers/post-tool-use.js +76 -116
  216. package/dist/daemon/handlers/post-tool-use.js.map +1 -1
  217. package/dist/daemon/handlers/pre-tool-use.d.ts +35 -10
  218. package/dist/daemon/handlers/pre-tool-use.d.ts.map +1 -1
  219. package/dist/daemon/handlers/pre-tool-use.js +71 -38
  220. package/dist/daemon/handlers/pre-tool-use.js.map +1 -1
  221. package/dist/daemon/handlers/stop.d.ts +20 -0
  222. package/dist/daemon/handlers/stop.d.ts.map +1 -1
  223. package/dist/daemon/handlers/stop.js +96 -8
  224. package/dist/daemon/handlers/stop.js.map +1 -1
  225. package/dist/daemon/handlers/user-prompt.d.ts +16 -1
  226. package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
  227. package/dist/daemon/handlers/user-prompt.js +97 -56
  228. package/dist/daemon/handlers/user-prompt.js.map +1 -1
  229. package/dist/daemon/handlers/violation-content-backfill.d.ts +76 -0
  230. package/dist/daemon/handlers/violation-content-backfill.d.ts.map +1 -0
  231. package/dist/daemon/handlers/violation-content-backfill.js +167 -0
  232. package/dist/daemon/handlers/violation-content-backfill.js.map +1 -0
  233. package/dist/daemon/index.d.ts +19 -0
  234. package/dist/daemon/index.d.ts.map +1 -1
  235. package/dist/daemon/index.js +125 -200
  236. package/dist/daemon/index.js.map +1 -1
  237. package/dist/daemon/rules/defaults.d.ts.map +1 -1
  238. package/dist/daemon/rules/defaults.js +151 -64
  239. package/dist/daemon/rules/defaults.js.map +1 -1
  240. package/dist/daemon/rules/types.d.ts +28 -22
  241. package/dist/daemon/rules/types.d.ts.map +1 -1
  242. package/dist/daemon/rules/workflow-defaults.js +9 -9
  243. package/dist/daemon/rules/workflow-defaults.js.map +1 -1
  244. package/dist/daemon/services/codegraph-sync.d.ts +94 -0
  245. package/dist/daemon/services/codegraph-sync.d.ts.map +1 -0
  246. package/dist/daemon/services/codegraph-sync.js +159 -0
  247. package/dist/daemon/services/codegraph-sync.js.map +1 -0
  248. package/dist/daemon/services/decision-hint.d.ts +47 -10
  249. package/dist/daemon/services/decision-hint.d.ts.map +1 -1
  250. package/dist/daemon/services/decision-hint.js +99 -24
  251. package/dist/daemon/services/decision-hint.js.map +1 -1
  252. package/dist/daemon/services/event-ttl-sweep.d.ts.map +1 -1
  253. package/dist/daemon/services/event-ttl-sweep.js +3 -2
  254. package/dist/daemon/services/event-ttl-sweep.js.map +1 -1
  255. package/dist/daemon/services/feedback-aggregator.d.ts +14 -26
  256. package/dist/daemon/services/feedback-aggregator.d.ts.map +1 -1
  257. package/dist/daemon/services/feedback-aggregator.js +23 -63
  258. package/dist/daemon/services/feedback-aggregator.js.map +1 -1
  259. package/dist/daemon/services/heartbeat-writer.d.ts +6 -15
  260. package/dist/daemon/services/heartbeat-writer.d.ts.map +1 -1
  261. package/dist/daemon/services/heartbeat-writer.js +7 -36
  262. package/dist/daemon/services/heartbeat-writer.js.map +1 -1
  263. package/dist/daemon/services/kb-injector.d.ts +1 -1
  264. package/dist/daemon/services/kb-injector.d.ts.map +1 -1
  265. package/dist/daemon/services/kb-injector.js +10 -2
  266. package/dist/daemon/services/kb-injector.js.map +1 -1
  267. package/dist/daemon/services/kb-rebuild-scheduler.d.ts +95 -0
  268. package/dist/daemon/services/kb-rebuild-scheduler.d.ts.map +1 -0
  269. package/dist/daemon/services/kb-rebuild-scheduler.js +149 -0
  270. package/dist/daemon/services/kb-rebuild-scheduler.js.map +1 -0
  271. package/dist/daemon/services/loop-hint.d.ts +139 -0
  272. package/dist/daemon/services/loop-hint.d.ts.map +1 -0
  273. package/dist/daemon/services/loop-hint.js +272 -0
  274. package/dist/daemon/services/loop-hint.js.map +1 -0
  275. package/dist/daemon/services/outcome-classification-service.js +1 -1
  276. package/dist/daemon/services/outcome-classification-service.js.map +1 -1
  277. package/dist/daemon/services/task-segmenter.d.ts +11 -0
  278. package/dist/daemon/services/task-segmenter.d.ts.map +1 -1
  279. package/dist/daemon/services/task-segmenter.js +48 -2
  280. package/dist/daemon/services/task-segmenter.js.map +1 -1
  281. package/dist/daemon/startup/maintenance-schedulers.d.ts +68 -0
  282. package/dist/daemon/startup/maintenance-schedulers.d.ts.map +1 -0
  283. package/dist/daemon/startup/maintenance-schedulers.js +294 -0
  284. package/dist/daemon/startup/maintenance-schedulers.js.map +1 -0
  285. package/dist/daemon/templates/agents/agent-retro-distiller.md +106 -0
  286. package/dist/daemon/templates/agents/claudemd-writer.md +1 -0
  287. package/dist/daemon/templates/agents/coder.md +165 -8
  288. package/dist/daemon/templates/agents/decision-maker.md +107 -21
  289. package/dist/daemon/templates/agents/doc-reviewer.md +4 -1
  290. package/dist/daemon/templates/agents/harness-debug-full.md +85 -3
  291. package/dist/daemon/templates/agents/knowledge-builder.md +1 -0
  292. package/dist/daemon/templates/agents/patch-applier.md +1 -0
  293. package/dist/daemon/templates/agents/planner.md +55 -3
  294. package/dist/daemon/templates/agents/safety-net-implementer.md +278 -0
  295. package/dist/daemon/templates/agents/skill-distiller.md +1 -0
  296. package/dist/daemon/templates/agents/task-boundary-classifier.md +1 -0
  297. package/dist/daemon/templates/agents/verify-agent.md +128 -5
  298. package/dist/hooks/stop.sh +7 -1
  299. package/dist/knowledge/builder.js +36 -7
  300. package/dist/knowledge/builder.js.map +1 -1
  301. package/dist/knowledge/constants.d.ts +10 -5
  302. package/dist/knowledge/constants.d.ts.map +1 -1
  303. package/dist/knowledge/constants.js +10 -5
  304. package/dist/knowledge/constants.js.map +1 -1
  305. package/dist/knowledge/graph/edge-extractor.d.ts +45 -0
  306. package/dist/knowledge/graph/edge-extractor.d.ts.map +1 -0
  307. package/dist/knowledge/graph/edge-extractor.js +242 -0
  308. package/dist/knowledge/graph/edge-extractor.js.map +1 -0
  309. package/dist/knowledge/graph/impact.d.ts +73 -0
  310. package/dist/knowledge/graph/impact.d.ts.map +1 -0
  311. package/dist/knowledge/graph/impact.js +94 -0
  312. package/dist/knowledge/graph/impact.js.map +1 -0
  313. package/dist/knowledge/graph/types.d.ts +22 -0
  314. package/dist/knowledge/graph/types.d.ts.map +1 -0
  315. package/dist/knowledge/graph/types.js +13 -0
  316. package/dist/knowledge/graph/types.js.map +1 -0
  317. package/dist/knowledge/prompt.d.ts +9 -0
  318. package/dist/knowledge/prompt.d.ts.map +1 -1
  319. package/dist/knowledge/prompt.js +17 -5
  320. package/dist/knowledge/prompt.js.map +1 -1
  321. package/dist/knowledge/query.d.ts +13 -0
  322. package/dist/knowledge/query.d.ts.map +1 -1
  323. package/dist/knowledge/query.js +107 -10
  324. package/dist/knowledge/query.js.map +1 -1
  325. package/dist/knowledge/repo-map.d.ts +11 -5
  326. package/dist/knowledge/repo-map.d.ts.map +1 -1
  327. package/dist/knowledge/repo-map.js +42 -3
  328. package/dist/knowledge/repo-map.js.map +1 -1
  329. package/dist/knowledge/validator.d.ts.map +1 -1
  330. package/dist/knowledge/validator.js +69 -2
  331. package/dist/knowledge/validator.js.map +1 -1
  332. package/dist/mcp/server.d.ts +64 -8
  333. package/dist/mcp/server.d.ts.map +1 -1
  334. package/dist/mcp/server.js +233 -18
  335. package/dist/mcp/server.js.map +1 -1
  336. package/dist/skills/distill/distiller.js +1 -1
  337. package/dist/skills/distill/distiller.js.map +1 -1
  338. package/dist/skills/distilled/distilled-api-design.md +4 -0
  339. package/dist/skills/distilled/distilled-brainstorming.md +79 -0
  340. package/dist/skills/distilled/distilled-brand-guidelines.md +86 -0
  341. package/dist/skills/distilled/distilled-canvas-design.md +128 -0
  342. package/dist/skills/distilled/distilled-claude-api.md +185 -0
  343. package/dist/skills/distilled/distilled-creator.md +5 -2
  344. package/dist/skills/distilled/distilled-dispatching-parallel-agents.md +136 -0
  345. package/dist/skills/distilled/distilled-doc-coauthoring.md +144 -0
  346. package/dist/skills/distilled/distilled-docx.md +231 -0
  347. package/dist/skills/distilled/distilled-executing-plans.md +85 -50
  348. package/dist/skills/distilled/distilled-finishing-a-development-branch.md +213 -0
  349. package/dist/skills/distilled/distilled-frontend-design.md +118 -0
  350. package/dist/skills/distilled/distilled-harness-engineering.md +1 -1
  351. package/dist/skills/distilled/distilled-receiving-code-review.md +185 -0
  352. package/dist/skills/distilled/distilled-subagent-driven-development.md +124 -0
  353. package/dist/skills/distilled/distilled-systematic-debugging.md +108 -260
  354. package/dist/skills/distilled/distilled-test-driven-development.md +432 -0
  355. package/dist/skills/distilled/distilled-using-superpowers.md +134 -0
  356. package/dist/skills/distilled/distilled-verification-before-completion.md +88 -78
  357. package/dist/skills/distilled/distilled-writing-skills.md +175 -0
  358. package/dist/skills/registry.d.ts +10 -50
  359. package/dist/skills/registry.d.ts.map +1 -1
  360. package/dist/skills/registry.js +7 -118
  361. package/dist/skills/registry.js.map +1 -1
  362. package/dist/skills/tools/pipeline-suggest.js +2 -2
  363. package/dist/skills/tools/pipeline-suggest.js.map +1 -1
  364. package/dist/skills/tools/skill-invoke.d.ts +2 -1
  365. package/dist/skills/tools/skill-invoke.d.ts.map +1 -1
  366. package/dist/skills/tools/skill-invoke.js +3 -1
  367. package/dist/skills/tools/skill-invoke.js.map +1 -1
  368. package/dist/web/analytics/anti-pattern-detector.d.ts.map +1 -1
  369. package/dist/web/analytics/anti-pattern-detector.js +6 -1
  370. package/dist/web/analytics/anti-pattern-detector.js.map +1 -1
  371. package/dist/web/analytics/drift-detector.d.ts +6 -0
  372. package/dist/web/analytics/drift-detector.d.ts.map +1 -1
  373. package/dist/web/analytics/drift-detector.js +15 -8
  374. package/dist/web/analytics/drift-detector.js.map +1 -1
  375. package/dist/web/analytics/weekly-report.d.ts +13 -0
  376. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  377. package/dist/web/analytics/weekly-report.js +17 -3
  378. package/dist/web/analytics/weekly-report.js.map +1 -1
  379. package/dist/web/routes/_helpers.d.ts +31 -0
  380. package/dist/web/routes/_helpers.d.ts.map +1 -1
  381. package/dist/web/routes/_helpers.js +33 -0
  382. package/dist/web/routes/_helpers.js.map +1 -1
  383. package/dist/web/routes/agent-distill.d.ts +49 -0
  384. package/dist/web/routes/agent-distill.d.ts.map +1 -0
  385. package/dist/web/routes/agent-distill.js +526 -0
  386. package/dist/web/routes/agent-distill.js.map +1 -0
  387. package/dist/web/routes/config.d.ts +56 -0
  388. package/dist/web/routes/config.d.ts.map +1 -0
  389. package/dist/web/routes/config.js +243 -0
  390. package/dist/web/routes/config.js.map +1 -0
  391. package/dist/web/routes/decisions.js +1 -1
  392. package/dist/web/routes/decisions.js.map +1 -1
  393. package/dist/web/routes/error-handler.d.ts +0 -4
  394. package/dist/web/routes/error-handler.d.ts.map +1 -1
  395. package/dist/web/routes/error-handler.js +0 -8
  396. package/dist/web/routes/error-handler.js.map +1 -1
  397. package/dist/web/routes/events.d.ts.map +1 -1
  398. package/dist/web/routes/events.js +2 -1
  399. package/dist/web/routes/events.js.map +1 -1
  400. package/dist/web/routes/insights.d.ts.map +1 -1
  401. package/dist/web/routes/insights.js +0 -0
  402. package/dist/web/routes/insights.js.map +1 -1
  403. package/dist/web/routes/knowledge.d.ts +43 -2
  404. package/dist/web/routes/knowledge.d.ts.map +1 -1
  405. package/dist/web/routes/knowledge.js +117 -6
  406. package/dist/web/routes/knowledge.js.map +1 -1
  407. package/dist/web/routes/pipeline.d.ts +0 -9
  408. package/dist/web/routes/pipeline.d.ts.map +1 -1
  409. package/dist/web/routes/pipeline.js +0 -4
  410. package/dist/web/routes/pipeline.js.map +1 -1
  411. package/dist/web/routes/rules.d.ts.map +1 -1
  412. package/dist/web/routes/rules.js +20 -6
  413. package/dist/web/routes/rules.js.map +1 -1
  414. package/dist/web/routes/sessions.d.ts.map +1 -1
  415. package/dist/web/routes/sessions.js +8 -7
  416. package/dist/web/routes/sessions.js.map +1 -1
  417. package/dist/web/routes/skill-stats.d.ts.map +1 -1
  418. package/dist/web/routes/skill-stats.js +153 -16
  419. package/dist/web/routes/skill-stats.js.map +1 -1
  420. package/dist/web/routes/skills-distill.js +1 -1
  421. package/dist/web/routes/skills-distill.js.map +1 -1
  422. package/dist/web/routes/stats.d.ts.map +1 -1
  423. package/dist/web/routes/stats.js +2 -1
  424. package/dist/web/routes/stats.js.map +1 -1
  425. package/dist/web/routes/task-timeline.d.ts +95 -19
  426. package/dist/web/routes/task-timeline.d.ts.map +1 -1
  427. package/dist/web/routes/task-timeline.js +344 -88
  428. package/dist/web/routes/task-timeline.js.map +1 -1
  429. package/dist/web/routes/tasks.d.ts.map +1 -1
  430. package/dist/web/routes/tasks.js +52 -30
  431. package/dist/web/routes/tasks.js.map +1 -1
  432. package/dist/web/routes/violations.d.ts +1 -1
  433. package/dist/web/routes/violations.d.ts.map +1 -1
  434. package/dist/web/routes/violations.js +3 -2
  435. package/dist/web/routes/violations.js.map +1 -1
  436. package/dist/web/server.d.ts.map +1 -1
  437. package/dist/web/server.js +20 -0
  438. package/dist/web/server.js.map +1 -1
  439. package/dist/web/services/agent-distill-manager.d.ts +122 -0
  440. package/dist/web/services/agent-distill-manager.d.ts.map +1 -0
  441. package/dist/web/services/agent-distill-manager.js +397 -0
  442. package/dist/web/services/agent-distill-manager.js.map +1 -0
  443. package/dist/web/services/distill-manager.d.ts +47 -0
  444. package/dist/web/services/distill-manager.d.ts.map +1 -1
  445. package/dist/web/services/distill-manager.js +103 -0
  446. package/dist/web/services/distill-manager.js.map +1 -1
  447. package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js +2 -0
  448. package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js.map +1 -0
  449. package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js +3 -0
  450. package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js.map +1 -0
  451. package/dist/web/static/assets/AgentsPage-Qd9FExLG.js +2 -0
  452. package/dist/web/static/assets/AgentsPage-Qd9FExLG.js.map +1 -0
  453. package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js +2 -0
  454. package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js.map +1 -0
  455. package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js +2 -0
  456. package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js.map +1 -0
  457. package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js +2 -0
  458. package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js.map +1 -0
  459. package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js +2 -0
  460. package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js.map +1 -0
  461. package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js +4 -0
  462. package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js.map +1 -0
  463. package/dist/web/static/assets/DistillPage-O7BHtRN8.js +2 -0
  464. package/dist/web/static/assets/DistillPage-O7BHtRN8.js.map +1 -0
  465. package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js +2 -0
  466. package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js.map +1 -0
  467. package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js +2 -0
  468. package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js.map +1 -0
  469. package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js +2 -0
  470. package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js.map +1 -0
  471. package/dist/web/static/assets/IssuesPage-SKmhlCrw.js +2 -0
  472. package/dist/web/static/assets/IssuesPage-SKmhlCrw.js.map +1 -0
  473. package/dist/web/static/assets/KbDetailPage-Yna86Na8.js +2 -0
  474. package/dist/web/static/assets/KbDetailPage-Yna86Na8.js.map +1 -0
  475. package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js +2 -0
  476. package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js.map +1 -0
  477. package/dist/web/static/assets/{MarkdownRenderer-DZmTl-8J.js → MarkdownRenderer-DlDQNihj.js} +2 -2
  478. package/dist/web/static/assets/{MarkdownRenderer-DZmTl-8J.js.map → MarkdownRenderer-DlDQNihj.js.map} +1 -1
  479. package/dist/web/static/assets/NotFound-LMzbP51V.js +2 -0
  480. package/dist/web/static/assets/{NotFound-BQPh0vaF.js.map → NotFound-LMzbP51V.js.map} +1 -1
  481. package/dist/web/static/assets/SettingsPage-DzoK4PKg.js +2 -0
  482. package/dist/web/static/assets/SettingsPage-DzoK4PKg.js.map +1 -0
  483. package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js +2 -0
  484. package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js.map +1 -0
  485. package/dist/web/static/assets/SkillsPage-aojkJpBc.js +2 -0
  486. package/dist/web/static/assets/SkillsPage-aojkJpBc.js.map +1 -0
  487. package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js +4 -0
  488. package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js.map +1 -0
  489. package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js +6 -0
  490. package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js.map +1 -0
  491. package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js +2 -0
  492. package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js.map +1 -0
  493. package/dist/web/static/assets/arco-DV6xCLhr.js +14 -0
  494. package/dist/web/static/assets/arco-DV6xCLhr.js.map +1 -0
  495. package/dist/web/static/assets/charts-BSV4cyC4.js +37 -0
  496. package/dist/web/static/assets/charts-BSV4cyC4.js.map +1 -0
  497. package/dist/web/static/assets/{index-7bl3kbcx.css → index-B_v_MKlb.css} +1 -1
  498. package/dist/web/static/assets/index-DileOOE4.js +4 -0
  499. package/dist/web/static/assets/index-DileOOE4.js.map +1 -0
  500. package/dist/web/static/assets/markdown-CA7ePUts.js +30 -0
  501. package/dist/web/static/assets/markdown-CA7ePUts.js.map +1 -0
  502. package/dist/web/static/assets/{outcome-DUn1NjlC.js → outcome-BKGy9azt.js} +2 -2
  503. package/dist/web/static/assets/{outcome-DUn1NjlC.js.map → outcome-BKGy9azt.js.map} +1 -1
  504. package/dist/web/static/assets/{query-S6X1S7K9.js → query-CgCOpYWf.js} +2 -2
  505. package/dist/web/static/assets/{query-S6X1S7K9.js.map → query-CgCOpYWf.js.map} +1 -1
  506. package/dist/web/static/assets/{react-router-JVUrkhdd.js → react-router-Cxmg8RuL.js} +3 -3
  507. package/dist/web/static/assets/{react-router-JVUrkhdd.js.map → react-router-Cxmg8RuL.js.map} +1 -1
  508. package/dist/web/static/assets/{syntax-highlighter-BkZfCDsz.js → syntax-highlighter-BDYycNja.js} +3 -3
  509. package/dist/web/static/assets/{syntax-highlighter-BkZfCDsz.js.map → syntax-highlighter-BDYycNja.js.map} +1 -1
  510. package/dist/web/static/assets/task-title-BhOcemuR.js +2 -0
  511. package/dist/web/static/assets/task-title-BhOcemuR.js.map +1 -0
  512. package/dist/web/static/assets/useAgentStats-B-uTgqBd.js +2 -0
  513. package/dist/web/static/assets/useAgentStats-B-uTgqBd.js.map +1 -0
  514. package/dist/web/static/assets/useDecisions-D-G2Ft5T.js +2 -0
  515. package/dist/web/static/assets/useDecisions-D-G2Ft5T.js.map +1 -0
  516. package/dist/web/static/assets/useDistill-21dZkXlT.js +3 -0
  517. package/dist/web/static/assets/useDistill-21dZkXlT.js.map +1 -0
  518. package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js +2 -0
  519. package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js.map +1 -0
  520. package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js +2 -0
  521. package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js.map +1 -0
  522. package/dist/web/static/assets/useKbHits-xKXWgqh9.js +2 -0
  523. package/dist/web/static/assets/useKbHits-xKXWgqh9.js.map +1 -0
  524. package/dist/web/static/assets/useSkillStats-B5hbIwdf.js +2 -0
  525. package/dist/web/static/assets/useSkillStats-B5hbIwdf.js.map +1 -0
  526. package/dist/web/static/assets/vendor-DS-q4Eyc.js +36 -0
  527. package/dist/web/static/assets/vendor-DS-q4Eyc.js.map +1 -0
  528. package/dist/web/static/index.html +6 -6
  529. package/package.json +5 -3
  530. package/dist/core/storage/workflow-recommendations.d.ts +0 -124
  531. package/dist/core/storage/workflow-recommendations.d.ts.map +0 -1
  532. package/dist/core/storage/workflow-recommendations.js +0 -274
  533. package/dist/core/storage/workflow-recommendations.js.map +0 -1
  534. package/dist/daemon/services/experience-extractor.d.ts.map +0 -1
  535. package/dist/daemon/services/experience-extractor.js.map +0 -1
  536. package/dist/daemon/services/violation-reporter.d.ts.map +0 -1
  537. package/dist/daemon/services/violation-reporter.js.map +0 -1
  538. package/dist/daemon/templates/agents/harness-hotfix.md +0 -99
  539. package/dist/daemon/templates/agents/hybrid-feature-with-safety.md +0 -104
  540. package/dist/daemon/templates/agents/refactor-specialist.md +0 -98
  541. package/dist/skills/distill/claude-cli-resolver.d.ts.map +0 -1
  542. package/dist/skills/distill/claude-cli-resolver.js.map +0 -1
  543. package/dist/skills/distilled/distilled-defi-amm-security.md +0 -293
  544. package/dist/skills/keyword-score.d.ts +0 -29
  545. package/dist/skills/keyword-score.d.ts.map +0 -1
  546. package/dist/skills/keyword-score.js +0 -54
  547. package/dist/skills/keyword-score.js.map +0 -1
  548. package/dist/web/static/assets/AgentContentPage-DkeRNxok.js +0 -2
  549. package/dist/web/static/assets/AgentContentPage-DkeRNxok.js.map +0 -1
  550. package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js +0 -2
  551. package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js.map +0 -1
  552. package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js +0 -3
  553. package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js.map +0 -1
  554. package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js +0 -2
  555. package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js.map +0 -1
  556. package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js +0 -2
  557. package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js.map +0 -1
  558. package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js +0 -2
  559. package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js.map +0 -1
  560. package/dist/web/static/assets/DriftTab-DqpepOhI.js +0 -2
  561. package/dist/web/static/assets/DriftTab-DqpepOhI.js.map +0 -1
  562. package/dist/web/static/assets/HealthHomePage-CN6zNIie.js +0 -3
  563. package/dist/web/static/assets/HealthHomePage-CN6zNIie.js.map +0 -1
  564. package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js +0 -2
  565. package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js.map +0 -1
  566. package/dist/web/static/assets/NotFound-BQPh0vaF.js +0 -2
  567. package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js +0 -2
  568. package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js.map +0 -1
  569. package/dist/web/static/assets/SettingsPage-oLJBNzQj.js +0 -2
  570. package/dist/web/static/assets/SettingsPage-oLJBNzQj.js.map +0 -1
  571. package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js +0 -2
  572. package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js.map +0 -1
  573. package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js +0 -2
  574. package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js.map +0 -1
  575. package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js +0 -2
  576. package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js.map +0 -1
  577. package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js +0 -6
  578. package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js.map +0 -1
  579. package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js +0 -3
  580. package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js.map +0 -1
  581. package/dist/web/static/assets/arco-Bhi3a6Qp.js +0 -14
  582. package/dist/web/static/assets/arco-Bhi3a6Qp.js.map +0 -1
  583. package/dist/web/static/assets/charts-BuHQWDbQ.js +0 -37
  584. package/dist/web/static/assets/charts-BuHQWDbQ.js.map +0 -1
  585. package/dist/web/static/assets/index-BIYnq1Dx.js +0 -4
  586. package/dist/web/static/assets/index-BIYnq1Dx.js.map +0 -1
  587. package/dist/web/static/assets/useTabsParam-k8qte_0C.js +0 -2
  588. package/dist/web/static/assets/useTabsParam-k8qte_0C.js.map +0 -1
  589. package/dist/web/static/assets/vendor-DWgdB1eY.js +0 -65
  590. package/dist/web/static/assets/vendor-DWgdB1eY.js.map +0 -1
  591. /package/dist/{skills/distill → core/utils}/claude-cli-resolver.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SkillsPage-aojkJpBc.js","sources":["../../src/pages/ai/SkillsPage.tsx"],"sourcesContent":["/**\n * SkillsPage — AI 资源 · Skill 调用列表 (Phase 2c, decision 29688066).\n *\n * 替换 `/ai/skills` 的占位组件。把原型「Skill 调用」列表翻译成真 Arco\n * 组件(**严禁直搬原型 Tailwind CSS**):Card 页头汇总 + Arco Table(按调用数排序),\n * 列:skill id / 调用次数 / 有用性(helped 占比 + ★)/ 主要调用方 / 最近调用 / 操作。\n * 点行进整页详情 `/ai/skills/:id`。数据接真实端点(见 useSkillStats),受全局时间窗驱动。\n *\n * 口径见 skill-derive.ts:列「调用次数」=invocations[].total(全行,含注入/历史\n * 匹配),副信息「真调 invoked」=真实使用;有用性=actionable_rate(helped/\n * total_rated);主要调用方降级为 top_workflow(agent_id 列实测恒空)。\n * 页头主数字用「真实调用」=Σ invoked(与工作台 KPI 同口径,decision 2d6d59b0),\n * 「总行」降为次要小字消除「工作台 2、这里 165」的困惑。\n */\nimport { useState } from 'react'\nimport { useNavigate } from 'react-router-dom'\n\nimport Card from '@arco-design/web-react/es/Card'\nimport Table from '@arco-design/web-react/es/Table'\nimport Tag from '@arco-design/web-react/es/Tag'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport Button from '@arco-design/web-react/es/Button'\nimport Radio from '@arco-design/web-react/es/Radio'\nimport Rate from '@arco-design/web-react/es/Rate'\nimport Result from '@arco-design/web-react/es/Result'\nimport { IconRight, IconRobot } from '@arco-design/web-react/icon'\n\nimport { useSkillStats } from '../../hooks/useSkillStats'\nimport GlobalScopeHint from '../../components/ai/GlobalScopeHint'\nimport {\n formatPct,\n formatTs,\n ratingStars,\n filterSkillRows,\n type SkillRow,\n type SkillUsageFilter,\n} from '../../hooks/skill-derive'\n\nfunction usefulnessCell(row: SkillRow) {\n if (row.totalRated === 0) {\n return (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 未评分\n </Typography.Text>\n )\n }\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <Rate\n readonly\n allowHalf\n value={ratingStars(row.actionableRate)}\n style={{ fontSize: 13 }}\n />\n <Typography.Text style={{ fontWeight: 600, fontSize: 13 }}>\n {formatPct(row.actionableRate)}\n </Typography.Text>\n </div>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11 }}>\n {row.helped} helped · {row.partial} partial · {row.notActionable} 无效\n {row.pending > 0 ? ` · ${row.pending} 待评` : ''}\n </Typography.Text>\n </div>\n )\n}\n\nexport default function SkillsPage() {\n const navigate = useNavigate()\n const { view, loading, isError, error, project, isAllProjects } = useSkillStats()\n // decision 568a8c53 Q2: 列表三态筛选——全部 / 仅调用过 / 仅未使用。\n const [usageFilter, setUsageFilter] = useState<SkillUsageFilter>('all')\n\n if (isError) {\n return (\n <div style={{ padding: 16 }}>\n <Result\n status=\"error\"\n title=\"加载 Skill 调用失败\"\n subTitle={error?.message || '/api/skill-stats/invocations 端点不可用'}\n />\n </div>\n )\n }\n\n const rows = filterSkillRows(view.rows, usageFilter)\n\n const columns = [\n {\n title: 'Skill',\n dataIndex: 'id',\n render: (_: unknown, row: SkillRow) => (\n <div style={{ minWidth: 0 }}>\n <Typography.Text code style={{ fontSize: 13 }}>\n {row.id}\n </Typography.Text>\n {row.isUnused && (\n <Tag color=\"gray\" size=\"small\" style={{ marginLeft: 6 }}>\n 未使用\n </Tag>\n )}\n {row.description && (\n <div style={{ marginTop: 2 }}>\n <Typography.Text\n type=\"secondary\"\n style={{ fontSize: 12 }}\n ellipsis={{ rows: 1, showTooltip: true }}\n >\n {row.description}\n </Typography.Text>\n </div>\n )}\n </div>\n ),\n },\n {\n title: '调用次数',\n dataIndex: 'calls',\n width: 116,\n sorter: (a: SkillRow, b: SkillRow) => a.calls - b.calls,\n render: (_: unknown, row: SkillRow) => (\n <div>\n <Typography.Text style={{ fontWeight: 600 }}>{row.calls}</Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, marginLeft: 6 }}>\n 真调 {row.invoked}\n </Typography.Text>\n </div>\n ),\n },\n {\n title: '有用性',\n dataIndex: 'actionableRate',\n width: 200,\n sorter: (a: SkillRow, b: SkillRow) =>\n (a.actionableRate ?? -1) - (b.actionableRate ?? -1),\n render: (_: unknown, row: SkillRow) => usefulnessCell(row),\n },\n {\n title: '主要调用方',\n dataIndex: 'caller',\n width: 140,\n render: (_: unknown, row: SkillRow) =>\n row.caller ? (\n <Tag color=\"arcoblue\" size=\"small\" icon={<IconRobot />}>\n {row.caller}\n </Tag>\n ) : (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n —\n </Typography.Text>\n ),\n },\n {\n title: '最近调用',\n dataIndex: 'lastTs',\n width: 124,\n sorter: (a: SkillRow, b: SkillRow) => a.lastTs - b.lastTs,\n render: (_: unknown, row: SkillRow) => (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n {formatTs(row.lastTs)}\n </Typography.Text>\n ),\n },\n {\n title: '操作',\n dataIndex: 'op',\n width: 76,\n align: 'right' as const,\n render: (_: unknown, row: SkillRow) => (\n <Button\n type=\"text\"\n size=\"mini\"\n onClick={(e) => {\n e.stopPropagation()\n navigate(`/ai/skills/${encodeURIComponent(row.id)}`)\n }}\n >\n 详情 <IconRight />\n </Button>\n ),\n },\n ]\n\n return (\n <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 16 }}>\n <Card bordered>\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>\n <Typography.Title heading={6} style={{ margin: 0 }}>\n Skill 调用\n </Typography.Title>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 方法论 skill 调用与有用性自评 · skill_invocations(按调用数排序)\n </Typography.Text>\n <GlobalScopeHint project={project} isAllProjects={isAllProjects} usageLabel=\"调用统计\" />\n <div style={{ flex: 1 }} />\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n Skill 数{' '}\n <Typography.Text style={{ fontWeight: 600 }}>{view.totalSkills}</Typography.Text>\n {view.unusedSkills > 0 && (\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, marginLeft: 6 }}>\n · 未使用{' '}\n <Typography.Text style={{ fontWeight: 600 }}>{view.unusedSkills}</Typography.Text>\n </Typography.Text>\n )}\n </Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 真实调用{' '}\n <Typography.Text style={{ fontWeight: 600, color: 'rgb(var(--arcoblue-6))' }}>\n {view.totalInvoked}\n </Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, marginLeft: 6 }}>\n · 总行 {view.totalCalls}(含注入/历史匹配)\n </Typography.Text>\n </Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 已评分{' '}\n <Typography.Text style={{ fontWeight: 600 }}>\n {view.totalHelped}/{view.totalRated} helped\n </Typography.Text>\n </Typography.Text>\n </div>\n <div style={{ marginTop: 12 }}>\n <Radio.Group\n type=\"button\"\n size=\"small\"\n value={usageFilter}\n onChange={(v) => setUsageFilter(v as SkillUsageFilter)}\n >\n <Radio value=\"all\">全部</Radio>\n <Radio value=\"invoked\">仅调用过</Radio>\n <Radio value=\"unused\">仅未使用</Radio>\n </Radio.Group>\n </div>\n </Card>\n\n <Card bordered style={{ padding: 0 }}>\n <Table<SkillRow>\n rowKey=\"id\"\n loading={loading}\n data={rows}\n columns={columns}\n pagination={rows.length > 20 ? { pageSize: 20, showTotal: true } : false}\n border={{ wrapper: false, cell: false }}\n noDataElement={\n <Typography.Text type=\"secondary\">\n {usageFilter === 'unused'\n ? '没有未使用的 skill'\n : usageFilter === 'invoked'\n ? '窗口内暂无 skill 调用记录'\n : '暂无 skill'}\n </Typography.Text>\n }\n onRow={(row) => ({\n onClick: () => navigate(`/ai/skills/${encodeURIComponent(row.id)}`),\n style: { cursor: 'pointer' },\n })}\n />\n </Card>\n </div>\n )\n}\n"],"names":["usefulnessCell","row","jsx","Typography","jsxs","Rate","ratingStars","formatPct","SkillsPage","navigate","useNavigate","view","loading","isError","error","project","isAllProjects","useSkillStats","usageFilter","setUsageFilter","useState","Result","rows","filterSkillRows","columns","_","Tag","a","b","IconRobot","formatTs","Button","e","IconRight","Card","GlobalScopeHint","Radio","v","Table"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import{r as ge,j as e}from"./react-vendor-tkvCrao7.js";import{d as ye,u as je,L as _}from"./react-router-Cxmg8RuL.js";import{J as k,d as be,D as ve,F as N,K as ae,V as ce,W,X as Se,T as c,Y as de,b as u,Z as U,_ as J,E as ue,u as H,v as Y,$ as ke,x as we,a0 as pe,y as fe,O as xe,t as Te,i as V}from"./arco-DV6xCLhr.js";import{M as w}from"./MarkdownRenderer-DlDQNihj.js";import{u as Z}from"./query-CgCOpYWf.js";import{n as Ie}from"./task-title-BhOcemuR.js";import{p as q}from"./index-DileOOE4.js";import{f as G}from"./date-fns-sbWH3_uq.js";import"./vendor-DS-q4Eyc.js";import"./syntax-highlighter-BDYycNja.js";import"./markdown-CA7ePUts.js";import"./lucide-CnlPQoG8.js";const ze=["content","result","text","content_text","markdown","message","output","final","summary"];function ee(n){if(typeof n=="string")return n.trim()?n:null;if(Array.isArray(n)){const t=[];for(const l of n)typeof l=="string"?t.push(l):l&&typeof l=="object"&&typeof l.text=="string"&&t.push(l.text);const s=t.join(`
2
+
3
+ `).trim();return s||null}return null}function M(n){try{return JSON.stringify(n,null,2)}catch{return String(n)}}function Ce(n){const t=(n??"").trim();if(!t)return{kind:"md",markdown:""};if(!(t.startsWith("{")||t.startsWith("[")))return{kind:"md",markdown:t};let l;try{l=JSON.parse(t)}catch{return{kind:"md",markdown:t}}if(l===null||typeof l!="object")return{kind:"md",markdown:t};if(!Array.isArray(l)){const o=l;for(const r of ze)if(r in o){const i=ee(o[r]);if(i)return{kind:"json-with-md",markdown:i,json:l,pretty:M(l),bodyKey:r}}return{kind:"json",json:l,pretty:M(l)}}const d=ee(l);return d?{kind:"json-with-md",markdown:d,json:l,pretty:M(l),bodyKey:"(array)"}:{kind:"json",json:l,pretty:M(l)}}const _e=new Set(["verify-agent"]),te=/Verdict[::]\s*\**\s*(PASS|FAIL|BLOCKED|SKIP)\b/gi;function $e(n){if(!n)return null;const t=n;let s=null;te.lastIndex=0;let l;for(;(l=te.exec(t))!==null;)s=l[1].toUpperCase();if(s){if(s==="FAIL"||s==="BLOCKED")return"FAIL";if(s==="PASS"||s==="SKIP")return"PASS"}return/\bFAIL\b|\bBLOCKED\b/.test(t)?"FAIL":/\bPARTIAL\b/.test(t)?"PARTIAL":/\bPASS\b|\bSKIP\b/.test(t)?"PASS":null}function Ae(n){if(!n)return!1;const t=n.toLowerCase();return t==="coder"||t.includes("implementer")||t.includes("safety-net")||t.includes("feature-developer")||t.includes("refactor")||t.includes("general-purpose")||t.startsWith("harness-")}function De(n){if(!n)return!1;const t=n.toLowerCase();return t==="decision-maker"||t.includes("planner")}function me(n){return n?_e.has(n.toLowerCase()):!1}function Me(n){return De(n)?{step:"decision",fallback:!1}:me(n)?{step:"verify",fallback:!1}:Ae(n)?{step:"implement",fallback:!1}:{step:"implement",fallback:!0}}const Ee=200,E={decision:"决策",implement:"实施",verify:"验证",commit:"提交"};function I(n){if(!n)return null;const t=new Date(n).getTime();return Number.isFinite(t)?t:null}function Re(n,t){const s=(n.subagent_type??"").toLowerCase(),l=I(n.at);let d,o=Number.POSITIVE_INFINITY;for(const r of t){if((r.subagent_type??"").toLowerCase()!==s)continue;const i=I(r.timestamp),f=l!==null&&i!==null?Math.abs(l-i):Number.POSITIVE_INFINITY;f<o&&(o=f,d=r)}return d}function Le(n,t){if(n){const s=I(n.timestamp),l=I(n.end_timestamp);if(s!==null&&l!==null&&l>=s)return l-s}return(t==null?void 0:t.duration_ms)??null}function Fe(n,t){return n&&(n.prompt||n.output)?{prompt:n.prompt??null,output:n.output??null,truncated:!1}:t?{prompt:t.prompt_preview||null,output:t.output_preview||null,truncated:!0}:{prompt:null,output:null,truncated:!1}}function Be(n,t,s){const l=Re(n,t),d=Fe(l,n),o=me(n.subagent_type),r=(l==null?void 0:l.linked)===0;return{actor:n.subagent_type??"(unknown)",at:n.at??null,durationMs:Le(l,n),fullPrompt:d.prompt,fullOutput:d.output,verdict:o?$e(d.output??n.output_preview):null,commit:null,commitMessage:null,truncated:d.truncated,fallback:s,adjacent:r,bestEffort:!1}}const K=(n,t)=>(I(n.at)??0)-(I(t.at)??0),R=n=>n.filter(t=>!t.adjacent).length,L=n=>n.filter(t=>t.adjacent).length;function F(n){const t=n.filter(r=>!r.adjacent);if(t.length===0)return null;const s=new Map,l=new Map;let d=0;for(const r of t)s.has(r.actor)||s.set(r.actor,d++),l.set(r.actor,(l.get(r.actor)??0)+1);return[...l.entries()].sort((r,i)=>i[1]-r[1]||(s.get(r[0])??0)-(s.get(i[0])??0)).map(([r,i])=>i>1?`${r} ×${i}`:r).join(" + ")}function We(n,t=[]){var a,j,X;const s=n.filter(h=>h.kind==="agent_spawn"),l=n.filter(h=>h.kind==="decision_resolved"),d=n.filter(h=>h.kind==="commit"),o=[],r=[],i=[];for(const h of s){const{step:z,fallback:P}=Me(h.subagent_type),C=Be(h,t,P);z==="decision"?o.push(C):z==="verify"?i.push(C):r.push(C)}o.sort(K),r.sort(K),i.sort(K);const f=d.map(h=>{const z=typeof h.message_full=="string",P=(z?h.message_full:h.message_preview)||null,C=z?h.message_truncated===!0:h.message_preview.length>=Ee;return{actor:"commit",at:h.at??null,durationMs:null,fullPrompt:null,fullOutput:null,verdict:null,commit:h.hash,commitMessage:P,truncated:C,fallback:!1,adjacent:!1,bestEffort:h.attribution==="best-effort"}}),m=l[0],y=f[f.length-1],p=o.find(h=>h.actor.toLowerCase()==="decision-maker")??o[0],v=(m==null?void 0:m.at)??(p==null?void 0:p.at)??null,O=(p==null?void 0:p.actor)??(m?"decision-maker":null),S=o.length>0||!!m,b=ne("决策",o,{decisionEv:m,empty:"本任务未记录决策步骤(可能为元任务 / 纯确认 / skip decision)。"}),g=r[r.length-1],$=ne("实施",r,{empty:"本任务未记录实施 agent 委托。"}),x=i[i.length-1],T=(x==null?void 0:x.verdict)??null,A=i.length>0?i.length===1?`verify-agent 裁决:${T??"未解析出 verdict"}(完整报告见下方)。`:`${i.length} 个 verify-agent 验证(最终裁决 ${T??"未解析"};逐条报告见下方)。`:"本任务未记录 verify-agent 验证步骤。",D=f.length>0?f.length===1?`提交 ${y.commit}。`:`${f.length} 个提交(最终 ${y.commit};逐条见下方)。`:"未产生提交(验证未通过 / 无代码改动)。";return[{key:"decision",label:E.decision,entries:o,actor:O,actorSummary:F(o),at:v,verdict:null,commit:null,present:S,detail:b,fullPrompt:(p==null?void 0:p.fullPrompt)??null,fullOutput:(p==null?void 0:p.fullOutput)??null,durationMs:(p==null?void 0:p.durationMs)??null,decisionId:(m==null?void 0:m.decision_id)??null,decisionStatus:(m==null?void 0:m.status)??null,commitMessage:null,truncated:(p==null?void 0:p.truncated)??!1,agentCount:o.length,strictCount:R(o),adjacentCount:L(o)},{key:"implement",label:E.implement,entries:r,actor:(g==null?void 0:g.actor)??null,actorSummary:F(r),at:((a=r[0])==null?void 0:a.at)??null,verdict:null,commit:null,present:r.length>0,detail:$,fullPrompt:(g==null?void 0:g.fullPrompt)??null,fullOutput:(g==null?void 0:g.fullOutput)??null,durationMs:(g==null?void 0:g.durationMs)??null,decisionId:null,decisionStatus:null,commitMessage:null,truncated:(g==null?void 0:g.truncated)??!1,agentCount:r.length,strictCount:R(r),adjacentCount:L(r)},{key:"verify",label:E.verify,entries:i,actor:(x==null?void 0:x.actor)??null,actorSummary:F(i),at:((j=i[0])==null?void 0:j.at)??null,verdict:T,commit:null,present:i.length>0,detail:A,fullPrompt:(x==null?void 0:x.fullPrompt)??null,fullOutput:(x==null?void 0:x.fullOutput)??null,durationMs:(x==null?void 0:x.durationMs)??null,decisionId:null,decisionStatus:null,commitMessage:null,truncated:(x==null?void 0:x.truncated)??!1,agentCount:i.length,strictCount:R(i),adjacentCount:L(i)},{key:"commit",label:E.commit,entries:f,actor:y?"commit":null,actorSummary:F(f),at:((X=f[0])==null?void 0:X.at)??null,verdict:null,commit:(y==null?void 0:y.commit)??null,present:f.length>0,detail:D,fullPrompt:null,fullOutput:null,durationMs:null,decisionId:null,decisionStatus:null,commitMessage:(y==null?void 0:y.commitMessage)??null,truncated:(y==null?void 0:y.truncated)??!1,agentCount:f.length,strictCount:R(f),adjacentCount:L(f)}]}function ne(n,t,s){if(t.length===0)return s.decisionEv?`决策 #${s.decisionEv.decision_id} 已 ${s.decisionEv.status}。`:s.empty;const l=new Map;for(const r of t)l.set(r.actor,(l.get(r.actor)??0)+1);const d=[...l.entries()].map(([r,i])=>i>1?`${r} ×${i}`:r),o=s.decisionEv?`决策 #${s.decisionEv.decision_id} 已 ${s.decisionEv.status};`:"";return t.length===1?`${o}${d[0]} 执行(完整 prompt / 产出见下方)。`:`${o}${n}步共 ${t.length} 个执行单元:${d.join("、")}(逐条见下方)。`}const Oe=["code","spec","changelog","template","archive"];function Pe(n){if(!n)return[];const t=[];for(const s of Oe)for(const l of n[s]??[])t.push({path:l,bucket:s});return t}function Ke(n){return n.filter(t=>t.kind==="commit").map(t=>({hash:t.hash,message:t.message_preview}))}function Ne(n){return n.filter(t=>t.kind==="daemon_enforce").map((t,s)=>({id:`${t.at}-${t.rule_id}-${s}`,rule_id:t.rule_id,tool:t.tool,decision:t.decision,hint:t.hint,at:t.at}))}function se(n){if(n==null||n==="")return null;if(typeof n=="number")return n;const t=String(n).toLowerCase();return t==="helped"?3:t==="partial"?2:t==="not-actionable"?1:null}function He(n,t,s){const l=(n??[]).map(r=>({skill_id:r.skill_id,reason:r.reason,usefulness:se(r.usefulness)})),d=new Set;for(const r of t??[])r.subagent_type&&d.add(r.subagent_type);return{kbPulls:(s??[]).map(r=>({name:r.page,reason:r.reason??null,usefulness:se(r.usefulness),ts:typeof r.ts=="number"?r.ts:null})),skills:l,agents:[...d]}}function Ve(n){const t=n.filter(o=>o.kind==="user_prompt").slice().sort((o,r)=>o.at<r.at?-1:o.at>r.at?1:0),s=new Set,l=[];let d=0;for(const o of t){if(o.event_id){if(s.has(o.event_id))continue;s.add(o.event_id)}const r=o.kind_label??"user",i=r==="user";l.push({at:o.at,text:o.text,isHuman:i,kind:r,roundNo:i?++d:null,taskId:o.task_id??null,eventId:o.event_id??null})}return l}function Ue(n){const t=n.find(s=>s.kind==="decision_resolved");return(t==null?void 0:t.decision_id)??null}function Je(n){const t=n==null?void 0:n.workflow;return!t||!t.aggregated?{crossRound:!1,taskCount:1,decisionId:(t==null?void 0:t.decision_id)??null,source:(t==null?void 0:t.source)??null}:{crossRound:t.turn_count>1,taskCount:t.turn_count,decisionId:t.decision_id,source:t.source??(t.decision_id?"decision_id":"parent_task")}}function Ye(n){return n.key==="decision"&&n.present&&n.entries.length===0&&!!n.decisionId}function qe(n){return n.present?"finish":"wait"}function Ge(n,t){if(!t)return"进行中";const s=new Date(t).getTime()-new Date(n).getTime();if(!Number.isFinite(s)||s<0)return"—";const l=Math.round(s/1e3);if(l<60)return`${l}s`;const d=Math.floor(l/60),o=l%60;return d<60?o?`${d}m${o}s`:`${d}m`:`${Math.floor(d/60)}h${d%60}m`}async function Qe(n){const t=await fetch(`/api/tasks/${n}`);if(!t.ok)throw new Error(`Failed to fetch task detail (${t.status})`);const s=await t.json();return{...s.task,userPrompts:s.userPrompts??[],injections:s.injections??[],timeline:s.timeline??[],skillInvocations:s.skillInvocations??[],kbPulls:s.kbPulls??[],artifacts:s.artifacts??[],pendingSpecs:s.pendingSpecs??[],agentSpawns:s.agentSpawns??[]}}async function Xe(n){const t=await fetch(`/api/tasks/${n}/timeline`);if(!t.ok)throw new Error(`Failed to fetch task timeline (${t.status})`);return t.json()}function Ze(n){const t=Z({queryKey:["task-detail-page",n],queryFn:()=>Qe(n),enabled:!!n,refetchInterval:15e3}),s=Z({queryKey:["task-detail-timeline",n],queryFn:()=>Xe(n),enabled:!!n,refetchInterval:15e3}),l=t.isLoading||s.isLoading,d=t.error||s.error;let o=null;if(t.data&&s.data){const r=s.data.events;o={detail:t.data,timeline:s.data,chain:We(r,t.data.agentSpawns),changedFiles:Pe(s.data.artifacts),commits:Ke(r),issues:Ne(r),used:He(t.data.skillInvocations,t.data.agentSpawns,t.data.kbPulls),userPromptRounds:Ve(r),relatedDecisionId:Ue(r),workflowSpan:Je(s.data)}}return{vm:o,isLoading:l,error:d,refetch:()=>{t.refetch(),s.refetch()}}}const et=ae.Row,re=ae.Col,tt=ce.Step,B=W.Item;function nt(n){if(n===null||!Number.isFinite(n)||n<0)return null;if(n<1e3)return`${n}ms`;const t=n/1e3;if(t<60)return`${t.toFixed(1)}s`;const s=Math.floor(t/60),l=Math.round(t%60);return l?`${s}m${l}s`:`${s}m`}function he({text:n,maxHeight:t=360}){return e.jsx("div",{style:{background:"var(--color-fill-1)",border:"1px solid var(--color-border-2)",borderRadius:4,padding:"4px 12px",maxHeight:t,overflow:"auto",wordBreak:"break-word",color:"var(--color-text-1)"},children:e.jsx(w,{content:n})})}function st({raw:n,maxHeight:t=360}){const s=Ce(n),l=d=>e.jsx("div",{style:{background:"var(--color-fill-1)",border:"1px solid var(--color-border-2)",borderRadius:4,padding:"4px 12px",maxHeight:t,overflow:"auto",wordBreak:"break-word",color:"var(--color-text-1)"},children:d});return s.kind==="md"?l(e.jsx(w,{content:s.markdown})):s.kind==="json"?l(e.jsx(w,{content:"```json\n"+s.pretty+"\n```"})):l(e.jsxs(e.Fragment,{children:[e.jsx(w,{content:s.markdown}),e.jsx(W,{bordered:!1,defaultActiveKey:[],style:{background:"transparent",marginTop:4},children:e.jsx(B,{name:"raw-json",header:e.jsxs(V,{size:6,children:[e.jsx(Y,{}),e.jsx("span",{style:{fontSize:12},children:"原始 JSON / 完整信封"}),e.jsxs(c.Text,{type:"secondary",style:{fontSize:11},children:["正文字段 ",s.bodyKey," 已抽出渲染,其余结构在此"]})]}),children:e.jsx(w,{content:"```json\n"+s.pretty+"\n```"})})})]}))}function le(n){return n==="success"?e.jsx(u,{color:"green",children:"成功"}):n==="partial"?e.jsx(u,{color:"orange",children:"部分"}):n==="failed"?e.jsx(u,{color:"red",children:"失败"}):n==="abandoned"?e.jsx(u,{color:"gray",children:"放弃"}):null}function oe(n){return n==="completed"?e.jsx(u,{color:"green",children:"已完成"}):n==="active"?e.jsx(u,{color:"arcoblue",children:"进行中"}):n==="abandoned"?e.jsx(u,{color:"gray",children:"已放弃"}):e.jsx(u,{children:n})}function Q(n){return n==="PASS"?e.jsx(u,{color:"green",size:"small",children:"PASS"}):n==="FAIL"?e.jsx(u,{color:"red",size:"small",children:"FAIL"}):n==="PARTIAL"?e.jsx(u,{color:"orange",size:"small",children:"PARTIAL"}):null}const rt={code:{label:"代码",color:"arcoblue"},spec:{label:"Spec",color:"purple"},changelog:{label:"Changelog",color:"green"},template:{label:"模板",color:"cyan"},archive:{label:"存档",color:"gray"}};function ie({n}){if(n===null)return null;const t=Math.round(n);return e.jsx("span",{style:{display:"inline-flex",alignItems:"center",gap:1},children:Array.from({length:3}).map((s,l)=>e.jsx(pe,{style:{fontSize:11,color:l<t?"var(--cf-tag-orange, #FF7D00)":"var(--color-fill-3, #E5E6EB)"}},l))})}function lt({stepKey:n,entry:t,index:s,total:l}){const d=nt(t.durationMs),o=t.actor==="commit"||n==="commit",r=o?"Commit Message":"完整 Prompt",i=n==="verify"?"完整 verify 报告":"完整产出 / Result",f=o?t.commitMessage:t.fullPrompt,m=!!(f||!o&&t.fullOutput);return e.jsxs("div",{style:{border:"1px solid var(--color-border-2)",borderRadius:4,padding:"10px 12px",background:"var(--color-bg-2)"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:m?8:0,flexWrap:"wrap"},children:[l>1&&e.jsxs(c.Text,{type:"secondary",style:{fontSize:11,fontFamily:"monospace"},children:["#",s+1,"/",l]}),e.jsx(u,{size:"small",color:o?"gray":"arcoblue",bordered:!0,icon:o?e.jsx(H,{}):e.jsx(fe,{}),children:t.actor}),t.fallback&&e.jsx(u,{size:"small",color:"orange",children:"其它(未知 agent 类型)"}),t.adjacent&&e.jsx(u,{size:"small",color:"gray",bordered:!0,children:"疑似邻接任务"}),t.at&&e.jsxs(c.Text,{type:"secondary",style:{fontSize:12},children:[e.jsx(de,{style:{marginRight:2}}),G(q(t.at),"HH:mm:ss")]}),d&&e.jsxs(c.Text,{type:"secondary",style:{fontSize:12},children:["耗时 ",d]}),t.verdict&&Q(t.verdict),t.commit&&e.jsx(u,{size:"small",icon:e.jsx(H,{}),style:{fontFamily:"monospace"},children:t.commit.slice(0,10)}),t.truncated&&e.jsx(u,{size:"small",color:"orange",children:"内容可能被截断"}),o&&t.bestEffort&&e.jsx(u,{size:"small",color:"gray",bordered:!0,title:"提交段按工作流时间窗 best-effort 归因,可能漏或误纳邻接 commit",children:"提交按时间窗归因(可能不精确)"})]}),m?e.jsxs(W,{bordered:!1,defaultActiveKey:l<=2?["prompt"]:[],style:{background:"transparent"},children:[f?e.jsx(B,{name:"prompt",header:e.jsxs(V,{size:6,children:[e.jsx(J,{}),e.jsx("span",{style:{fontSize:13,fontWeight:500},children:r}),e.jsxs(c.Text,{type:"secondary",style:{fontSize:11},children:[f.length," 字符"]})]}),children:e.jsx(he,{text:f})}):null,!o&&t.fullOutput?e.jsx(B,{name:"output",header:e.jsxs(V,{size:6,children:[e.jsx(Y,{}),e.jsx("span",{style:{fontSize:13,fontWeight:500},children:i}),e.jsxs(c.Text,{type:"secondary",style:{fontSize:11},children:[t.fullOutput.length," 字符"]})]}),children:e.jsx(st,{raw:t.fullOutput})}):null]}):null]})}function ot({decisionId:n,status:t}){return e.jsxs("div",{style:{border:"1px solid var(--color-border-2)",borderRadius:4,padding:"10px 12px",background:"var(--color-bg-2)",display:"flex",flexDirection:"column",gap:8},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[e.jsxs(u,{size:"small",color:"green",bordered:!0,icon:e.jsx(xe,{}),children:["决策已",t==="resolved"?"解决":t??"处理"]}),e.jsxs(c.Text,{style:{fontSize:13,color:"var(--color-text-2)"},children:["本任务决策 #",n," 已批准 / 解决(未经 decision-maker spawn,常见于 skip decision 的快捷批准)。"]})]}),e.jsx(_,{to:`/decisions/${n}`,children:e.jsx(N,{type:"outline",size:"small",icon:e.jsx(U,{}),children:"查看完整决策内容(选项 / 推荐 / Triage)"})})]})}function it({stepNo:n,step:t}){return e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:10,flexWrap:"wrap"},children:[e.jsxs(c.Text,{style:{fontWeight:600,fontSize:13},children:["第 ",n," 步 · ",t.label]}),t.strictCount>0&&e.jsxs(u,{size:"small",color:"arcoblue",children:[t.strictCount," 个执行单元"]}),t.adjacentCount>0&&e.jsxs(u,{size:"small",color:"gray",bordered:!0,children:["+",t.adjacentCount," 疑似邻接"]}),t.key==="verify"&&Q(t.verdict),t.decisionId&&e.jsx(_,{to:`/decisions/${t.decisionId}`,children:e.jsxs(u,{size:"small",color:"purple",icon:e.jsx(U,{}),style:{cursor:"pointer"},children:["#",t.decisionId,t.decisionStatus?` · ${t.decisionStatus}`:""]})})]}),e.jsx(c.Paragraph,{style:{fontSize:13,margin:"0 0 10px",color:"var(--color-text-2)",whiteSpace:"pre-wrap"},children:t.detail}),t.entries.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:t.entries.map((s,l)=>e.jsx(lt,{stepKey:t.key,entry:s,index:l,total:t.entries.length},`${s.actor}-${s.at??l}-${l}`))}):Ye(t)&&t.decisionId?e.jsx(ot,{decisionId:t.decisionId,status:t.decisionStatus}):null]})}function at({rounds:n,fallback:t}){const s=n.filter(r=>r.isHuman),l=n.filter(r=>!r.isHuman),d=r=>{try{return G(q(r),"MM-dd HH:mm:ss")}catch{return r}},o=r=>r==="agent-callback"?"task-notification 回灌":r==="image"?"图片附件":"系统消息";return e.jsxs(k,{bordered:!0,title:e.jsxs("span",{style:{fontSize:14,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx(J,{}),"人工输入(逐轮)"]}),extra:s.length>0?e.jsxs(c.Text,{type:"secondary",style:{fontSize:12},children:[s.length," 轮"]}):null,children:[s.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:12},children:s.map(r=>e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:4},children:[e.jsxs(u,{color:"arcoblue",size:"small",children:["第 ",r.roundNo," 轮"]}),e.jsx(c.Text,{type:"secondary",style:{fontSize:12},children:d(r.at)})]}),e.jsx("div",{style:{borderLeft:"3px solid rgb(var(--arcoblue-6))",background:"var(--color-fill-1)",padding:"4px 14px",borderRadius:"0 4px 4px 0",color:"var(--color-text-2)",wordBreak:"break-word",maxHeight:320,overflow:"auto"},children:e.jsx(w,{content:r.text})})]},r.eventId??`${r.at}-${r.roundNo}`))}):t?e.jsx("div",{style:{borderLeft:"3px solid rgb(var(--arcoblue-6))",background:"var(--color-fill-1)",padding:"4px 14px",borderRadius:"0 4px 4px 0",color:"var(--color-text-2)",wordBreak:"break-word",maxHeight:320,overflow:"auto"},children:e.jsx(w,{content:t})}):e.jsx(ue,{description:"无人工输入(可能为元任务)"}),l.length>0&&e.jsx(W,{style:{marginTop:s.length>0||t?12:0},children:e.jsx(B,{name:"machine-refills",header:e.jsxs(c.Text,{type:"secondary",style:{fontSize:12},children:[l.length," 条系统回灌(","<task-notification>"," 等,非人工输入)"]}),children:e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:l.map((r,i)=>e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:4},children:[e.jsx(u,{color:"gray",size:"small",children:"系统回灌"}),e.jsxs(c.Text,{type:"secondary",style:{fontSize:12},children:[o(r.kind)," · ",d(r.at)]})]}),e.jsx(he,{text:r.text,maxHeight:200})]},r.eventId??`${r.at}-${i}`))})})})]})}function vt(){var A,D;const{taskId:n}=ye(),t=je(),{vm:s,isLoading:l,error:d}=Ze(n),[o,r]=ge.useState(null);if(l)return e.jsx("div",{style:{padding:16},children:e.jsx(k,{bordered:!0,children:e.jsx(be,{animation:!0,text:{rows:8}})})});if(d||!s)return e.jsx("div",{style:{padding:16},children:e.jsx(ve,{status:"error",title:"加载任务详情失败",subTitle:(d==null?void 0:d.message)||"任务不存在或端点不可用",extra:e.jsx(N,{type:"primary",onClick:()=>t("/tasks"),children:"返回任务列表"})})});const{detail:i,chain:f,changedFiles:m,commits:y,issues:p,used:v,userPromptRounds:O,relatedDecisionId:S,workflowSpan:b}=s,g=Ie(i.title,(A=i.userPrompts[0])==null?void 0:A.content),$=Ge(i.start_time,i.end_time),x=G(q(i.start_time),"MM-dd HH:mm"),T=o!==null?f[o-1]??null:null;return e.jsxs("div",{style:{padding:16,display:"flex",flexDirection:"column",gap:16},children:[e.jsxs(k,{bordered:!0,children:[e.jsx(N,{type:"text",size:"small",icon:e.jsx(Se,{}),style:{marginBottom:8,paddingLeft:0},onClick:()=>t("/tasks"),children:"返回任务"}),e.jsx("div",{style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:16,flexWrap:"wrap"},children:e.jsxs("div",{style:{minWidth:0,flex:1},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[e.jsx(c.Title,{heading:5,style:{margin:0},children:g}),oe(i.status),le(i.outcome)]}),e.jsxs("div",{style:{display:"flex",gap:12,flexWrap:"wrap",marginTop:8,alignItems:"center"},children:[e.jsxs(c.Text,{type:"secondary",style:{fontSize:12,display:"inline-flex",alignItems:"center",gap:4},children:[e.jsx(de,{})," 耗时 ",$]}),e.jsx(c.Text,{type:"secondary",style:{fontSize:12},children:x}),e.jsx(c.Text,{type:"secondary",style:{fontSize:12,fontFamily:"monospace"},title:i.id,children:i.id.length>16?`${i.id.slice(0,16)}…`:i.id}),S&&e.jsx(_,{to:`/decisions/${S}`,style:{fontSize:12},children:e.jsxs(u,{color:"arcoblue",bordered:!0,icon:e.jsx(U,{}),style:{cursor:"pointer"},children:["#",S]})})]})]})})]}),e.jsxs(k,{bordered:!0,title:e.jsxs("span",{style:{fontSize:14,fontWeight:600,display:"inline-flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:["执行链路",b.crossRound&&e.jsxs(u,{color:"purple",bordered:!0,style:{fontWeight:400},children:["跨 ",b.taskCount," 轮工作流",b.source==="parent_task"?"(按任务链路推断聚合)":b.decisionId?`(按 decision #${b.decisionId} 聚合)`:""]}),b.crossRound&&b.source==="parent_task"&&e.jsx(c.Text,{type:"secondary",style:{fontSize:12,fontWeight:400},children:"无决策 ID,按 parent_task 链路保守串联,可能不完整"})]}),extra:e.jsx(c.Text,{type:"secondary",style:{fontSize:12},children:"点步骤查看细节"}),children:[e.jsx(ce,{type:"arrow",current:o??-1,onChange:a=>r(j=>j===a?null:a),style:{cursor:"pointer"},children:f.map(a=>e.jsx(tt,{title:a.label,status:qe(a),description:e.jsxs("span",{style:{fontSize:12,display:"inline-flex",alignItems:"center",gap:4,flexWrap:"wrap"},children:[a.key==="verify"&&a.verdict?Q(a.verdict):null,a.actorSummary??a.actor?e.jsxs(c.Text,{type:"secondary",style:{fontSize:11},children:[a.actorSummary??a.actor,a.adjacentCount>0?` (+${a.adjacentCount})`:""]}):a.key==="verify"&&a.verdict?null:e.jsx(c.Text,{type:"secondary",style:{fontSize:11},children:"—"})]})},a.key))}),e.jsx("div",{style:{marginTop:12,borderTop:"1px solid var(--color-border-2)",paddingTop:12},children:T?e.jsx(it,{stepNo:o??1,step:T}):e.jsx(c.Text,{type:"secondary",style:{fontSize:12},children:"点击上方任一步骤,在此展开该步的完整 prompt / 产出 / verdict / commit 细节。"})})]}),e.jsxs(et,{gutter:16,align:"start",children:[e.jsx(re,{xs:24,xl:16,style:{marginBottom:16},children:e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[e.jsx(at,{rounds:O,fallback:(D=i.userPrompts[0])==null?void 0:D.content}),e.jsxs(k,{bordered:!0,title:e.jsxs("span",{style:{fontSize:14,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx(Y,{}),"改动文件 · Commits"]}),extra:e.jsxs(c.Text,{type:"secondary",style:{fontSize:12},children:[m.length," 文件 · ",y.length," commit"]}),children:[m.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column"},children:m.map(a=>{const j=rt[a.bucket];return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"6px 0",borderBottom:"1px solid var(--color-border-1)"},children:[e.jsx(J,{style:{color:"var(--color-text-3)",flexShrink:0}}),e.jsx(c.Text,{code:!0,style:{fontSize:12,flex:1,minWidth:0},ellipsis:!0,title:a.path,children:a.path}),e.jsx(u,{size:"small",color:j.color,children:j.label})]},a.path)})}):e.jsx(ue,{description:"本任务无改动文件"}),e.jsx(c.Text,{style:{fontSize:12,fontWeight:500,color:"var(--color-text-3)",display:"block",marginTop:16,marginBottom:8},children:"Commits"}),y.length>0?y.map((a,j)=>e.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:8,padding:"6px 0",borderBottom:"1px solid var(--color-border-1)"},children:[e.jsx(H,{style:{color:"var(--color-text-3)",marginTop:2,flexShrink:0}}),e.jsxs("div",{style:{minWidth:0},children:[e.jsx(c.Text,{style:{fontFamily:"monospace",fontSize:13,color:"rgb(var(--arcoblue-6))"},children:a.hash.slice(0,10)}),e.jsx(c.Paragraph,{style:{fontSize:12,margin:"2px 0 0",color:"var(--color-text-2)"},ellipsis:{rows:2},children:a.message||"(无 message)"})]})]},`${a.hash}-${j}`)):e.jsx(c.Text,{type:"secondary",style:{fontSize:13},children:"未产生提交(验证未通过 / 无代码改动)"})]})]})}),e.jsx(re,{xs:24,xl:8,style:{marginBottom:16},children:e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[e.jsx(k,{bordered:!0,title:e.jsx("span",{style:{fontSize:14,fontWeight:600},children:"概要"}),children:e.jsx(ke,{colon:" :",size:"small",column:1,labelStyle:{width:88,color:"var(--color-text-3)"},data:[{label:"状态",value:oe(i.status)},{label:"结果",value:le(i.outcome)??e.jsx(c.Text,{type:"secondary",children:"—"})},{label:"耗时",value:$},{label:"事件数",value:i.event_count},{label:"Task ID",value:e.jsx(c.Text,{code:!0,style:{fontSize:11},children:i.id})},{label:"关联决策",value:S?e.jsxs(_,{to:`/decisions/${S}`,style:{fontFamily:"monospace"},children:["#",S]}):e.jsx(c.Text,{type:"secondary",children:"—"})}]})}),e.jsxs(k,{bordered:!0,title:e.jsx("span",{style:{fontSize:14,fontWeight:600},children:"用了什么"}),children:[e.jsxs(c.Text,{style:{fontSize:12,fontWeight:500,color:"var(--color-text-3)",display:"flex",alignItems:"center",gap:4},children:[e.jsx(we,{})," KB 主动 pull"]}),v.kbPulls.length>0?v.kbPulls.map((a,j)=>e.jsxs("div",{style:{padding:"3px 0"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx(c.Text,{style:{fontFamily:"monospace",fontSize:12},children:a.name}),a.usefulness!==null&&e.jsx(ie,{n:a.usefulness})]}),a.reason&&e.jsx(c.Text,{type:"secondary",style:{fontSize:11},children:a.reason})]},`${a.name}-${a.ts??j}`)):e.jsx(c.Text,{type:"secondary",style:{fontSize:12,display:"block",padding:"2px 0"},children:"无主动 pull"}),e.jsxs(c.Text,{style:{fontSize:12,fontWeight:500,color:"var(--color-text-3)",display:"flex",alignItems:"center",gap:4,marginTop:12,paddingTop:8,borderTop:"1px solid var(--color-border-1)"},children:[e.jsx(pe,{})," Skill(带有用性评分)"]}),v.skills.length>0?v.skills.map(a=>e.jsxs("div",{style:{padding:"3px 0"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx(c.Text,{style:{fontFamily:"monospace",fontSize:12},children:a.skill_id}),e.jsx(ie,{n:a.usefulness})]}),e.jsx(c.Text,{type:"secondary",style:{fontSize:11},children:a.reason})]},a.skill_id)):e.jsx(c.Text,{type:"secondary",style:{fontSize:12,display:"block",padding:"2px 0"},children:"未调用 Skill"}),e.jsxs(c.Text,{style:{fontSize:12,fontWeight:500,color:"var(--color-text-3)",display:"flex",alignItems:"center",gap:4,marginTop:12,paddingTop:8,borderTop:"1px solid var(--color-border-1)"},children:[e.jsx(fe,{})," Agent 委托"]}),e.jsx("div",{style:{marginTop:4},children:v.agents.length>0?v.agents.map(a=>e.jsx(u,{size:"small",style:{marginRight:6,marginBottom:6},children:a},a)):e.jsx(c.Text,{type:"secondary",style:{fontSize:12},children:"无"})})]}),e.jsx(k,{bordered:!0,title:e.jsxs("span",{style:{fontSize:14,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx(Te,{style:{color:p.length>0?"var(--cf-tag-orange, #FF7D00)":"var(--color-text-3)"}}),"问题"]}),extra:p.length>0?e.jsxs(c.Text,{style:{fontSize:12,color:"rgb(var(--red-6))"},children:[p.length," 项"]}):void 0,children:p.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:p.map(a=>e.jsxs("div",{style:{border:"1px solid var(--color-border-2)",borderRadius:4,padding:10},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:4},children:[e.jsx(u,{size:"small",color:a.decision==="deny"?"red":"orange",children:a.decision}),e.jsx(c.Text,{style:{fontSize:13,fontWeight:500},children:a.rule_id}),e.jsx(u,{size:"small",children:a.tool})]}),a.hint&&e.jsx(c.Paragraph,{style:{fontSize:12,margin:0,color:"var(--color-text-2)"},ellipsis:{rows:3},children:a.hint}),e.jsx(_,{to:"/issues",style:{fontSize:12},children:"在「问题」中查看"})]},a.id))}):e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,fontSize:13,color:"rgb(var(--green-6))"},children:[e.jsx(xe,{}),"本任务无拦截 / 违规 / 失败"]})})]})})]})]})}export{vt as default};
4
+ //# sourceMappingURL=TaskDetailPage-1ckxnGhw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskDetailPage-1ckxnGhw.js","sources":["../../src/hooks/task-detail-derive.ts","../../src/hooks/useTaskDetail.ts","../../src/pages/TaskDetailPage.tsx"],"sourcesContent":["/**\n * task-detail-derive — 任务详情整页 (Phase 2a, decision 29688066) 纯数据派生层。\n *\n * 把任务详情页所有「真实端点响应 → 视图模型」的计算抽成纯函数,零 DOM / 零 react\n * 依赖,便于在 node 环境下单测(项目无 jsdom / RTL,见 dashboard-shape-contract\n * 注解)。`TaskDetailPage.tsx` 负责 react-query 取数 + 渲染,调这些纯函数。\n *\n * 数据源(两个现有端点,零新后端):\n * GET /api/tasks/:id → task / userPrompts / skillInvocations / agentSpawns\n * (TaskDetailData,见 ai-summary/types.ts)\n * GET /api/tasks/:id/timeline → events(user_prompt / daemon_enforce / agent_spawn /\n * commit / decision_resolved)+ artifacts buckets\n * (TimelineResponse,见 src/web/routes/task-timeline.ts)\n *\n * 派生的视图模型:\n * - chainSteps:横向执行链路①决策②实施③验证④提交(从 timeline events 装配,缺步降级)\n * - changedFiles:改动文件(artifacts 各 bucket 扁平化 + commit 信息)\n * - commits:提交列表(timeline commit events)\n * - usedResources:用了什么(KB pull / Skill ★ / Agent 委托)\n * - issues:问题(timeline daemon_enforce events)\n *\n * 降级策略(spec):后端不提供 diff 行数(+N/-M)→ 文件只展示路径,不显示行统计;\n * KB 主动 pull 接 /api/tasks/:id 的 kbPulls[] 真实数据(decision 93b3075b,该任务\n * 执行窗内 agent 真实拉取的 KB,后端 project+时间窗+reason scope);旧后端缺该字段\n * 或真无主动 pull → [],UI 显「无主动 pull」。skill 有用性评分 usefulness 若 payload\n * 未带则不显示 ★。\n */\n\n// ─── Server response shapes (mirror the two endpoints) ──────────────────────\n\n/** Subset of GET /api/tasks/:id/timeline events we consume. */\n/**\n * 后端 user_prompt 事件携带的分类标签(decision ed5c3e93,单源口径)。后端用\n * classifyPromptKind 填,前端零重复逻辑:'user' 真人工 / 'agent-callback'\n * `<task-notification>` 机器回灌 / 'image' / 'system' 其它非人工信封。\n */\nexport type PromptKindLabel = 'user' | 'agent-callback' | 'image' | 'system'\n\nexport type TimelineEvent =\n | {\n kind: 'user_prompt'\n at: string\n text: string\n /** UserPromptSubmit 事件 id(去重用;旧响应缺省)。 */\n event_id?: string\n /** 该轮所属 per-prompt task(decision ed5c3e93,跨轮关联);单 task 臂缺省。 */\n task_id?: string | null\n /** 后端 classifyPromptKind 分类(decision ed5c3e93);旧响应缺省 → 视为 'user'。 */\n kind_label?: PromptKindLabel\n }\n | {\n kind: 'daemon_enforce'\n at: string\n rule_id: string\n tool: string\n decision: 'deny' | 'warn' | 'bypass' | 'dry_run'\n hint: string | null\n }\n | {\n kind: 'agent_spawn'\n at: string\n subagent_type: string | null\n name: string | null\n duration_ms: number | null\n prompt_preview: string\n output_preview: string\n /**\n * 该 spawn 所属的发起 task(decision c425f26f, Batch 2)。仅跨 task 聚合\n * (workflow.aggregated)时由后端填充;与详情页请求的 taskId 不同 → 该 spawn\n * 「来自第 K 轮」。单 task(非聚合)响应缺省。\n */\n task_id?: string | null\n }\n | {\n kind: 'commit'\n at: string\n hash: string\n /** ≤200 字预览(概览/列表用)。 */\n message_preview: string\n /** 完整 commit message(≤8KB;后端 additive 字段,decision 638e2ebd)。旧响应缺则回退 preview。 */\n message_full?: string\n /** message_full 是否被 cap 截断(旧响应缺 → false)。 */\n message_truncated?: boolean\n /**\n * 归因置信度(decision c425f26f, Batch 2, 用户拍板 #4):\n * - 'exact' 提交落在本 task 自己窗内(精确)。\n * - 'best-effort' 提交按工作流时间窗启发式归因(同 session + [首 spawn,\n * 末 spawn+宽限]);可能漏(独立新 task 在窗外)或误纳(邻接\n * 非本工作流 commit)。**永不据此写 outcome**。\n * 旧响应缺省 → 视为 'exact'。\n */\n attribution?: 'exact' | 'best-effort'\n }\n | { kind: 'decision_resolved'; at: string; decision_id: string; status: string }\n\nexport interface ArtifactsBucket {\n spec: string[]\n archive: string[]\n changelog: string[]\n template: string[]\n code: string[]\n}\n\n/**\n * 跨 task 工作流聚合元数据(decision c425f26f, Batch 2)。后端按发起 task 的\n * decision_id 把整工作流的 spawn 聚合进四段时填充。旧响应缺省 → 视为单 task。\n */\nexport interface WorkflowMeta {\n /** 四段按哪个 decision_id 聚合;无 → null。 */\n decision_id: string | null\n /** true = agent_spawn 段来自跨 task 聚合;false = 单 task(无 decision_id)。 */\n aggregated: boolean\n /** 聚合 spawn 横跨的 distinct 发起 task 数(「跨 N 轮」的 N)。 */\n turn_count: number\n /**\n * 四段按什么聚合(decision f47c2c90, 二期B):\n * - 'decision_id' 有 decision_id → 一期A 精确聚合。\n * - 'parent_task' 无 decision_id → 二期B 按 parent_task 链路保守串联(启发式,可能不完整)。\n * - null 单 task / 旧响应。\n * A、B 互斥(每个 task 至多走一条)。旧响应缺省 → 视为 null。\n */\n source?: 'decision_id' | 'parent_task' | null\n}\n\nexport interface TimelineResponse {\n task_id: string\n events: TimelineEvent[]\n artifacts: ArtifactsBucket\n /** 跨 task 工作流聚合元数据(additive;旧响应缺省 → 视为单 task)。 */\n workflow?: WorkflowMeta\n}\n\n// ─── View models ────────────────────────────────────────────────────────────\n\nexport type StepKey = 'decision' | 'implement' | 'verify' | 'commit'\nexport type VerifyVerdict = 'PASS' | 'FAIL' | 'PARTIAL' | null\n\n/**\n * 单个「执行单元」—— 一个 agent spawn 或一个 commit,归属于某步。\n * 一步可有多个(决策步 decision-maker + 多个 planner;实施步十几个 coder;\n * 验证步多个 verify-agent;提交步多个 commit)。每条带完整 prompt / output,\n * 验证条带 verdict,提交条带 hash / message。\n */\nexport interface StepAgentEntry {\n /** 执行者 subagent_type(agent 条),或 'commit'(提交条)。 */\n actor: string\n /** ISO timestamp(agent spawn 的 timestamp / commit 的 at)。 */\n at: string | null\n /** 耗时(ms),agent 条来自 [timestamp,end_timestamp] 或 timeline duration_ms;commit 条 null。 */\n durationMs: number | null\n /** 完整 prompt(agent 条);commit 条放 commit message;无 → null。 */\n fullPrompt: string | null\n /** 完整 output / result(agent 条);commit 条 null;无 → null。 */\n fullOutput: string | null\n /** 验证条专用:PASS/FAIL/PARTIAL;其它 null。 */\n verdict: VerifyVerdict\n /** 提交条专用:commit 短/全 hash;其它 null。 */\n commit: string | null\n /** 提交条专用:完整 commit message;其它 null。 */\n commitMessage: string | null\n /** fullPrompt/fullOutput 是否来自 timeline preview(被截断)而非 agentSpawns 完整内容。 */\n truncated: boolean\n /**\n * 该条是否为「兜底归入本步」的未知 agent 类型(未匹配到任何已知步桶)。\n * true 时 UI 可加「其它」标记;分桶口径见 buildChain。\n */\n fallback: boolean\n /**\n * 该 spawn 是否为「时间窗兜底捞来」(来自匹配到的 agentSpawn 的 `linked===0`)——\n * 即未严格归属本任务(task_events 臂),而是被 session+时间窗兜底臂吸入(可能是\n * 本任务自己漏 link 的孤儿,也可能是邻接任务的 spawn)。沿用「不丢任何 spawn」原则\n * 保留展示,但 UI 标「疑似邻接任务」与严格归属(linked=1)区分。匹配不到完整 spawn\n * (无 linked 信息)时默认 false(按严格归属处理)。\n */\n adjacent: boolean\n /**\n * 提交条专用:该 commit 是否为「best-effort 时间窗归因」(decision c425f26f,\n * Batch 2)。来自 timeline commit 事件的 `attribution==='best-effort'`。true 时 UI\n * 加小字「提交段按时间窗 best-effort 归因,可能不精确」。exact / 旧响应缺省 → false。\n */\n bestEffort: boolean\n}\n\nexport interface ChainStep {\n key: StepKey\n /** ①决策 ②实施 ③验证 ④提交 */\n label: string\n /**\n * 该步所有执行单元(agent spawn / commit),按时间升序。核心改造:每步收集\n * 「全部」归属本步的 agent/commit,不再单挑一个(decision 5fb088f9)。\n */\n entries: StepAgentEntry[]\n /**\n * 主执行者(向后兼容 + 部分内部逻辑用):实施 / 验证步取最后一个 entry,\n * 决策步取 decision-maker,提交步取 'commit'。无 entry → null。\n *\n * ⚠️ 注意:**不要**用 `actor` + `strictCount` 直接拼 Steps 副标题——一步可有\n * 多种 actor(决策步 decision-maker + planner、实施步 coder + safety-net-implementer),\n * 那样会把混合错拼成「decision-maker ×2」。副标题请用 `actorSummary`(已按 actor\n * 分组计数,如「decision-maker + planner」)。\n */\n actor: string | null\n /**\n * Steps 概览副标题用的「按 actor 分组计数」紧凑摘要(仅计严格归属 strict,\n * adjacent 不计入此串、由 adjacentCount 单独标)。口径:\n * - 单 actor 单条 → `decision-maker`\n * - 单 actor 多条 → `decision-maker ×2`\n * - 多 actor 混合 → `decision-maker + planner` / `coder ×3 + planner`\n * - 提交步 → `commit` / `commit ×N`\n * - 无严格归属 entry(空步 / 仅 adjacent / 仅 decision_resolved)→ null\n * 多个相同 actor 用 `×N`,不同 actor 用 ` + ` 连接,按数量降序、同数按首次出现序。\n */\n actorSummary: string | null\n /** ISO timestamp this step started/landed, or null when absent.(取首个 entry / 决策事件) */\n at: string | null\n /** verify 步专用:PASS/FAIL/PARTIAL(取最后一个 verify entry 的 verdict);其它步为 null。 */\n verdict: VerifyVerdict\n /** commit 步专用:短 hash(取最后一个 commit);其它步为 null。 */\n commit: string | null\n /** 该步是否有真实信号(无信号 → 灰显占位)。 */\n present: boolean\n /** 展开面板一行式摘要(缺步降级文案沿用旧逻辑;多 agent 时含数量)。 */\n detail: string\n /**\n * 该步完整 prompt(主 entry:实施/验证取最后一个,决策取 decision-maker)——\n * 优先取 /api/tasks/:id agentSpawns 的完整 prompt(≤16KB),匹配不到时回退\n * timeline 的 *_preview。decision/commit 步无 prompt → null。向后兼容字段。\n */\n fullPrompt: string | null\n /** 该步完整 output / result(主 entry,来源同 fullPrompt,≤8KB)。无 → null。 */\n fullOutput: string | null\n /** 该步耗时(ms,主 entry)。 */\n durationMs: number | null\n /** decision 步专用:关联 decision id(无 → null)。 */\n decisionId: string | null\n /** decision 步专用:decision 状态(resolved/...,无 → null)。 */\n decisionStatus: string | null\n /** commit 步专用:完整 commit message(主 entry = 最后一个 commit)。无 → null。 */\n commitMessage: string | null\n /** 主 entry 的 fullPrompt/fullOutput 是否被截断(来自 timeline preview)。 */\n truncated: boolean\n /** 该步执行单元数量(entries.length,UI 显「coder ×N」用)。 */\n agentCount: number\n /**\n * 该步「严格归属本任务」(adjacent=false)的执行单元数 —— 主计数口径。\n * Steps 副标题 /「M 个执行单元」以此为主数(spec f4d64791),不含疑似邻接任务。\n */\n strictCount: number\n /**\n * 该步「疑似邻接任务」(adjacent=true,linked=0 兜底捞来)的执行单元数。\n * >0 时 UI 在主数旁额外标「+N 疑似邻接」。当前实测多为 0(纯防御)。\n */\n adjacentCount: number\n}\n\nexport interface ChangedFile {\n path: string\n /** 归类:spec / changelog / archive / template / code(驱动图标 + 标签)。 */\n bucket: keyof ArtifactsBucket\n}\n\nexport interface CommitRow {\n hash: string\n message: string\n}\n\nexport interface IssueRow {\n id: string\n rule_id: string\n tool: string\n decision: 'deny' | 'warn' | 'bypass' | 'dry_run'\n hint: string | null\n at: string\n}\n\n// ─── Agent output smart display(智能展示 agent 产出,decision deb6e2f3)────────\n//\n// 实测产出 shape(curl localhost:3721 /api/tasks/:id agentSpawns[].output):\n// agent 产出几乎都是一个 **JSON 信封**(Task/Agent 工具的结果对象),顶层键固定为:\n// { status, prompt, agentId, agentType, content, totalDurationMs, totalTokens,\n// totalToolUseCount, usage, toolStats }\n// 其中 **agent 真正的 markdown 正文在 `content` 字段** —— 它是 Claude 消息内容块\n// 数组 `[{ type:'text', text:'...md...' }]`(实测 ≤1 块)。其余键(status/usage/\n// duration/token/toolStats…)是结构化外壳,不该和正文混渲。\n//\n// 旧 UI 把整坨 JSON 当 markdown 渲染 → 大括号 / key / 转义和正文混一起很乱。本函数\n// 把 raw 智能识别为三类,交给 UI 分区展示(正文渲 md、外壳折叠看原始 JSON)。\n//\n// 健壮性(实测必踩):8KB output cap 会把 JSON 拦腰截断(结尾 `…(truncated)`),\n// 此时 JSON.parse 失败 —— 必须优雅退回当纯文本/markdown 渲染,**绝不丢内容、不崩**。\n\n/** parseAgentOutput 的判别结果。 */\nexport type ParsedAgentOutput =\n | {\n /** 纯 markdown / 纯文本(非 JSON,或 JSON.parse 失败的截断信封)。整坨当 md 渲。 */\n kind: 'md'\n markdown: string\n }\n | {\n /** 纯结构化 JSON(无可抽取的大段 md 正文)。pretty-print 后高亮展示。 */\n kind: 'json'\n json: unknown\n /** pretty-print(2 空格缩进)的 JSON 文本,供 ```json fenced 高亮。 */\n pretty: string\n }\n | {\n /** JSON 信封 + 抽出了 markdown 正文。正文渲 md(主),余下结构化外壳折叠。 */\n kind: 'json-with-md'\n /** 抽出的 markdown 正文(来自候选键,content 块数组已拍平为文本)。 */\n markdown: string\n /** 完整原始 JSON(含正文键),供折叠区 pretty 高亮看原始信封。 */\n json: unknown\n pretty: string\n /** 命中的正文候选键名(调试 / UI 提示用)。 */\n bodyKey: string\n }\n\n/**\n * markdown 正文候选键优先级。实测 Task/Agent 工具信封正文在 `content`(内容块数组),\n * 兜底兼容其它常见 agent 产出字段(`result`/`text`/`message`/`markdown`/`output`/`final`)。\n * 按此序取第一个能抽出非空文本的键。\n */\nconst MD_BODY_KEYS = ['content', 'result', 'text', 'content_text', 'markdown', 'message', 'output', 'final', 'summary'] as const\n\n/**\n * 把一个候选键的值抽成 markdown 文本:\n * - string → 原样(trim 后非空才算命中)\n * - 内容块数组 `[{type:'text', text}]`(Claude 消息 content)→ 拼接各块 text\n * - 其它(object / number / null …)→ 不算正文(返回 null,让 caller 试下一个键)\n */\nfunction extractBodyText(value: unknown): string | null {\n if (typeof value === 'string') {\n return value.trim() ? value : null\n }\n if (Array.isArray(value)) {\n // Claude content-block 数组:[{ type:'text', text:'...' }, ...]\n const parts: string[] = []\n for (const block of value) {\n if (typeof block === 'string') {\n parts.push(block)\n } else if (block && typeof block === 'object' && typeof (block as { text?: unknown }).text === 'string') {\n parts.push((block as { text: string }).text)\n }\n }\n const joined = parts.join('\\n\\n').trim()\n return joined ? joined : null\n }\n return null\n}\n\n/** 安全 pretty-print(2 空格缩进)。循环引用等异常 → String() 兜底。 */\nfunction safePretty(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2)\n } catch {\n return String(value)\n }\n}\n\n/**\n * 智能识别 agent 产出 raw(纯函数,可单测)。三类:\n *\n * 1. **非 JSON / parse 失败**(含 8KB 截断的信封)→ `kind:'md'`,整坨当 markdown\n * 渲染(不丢内容、不崩)。\n * 2. **JSON 信封 + 含 markdown 正文**(按 MD_BODY_KEYS 候选键抽到非空正文)→\n * `kind:'json-with-md'`:`markdown` = 抽出的正文(主区渲 md),`json`/`pretty`\n * = 完整原始信封(折叠区高亮看外壳)。\n * 3. **纯结构化 JSON**(object/数组,但抽不到大段 md 正文)→ `kind:'json'`,\n * pretty-print + 高亮展示。\n *\n * 退回原则:JSON.parse 失败 → md;parse 成 object 但抽不到正文 → json(不丢、原样\n * 高亮);parse 成非 object/数组的标量(number/bool/string)→ 当 md(原样文本)。\n */\nexport function parseAgentOutput(raw: string | null | undefined): ParsedAgentOutput {\n const text = (raw ?? '').trim()\n if (!text) return { kind: 'md', markdown: '' }\n\n // 只在「看起来像 JSON」(以 { 或 [ 开头)时才尝试 parse,避免把普通 markdown\n // 正文(如以数字开头的文本)误判。\n const looksJson = text.startsWith('{') || text.startsWith('[')\n if (!looksJson) {\n return { kind: 'md', markdown: text }\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n // 截断的信封 / 非法 JSON → 当纯 markdown 渲染(不丢内容)。\n return { kind: 'md', markdown: text }\n }\n\n // parse 成标量(不是 object / 数组)→ 没有可抽的结构,当文本渲。\n if (parsed === null || typeof parsed !== 'object') {\n return { kind: 'md', markdown: text }\n }\n\n // object(非数组)信封:按候选键抽 markdown 正文。\n if (!Array.isArray(parsed)) {\n const env = parsed as Record<string, unknown>\n for (const key of MD_BODY_KEYS) {\n if (key in env) {\n const body = extractBodyText(env[key])\n if (body) {\n return { kind: 'json-with-md', markdown: body, json: parsed, pretty: safePretty(parsed), bodyKey: key }\n }\n }\n }\n // 抽不到大段正文 → 纯结构化 JSON。\n return { kind: 'json', json: parsed, pretty: safePretty(parsed) }\n }\n\n // 顶层数组:可能是内容块数组([{type:'text',text}])→ 抽正文;否则纯 JSON 数组。\n const arrBody = extractBodyText(parsed)\n if (arrBody) {\n return { kind: 'json-with-md', markdown: arrBody, json: parsed, pretty: safePretty(parsed), bodyKey: '(array)' }\n }\n return { kind: 'json', json: parsed, pretty: safePretty(parsed) }\n}\n\n// ─── Verdict parsing ─────────────────────────────────────────────────────────\n\nconst VERIFY_AGENTS = new Set(['verify-agent'])\n\n/**\n * 显式裁决声明行正则:匹配 verify-agent 模板的 `## Verdict: PASS`(大小写不敏感、\n * 可带 0..6 个 `#` 前缀、verdict 词可被 `**` 粗体包裹)。\n *\n * ⚠️ 关键:verify-agent 的完整 output 是「一大段含模板 + 描述性文字」的 blob,\n * 正文里 FAIL / PASS / BLOCKED 这些词会作为**描述**多次出现(如 verdict 定义\n * \"**FAIL**: happy path broken\"、约束 \"FAIL when in doubt\"、probe 结果文字)。\n * 旧逻辑「按 FAIL 词优先 / 首次出现」会被正文带偏——实测把真实 `## Verdict: PASS`\n * 的报告全判成 FAIL(某 rollout 任务 18 个验证步全 PASS 却全显 FAIL,decision f4d64791)。\n *\n * 修法:只认**显式裁决声明行**(`Verdict: <X>`)。注意 output 经端点 JSON 包裹 +\n * gzip 解码后,换行可能是真实 `\\n` 也可能是被转义的字面 `\\n`,因此**不**用 `^` 锚定\n * 行首,只匹配 `Verdict:` 紧跟裁决词的声明片段。多处声明取**最后一个**(最终/最权威\n * 那次裁决)。完全没有显式裁决行时才退回旧关键词启发式。\n */\nconst VERDICT_DECL_RE = /Verdict[::]\\s*\\**\\s*(PASS|FAIL|BLOCKED|SKIP)\\b/gi\n\n/**\n * 从 verify-agent 的完整 output(或 output_preview)抽取 PASS/FAIL/PARTIAL verdict。\n *\n * 优先级:\n * 1. **显式裁决声明行** `Verdict: PASS|FAIL|BLOCKED|SKIP`(取最后一次声明)——\n * FAIL/BLOCKED → 'FAIL'(未通过);PASS/SKIP → 'PASS'(通过)。这是权威口径,\n * 不受正文里描述性 FAIL/PASS 词干扰。\n * 2. 无任何显式裁决行时,退回旧关键词启发式(FAIL/BLOCKED → FAIL、PARTIAL → PARTIAL、\n * PASS/SKIP → PASS),用于只有截断 preview、没解析出明确裁决行的情况。\n */\nexport function parseVerifyVerdict(output: string | null | undefined): VerifyVerdict {\n if (!output) return null\n const text = output\n\n // 1) 显式裁决声明行优先(取最后一次声明 = 最终裁决)。\n let last: string | null = null\n VERDICT_DECL_RE.lastIndex = 0\n let m: RegExpExecArray | null\n while ((m = VERDICT_DECL_RE.exec(text)) !== null) {\n last = m[1].toUpperCase()\n }\n if (last) {\n if (last === 'FAIL' || last === 'BLOCKED') return 'FAIL'\n if (last === 'PASS' || last === 'SKIP') return 'PASS'\n }\n\n // 2) 无显式裁决行 → 退回旧关键词启发式(未解析出明确 verdict 的兜底)。\n if (/\\bFAIL\\b|\\bBLOCKED\\b/.test(text)) return 'FAIL'\n if (/\\bPARTIAL\\b/.test(text)) return 'PARTIAL'\n if (/\\bPASS\\b|\\bSKIP\\b/.test(text)) return 'PASS'\n return null\n}\n\n/** agent subagent_type 是否属于「实施」类(coder / safety-net-implementer 等)。 */\nexport function isImplementAgent(subagentType: string | null): boolean {\n if (!subagentType) return false\n const t = subagentType.toLowerCase()\n return (\n t === 'coder' ||\n t.includes('implementer') ||\n t.includes('safety-net') ||\n t.includes('feature-developer') ||\n t.includes('refactor') ||\n t.includes('general-purpose') ||\n t.startsWith('harness-')\n )\n}\n\n/** agent subagent_type 是否属于「决策」类(decision-maker / planner)。 */\nexport function isDecisionAgent(subagentType: string | null): boolean {\n if (!subagentType) return false\n const t = subagentType.toLowerCase()\n return t === 'decision-maker' || t.includes('planner')\n}\n\n/** agent subagent_type 是否属于「验证」类(verify-agent)。 */\nexport function isVerifyAgent(subagentType: string | null): boolean {\n if (!subagentType) return false\n return VERIFY_AGENTS.has(subagentType.toLowerCase())\n}\n\n/**\n * 把一个 agent subagent_type 分桶到四步之一(不含 commit,commit 由 timeline\n * commit 事件单独成桶)。未匹配任何已知步 → 兜底归 'implement'(执行类最自然),\n * 并由 caller 标 fallback=true。**确保不丢任何 spawn**:每个 spawn 必落一桶。\n */\nexport function classifyAgentStep(subagentType: string | null): {\n step: Exclude<StepKey, 'commit'>\n fallback: boolean\n} {\n if (isDecisionAgent(subagentType)) return { step: 'decision', fallback: false }\n if (isVerifyAgent(subagentType)) return { step: 'verify', fallback: false }\n if (isImplementAgent(subagentType)) return { step: 'implement', fallback: false }\n // 未知 agent 类型 → 兜底归实施步(不丢),标 fallback。\n return { step: 'implement', fallback: true }\n}\n\n// ─── Chain assembly ──────────────────────────────────────────────────────────\n\n/**\n * 后端 message_preview 的截断长度(src/web/routes/task-timeline.ts\n * COMMIT_MESSAGE_PREVIEW_LEN)。仅用于旧响应(无 message_full / message_truncated\n * 字段)的 truncated 兜底推断:preview 撑满即视为被截断。\n */\nconst COMMIT_PREVIEW_CAP = 200\n\nconst STEP_LABEL: Record<StepKey, string> = {\n decision: '决策',\n implement: '实施',\n verify: '验证',\n commit: '提交',\n}\n\n/**\n * /api/tasks/:id agentSpawns 子集(见 ai-summary/types.ts AgentSpawn)。\n * 完整 prompt(≤16KB)/ output(≤8KB)已由后端 gzip 解码 + cap。\n */\nexport interface AgentSpawnFull {\n timestamp: string\n end_timestamp: string | null\n subagent_type: string | null\n name: string | null\n description: string | null\n prompt: string | null\n prompt_length: number\n output: string | null\n output_length: number\n /**\n * 1 = 严格归属本任务(task_events 臂);0 = 时间窗兜底(session+window 臂,\n * 可能是漏 link 的孤儿或邻接任务 spawn)。后端 queryEventsByTaskIdWithFallback\n * 透传(src/web/routes/tasks.ts)。后端旧响应 / 缺字段时按严格归属 1 处理。\n */\n linked?: 0 | 1\n}\n\n/** 解析 ISO → epoch ms(无效返回 null)。 */\nfunction isoToMs(iso: string | null | undefined): number | null {\n if (!iso) return null\n const ms = new Date(iso).getTime()\n return Number.isFinite(ms) ? ms : null\n}\n\n/**\n * 把 timeline 的 agent_spawn event 匹配到 /api/tasks/:id 的完整 agentSpawn。\n * 匹配口径:subagent_type 相同 + timestamp 最近(容忍 ±2s 抖动,取绝对差最小)。\n * 匹配不到返回 undefined。\n */\nfunction matchSpawn(\n ev: Extract<TimelineEvent, { kind: 'agent_spawn' }>,\n spawns: AgentSpawnFull[],\n): AgentSpawnFull | undefined {\n const evType = (ev.subagent_type ?? '').toLowerCase()\n const evMs = isoToMs(ev.at)\n let best: AgentSpawnFull | undefined\n let bestDelta = Number.POSITIVE_INFINITY\n for (const s of spawns) {\n if ((s.subagent_type ?? '').toLowerCase() !== evType) continue\n const sMs = isoToMs(s.timestamp)\n const delta = evMs !== null && sMs !== null ? Math.abs(evMs - sMs) : Number.POSITIVE_INFINITY\n if (delta < bestDelta) {\n bestDelta = delta\n best = s\n }\n }\n return best\n}\n\n/** spawn 的耗时(ms),优先 [timestamp,end_timestamp],回退 timeline duration_ms。 */\nfunction spawnDuration(\n full: AgentSpawnFull | undefined,\n ev: Extract<TimelineEvent, { kind: 'agent_spawn' }> | undefined,\n): number | null {\n if (full) {\n const a = isoToMs(full.timestamp)\n const b = isoToMs(full.end_timestamp)\n if (a !== null && b !== null && b >= a) return b - a\n }\n return ev?.duration_ms ?? null\n}\n\ntype AgentSpawnEvent = Extract<TimelineEvent, { kind: 'agent_spawn' }>\n\n/** 完整内容取用:优先 agentSpawns 完整字段,回退 timeline preview(标 truncated)。 */\nfunction pickContent(\n full: AgentSpawnFull | undefined,\n ev: AgentSpawnEvent | undefined,\n): { prompt: string | null; output: string | null; truncated: boolean } {\n if (full && (full.prompt || full.output)) {\n return { prompt: full.prompt ?? null, output: full.output ?? null, truncated: false }\n }\n if (ev) {\n return {\n prompt: ev.prompt_preview || null,\n output: ev.output_preview || null,\n truncated: true,\n }\n }\n return { prompt: null, output: null, truncated: false }\n}\n\n/** 把一个 timeline agent_spawn event → 完整 StepAgentEntry(匹配 agentSpawns 补全完整内容)。 */\nfunction spawnToEntry(ev: AgentSpawnEvent, agentSpawns: AgentSpawnFull[], fallback: boolean): StepAgentEntry {\n const full = matchSpawn(ev, agentSpawns)\n const content = pickContent(full, ev)\n const isVerify = isVerifyAgent(ev.subagent_type)\n // adjacent = 匹配到的完整 spawn linked===0(时间窗兜底,疑似邻接任务)。匹配不到\n // 完整 spawn(无 linked 信息)→ 按严格归属处理(false)。\n const adjacent = full?.linked === 0\n return {\n actor: ev.subagent_type ?? '(unknown)',\n at: ev.at ?? null,\n durationMs: spawnDuration(full, ev),\n fullPrompt: content.prompt,\n fullOutput: content.output,\n verdict: isVerify ? parseVerifyVerdict(content.output ?? ev.output_preview) : null,\n commit: null,\n commitMessage: null,\n truncated: content.truncated,\n fallback,\n adjacent,\n bestEffort: false,\n }\n}\n\nconst cmpAt = (a: { at: string | null }, b: { at: string | null }) =>\n (isoToMs(a.at) ?? 0) - (isoToMs(b.at) ?? 0)\n\n/** 严格归属(adjacent=false)的 entry 数 —— 主计数口径。 */\nconst strictCountOf = (entries: StepAgentEntry[]) => entries.filter(e => !e.adjacent).length\n/** 疑似邻接(adjacent=true,linked=0 兜底)的 entry 数。 */\nconst adjacentCountOf = (entries: StepAgentEntry[]) => entries.filter(e => e.adjacent).length\n\n/**\n * 按 actor 分组计数生成 Steps 副标题用的紧凑摘要(仅严格归属 entry)。\n * 关键修复(decision 97b89eaf):一步可有多种 actor(决策步 decision-maker + planner、\n * 实施步 coder + safety-net-implementer),旧版「`${actor} ×${strictCount}`」把混合错\n * 拼成「decision-maker ×2」——实为 decision-maker ×1 + planner ×1。本函数按 actor 分组:\n * 单 actor 单条 → `decision-maker`;单 actor 多条 → `coder ×3`;\n * 多 actor → `decision-maker + planner` / `coder ×3 + planner`。\n * 分组按数量降序、同数按首次出现序(稳定),不同 actor 用 ` + ` 连接。无严格归属 → null。\n */\nfunction actorSummaryOf(entries: StepAgentEntry[]): string | null {\n const strict = entries.filter(e => !e.adjacent)\n if (strict.length === 0) return null\n // 保留首次出现序,便于同数稳定排序。\n const order = new Map<string, number>()\n const counts = new Map<string, number>()\n let seq = 0\n for (const e of strict) {\n if (!order.has(e.actor)) order.set(e.actor, seq++)\n counts.set(e.actor, (counts.get(e.actor) ?? 0) + 1)\n }\n const parts = [...counts.entries()]\n .sort((a, b) => b[1] - a[1] || (order.get(a[0]) ?? 0) - (order.get(b[0]) ?? 0))\n .map(([actor, n]) => (n > 1 ? `${actor} ×${n}` : actor))\n return parts.join(' + ')\n}\n\n/**\n * 从 timeline events + /api/tasks/:id agentSpawns 装配①决策②实施③验证④提交四步链路。\n *\n * 核心改造(decision 5fb088f9):每步收集「全部」归属该步的 spawn / commit,不再单挑\n * 一个。分桶口径(确保不丢任何 spawn,总数对得上 agentSpawns event 数):\n * 决策 → decision-maker / planner 类 agent_spawn(+ decision_resolved 事件供 id/status)\n * 实施 → isImplementAgent 命中(coder / safety-net-implementer / general-purpose /\n * harness-* / *implementer / *refactor),**外加未匹配任何已知步的未知 agent\n * 类型**(兜底归此步并标 fallback=true,确保零丢失)\n * 验证 → verify-agent 类 agent_spawn(每条 verdict 从完整 output 解析)\n * 提交 → 所有 commit 事件(不止最后一个)\n *\n * 完整内容(零后端):每个 agent entry 把 timeline event 匹配到 agentSpawns 的完整\n * prompt/output;匹配不到时回退 timeline 的 *_preview 并标 truncated=true。\n *\n * 向后兼容:scalar 字段(actor / fullPrompt / verdict / commit / ...)取「主 entry」\n * (实施/验证 = 最后一个,决策 = decision-maker,提交 = 最后一个 commit),既有\n * 单 agent 渲染 / 测试不破。\n *\n * 缺步策略:四步恒定渲染(保持链路结构感);无 entry 的步 present=false(灰显)。\n */\nexport function buildChain(\n events: TimelineEvent[],\n agentSpawns: AgentSpawnFull[] = [],\n): ChainStep[] {\n const spawns = events.filter((e): e is AgentSpawnEvent => e.kind === 'agent_spawn')\n const decisions = events.filter(\n (e): e is Extract<TimelineEvent, { kind: 'decision_resolved' }> =>\n e.kind === 'decision_resolved',\n )\n const commits = events.filter(\n (e): e is Extract<TimelineEvent, { kind: 'commit' }> => e.kind === 'commit',\n )\n\n // 把每个 spawn 分桶到 decision / implement / verify(不丢任何 spawn)。\n const decisionEntries: StepAgentEntry[] = []\n const implementEntries: StepAgentEntry[] = []\n const verifyEntries: StepAgentEntry[] = []\n for (const ev of spawns) {\n const { step, fallback } = classifyAgentStep(ev.subagent_type)\n const entry = spawnToEntry(ev, agentSpawns, fallback)\n if (step === 'decision') decisionEntries.push(entry)\n else if (step === 'verify') verifyEntries.push(entry)\n else implementEntries.push(entry)\n }\n decisionEntries.sort(cmpAt)\n implementEntries.sort(cmpAt)\n verifyEntries.sort(cmpAt)\n\n // commit entries(保序,timeline 已按时间)。完整 commit message 优先取后端\n // additive 的 message_full(≤8KB,decision 638e2ebd);旧响应无该字段时回退\n // message_preview(200 字)并标 truncated。truncated 口径:后端 message_truncated\n // (cap 命中)为准;缺该字段时回退「用的是 preview 而非 full」推断。\n const commitEntries: StepAgentEntry[] = commits.map(c => {\n const hasFull = typeof c.message_full === 'string'\n const message = (hasFull ? c.message_full : c.message_preview) || null\n const truncated = hasFull ? c.message_truncated === true : c.message_preview.length >= COMMIT_PREVIEW_CAP\n return {\n actor: 'commit',\n at: c.at ?? null,\n durationMs: null,\n fullPrompt: null,\n fullOutput: null,\n verdict: null,\n commit: c.hash,\n commitMessage: message,\n truncated,\n fallback: false,\n adjacent: false,\n bestEffort: c.attribution === 'best-effort',\n }\n })\n\n const decisionEv = decisions[0]\n const lastCommit = commitEntries[commitEntries.length - 1]\n\n // ── 决策步 ──\n const decisionPrimary = decisionEntries.find(e => e.actor.toLowerCase() === 'decision-maker')\n ?? decisionEntries[0]\n const decisionAt = decisionEv?.at ?? decisionPrimary?.at ?? null\n const decisionActor = decisionPrimary?.actor ?? (decisionEv ? 'decision-maker' : null)\n const decisionPresent = decisionEntries.length > 0 || !!decisionEv\n const decisionDetail = describeStep('决策', decisionEntries, {\n decisionEv,\n empty: '本任务未记录决策步骤(可能为元任务 / 纯确认 / skip decision)。',\n })\n\n // ── 实施步 ──\n const implementPrimary = implementEntries[implementEntries.length - 1]\n const implementDetail = describeStep('实施', implementEntries, {\n empty: '本任务未记录实施 agent 委托。',\n })\n\n // ── 验证步 ──\n const verifyPrimary = verifyEntries[verifyEntries.length - 1]\n const verdict = verifyPrimary?.verdict ?? null\n const verifyDetail = verifyEntries.length > 0\n ? verifyEntries.length === 1\n ? `verify-agent 裁决:${verdict ?? '未解析出 verdict'}(完整报告见下方)。`\n : `${verifyEntries.length} 个 verify-agent 验证(最终裁决 ${verdict ?? '未解析'};逐条报告见下方)。`\n : '本任务未记录 verify-agent 验证步骤。'\n\n // ── 提交步 ──\n const commitDetail = commitEntries.length > 0\n ? commitEntries.length === 1\n ? `提交 ${lastCommit.commit}。`\n : `${commitEntries.length} 个提交(最终 ${lastCommit.commit};逐条见下方)。`\n : '未产生提交(验证未通过 / 无代码改动)。'\n\n return [\n {\n key: 'decision',\n label: STEP_LABEL.decision,\n entries: decisionEntries,\n actor: decisionActor,\n actorSummary: actorSummaryOf(decisionEntries),\n at: decisionAt,\n verdict: null,\n commit: null,\n present: decisionPresent,\n detail: decisionDetail,\n fullPrompt: decisionPrimary?.fullPrompt ?? null,\n fullOutput: decisionPrimary?.fullOutput ?? null,\n durationMs: decisionPrimary?.durationMs ?? null,\n decisionId: decisionEv?.decision_id ?? null,\n decisionStatus: decisionEv?.status ?? null,\n commitMessage: null,\n truncated: decisionPrimary?.truncated ?? false,\n agentCount: decisionEntries.length,\n strictCount: strictCountOf(decisionEntries),\n adjacentCount: adjacentCountOf(decisionEntries),\n },\n {\n key: 'implement',\n label: STEP_LABEL.implement,\n entries: implementEntries,\n actor: implementPrimary?.actor ?? null,\n actorSummary: actorSummaryOf(implementEntries),\n at: implementEntries[0]?.at ?? null,\n verdict: null,\n commit: null,\n present: implementEntries.length > 0,\n detail: implementDetail,\n fullPrompt: implementPrimary?.fullPrompt ?? null,\n fullOutput: implementPrimary?.fullOutput ?? null,\n durationMs: implementPrimary?.durationMs ?? null,\n decisionId: null,\n decisionStatus: null,\n commitMessage: null,\n truncated: implementPrimary?.truncated ?? false,\n agentCount: implementEntries.length,\n strictCount: strictCountOf(implementEntries),\n adjacentCount: adjacentCountOf(implementEntries),\n },\n {\n key: 'verify',\n label: STEP_LABEL.verify,\n entries: verifyEntries,\n actor: verifyPrimary?.actor ?? null,\n actorSummary: actorSummaryOf(verifyEntries),\n at: verifyEntries[0]?.at ?? null,\n verdict,\n commit: null,\n present: verifyEntries.length > 0,\n detail: verifyDetail,\n fullPrompt: verifyPrimary?.fullPrompt ?? null,\n fullOutput: verifyPrimary?.fullOutput ?? null,\n durationMs: verifyPrimary?.durationMs ?? null,\n decisionId: null,\n decisionStatus: null,\n commitMessage: null,\n truncated: verifyPrimary?.truncated ?? false,\n agentCount: verifyEntries.length,\n strictCount: strictCountOf(verifyEntries),\n adjacentCount: adjacentCountOf(verifyEntries),\n },\n {\n key: 'commit',\n label: STEP_LABEL.commit,\n entries: commitEntries,\n actor: lastCommit ? 'commit' : null,\n actorSummary: actorSummaryOf(commitEntries),\n at: commitEntries[0]?.at ?? null,\n verdict: null,\n commit: lastCommit?.commit ?? null,\n present: commitEntries.length > 0,\n detail: commitDetail,\n fullPrompt: null,\n fullOutput: null,\n durationMs: null,\n decisionId: null,\n decisionStatus: null,\n commitMessage: lastCommit?.commitMessage ?? null,\n truncated: lastCommit?.truncated ?? false,\n agentCount: commitEntries.length,\n strictCount: strictCountOf(commitEntries),\n adjacentCount: adjacentCountOf(commitEntries),\n },\n ]\n}\n\n/** 生成步骤一行式摘要(多 agent 时含数量 + 各 actor 计数)。 */\nfunction describeStep(\n label: string,\n entries: StepAgentEntry[],\n opts: {\n empty: string\n decisionEv?: Extract<TimelineEvent, { kind: 'decision_resolved' }>\n },\n): string {\n if (entries.length === 0) {\n if (opts.decisionEv) return `决策 #${opts.decisionEv.decision_id} 已 ${opts.decisionEv.status}。`\n return opts.empty\n }\n // 按 actor 计数(coder ×8、planner ×2)。\n const counts = new Map<string, number>()\n for (const e of entries) counts.set(e.actor, (counts.get(e.actor) ?? 0) + 1)\n const parts = [...counts.entries()].map(([a, n]) => (n > 1 ? `${a} ×${n}` : a))\n const prefix = opts.decisionEv ? `决策 #${opts.decisionEv.decision_id} 已 ${opts.decisionEv.status};` : ''\n if (entries.length === 1) {\n return `${prefix}${parts[0]} 执行(完整 prompt / 产出见下方)。`\n }\n return `${prefix}${label}步共 ${entries.length} 个执行单元:${parts.join('、')}(逐条见下方)。`\n}\n\n// ─── Changed files / commits ─────────────────────────────────────────────────\n\nconst BUCKET_ORDER: Array<keyof ArtifactsBucket> = [\n 'code',\n 'spec',\n 'changelog',\n 'template',\n 'archive',\n]\n\n/** 扁平化 artifacts buckets → 改动文件列表(code 优先,去重已由后端保证桶内唯一)。 */\nexport function deriveChangedFiles(artifacts: ArtifactsBucket | undefined): ChangedFile[] {\n if (!artifacts) return []\n const out: ChangedFile[] = []\n for (const bucket of BUCKET_ORDER) {\n for (const path of artifacts[bucket] ?? []) {\n out.push({ path, bucket })\n }\n }\n return out\n}\n\n/** timeline commit events → commit 行(保序)。 */\nexport function deriveCommits(events: TimelineEvent[]): CommitRow[] {\n return events\n .filter((e): e is Extract<TimelineEvent, { kind: 'commit' }> => e.kind === 'commit')\n .map(e => ({ hash: e.hash, message: e.message_preview }))\n}\n\n// ─── Issues ──────────────────────────────────────────────────────────────────\n\n/** timeline daemon_enforce events → 问题行(deny/warn)。dry_run 已被后端过滤。 */\nexport function deriveIssues(events: TimelineEvent[]): IssueRow[] {\n return events\n .filter(\n (e): e is Extract<TimelineEvent, { kind: 'daemon_enforce' }> => e.kind === 'daemon_enforce',\n )\n .map((e, i) => ({\n id: `${e.at}-${e.rule_id}-${i}`,\n rule_id: e.rule_id,\n tool: e.tool,\n decision: e.decision,\n hint: e.hint,\n at: e.at,\n }))\n}\n\n// ─── Used resources(用了什么)────────────────────────────────────────────────\n\nexport interface UsedSkill {\n skill_id: string\n reason: string\n /** 0..3(★ 满分 3);payload 无 usefulness 时为 null(不渲染 ★)。 */\n usefulness: number | null\n}\n\n/**\n * 「用了什么」里的一条 KB 主动 pull(decision 93b3075b)。接 /api/tasks/:id 的\n * kbPulls[](该任务执行窗内 agent 真实拉取)。Phase 2a 曾把 KB pull 维度硬编为\n * 「无主动 pull」降级占位(payload 无 kb_query_log 维度),现接真实数据。\n */\nexport interface UsedKbPull {\n /** KB page/topic(如 modules/web)。 */\n name: string\n /** verbatim reason(如 safetynet/kb-precedent);无 → null。 */\n reason: string | null\n /** 0..3 ★(helped=3/partial=2/not-actionable=1);未评 → null(不渲 ★)。 */\n usefulness: number | null\n /** epoch ms(无 → null)。 */\n ts: number | null\n}\n\nexport interface UsedResources {\n /** KB 主动 pull —— 接 /api/tasks/:id kbPulls[](真实数据,decision 93b3075b);真无则 []。 */\n kbPulls: UsedKbPull[]\n skills: UsedSkill[]\n /** Agent 委托:去重的 subagent_type 列表。 */\n agents: string[]\n}\n\ninterface SkillInvocationLike {\n skill_id: string\n reason: string\n usefulness?: string | number | null\n}\n\ninterface AgentSpawnLike {\n subagent_type: string | null\n}\n\n/** /api/tasks/:id kbPulls[] 子集(decision 93b3075b)。 */\nexport interface KbPullLike {\n page: string\n reason?: string | null\n usefulness?: string | number | null\n ts?: number | null\n}\n\n/** usefulness 文本(helped/partial/not-actionable)→ ★ 数(3/1.5→2/0)。 */\nfunction usefulnessToStars(u: string | number | null | undefined): number | null {\n if (u === null || u === undefined || u === '') return null\n if (typeof u === 'number') return u\n const s = String(u).toLowerCase()\n if (s === 'helped') return 3\n if (s === 'partial') return 2\n if (s === 'not-actionable') return 1\n return null\n}\n\n/**\n * 装配「用了什么」:KB 主动 pull(task 详情 kbPulls,decision 93b3075b)+ Skill 调用\n * (skillInvocations)+ Agent 委托(agentSpawns 去重 subagent_type)。\n *\n * KB pull 接真实数据:kbPulls 入参为 /api/tasks/:id 的 kbPulls[](该任务执行窗内\n * agent 真实拉取的 KB,由后端 project+时间窗+reason scope)。usefulness 文本 →\n * ★(helped=3/partial=2/not-actionable=1)。kbPulls 缺省(旧后端无字段)→ [] →\n * UI 仍显「无主动 pull」(真无主动 pull 时也是 [])。\n */\nexport function deriveUsedResources(\n skillInvocations: SkillInvocationLike[] | undefined,\n agentSpawns: AgentSpawnLike[] | undefined,\n kbPulls?: KbPullLike[] | undefined,\n): UsedResources {\n const skills: UsedSkill[] = (skillInvocations ?? []).map(s => ({\n skill_id: s.skill_id,\n reason: s.reason,\n usefulness: usefulnessToStars(s.usefulness),\n }))\n const agentSet = new Set<string>()\n for (const a of agentSpawns ?? []) {\n if (a.subagent_type) agentSet.add(a.subagent_type)\n }\n const kb: UsedKbPull[] = (kbPulls ?? []).map(k => ({\n name: k.page,\n reason: k.reason ?? null,\n usefulness: usefulnessToStars(k.usefulness),\n ts: typeof k.ts === 'number' ? k.ts : null,\n }))\n return { kbPulls: kb, skills, agents: [...agentSet] }\n}\n\n// ─── Per-turn human input(逐轮人工输入,decision ed5c3e93)─────────────────────\n\n/**\n * 一条「逐轮人工输入」视图模型。从 timeline 的 user_prompt 事件派生。\n * 真人工(isHuman)连续编「第 K 轮」;机器回灌(`<task-notification>` 等)\n * isHuman:false、roundNo:null,折叠进「N 条系统回灌」可展开区(不丢弃、可审计)。\n */\nexport interface UserPromptRound {\n /** ISO timestamp(events.timestamp)。 */\n at: string\n /** 明文 prompt(≤1000 字,后端已 slice)。 */\n text: string\n /** classifyPromptKind === 'user' → 真人工。 */\n isHuman: boolean\n /** 分类标签(来自后端 kind_label;缺省视为 'user')。 */\n kind: PromptKindLabel\n /** 仅真人工按出现序从 1 连续编号(第 K 轮);机器回灌 → null。 */\n roundNo: number | null\n /** 跨轮关联:来自哪个 per-prompt task(后端 task_id);缺省 null。 */\n taskId: string | null\n /** UserPromptSubmit 事件 id(去重 / key 用);缺省 null。 */\n eventId: string | null\n}\n\n/**\n * 把 timeline 的所有 user_prompt 事件派生成「逐轮人工输入」列表(decision\n * ed5c3e93,纯函数,可 node 单测)。\n *\n * 口径:\n * - 过滤 kind==='user_prompt',按 `at` 升序(稳定排序)。\n * - isHuman = kind_label==='user'(缺 kind_label 的旧响应保守视为 'user'/人工,\n * 单源口径在后端 classifyPromptKind,前端零重复判定逻辑)。\n * - roundNo:仅对 isHuman 的条目按出现序从 1 递增;机器回灌(agent-callback /\n * image / system)→ null,不占编号。\n * - 去重防御:按 event_id 再去一次重(后端已去,双保险);无 event_id 的不去重。\n */\nexport function deriveUserPromptRounds(events: TimelineEvent[]): UserPromptRound[] {\n const prompts = events\n .filter((e): e is Extract<TimelineEvent, { kind: 'user_prompt' }> => e.kind === 'user_prompt')\n .slice()\n .sort((a, b) => (a.at < b.at ? -1 : a.at > b.at ? 1 : 0))\n\n const seen = new Set<string>()\n const out: UserPromptRound[] = []\n let roundCounter = 0\n for (const e of prompts) {\n if (e.event_id) {\n if (seen.has(e.event_id)) continue\n seen.add(e.event_id)\n }\n const kind: PromptKindLabel = e.kind_label ?? 'user'\n const isHuman = kind === 'user'\n out.push({\n at: e.at,\n text: e.text,\n isHuman,\n kind,\n roundNo: isHuman ? ++roundCounter : null,\n taskId: e.task_id ?? null,\n eventId: e.event_id ?? null,\n })\n }\n return out\n}\n\n// ─── Related decision link ───────────────────────────────────────────────────\n\n/**\n * 从 timeline 抽取关联决策 id(第一个 decision_resolved),供页头 + 概要链到\n * /decisions/:id(详情页 Phase 3 才做,先留链接)。无则 null。\n */\nexport function deriveRelatedDecisionId(events: TimelineEvent[]): string | null {\n const d = events.find(\n (e): e is Extract<TimelineEvent, { kind: 'decision_resolved' }> =>\n e.kind === 'decision_resolved',\n )\n return d?.decision_id ?? null\n}\n\n/**\n * 跨 N 轮工作流标注派生(decision c425f26f, Batch 2)。从 timeline.workflow 元数据\n * 算出页头是否该标「跨 N 轮工作流(按 decision #XXXX 聚合)」。\n *\n * 口径:\n * - crossRound = aggregated && turn_count > 1(真跨多 task 才标,单轮聚合不标)。\n * - taskCount = turn_count(跨几轮的 N)。\n * - decisionId = workflow.decision_id(聚合锚点;无 → null)。\n * 旧响应 / 无 decision_id 的 task(workflow 缺省或 aggregated=false)→ crossRound=false,\n * 维持单轮展示无标注。\n */\nexport function deriveWorkflowSpan(timeline: TimelineResponse | undefined | null): {\n crossRound: boolean\n taskCount: number\n decisionId: string | null\n /**\n * 聚合来源(decision f47c2c90, 二期B)。'decision_id' = 一期A 精确聚合;\n * 'parent_task' = 二期B 按任务链路保守推断聚合(UI 应标「按任务链路推断聚合」+\n * 不精确小字);null = 单 task / 未聚合 / 旧响应。\n */\n source: 'decision_id' | 'parent_task' | null\n} {\n const wf = timeline?.workflow\n if (!wf || !wf.aggregated) {\n return {\n crossRound: false,\n taskCount: 1,\n decisionId: wf?.decision_id ?? null,\n source: wf?.source ?? null,\n }\n }\n return {\n crossRound: wf.turn_count > 1,\n taskCount: wf.turn_count,\n decisionId: wf.decision_id,\n // 旧后端 aggregated=true 但无 source 字段时:有 decision_id 视为 'decision_id',\n // 否则视为 'parent_task'(与后端互斥契约一致)。\n source: wf.source ?? (wf.decision_id ? 'decision_id' : 'parent_task'),\n }\n}\n\n/**\n * 决策步是否应展示「仅 decision_resolved(无 spawn)」的合法 entry 卡片\n * (decision 70bb11bd)。bypass(skip decision)任务的真实情形:决策步有\n * decision_resolved 事件(→ present + decisionId)但无任何 agent spawn(entries 空)。\n * 此时该步是合法决策记录,应正向展示 + 链到 /decisions/:id,而非道歉式「无内容」。\n * 有 decision-maker spawn 的正常 BMAD 任务(entries>0)走逐条完整内容展示,不触发此卡片。\n */\nexport function shouldShowDecisionResolvedEntry(step: ChainStep): boolean {\n return (\n step.key === 'decision' &&\n step.present &&\n step.entries.length === 0 &&\n !!step.decisionId\n )\n}\n\n/**\n * Arco Steps 的视觉 status(decision 70bb11bd)。**不**用 `'error'`——它会把整步涂成\n * 实心大红块,刺眼且与其它步视觉不协调。FAIL / PARTIAL 等 verdict 改由步标题旁的小\n * Tag 表达,step 本身一律 `'finish'`(已发生)/ `'wait'`(缺步)。\n */\nexport function stepVisualStatus(step: ChainStep): 'finish' | 'wait' {\n return step.present ? 'finish' : 'wait'\n}\n\n/** 耗时格式化:start/end ISO → \"1m23s\" / \"进行中\"。 */\nexport function formatDuration(startTime: string, endTime: string | null | undefined): string {\n if (!endTime) return '进行中'\n const ms = new Date(endTime).getTime() - new Date(startTime).getTime()\n if (!Number.isFinite(ms) || ms < 0) return '—'\n const sec = Math.round(ms / 1000)\n if (sec < 60) return `${sec}s`\n const m = Math.floor(sec / 60)\n const s = sec % 60\n if (m < 60) return s ? `${m}m${s}s` : `${m}m`\n const h = Math.floor(m / 60)\n return `${h}h${m % 60}m`\n}\n","/**\n * useTaskDetail — 任务详情整页 (Phase 2a, decision 29688066) 取数 hook。\n *\n * 并行拉两个现有端点(react-query,零新后端):\n * GET /api/tasks/:id → 任务概要 / 原始 prompt / skill 调用 / agent 委托\n * GET /api/tasks/:id/timeline → 执行链路 events + artifacts buckets\n *\n * 取数后调 task-detail-derive.ts 纯函数装配视图模型(chain / 改动文件 / commits /\n * 用了什么 / 问题 / 关联决策)。页面组件只渲染派生结果。\n */\nimport { useQuery } from '@tanstack/react-query'\n\nimport type { TaskDetailData } from '../components/ai-summary/types'\nimport {\n buildChain,\n deriveChangedFiles,\n deriveCommits,\n deriveIssues,\n deriveUsedResources,\n deriveRelatedDecisionId,\n deriveWorkflowSpan,\n deriveUserPromptRounds,\n type TimelineResponse,\n type ChainStep,\n type ChangedFile,\n type CommitRow,\n type IssueRow,\n type UsedResources,\n type UserPromptRound,\n} from './task-detail-derive'\n\nasync function fetchTaskDetail(taskId: string): Promise<TaskDetailData> {\n const res = await fetch(`/api/tasks/${taskId}`)\n if (!res.ok) throw new Error(`Failed to fetch task detail (${res.status})`)\n const raw = await res.json()\n return {\n ...raw.task,\n userPrompts: raw.userPrompts ?? [],\n injections: raw.injections ?? [],\n timeline: raw.timeline ?? [],\n skillInvocations: raw.skillInvocations ?? [],\n kbPulls: raw.kbPulls ?? [],\n artifacts: raw.artifacts ?? [],\n pendingSpecs: raw.pendingSpecs ?? [],\n agentSpawns: raw.agentSpawns ?? [],\n }\n}\n\nasync function fetchTaskTimeline(taskId: string): Promise<TimelineResponse> {\n const res = await fetch(`/api/tasks/${taskId}/timeline`)\n if (!res.ok) throw new Error(`Failed to fetch task timeline (${res.status})`)\n return res.json()\n}\n\nexport interface TaskDetailViewModel {\n detail: TaskDetailData\n timeline: TimelineResponse\n chain: ChainStep[]\n changedFiles: ChangedFile[]\n commits: CommitRow[]\n issues: IssueRow[]\n used: UsedResources\n /** 逐轮人工输入(decision ed5c3e93)。真人工编「第 K 轮」,机器回灌折叠展示。 */\n userPromptRounds: UserPromptRound[]\n relatedDecisionId: string | null\n /** 跨 N 轮工作流标注(decision c425f26f Batch 2 + f47c2c90 二期B)。 */\n workflowSpan: {\n crossRound: boolean\n taskCount: number\n decisionId: string | null\n source: 'decision_id' | 'parent_task' | null\n }\n}\n\nexport function useTaskDetail(taskId: string | undefined) {\n const detailQ = useQuery({\n queryKey: ['task-detail-page', taskId],\n queryFn: () => fetchTaskDetail(taskId!),\n enabled: !!taskId,\n refetchInterval: 15000,\n })\n\n const timelineQ = useQuery({\n queryKey: ['task-detail-timeline', taskId],\n queryFn: () => fetchTaskTimeline(taskId!),\n enabled: !!taskId,\n refetchInterval: 15000,\n })\n\n const isLoading = detailQ.isLoading || timelineQ.isLoading\n const error = detailQ.error || timelineQ.error\n\n let vm: TaskDetailViewModel | null = null\n if (detailQ.data && timelineQ.data) {\n const events = timelineQ.data.events\n vm = {\n detail: detailQ.data,\n timeline: timelineQ.data,\n chain: buildChain(events, detailQ.data.agentSpawns),\n changedFiles: deriveChangedFiles(timelineQ.data.artifacts),\n commits: deriveCommits(events),\n issues: deriveIssues(events),\n used: deriveUsedResources(detailQ.data.skillInvocations, detailQ.data.agentSpawns, detailQ.data.kbPulls),\n userPromptRounds: deriveUserPromptRounds(events),\n relatedDecisionId: deriveRelatedDecisionId(events),\n workflowSpan: deriveWorkflowSpan(timelineQ.data),\n }\n }\n\n return {\n vm,\n isLoading,\n error: error as Error | null,\n refetch: () => {\n void detailQ.refetch()\n void timelineQ.refetch()\n },\n }\n}\n","/**\n * TaskDetailPage — 任务详情整页 (Phase 2a, decision 29688066).\n *\n * 替换 `/tasks/:taskId` 的占位组件。把原型「任务详情整页」翻译成真 Arco\n * 组件(**严禁直搬原型 Tailwind CSS**):\n * A. 页头横条:标题 + outcome Tag + 元信息(项目/耗时/时间/task-id/关联决策链接)+ 操作按钮\n * B. 横向 Arco Steps 执行链路:①决策 ②实施 ③验证(PASS/FAIL/PARTIAL) ④提交,点步展开细节\n * C. 左右双栏:左 = 原始 prompt + 改动文件 + commits;右 = 概要(Descriptions) +\n * 用了什么(KB pull / Skill ★ / Agent) + 问题\n *\n * 数据全部接真实端点(GET /api/tasks/:id + GET /api/tasks/:id/timeline),取数 +\n * 派生在 useTaskDetail / task-detail-derive,本组件只渲染。关联决策链到\n * /decisions/:id(详情页 Phase 3 才做,先留链接)。\n */\nimport type { ReactNode } from 'react'\nimport { useState } from 'react'\nimport { useParams, useNavigate, Link } from 'react-router-dom'\n\nimport Card from '@arco-design/web-react/es/Card'\nimport Grid from '@arco-design/web-react/es/Grid'\nimport Steps from '@arco-design/web-react/es/Steps'\nimport Tag from '@arco-design/web-react/es/Tag'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport Descriptions from '@arco-design/web-react/es/Descriptions'\nimport Button from '@arco-design/web-react/es/Button'\nimport Empty from '@arco-design/web-react/es/Empty'\nimport Skeleton from '@arco-design/web-react/es/Skeleton'\nimport Result from '@arco-design/web-react/es/Result'\nimport Collapse from '@arco-design/web-react/es/Collapse'\nimport Space from '@arco-design/web-react/es/Space'\nimport {\n IconLeft,\n IconFile,\n IconCode,\n IconBranch,\n IconBook,\n IconRobot,\n IconStarFill,\n IconCheckCircle,\n IconExclamationCircle,\n IconClockCircle,\n IconLink,\n} from '@arco-design/web-react/icon'\n\nimport MarkdownRenderer from '../components/MarkdownRenderer'\nimport { useTaskDetail } from '../hooks/useTaskDetail'\nimport {\n formatDuration,\n stepVisualStatus,\n shouldShowDecisionResolvedEntry,\n parseAgentOutput,\n type ChainStep,\n type ChangedFile,\n type StepAgentEntry,\n type UserPromptRound,\n} from '../hooks/task-detail-derive'\nimport { normalizeTaskTitle } from '../utils/task-title'\nimport { parseUTC } from '../utils/time'\nimport { format } from 'date-fns'\n\nconst Row = Grid.Row\nconst Col = Grid.Col\nconst Step = Steps.Step\nconst CollapseItem = Collapse.Item\n\n/** 耗时(ms)→ 人读 \"1.2s\" / \"850ms\" / \"2m3s\"。null → null。 */\nfunction formatMs(ms: number | null): string | null {\n if (ms === null || !Number.isFinite(ms) || ms < 0) return null\n if (ms < 1000) return `${ms}ms`\n const sec = ms / 1000\n if (sec < 60) return `${sec.toFixed(1)}s`\n const m = Math.floor(sec / 60)\n const s = Math.round(sec % 60)\n return s ? `${m}m${s}s` : `${m}m`\n}\n\n/**\n * 长文本可滚动 Markdown 块(完整 prompt / output / commit message)。\n *\n * 内容(agent prompt / 产出 / commit message)几乎都是 markdown(`**粗体**`、\n * `## 标题`、`` `code` ``、列表、`<!-- 注释 -->`)。用复用的 `MarkdownRenderer`\n * 渲染(react-markdown + remark-gfm,**禁 raw HTML**:无 rehype-raw、无\n * dangerouslySetInnerHTML——agent 输出不可信,安全第一;链接默认 rel noopener;\n * 代码块/行内 code 等宽 + 浅底)。非 markdown 内容(JSON blob / 纯文本)优雅降级\n * 为段落,不报错、不丢内容。外层保持可滚动 + 高度上限,长内容不撑爆。\n */\nfunction ScrollBlock({ text, maxHeight = 360 }: { text: string; maxHeight?: number }) {\n return (\n <div\n style={{\n background: 'var(--color-fill-1)',\n border: '1px solid var(--color-border-2)',\n borderRadius: 4,\n padding: '4px 12px',\n maxHeight,\n overflow: 'auto',\n wordBreak: 'break-word',\n color: 'var(--color-text-1)',\n }}\n >\n <MarkdownRenderer content={text} />\n </div>\n )\n}\n\n/**\n * 智能产出块(decision deb6e2f3):agent 产出常是「JSON 信封 + 某字段装 markdown\n * 正文」,整坨当 md 渲染会把括号 / key / 转义和正文混一起很乱。这里用纯函数\n * `parseAgentOutput` 识别三类,分区展示:\n * - `json-with-md`:抽出的 markdown 正文渲为主区(复用安全 `MarkdownRenderer`,\n * 无 raw HTML / 无 dangerouslySetInnerHTML),下方一个默认收起的「原始 JSON /\n * 完整信封」Collapse(pretty-print 经 MarkdownRenderer 的 ```json fenced 高亮)。\n * - `json`:纯结构化 JSON,pretty-print + ```json 高亮(无折叠,本身就是要看的)。\n * - `md`:纯 markdown / 纯文本(含截断信封退回)→ 照渲。\n * 全程零 dangerouslySetInnerHTML —— JSON 也走 MarkdownRenderer 的代码块高亮,安全。\n */\nfunction AgentOutputBlock({ raw, maxHeight = 360 }: { raw: string; maxHeight?: number }) {\n const parsed = parseAgentOutput(raw)\n\n const shell = (children: ReactNode) => (\n <div\n style={{\n background: 'var(--color-fill-1)',\n border: '1px solid var(--color-border-2)',\n borderRadius: 4,\n padding: '4px 12px',\n maxHeight,\n overflow: 'auto',\n wordBreak: 'break-word',\n color: 'var(--color-text-1)',\n }}\n >\n {children}\n </div>\n )\n\n if (parsed.kind === 'md') {\n return shell(<MarkdownRenderer content={parsed.markdown} />)\n }\n\n if (parsed.kind === 'json') {\n // 纯结构化 JSON:高亮 pretty-print(fenced ```json 走 MarkdownRenderer 高亮)。\n return shell(<MarkdownRenderer content={'```json\\n' + parsed.pretty + '\\n```'} />)\n }\n\n // json-with-md:主区渲抽出的 markdown 正文,下方折叠原始信封 JSON。\n return shell(\n <>\n <MarkdownRenderer content={parsed.markdown} />\n <Collapse\n bordered={false}\n defaultActiveKey={[]}\n style={{ background: 'transparent', marginTop: 4 }}\n >\n <CollapseItem\n name=\"raw-json\"\n header={\n <Space size={6}>\n <IconCode />\n <span style={{ fontSize: 12 }}>原始 JSON / 完整信封</span>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11 }}>\n 正文字段 {parsed.bodyKey} 已抽出渲染,其余结构在此\n </Typography.Text>\n </Space>\n }\n >\n <MarkdownRenderer content={'```json\\n' + parsed.pretty + '\\n```'} />\n </CollapseItem>\n </Collapse>\n </>,\n )\n}\n\n// ─── small render helpers ────────────────────────────────────────────────────\n\nfunction outcomeTag(outcome: string | null | undefined) {\n if (outcome === 'success') return <Tag color=\"green\">成功</Tag>\n if (outcome === 'partial') return <Tag color=\"orange\">部分</Tag>\n if (outcome === 'failed') return <Tag color=\"red\">失败</Tag>\n if (outcome === 'abandoned') return <Tag color=\"gray\">放弃</Tag>\n return null\n}\n\nfunction statusTag(status: string) {\n if (status === 'completed') return <Tag color=\"green\">已完成</Tag>\n if (status === 'active') return <Tag color=\"arcoblue\">进行中</Tag>\n if (status === 'abandoned') return <Tag color=\"gray\">已放弃</Tag>\n return <Tag>{status}</Tag>\n}\n\nfunction verdictTag(verdict: 'PASS' | 'FAIL' | 'PARTIAL' | null) {\n if (verdict === 'PASS') return <Tag color=\"green\" size=\"small\">PASS</Tag>\n if (verdict === 'FAIL') return <Tag color=\"red\" size=\"small\">FAIL</Tag>\n if (verdict === 'PARTIAL') return <Tag color=\"orange\" size=\"small\">PARTIAL</Tag>\n return null\n}\n\nconst BUCKET_TAG: Record<ChangedFile['bucket'], { label: string; color: string }> = {\n code: { label: '代码', color: 'arcoblue' },\n spec: { label: 'Spec', color: 'purple' },\n changelog: { label: 'Changelog', color: 'green' },\n template: { label: '模板', color: 'cyan' },\n archive: { label: '存档', color: 'gray' },\n}\n\nfunction Stars({ n }: { n: number | null }) {\n if (n === null) return null\n const full = Math.round(n)\n return (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 1 }}>\n {Array.from({ length: 3 }).map((_, i) => (\n <IconStarFill\n key={i}\n style={{ fontSize: 11, color: i < full ? 'var(--cf-tag-orange, #FF7D00)' : 'var(--color-fill-3, #E5E6EB)' }}\n />\n ))}\n </span>\n )\n}\n\n// ─── step detail panel ───────────────────────────────────────────────────────\n\n/**\n * 单个执行单元(agent spawn / commit)卡片:元信息条 + 完整 prompt / output /\n * commit message(可滚动代码块,长文用 Collapse 折叠)。\n */\nfunction StepEntryCard({\n stepKey,\n entry,\n index,\n total,\n}: {\n stepKey: ChainStep['key']\n entry: StepAgentEntry\n index: number\n total: number\n}) {\n const durationText = formatMs(entry.durationMs)\n const isCommit = entry.actor === 'commit' || stepKey === 'commit'\n const promptLabel = isCommit ? 'Commit Message' : '完整 Prompt'\n const outputLabel = stepKey === 'verify' ? '完整 verify 报告' : '完整产出 / Result'\n const promptText = isCommit ? entry.commitMessage : entry.fullPrompt\n const hasBody = !!(promptText || (!isCommit && entry.fullOutput))\n\n return (\n <div\n style={{\n border: '1px solid var(--color-border-2)',\n borderRadius: 4,\n padding: '10px 12px',\n background: 'var(--color-bg-2)',\n }}\n >\n {/* 元信息条 */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: hasBody ? 8 : 0, flexWrap: 'wrap' }}>\n {total > 1 && (\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, fontFamily: 'monospace' }}>\n #{index + 1}/{total}\n </Typography.Text>\n )}\n <Tag size=\"small\" color={isCommit ? 'gray' : 'arcoblue'} bordered icon={isCommit ? <IconBranch /> : <IconRobot />}>\n {entry.actor}\n </Tag>\n {entry.fallback && (\n <Tag size=\"small\" color=\"orange\">其它(未知 agent 类型)</Tag>\n )}\n {entry.adjacent && (\n <Tag size=\"small\" color=\"gray\" bordered>疑似邻接任务</Tag>\n )}\n {entry.at && (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n <IconClockCircle style={{ marginRight: 2 }} />\n {format(parseUTC(entry.at), 'HH:mm:ss')}\n </Typography.Text>\n )}\n {durationText && (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>耗时 {durationText}</Typography.Text>\n )}\n {entry.verdict && verdictTag(entry.verdict)}\n {entry.commit && (\n <Tag size=\"small\" icon={<IconBranch />} style={{ fontFamily: 'monospace' }}>\n {entry.commit.slice(0, 10)}\n </Tag>\n )}\n {entry.truncated && (\n <Tag size=\"small\" color=\"orange\">内容可能被截断</Tag>\n )}\n {/* commit best-effort 归因小字(decision c425f26f, Batch 2, 用户拍板 #4):\n 提交段按时间窗启发式归因,诚实标注可能不精确。 */}\n {isCommit && entry.bestEffort && (\n <Tag size=\"small\" color=\"gray\" bordered title=\"提交段按工作流时间窗 best-effort 归因,可能漏或误纳邻接 commit\">\n 提交按时间窗归因(可能不精确)\n </Tag>\n )}\n </div>\n\n {hasBody ? (\n <Collapse\n bordered={false}\n defaultActiveKey={total <= 2 ? ['prompt'] : []}\n style={{ background: 'transparent' }}\n >\n {promptText ? (\n <CollapseItem\n name=\"prompt\"\n header={\n <Space size={6}>\n <IconFile />\n <span style={{ fontSize: 13, fontWeight: 500 }}>{promptLabel}</span>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11 }}>{promptText.length} 字符</Typography.Text>\n </Space>\n }\n >\n <ScrollBlock text={promptText} />\n </CollapseItem>\n ) : null}\n {!isCommit && entry.fullOutput ? (\n <CollapseItem\n name=\"output\"\n header={\n <Space size={6}>\n <IconCode />\n <span style={{ fontSize: 13, fontWeight: 500 }}>{outputLabel}</span>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11 }}>{entry.fullOutput.length} 字符</Typography.Text>\n </Space>\n }\n >\n <AgentOutputBlock raw={entry.fullOutput} />\n </CollapseItem>\n ) : null}\n </Collapse>\n ) : null}\n </div>\n )\n}\n\n/**\n * 决策步「仅有 decision_resolved、无 decision-maker spawn」时的合法 entry 卡片\n * (decision 70bb11bd)。bypass(skip decision)任务的真实情形:决策被\n * approve/outcome 回填产生一条 decision_resolved 事件,但没有 decision-maker spawn。\n * 这是合法决策记录,正向展示 + 链到 /decisions/:id 看完整决策内容(options /\n * recommendation / Triage),而非道歉式「该步无完整执行单元可展示」措辞。\n */\nfunction DecisionResolvedEntry({\n decisionId,\n status,\n}: {\n decisionId: string\n status: string | null\n}) {\n return (\n <div\n style={{\n border: '1px solid var(--color-border-2)',\n borderRadius: 4,\n padding: '10px 12px',\n background: 'var(--color-bg-2)',\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n <Tag size=\"small\" color=\"green\" bordered icon={<IconCheckCircle />}>\n 决策已{status === 'resolved' ? '解决' : (status ?? '处理')}\n </Tag>\n <Typography.Text style={{ fontSize: 13, color: 'var(--color-text-2)' }}>\n 本任务决策 #{decisionId} 已批准 / 解决(未经 decision-maker spawn,常见于 skip decision 的快捷批准)。\n </Typography.Text>\n </div>\n <Link to={`/decisions/${decisionId}`}>\n <Button type=\"outline\" size=\"small\" icon={<IconLink />}>\n 查看完整决策内容(选项 / 推荐 / Triage)\n </Button>\n </Link>\n </div>\n )\n}\n\n/**\n * 选中步骤的丰富细节面板:步标题(含 agent 数量)+ 一行摘要 + 该步「全部」执行单元\n * 列表(每个 agent / commit 一张子卡,多 agent 时层次清楚、长列表逐条可折叠)。\n * 核心改造(decision 5fb088f9):不再只展示一个 agent —— 一步多个 agent 全展示。\n * 完整内容来自 /api/tasks/:id agentSpawns(零后端);缺失则诚实降级占位。\n */\nfunction StepDetailPanel({ stepNo, step }: { stepNo: number; step: ChainStep }) {\n return (\n <div>\n {/* 步标题条 */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10, flexWrap: 'wrap' }}>\n <Typography.Text style={{ fontWeight: 600, fontSize: 13 }}>\n 第 {stepNo} 步 · {step.label}\n </Typography.Text>\n {step.strictCount > 0 && (\n <Tag size=\"small\" color=\"arcoblue\">{step.strictCount} 个执行单元</Tag>\n )}\n {step.adjacentCount > 0 && (\n <Tag size=\"small\" color=\"gray\" bordered>+{step.adjacentCount} 疑似邻接</Tag>\n )}\n {step.key === 'verify' && verdictTag(step.verdict)}\n {step.decisionId && (\n <Link to={`/decisions/${step.decisionId}`}>\n <Tag size=\"small\" color=\"purple\" icon={<IconLink />} style={{ cursor: 'pointer' }}>\n #{step.decisionId}{step.decisionStatus ? ` · ${step.decisionStatus}` : ''}\n </Tag>\n </Link>\n )}\n </div>\n\n {/* 一行摘要 */}\n <Typography.Paragraph style={{ fontSize: 13, margin: '0 0 10px', color: 'var(--color-text-2)', whiteSpace: 'pre-wrap' }}>\n {step.detail}\n </Typography.Paragraph>\n\n {/* 该步所有执行单元(agent / commit)逐条展示 */}\n {step.entries.length > 0 ? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n {step.entries.map((entry, i) => (\n <StepEntryCard\n key={`${entry.actor}-${entry.at ?? i}-${i}`}\n stepKey={step.key}\n entry={entry}\n index={i}\n total={step.entries.length}\n />\n ))}\n </div>\n ) : (\n // 无执行单元的步。决策步常见情形:bypass(skip decision)的任务没有\n // decision-maker spawn,只有一条 decision_resolved 事件——这是**合法记录**,\n // 不是空状态/错误。把它当作正常 entry 展示,链到 /decisions/:id 看完整决策内容\n // (options / recommendation / Triage 都在那),而非道歉式「无内容」措辞\n // (decision 70bb11bd)。其它步(实施/验证/提交)无 entry 时不渲染。\n shouldShowDecisionResolvedEntry(step) && step.decisionId ? (\n <DecisionResolvedEntry decisionId={step.decisionId} status={step.decisionStatus} />\n ) : null\n )}\n </div>\n )\n}\n\n/**\n * 「人工输入(逐轮)」卡片(decision ed5c3e93)。升级自旧「原始 Prompt」单条卡。\n * 真人工逐轮列「第 K 轮 · 时间戳」+ MarkdownRenderer(禁 raw HTML);机器回灌\n * (<task-notification> 等)折叠进「N 条系统回灌」可展开区,不占轮次编号、可审计。\n * 空(无任何 user_prompt 事件)时回退旧 detail.userPrompts[0] 兜底渲染。\n */\nfunction UserPromptRoundsCard({\n rounds,\n fallback,\n}: {\n rounds: UserPromptRound[]\n fallback: string | undefined\n}) {\n const humans = rounds.filter((r) => r.isHuman)\n const machines = rounds.filter((r) => !r.isHuman)\n\n const fmtAt = (at: string) => {\n try {\n return format(parseUTC(at), 'MM-dd HH:mm:ss')\n } catch {\n return at\n }\n }\n\n const machineLabel = (kind: UserPromptRound['kind']) =>\n kind === 'agent-callback' ? 'task-notification 回灌' : kind === 'image' ? '图片附件' : '系统消息'\n\n return (\n <Card\n bordered\n title={\n <span style={{ fontSize: 14, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n <IconFile />人工输入(逐轮)\n </span>\n }\n extra={\n humans.length > 0 ? (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>{humans.length} 轮</Typography.Text>\n ) : null\n }\n >\n {humans.length > 0 ? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {humans.map((r) => (\n <div key={r.eventId ?? `${r.at}-${r.roundNo}`}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>\n <Tag color=\"arcoblue\" size=\"small\">第 {r.roundNo} 轮</Tag>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>{fmtAt(r.at)}</Typography.Text>\n </div>\n <div\n style={{\n borderLeft: '3px solid rgb(var(--arcoblue-6))',\n background: 'var(--color-fill-1)',\n padding: '4px 14px',\n borderRadius: '0 4px 4px 0',\n color: 'var(--color-text-2)',\n wordBreak: 'break-word',\n maxHeight: 320,\n overflow: 'auto',\n }}\n >\n <MarkdownRenderer content={r.text} />\n </div>\n </div>\n ))}\n </div>\n ) : fallback ? (\n // 无 user_prompt 事件但旧端点有原始 prompt → 兜底单条渲染(向后兼容)。\n <div\n style={{\n borderLeft: '3px solid rgb(var(--arcoblue-6))',\n background: 'var(--color-fill-1)',\n padding: '4px 14px',\n borderRadius: '0 4px 4px 0',\n color: 'var(--color-text-2)',\n wordBreak: 'break-word',\n maxHeight: 320,\n overflow: 'auto',\n }}\n >\n <MarkdownRenderer content={fallback} />\n </div>\n ) : (\n <Empty description=\"无人工输入(可能为元任务)\" />\n )}\n\n {machines.length > 0 && (\n <Collapse style={{ marginTop: humans.length > 0 || fallback ? 12 : 0 }}>\n <CollapseItem\n name=\"machine-refills\"\n header={\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n {machines.length} 条系统回灌({'<task-notification>'} 等,非人工输入)\n </Typography.Text>\n }\n >\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n {machines.map((r, i) => (\n <div key={r.eventId ?? `${r.at}-${i}`}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>\n <Tag color=\"gray\" size=\"small\">系统回灌</Tag>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n {machineLabel(r.kind)} · {fmtAt(r.at)}\n </Typography.Text>\n </div>\n <ScrollBlock text={r.text} maxHeight={200} />\n </div>\n ))}\n </div>\n </CollapseItem>\n </Collapse>\n )}\n </Card>\n )\n}\n\n// ─── page ────────────────────────────────────────────────────────────────────\n\nexport default function TaskDetailPage() {\n const { taskId } = useParams<{ taskId: string }>()\n const navigate = useNavigate()\n const { vm, isLoading, error } = useTaskDetail(taskId)\n // openStep 是 Arco Steps 的 1-based 步号(与 Step.index 同口径),null = 无展开。\n // current 永远给受控值 -1(无效步号 → 任何步都满足 current!==index,故步步可点、\n // 可重复点);切回 null 时给 -1 而非 undefined(undefined 会被 Arco 默认成 1,\n // 导致第 1 步点不动 + 受控失同步——这是「点击滞后/失灵」的根因)。\n const [openStep, setOpenStep] = useState<number | null>(null)\n\n if (isLoading) {\n return (\n <div style={{ padding: 16 }}>\n <Card bordered>\n <Skeleton animation text={{ rows: 8 }} />\n </Card>\n </div>\n )\n }\n\n if (error || !vm) {\n return (\n <div style={{ padding: 16 }}>\n <Result\n status=\"error\"\n title=\"加载任务详情失败\"\n subTitle={error?.message || '任务不存在或端点不可用'}\n extra={\n <Button type=\"primary\" onClick={() => navigate('/tasks')}>\n 返回任务列表\n </Button>\n }\n />\n </div>\n )\n }\n\n const { detail, chain, changedFiles, commits, issues, used, userPromptRounds, relatedDecisionId, workflowSpan } = vm\n const title = normalizeTaskTitle(detail.title, detail.userPrompts[0]?.content)\n const duration = formatDuration(detail.start_time, detail.end_time)\n const startedAt = format(parseUTC(detail.start_time), 'MM-dd HH:mm')\n\n // openStep 是 1-based 步号;chain 是 0-based 数组 → 取 openStep-1。\n const currentStep = openStep !== null ? chain[openStep - 1] ?? null : null\n\n return (\n <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 16 }}>\n {/* ── A. 页头横条 ─────────────────────────────────────────────── */}\n <Card bordered>\n <Button\n type=\"text\"\n size=\"small\"\n icon={<IconLeft />}\n style={{ marginBottom: 8, paddingLeft: 0 }}\n onClick={() => navigate('/tasks')}\n >\n 返回任务\n </Button>\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap' }}>\n <div style={{ minWidth: 0, flex: 1 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>\n <Typography.Title heading={5} style={{ margin: 0 }}>\n {title}\n </Typography.Title>\n {statusTag(detail.status)}\n {outcomeTag(detail.outcome)}\n </div>\n <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginTop: 8, alignItems: 'center' }}>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12, display: 'inline-flex', alignItems: 'center', gap: 4 }}>\n <IconClockCircle /> 耗时 {duration}\n </Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>{startedAt}</Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12, fontFamily: 'monospace' }} title={detail.id}>\n {detail.id.length > 16 ? `${detail.id.slice(0, 16)}…` : detail.id}\n </Typography.Text>\n {relatedDecisionId && (\n <Link to={`/decisions/${relatedDecisionId}`} style={{ fontSize: 12 }}>\n <Tag color=\"arcoblue\" bordered icon={<IconLink />} style={{ cursor: 'pointer' }}>\n #{relatedDecisionId}\n </Tag>\n </Link>\n )}\n </div>\n </div>\n </div>\n </Card>\n\n {/* ── B. 横向执行链路 Steps + 步下展开 ──────────────────────────── */}\n <Card\n bordered\n title={\n <span style={{ fontSize: 14, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n 执行链路\n {/* 跨 N 轮工作流标注(decision c425f26f Batch 2 + f47c2c90 二期B):四段\n 来自跨 task 聚合时诚实标注,不假装单轮。单 task / 既无 decision_id 也无\n parent 链 → 不标。decision_id 来源 = 精确聚合;parent_task 来源 = 按任务\n 链路保守推断聚合,额外标不精确小字以区别。 */}\n {workflowSpan.crossRound && (\n <Tag color=\"purple\" bordered style={{ fontWeight: 400 }}>\n 跨 {workflowSpan.taskCount} 轮工作流\n {workflowSpan.source === 'parent_task'\n ? '(按任务链路推断聚合)'\n : workflowSpan.decisionId\n ? `(按 decision #${workflowSpan.decisionId} 聚合)`\n : ''}\n </Tag>\n )}\n {workflowSpan.crossRound && workflowSpan.source === 'parent_task' && (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12, fontWeight: 400 }}>\n 无决策 ID,按 parent_task 链路保守串联,可能不完整\n </Typography.Text>\n )}\n </span>\n }\n extra={<Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>点步骤查看细节</Typography.Text>}\n >\n <Steps\n type=\"arrow\"\n current={openStep ?? -1}\n onChange={(stepIdx) => setOpenStep(prev => (prev === stepIdx ? null : stepIdx))}\n style={{ cursor: 'pointer' }}\n >\n {chain.map((step) => (\n <Step\n key={step.key}\n title={step.label}\n status={stepVisualStatus(step)}\n description={\n <span style={{ fontSize: 12, display: 'inline-flex', alignItems: 'center', gap: 4, flexWrap: 'wrap' }}>\n {step.key === 'verify' && step.verdict ? (\n verdictTag(step.verdict)\n ) : null}\n {step.actorSummary ?? step.actor ? (\n <Typography.Text type=\"secondary\" style={{ fontSize: 11 }}>\n {/* 副标题按 actor 分组计数(decision 97b89eaf):决策步混合\n decision-maker + planner 时不再错拼成「decision-maker ×2」。\n actorSummary 缺省(仅 decision_resolved 无 spawn)回退 actor。 */}\n {step.actorSummary ?? step.actor}\n {step.adjacentCount > 0 ? ` (+${step.adjacentCount})` : ''}\n </Typography.Text>\n ) : step.key === 'verify' && step.verdict ? null : (\n <Typography.Text type=\"secondary\" style={{ fontSize: 11 }}>—</Typography.Text>\n )}\n </span>\n }\n />\n ))}\n </Steps>\n <div style={{ marginTop: 12, borderTop: '1px solid var(--color-border-2)', paddingTop: 12 }}>\n {currentStep ? (\n <StepDetailPanel stepNo={openStep ?? 1} step={currentStep} />\n ) : (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 点击上方任一步骤,在此展开该步的完整 prompt / 产出 / verdict / commit 细节。\n </Typography.Text>\n )}\n </div>\n </Card>\n\n {/* ── C. 左右双栏 ─────────────────────────────────────────────── */}\n <Row gutter={16} align=\"start\">\n {/* 左主栏 */}\n <Col xs={24} xl={16} style={{ marginBottom: 16 }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n {/* 人工输入(逐轮)—— 升级自旧「原始 Prompt」卡(decision ed5c3e93)。\n 首条即原始 prompt,后续逐轮带「第 K 轮」+ 时间戳;机器回灌\n (<task-notification> 等)折叠进「N 条系统回灌」可展开区。 */}\n <UserPromptRoundsCard rounds={userPromptRounds} fallback={detail.userPrompts[0]?.content} />\n\n {/* 改动文件 + Commits */}\n <Card\n bordered\n title={<span style={{ fontSize: 14, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 6 }}><IconCode />改动文件 · Commits</span>}\n extra={<Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>{changedFiles.length} 文件 · {commits.length} commit</Typography.Text>}\n >\n {changedFiles.length > 0 ? (\n <div style={{ display: 'flex', flexDirection: 'column' }}>\n {changedFiles.map((f) => {\n const meta = BUCKET_TAG[f.bucket]\n return (\n <div\n key={f.path}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 0',\n borderBottom: '1px solid var(--color-border-1)',\n }}\n >\n <IconFile style={{ color: 'var(--color-text-3)', flexShrink: 0 }} />\n <Typography.Text code style={{ fontSize: 12, flex: 1, minWidth: 0 }} ellipsis title={f.path}>\n {f.path}\n </Typography.Text>\n <Tag size=\"small\" color={meta.color}>{meta.label}</Tag>\n </div>\n )\n })}\n </div>\n ) : (\n <Empty description=\"本任务无改动文件\" />\n )}\n\n <Typography.Text style={{ fontSize: 12, fontWeight: 500, color: 'var(--color-text-3)', display: 'block', marginTop: 16, marginBottom: 8 }}>\n Commits\n </Typography.Text>\n {commits.length > 0 ? (\n commits.map((c, i) => (\n <div key={`${c.hash}-${i}`} style={{ display: 'flex', alignItems: 'flex-start', gap: 8, padding: '6px 0', borderBottom: '1px solid var(--color-border-1)' }}>\n <IconBranch style={{ color: 'var(--color-text-3)', marginTop: 2, flexShrink: 0 }} />\n <div style={{ minWidth: 0 }}>\n <Typography.Text style={{ fontFamily: 'monospace', fontSize: 13, color: 'rgb(var(--arcoblue-6))' }}>\n {c.hash.slice(0, 10)}\n </Typography.Text>\n <Typography.Paragraph style={{ fontSize: 12, margin: '2px 0 0', color: 'var(--color-text-2)' }} ellipsis={{ rows: 2 }}>\n {c.message || '(无 message)'}\n </Typography.Paragraph>\n </div>\n </div>\n ))\n ) : (\n <Typography.Text type=\"secondary\" style={{ fontSize: 13 }}>\n 未产生提交(验证未通过 / 无代码改动)\n </Typography.Text>\n )}\n </Card>\n </div>\n </Col>\n\n {/* 右侧栏 */}\n <Col xs={24} xl={8} style={{ marginBottom: 16 }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n {/* 概要 */}\n <Card bordered title={<span style={{ fontSize: 14, fontWeight: 600 }}>概要</span>}>\n <Descriptions\n colon=\" :\"\n size=\"small\"\n column={1}\n labelStyle={{ width: 88, color: 'var(--color-text-3)' }}\n data={[\n { label: '状态', value: statusTag(detail.status) },\n { label: '结果', value: outcomeTag(detail.outcome) ?? <Typography.Text type=\"secondary\">—</Typography.Text> },\n { label: '耗时', value: duration },\n { label: '事件数', value: detail.event_count },\n { label: 'Task ID', value: <Typography.Text code style={{ fontSize: 11 }}>{detail.id}</Typography.Text> },\n {\n label: '关联决策',\n value: relatedDecisionId\n ? <Link to={`/decisions/${relatedDecisionId}`} style={{ fontFamily: 'monospace' }}>#{relatedDecisionId}</Link>\n : <Typography.Text type=\"secondary\">—</Typography.Text>,\n },\n ]}\n />\n </Card>\n\n {/* 用了什么 */}\n <Card bordered title={<span style={{ fontSize: 14, fontWeight: 600 }}>用了什么</span>}>\n <Typography.Text style={{ fontSize: 12, fontWeight: 500, color: 'var(--color-text-3)', display: 'flex', alignItems: 'center', gap: 4 }}>\n <IconBook /> KB 主动 pull\n </Typography.Text>\n {used.kbPulls.length > 0 ? (\n used.kbPulls.map((k, i) => (\n <div key={`${k.name}-${k.ts ?? i}`} style={{ padding: '3px 0' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <Typography.Text style={{ fontFamily: 'monospace', fontSize: 12 }}>{k.name}</Typography.Text>\n {k.usefulness !== null && <Stars n={k.usefulness} />}\n </div>\n {k.reason && <Typography.Text type=\"secondary\" style={{ fontSize: 11 }}>{k.reason}</Typography.Text>}\n </div>\n ))\n ) : (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12, display: 'block', padding: '2px 0' }}>无主动 pull</Typography.Text>\n )}\n\n <Typography.Text style={{ fontSize: 12, fontWeight: 500, color: 'var(--color-text-3)', display: 'flex', alignItems: 'center', gap: 4, marginTop: 12, paddingTop: 8, borderTop: '1px solid var(--color-border-1)' }}>\n <IconStarFill /> Skill(带有用性评分)\n </Typography.Text>\n {used.skills.length > 0 ? (\n used.skills.map((s) => (\n <div key={s.skill_id} style={{ padding: '3px 0' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <Typography.Text style={{ fontFamily: 'monospace', fontSize: 12 }}>{s.skill_id}</Typography.Text>\n <Stars n={s.usefulness} />\n </div>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11 }}>{s.reason}</Typography.Text>\n </div>\n ))\n ) : (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12, display: 'block', padding: '2px 0' }}>未调用 Skill</Typography.Text>\n )}\n\n <Typography.Text style={{ fontSize: 12, fontWeight: 500, color: 'var(--color-text-3)', display: 'flex', alignItems: 'center', gap: 4, marginTop: 12, paddingTop: 8, borderTop: '1px solid var(--color-border-1)' }}>\n <IconRobot /> Agent 委托\n </Typography.Text>\n <div style={{ marginTop: 4 }}>\n {used.agents.length > 0 ? (\n used.agents.map((a) => (\n <Tag key={a} size=\"small\" style={{ marginRight: 6, marginBottom: 6 }}>{a}</Tag>\n ))\n ) : (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>无</Typography.Text>\n )}\n </div>\n </Card>\n\n {/* 问题 */}\n <Card\n bordered\n title={<span style={{ fontSize: 14, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 6 }}><IconExclamationCircle style={{ color: issues.length > 0 ? 'var(--cf-tag-orange, #FF7D00)' : 'var(--color-text-3)' }} />问题</span>}\n extra={issues.length > 0 ? <Typography.Text style={{ fontSize: 12, color: 'rgb(var(--red-6))' }}>{issues.length} 项</Typography.Text> : undefined}\n >\n {issues.length > 0 ? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n {issues.map((iss) => (\n <div key={iss.id} style={{ border: '1px solid var(--color-border-2)', borderRadius: 4, padding: 10 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>\n <Tag size=\"small\" color={iss.decision === 'deny' ? 'red' : 'orange'}>{iss.decision}</Tag>\n <Typography.Text style={{ fontSize: 13, fontWeight: 500 }}>{iss.rule_id}</Typography.Text>\n <Tag size=\"small\">{iss.tool}</Tag>\n </div>\n {iss.hint && (\n <Typography.Paragraph style={{ fontSize: 12, margin: 0, color: 'var(--color-text-2)' }} ellipsis={{ rows: 3 }}>\n {iss.hint}\n </Typography.Paragraph>\n )}\n <Link to=\"/issues\" style={{ fontSize: 12 }}>在「问题」中查看</Link>\n </div>\n ))}\n </div>\n ) : (\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'rgb(var(--green-6))' }}>\n <IconCheckCircle />\n 本任务无拦截 / 违规 / 失败\n </div>\n )}\n </Card>\n </div>\n </Col>\n </Row>\n </div>\n )\n}\n"],"names":["MD_BODY_KEYS","extractBodyText","value","parts","block","joined","safePretty","parseAgentOutput","raw","text","parsed","env","key","body","arrBody","VERIFY_AGENTS","VERDICT_DECL_RE","parseVerifyVerdict","output","last","m","isImplementAgent","subagentType","isDecisionAgent","isVerifyAgent","classifyAgentStep","COMMIT_PREVIEW_CAP","STEP_LABEL","isoToMs","iso","ms","matchSpawn","ev","spawns","evType","evMs","best","bestDelta","s","sMs","delta","spawnDuration","full","a","b","pickContent","spawnToEntry","agentSpawns","fallback","content","isVerify","adjacent","cmpAt","strictCountOf","entries","e","adjacentCountOf","actorSummaryOf","strict","order","counts","seq","actor","n","buildChain","events","decisions","commits","decisionEntries","implementEntries","verifyEntries","step","entry","commitEntries","c","hasFull","message","truncated","decisionEv","lastCommit","decisionPrimary","decisionAt","decisionActor","decisionPresent","decisionDetail","describeStep","implementPrimary","implementDetail","verifyPrimary","verdict","verifyDetail","commitDetail","_a","_b","_c","label","opts","prefix","BUCKET_ORDER","deriveChangedFiles","artifacts","out","bucket","path","deriveCommits","deriveIssues","i","usefulnessToStars","u","deriveUsedResources","skillInvocations","kbPulls","skills","agentSet","k","deriveUserPromptRounds","prompts","seen","roundCounter","kind","isHuman","deriveRelatedDecisionId","d","deriveWorkflowSpan","timeline","wf","shouldShowDecisionResolvedEntry","stepVisualStatus","formatDuration","startTime","endTime","sec","fetchTaskDetail","taskId","res","fetchTaskTimeline","useTaskDetail","detailQ","useQuery","timelineQ","isLoading","error","vm","Row","Grid","Col","Step","Steps","CollapseItem","Collapse","formatMs","ScrollBlock","maxHeight","jsx","MarkdownRenderer","AgentOutputBlock","shell","children","jsxs","Fragment","Space","IconCode","Typography","outcomeTag","outcome","Tag","statusTag","status","verdictTag","BUCKET_TAG","Stars","_","IconStarFill","StepEntryCard","stepKey","index","total","durationText","isCommit","promptLabel","outputLabel","promptText","hasBody","IconBranch","IconRobot","IconClockCircle","format","parseUTC","IconFile","DecisionResolvedEntry","decisionId","IconCheckCircle","Link","Button","IconLink","StepDetailPanel","stepNo","UserPromptRoundsCard","rounds","humans","machines","fmtAt","at","machineLabel","Card","Empty","TaskDetailPage","useParams","navigate","useNavigate","openStep","setOpenStep","useState","Skeleton","Result","detail","chain","changedFiles","issues","used","userPromptRounds","relatedDecisionId","workflowSpan","title","normalizeTaskTitle","duration","startedAt","currentStep","IconLeft","stepIdx","prev","f","meta","Descriptions","IconBook","IconExclamationCircle","iss"],"mappings":"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"}