@winspan/claude-forge 8.54.4 → 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 (1053) hide show
  1. package/DEVELOPMENT.md +723 -46
  2. package/README.md +166 -21
  3. package/dist/catalogs/agents.json +67 -0
  4. package/dist/catalogs/skills.json +306 -0
  5. package/dist/claudemd/claudemd-generator.d.ts +45 -45
  6. package/dist/claudemd/claudemd-generator.d.ts.map +1 -1
  7. package/dist/claudemd/claudemd-generator.js +128 -449
  8. package/dist/claudemd/claudemd-generator.js.map +1 -1
  9. package/dist/claudemd/index.d.ts +14 -4
  10. package/dist/claudemd/index.d.ts.map +1 -1
  11. package/dist/claudemd/index.js +15 -4
  12. package/dist/claudemd/index.js.map +1 -1
  13. package/dist/claudemd/resume-manager.d.ts.map +1 -1
  14. package/dist/claudemd/resume-manager.js +37 -9
  15. package/dist/claudemd/resume-manager.js.map +1 -1
  16. package/dist/claudemd/templates/swarm-protocol.md +35 -186
  17. package/dist/claudemd/violations-manager.d.ts +40 -0
  18. package/dist/claudemd/violations-manager.d.ts.map +1 -0
  19. package/dist/claudemd/violations-manager.js +106 -0
  20. package/dist/claudemd/violations-manager.js.map +1 -0
  21. package/dist/cli/commands/admin.d.ts +15 -0
  22. package/dist/cli/commands/admin.d.ts.map +1 -0
  23. package/dist/cli/commands/admin.js +177 -0
  24. package/dist/cli/commands/admin.js.map +1 -0
  25. package/dist/cli/commands/agent.d.ts +169 -0
  26. package/dist/cli/commands/agent.d.ts.map +1 -0
  27. package/dist/cli/commands/agent.js +690 -0
  28. package/dist/cli/commands/agent.js.map +1 -0
  29. package/dist/cli/commands/agents.d.ts +18 -0
  30. package/dist/cli/commands/agents.d.ts.map +1 -0
  31. package/dist/cli/commands/agents.js +160 -0
  32. package/dist/cli/commands/agents.js.map +1 -0
  33. package/dist/cli/commands/bypass.d.ts +18 -0
  34. package/dist/cli/commands/bypass.d.ts.map +1 -0
  35. package/dist/cli/commands/bypass.js +87 -0
  36. package/dist/cli/commands/bypass.js.map +1 -0
  37. package/dist/cli/commands/claudemd.d.ts +60 -0
  38. package/dist/cli/commands/claudemd.d.ts.map +1 -1
  39. package/dist/cli/commands/claudemd.js +174 -37
  40. package/dist/cli/commands/claudemd.js.map +1 -1
  41. package/dist/cli/commands/codegraph.d.ts +17 -0
  42. package/dist/cli/commands/codegraph.d.ts.map +1 -0
  43. package/dist/cli/commands/codegraph.js +263 -0
  44. package/dist/cli/commands/codegraph.js.map +1 -0
  45. package/dist/cli/commands/config.d.ts.map +1 -1
  46. package/dist/cli/commands/config.js +94 -1
  47. package/dist/cli/commands/config.js.map +1 -1
  48. package/dist/cli/commands/daemon.d.ts +39 -0
  49. package/dist/cli/commands/daemon.d.ts.map +1 -1
  50. package/dist/cli/commands/daemon.js +167 -20
  51. package/dist/cli/commands/daemon.js.map +1 -1
  52. package/dist/cli/commands/decisions.d.ts +129 -0
  53. package/dist/cli/commands/decisions.d.ts.map +1 -0
  54. package/dist/cli/commands/decisions.js +706 -0
  55. package/dist/cli/commands/decisions.js.map +1 -0
  56. package/dist/cli/commands/doctor.d.ts +29 -0
  57. package/dist/cli/commands/doctor.d.ts.map +1 -0
  58. package/dist/cli/commands/doctor.js +124 -0
  59. package/dist/cli/commands/doctor.js.map +1 -0
  60. package/dist/cli/commands/entropy.d.ts +35 -0
  61. package/dist/cli/commands/entropy.d.ts.map +1 -0
  62. package/dist/cli/commands/entropy.js +121 -0
  63. package/dist/cli/commands/entropy.js.map +1 -0
  64. package/dist/cli/commands/executions.d.ts +1 -0
  65. package/dist/cli/commands/executions.d.ts.map +1 -1
  66. package/dist/cli/commands/executions.js +12 -2
  67. package/dist/cli/commands/executions.js.map +1 -1
  68. package/dist/cli/commands/fix.d.ts +31 -0
  69. package/dist/cli/commands/fix.d.ts.map +1 -0
  70. package/dist/cli/commands/fix.js +108 -0
  71. package/dist/cli/commands/fix.js.map +1 -0
  72. package/dist/cli/commands/governance.d.ts +21 -0
  73. package/dist/cli/commands/governance.d.ts.map +1 -0
  74. package/dist/cli/commands/governance.js +60 -0
  75. package/dist/cli/commands/governance.js.map +1 -0
  76. package/dist/cli/commands/init.d.ts +27 -0
  77. package/dist/cli/commands/init.d.ts.map +1 -1
  78. package/dist/cli/commands/init.js +158 -146
  79. package/dist/cli/commands/init.js.map +1 -1
  80. package/dist/cli/commands/insights-goal-check.d.ts +54 -0
  81. package/dist/cli/commands/insights-goal-check.d.ts.map +1 -0
  82. package/dist/cli/commands/insights-goal-check.js +318 -0
  83. package/dist/cli/commands/insights-goal-check.js.map +1 -0
  84. package/dist/cli/commands/insights.d.ts +15 -0
  85. package/dist/cli/commands/insights.d.ts.map +1 -0
  86. package/dist/cli/commands/insights.js +127 -0
  87. package/dist/cli/commands/insights.js.map +1 -0
  88. package/dist/cli/commands/knowledge.d.ts +117 -0
  89. package/dist/cli/commands/knowledge.d.ts.map +1 -0
  90. package/dist/cli/commands/knowledge.js +1070 -0
  91. package/dist/cli/commands/knowledge.js.map +1 -0
  92. package/dist/cli/commands/loop.d.ts +95 -0
  93. package/dist/cli/commands/loop.d.ts.map +1 -0
  94. package/dist/cli/commands/loop.js +408 -0
  95. package/dist/cli/commands/loop.js.map +1 -0
  96. package/dist/cli/commands/maintenance.d.ts +33 -0
  97. package/dist/cli/commands/maintenance.d.ts.map +1 -0
  98. package/dist/cli/commands/maintenance.js +75 -0
  99. package/dist/cli/commands/maintenance.js.map +1 -0
  100. package/dist/cli/commands/mcp.d.ts +22 -11
  101. package/dist/cli/commands/mcp.d.ts.map +1 -1
  102. package/dist/cli/commands/mcp.js +93 -5
  103. package/dist/cli/commands/mcp.js.map +1 -1
  104. package/dist/cli/commands/menu.d.ts.map +1 -1
  105. package/dist/cli/commands/menu.js +10 -184
  106. package/dist/cli/commands/menu.js.map +1 -1
  107. package/dist/cli/commands/project.d.ts +98 -0
  108. package/dist/cli/commands/project.d.ts.map +1 -0
  109. package/dist/cli/commands/project.js +382 -0
  110. package/dist/cli/commands/project.js.map +1 -0
  111. package/dist/cli/commands/skills.d.ts +131 -0
  112. package/dist/cli/commands/skills.d.ts.map +1 -1
  113. package/dist/cli/commands/skills.js +404 -118
  114. package/dist/cli/commands/skills.js.map +1 -1
  115. package/dist/cli/commands/spec.d.ts +40 -0
  116. package/dist/cli/commands/spec.d.ts.map +1 -0
  117. package/dist/cli/commands/spec.js +49 -0
  118. package/dist/cli/commands/spec.js.map +1 -0
  119. package/dist/cli/commands/stats.d.ts.map +1 -1
  120. package/dist/cli/commands/stats.js +11 -3
  121. package/dist/cli/commands/stats.js.map +1 -1
  122. package/dist/cli/commands/status.d.ts.map +1 -1
  123. package/dist/cli/commands/status.js +17 -2
  124. package/dist/cli/commands/status.js.map +1 -1
  125. package/dist/cli/commands/trace.d.ts.map +1 -1
  126. package/dist/cli/commands/trace.js +4 -9
  127. package/dist/cli/commands/trace.js.map +1 -1
  128. package/dist/cli/commands/violations.d.ts +14 -0
  129. package/dist/cli/commands/violations.d.ts.map +1 -0
  130. package/dist/cli/commands/violations.js +43 -0
  131. package/dist/cli/commands/violations.js.map +1 -0
  132. package/dist/cli/index.js +34 -0
  133. package/dist/cli/index.js.map +1 -1
  134. package/dist/cli/init/hook-manager.d.ts +1 -1
  135. package/dist/cli/init/hook-manager.d.ts.map +1 -1
  136. package/dist/cli/init/hook-manager.js +6 -0
  137. package/dist/cli/init/hook-manager.js.map +1 -1
  138. package/dist/cli/utils/resolve-session.d.ts +32 -0
  139. package/dist/cli/utils/resolve-session.d.ts.map +1 -0
  140. package/dist/cli/utils/resolve-session.js +39 -0
  141. package/dist/cli/utils/resolve-session.js.map +1 -0
  142. package/dist/core/config.d.ts +4 -1
  143. package/dist/core/config.d.ts.map +1 -1
  144. package/dist/core/config.js +11 -23
  145. package/dist/core/config.js.map +1 -1
  146. package/dist/core/constants.d.ts +51 -13
  147. package/dist/core/constants.d.ts.map +1 -1
  148. package/dist/core/constants.js +63 -13
  149. package/dist/core/constants.js.map +1 -1
  150. package/dist/core/diagnostics/checks.d.ts +151 -0
  151. package/dist/core/diagnostics/checks.d.ts.map +1 -0
  152. package/dist/core/diagnostics/checks.js +766 -0
  153. package/dist/core/diagnostics/checks.js.map +1 -0
  154. package/dist/core/diagnostics/daemon-status.d.ts +77 -0
  155. package/dist/core/diagnostics/daemon-status.d.ts.map +1 -0
  156. package/dist/core/diagnostics/daemon-status.js +113 -0
  157. package/dist/core/diagnostics/daemon-status.js.map +1 -0
  158. package/dist/core/diagnostics/entropy-checks.d.ts +83 -0
  159. package/dist/core/diagnostics/entropy-checks.d.ts.map +1 -0
  160. package/dist/core/diagnostics/entropy-checks.js +400 -0
  161. package/dist/core/diagnostics/entropy-checks.js.map +1 -0
  162. package/dist/core/diagnostics/fix-runner.d.ts +54 -0
  163. package/dist/core/diagnostics/fix-runner.d.ts.map +1 -0
  164. package/dist/core/diagnostics/fix-runner.js +90 -0
  165. package/dist/core/diagnostics/fix-runner.js.map +1 -0
  166. package/dist/core/diagnostics/heartbeat-reader.d.ts +28 -0
  167. package/dist/core/diagnostics/heartbeat-reader.d.ts.map +1 -0
  168. package/dist/core/diagnostics/heartbeat-reader.js +50 -0
  169. package/dist/core/diagnostics/heartbeat-reader.js.map +1 -0
  170. package/dist/core/diagnostics/knip-runner.d.ts +49 -0
  171. package/dist/core/diagnostics/knip-runner.d.ts.map +1 -0
  172. package/dist/core/diagnostics/knip-runner.js +100 -0
  173. package/dist/core/diagnostics/knip-runner.js.map +1 -0
  174. package/dist/core/diagnostics/markers.d.ts +96 -0
  175. package/dist/core/diagnostics/markers.d.ts.map +1 -0
  176. package/dist/core/diagnostics/markers.js +153 -0
  177. package/dist/core/diagnostics/markers.js.map +1 -0
  178. package/dist/core/event-fields.d.ts +27 -0
  179. package/dist/core/event-fields.d.ts.map +1 -1
  180. package/dist/core/event-fields.js +43 -0
  181. package/dist/core/event-fields.js.map +1 -1
  182. package/dist/core/governance/global-inject.d.ts +90 -0
  183. package/dist/core/governance/global-inject.d.ts.map +1 -0
  184. package/dist/core/governance/global-inject.js +184 -0
  185. package/dist/core/governance/global-inject.js.map +1 -0
  186. package/dist/core/insights/agent-anchor-guard.d.ts +77 -0
  187. package/dist/core/insights/agent-anchor-guard.d.ts.map +1 -0
  188. package/dist/core/insights/agent-anchor-guard.js +119 -0
  189. package/dist/core/insights/agent-anchor-guard.js.map +1 -0
  190. package/dist/core/insights/agent-distill-context.d.ts +55 -0
  191. package/dist/core/insights/agent-distill-context.d.ts.map +1 -0
  192. package/dist/core/insights/agent-distill-context.js +146 -0
  193. package/dist/core/insights/agent-distill-context.js.map +1 -0
  194. package/dist/core/insights/agent-distill-spawn.d.ts +56 -0
  195. package/dist/core/insights/agent-distill-spawn.d.ts.map +1 -0
  196. package/dist/core/insights/agent-distill-spawn.js +179 -0
  197. package/dist/core/insights/agent-distill-spawn.js.map +1 -0
  198. package/dist/core/insights/agent-drift.d.ts +66 -0
  199. package/dist/core/insights/agent-drift.d.ts.map +1 -0
  200. package/dist/core/insights/agent-drift.js +109 -0
  201. package/dist/core/insights/agent-drift.js.map +1 -0
  202. package/dist/core/insights/agent-evolution-sources.d.ts +21 -0
  203. package/dist/core/insights/agent-evolution-sources.d.ts.map +1 -0
  204. package/dist/core/insights/agent-evolution-sources.js +36 -0
  205. package/dist/core/insights/agent-evolution-sources.js.map +1 -0
  206. package/dist/core/insights/agent-health.d.ts +142 -0
  207. package/dist/core/insights/agent-health.d.ts.map +1 -0
  208. package/dist/core/insights/agent-health.js +296 -0
  209. package/dist/core/insights/agent-health.js.map +1 -0
  210. package/dist/core/insights/agent-patch-apply.d.ts +45 -0
  211. package/dist/core/insights/agent-patch-apply.d.ts.map +1 -0
  212. package/dist/core/insights/agent-patch-apply.js +165 -0
  213. package/dist/core/insights/agent-patch-apply.js.map +1 -0
  214. package/dist/core/insights/agent-suggest.d.ts +128 -0
  215. package/dist/core/insights/agent-suggest.d.ts.map +1 -0
  216. package/dist/core/insights/agent-suggest.js +284 -0
  217. package/dist/core/insights/agent-suggest.js.map +1 -0
  218. package/dist/core/insights/coverage-tiers.d.ts +46 -0
  219. package/dist/core/insights/coverage-tiers.d.ts.map +1 -0
  220. package/dist/core/insights/coverage-tiers.js +95 -0
  221. package/dist/core/insights/coverage-tiers.js.map +1 -0
  222. package/dist/core/insights/experience-extractor.d.ts +60 -0
  223. package/dist/core/insights/experience-extractor.d.ts.map +1 -0
  224. package/dist/core/insights/experience-extractor.js +319 -0
  225. package/dist/core/insights/experience-extractor.js.map +1 -0
  226. package/dist/core/insights/violation-reporter.d.ts +149 -0
  227. package/dist/core/insights/violation-reporter.d.ts.map +1 -0
  228. package/dist/core/insights/violation-reporter.js +391 -0
  229. package/dist/core/insights/violation-reporter.js.map +1 -0
  230. package/dist/core/loop/loop-engine.d.ts +140 -0
  231. package/dist/core/loop/loop-engine.d.ts.map +1 -0
  232. package/dist/core/loop/loop-engine.js +266 -0
  233. package/dist/core/loop/loop-engine.js.map +1 -0
  234. package/dist/core/queue/index.d.ts +16 -3
  235. package/dist/core/queue/index.d.ts.map +1 -1
  236. package/dist/core/queue/index.js +16 -4
  237. package/dist/core/queue/index.js.map +1 -1
  238. package/dist/core/storage/base.d.ts +317 -0
  239. package/dist/core/storage/base.d.ts.map +1 -1
  240. package/dist/core/storage/base.js +1093 -0
  241. package/dist/core/storage/base.js.map +1 -1
  242. package/dist/core/storage/codec/tool-input-codec.d.ts +93 -0
  243. package/dist/core/storage/codec/tool-input-codec.d.ts.map +1 -0
  244. package/dist/core/storage/codec/tool-input-codec.js +159 -0
  245. package/dist/core/storage/codec/tool-input-codec.js.map +1 -0
  246. package/dist/core/storage/codegraph-types.d.ts +79 -0
  247. package/dist/core/storage/codegraph-types.d.ts.map +1 -0
  248. package/dist/core/storage/codegraph-types.js +14 -0
  249. package/dist/core/storage/codegraph-types.js.map +1 -0
  250. package/dist/core/storage/codegraph.d.ts +186 -0
  251. package/dist/core/storage/codegraph.d.ts.map +1 -0
  252. package/dist/core/storage/codegraph.js +452 -0
  253. package/dist/core/storage/codegraph.js.map +1 -0
  254. package/dist/core/storage/decisions.d.ts +387 -0
  255. package/dist/core/storage/decisions.d.ts.map +1 -0
  256. package/dist/core/storage/decisions.js +534 -0
  257. package/dist/core/storage/decisions.js.map +1 -0
  258. package/dist/core/storage/events.d.ts +239 -8
  259. package/dist/core/storage/events.d.ts.map +1 -1
  260. package/dist/core/storage/events.js +705 -39
  261. package/dist/core/storage/events.js.map +1 -1
  262. package/dist/core/storage/feedback.d.ts +111 -0
  263. package/dist/core/storage/feedback.d.ts.map +1 -0
  264. package/dist/core/storage/feedback.js +186 -0
  265. package/dist/core/storage/feedback.js.map +1 -0
  266. package/dist/core/storage/forge-config.d.ts +40 -0
  267. package/dist/core/storage/forge-config.d.ts.map +1 -0
  268. package/dist/core/storage/forge-config.js +65 -0
  269. package/dist/core/storage/forge-config.js.map +1 -0
  270. package/dist/core/storage/injections.d.ts +68 -0
  271. package/dist/core/storage/injections.d.ts.map +1 -1
  272. package/dist/core/storage/injections.js +131 -5
  273. package/dist/core/storage/injections.js.map +1 -1
  274. package/dist/core/storage/knowledge.d.ts +332 -0
  275. package/dist/core/storage/knowledge.d.ts.map +1 -0
  276. package/dist/core/storage/knowledge.js +589 -0
  277. package/dist/core/storage/knowledge.js.map +1 -0
  278. package/dist/core/storage/maintenance.d.ts +36 -9
  279. package/dist/core/storage/maintenance.d.ts.map +1 -1
  280. package/dist/core/storage/maintenance.js +56 -24
  281. package/dist/core/storage/maintenance.js.map +1 -1
  282. package/dist/core/storage/pipeline-rollup.d.ts +111 -0
  283. package/dist/core/storage/pipeline-rollup.d.ts.map +1 -0
  284. package/dist/core/storage/pipeline-rollup.js +432 -0
  285. package/dist/core/storage/pipeline-rollup.js.map +1 -0
  286. package/dist/core/storage/routing.d.ts +50 -3
  287. package/dist/core/storage/routing.d.ts.map +1 -1
  288. package/dist/core/storage/routing.js +131 -10
  289. package/dist/core/storage/routing.js.map +1 -1
  290. package/dist/core/storage/rows.d.ts +31 -8
  291. package/dist/core/storage/rows.d.ts.map +1 -1
  292. package/dist/core/storage/schema.sql +367 -23
  293. package/dist/core/storage/sessions.d.ts +136 -0
  294. package/dist/core/storage/sessions.d.ts.map +1 -1
  295. package/dist/core/storage/sessions.js +352 -15
  296. package/dist/core/storage/sessions.js.map +1 -1
  297. package/dist/core/storage/skills.d.ts +160 -0
  298. package/dist/core/storage/skills.d.ts.map +1 -1
  299. package/dist/core/storage/skills.js +368 -7
  300. package/dist/core/storage/skills.js.map +1 -1
  301. package/dist/core/storage/sqlite.d.ts +309 -20
  302. package/dist/core/storage/sqlite.d.ts.map +1 -1
  303. package/dist/core/storage/sqlite.js +523 -16
  304. package/dist/core/storage/sqlite.js.map +1 -1
  305. package/dist/core/storage/tasks.d.ts +744 -2
  306. package/dist/core/storage/tasks.d.ts.map +1 -1
  307. package/dist/core/storage/tasks.js +1691 -17
  308. package/dist/core/storage/tasks.js.map +1 -1
  309. package/dist/core/storage/tool-intercepts.d.ts +69 -0
  310. package/dist/core/storage/tool-intercepts.d.ts.map +1 -0
  311. package/dist/core/storage/tool-intercepts.js +116 -0
  312. package/dist/core/storage/tool-intercepts.js.map +1 -0
  313. package/dist/core/types.d.ts +136 -18
  314. package/dist/core/types.d.ts.map +1 -1
  315. package/dist/core/types.js +10 -0
  316. package/dist/core/types.js.map +1 -1
  317. package/dist/core/utils/backup.d.ts +81 -0
  318. package/dist/core/utils/backup.d.ts.map +1 -0
  319. package/dist/core/utils/backup.js +98 -0
  320. package/dist/core/utils/backup.js.map +1 -0
  321. package/dist/core/utils/binary-paths.d.ts +124 -0
  322. package/dist/core/utils/binary-paths.d.ts.map +1 -0
  323. package/dist/core/utils/binary-paths.js +218 -0
  324. package/dist/core/utils/binary-paths.js.map +1 -0
  325. package/dist/core/utils/bypass-token.d.ts +75 -0
  326. package/dist/core/utils/bypass-token.d.ts.map +1 -0
  327. package/dist/core/utils/bypass-token.js +133 -0
  328. package/dist/core/utils/bypass-token.js.map +1 -0
  329. package/dist/core/utils/cc-builtin-agents.d.ts +3 -0
  330. package/dist/core/utils/cc-builtin-agents.d.ts.map +1 -0
  331. package/dist/core/utils/cc-builtin-agents.js +29 -0
  332. package/dist/core/utils/cc-builtin-agents.js.map +1 -0
  333. package/dist/core/utils/claude-cli-resolver.d.ts +26 -0
  334. package/dist/core/utils/claude-cli-resolver.d.ts.map +1 -0
  335. package/dist/core/utils/claude-cli-resolver.js +115 -0
  336. package/dist/core/utils/claude-cli-resolver.js.map +1 -0
  337. package/dist/core/utils/claude-cli-spawn.d.ts +106 -0
  338. package/dist/core/utils/claude-cli-spawn.d.ts.map +1 -0
  339. package/dist/core/utils/claude-cli-spawn.js +219 -0
  340. package/dist/core/utils/claude-cli-spawn.js.map +1 -0
  341. package/dist/core/utils/forge-resume-block.d.ts.map +1 -1
  342. package/dist/core/utils/forge-resume-block.js +3 -2
  343. package/dist/core/utils/forge-resume-block.js.map +1 -1
  344. package/dist/core/utils/logger.d.ts +15 -3
  345. package/dist/core/utils/logger.d.ts.map +1 -1
  346. package/dist/core/utils/logger.js +20 -2
  347. package/dist/core/utils/logger.js.map +1 -1
  348. package/dist/core/utils/noise-prompt.d.ts +97 -0
  349. package/dist/core/utils/noise-prompt.d.ts.map +1 -0
  350. package/dist/core/utils/noise-prompt.js +127 -0
  351. package/dist/core/utils/noise-prompt.js.map +1 -0
  352. package/dist/core/utils/path.d.ts +0 -4
  353. package/dist/core/utils/path.d.ts.map +1 -1
  354. package/dist/core/utils/path.js +0 -7
  355. package/dist/core/utils/path.js.map +1 -1
  356. package/dist/core/utils/time.d.ts +67 -0
  357. package/dist/core/utils/time.d.ts.map +1 -1
  358. package/dist/core/utils/time.js +147 -0
  359. package/dist/core/utils/time.js.map +1 -1
  360. package/dist/daemon/agent-sync.d.ts +24 -0
  361. package/dist/daemon/agent-sync.d.ts.map +1 -0
  362. package/dist/daemon/agent-sync.js +114 -0
  363. package/dist/daemon/agent-sync.js.map +1 -0
  364. package/dist/daemon/config-store.d.ts +55 -0
  365. package/dist/daemon/config-store.d.ts.map +1 -0
  366. package/dist/daemon/config-store.js +146 -0
  367. package/dist/daemon/config-store.js.map +1 -0
  368. package/dist/daemon/event-parser.d.ts +22 -0
  369. package/dist/daemon/event-parser.d.ts.map +1 -1
  370. package/dist/daemon/event-parser.js +54 -3
  371. package/dist/daemon/event-parser.js.map +1 -1
  372. package/dist/daemon/handlers/history-exporter.d.ts.map +1 -1
  373. package/dist/daemon/handlers/history-exporter.js +9 -8
  374. package/dist/daemon/handlers/history-exporter.js.map +1 -1
  375. package/dist/daemon/handlers/post-tool-use.d.ts +66 -4
  376. package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
  377. package/dist/daemon/handlers/post-tool-use.js +221 -8
  378. package/dist/daemon/handlers/post-tool-use.js.map +1 -1
  379. package/dist/daemon/handlers/pre-tool-use.d.ts +181 -0
  380. package/dist/daemon/handlers/pre-tool-use.d.ts.map +1 -0
  381. package/dist/daemon/handlers/pre-tool-use.js +618 -0
  382. package/dist/daemon/handlers/pre-tool-use.js.map +1 -0
  383. package/dist/daemon/handlers/stop.d.ts +55 -7
  384. package/dist/daemon/handlers/stop.d.ts.map +1 -1
  385. package/dist/daemon/handlers/stop.js +245 -8
  386. package/dist/daemon/handlers/stop.js.map +1 -1
  387. package/dist/daemon/handlers/user-prompt.d.ts +51 -14
  388. package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
  389. package/dist/daemon/handlers/user-prompt.js +223 -95
  390. package/dist/daemon/handlers/user-prompt.js.map +1 -1
  391. package/dist/daemon/handlers/violation-content-backfill.d.ts +76 -0
  392. package/dist/daemon/handlers/violation-content-backfill.d.ts.map +1 -0
  393. package/dist/daemon/handlers/violation-content-backfill.js +167 -0
  394. package/dist/daemon/handlers/violation-content-backfill.js.map +1 -0
  395. package/dist/daemon/hook-sync.d.ts.map +1 -1
  396. package/dist/daemon/hook-sync.js +2 -1
  397. package/dist/daemon/hook-sync.js.map +1 -1
  398. package/dist/daemon/index.d.ts +19 -0
  399. package/dist/daemon/index.d.ts.map +1 -1
  400. package/dist/daemon/index.js +439 -86
  401. package/dist/daemon/index.js.map +1 -1
  402. package/dist/daemon/lifecycle.d.ts +48 -1
  403. package/dist/daemon/lifecycle.d.ts.map +1 -1
  404. package/dist/daemon/lifecycle.js +98 -2
  405. package/dist/daemon/lifecycle.js.map +1 -1
  406. package/dist/daemon/router.d.ts +4 -1
  407. package/dist/daemon/router.d.ts.map +1 -1
  408. package/dist/daemon/router.js +4 -2
  409. package/dist/daemon/router.js.map +1 -1
  410. package/dist/daemon/rules/defaults.d.ts +20 -0
  411. package/dist/daemon/rules/defaults.d.ts.map +1 -0
  412. package/dist/daemon/rules/defaults.js +779 -0
  413. package/dist/daemon/rules/defaults.js.map +1 -0
  414. package/dist/daemon/rules/registry.d.ts +47 -0
  415. package/dist/daemon/rules/registry.d.ts.map +1 -0
  416. package/dist/daemon/rules/registry.js +84 -0
  417. package/dist/daemon/rules/registry.js.map +1 -0
  418. package/dist/daemon/rules/types.d.ts +176 -0
  419. package/dist/daemon/rules/types.d.ts.map +1 -0
  420. package/dist/daemon/rules/types.js +15 -0
  421. package/dist/daemon/rules/types.js.map +1 -0
  422. package/dist/daemon/rules/whitelist.d.ts +101 -0
  423. package/dist/daemon/rules/whitelist.d.ts.map +1 -0
  424. package/dist/daemon/rules/whitelist.js +210 -0
  425. package/dist/daemon/rules/whitelist.js.map +1 -0
  426. package/dist/daemon/rules/workflow-defaults.d.ts +52 -0
  427. package/dist/daemon/rules/workflow-defaults.d.ts.map +1 -0
  428. package/dist/daemon/rules/workflow-defaults.js +521 -0
  429. package/dist/daemon/rules/workflow-defaults.js.map +1 -0
  430. package/dist/daemon/server.d.ts +11 -1
  431. package/dist/daemon/server.d.ts.map +1 -1
  432. package/dist/daemon/server.js +7 -1
  433. package/dist/daemon/server.js.map +1 -1
  434. package/dist/daemon/services/codegraph-sync.d.ts +94 -0
  435. package/dist/daemon/services/codegraph-sync.d.ts.map +1 -0
  436. package/dist/daemon/services/codegraph-sync.js +159 -0
  437. package/dist/daemon/services/codegraph-sync.js.map +1 -0
  438. package/dist/daemon/services/context-injector.d.ts +34 -0
  439. package/dist/daemon/services/context-injector.d.ts.map +1 -0
  440. package/dist/daemon/services/context-injector.js +61 -0
  441. package/dist/daemon/services/context-injector.js.map +1 -0
  442. package/dist/daemon/services/decision-hint.d.ts +240 -0
  443. package/dist/daemon/services/decision-hint.d.ts.map +1 -0
  444. package/dist/daemon/services/decision-hint.js +562 -0
  445. package/dist/daemon/services/decision-hint.js.map +1 -0
  446. package/dist/daemon/services/event-ttl-sweep.d.ts +86 -0
  447. package/dist/daemon/services/event-ttl-sweep.d.ts.map +1 -0
  448. package/dist/daemon/services/event-ttl-sweep.js +124 -0
  449. package/dist/daemon/services/event-ttl-sweep.js.map +1 -0
  450. package/dist/daemon/services/feedback-aggregator.d.ts +167 -0
  451. package/dist/daemon/services/feedback-aggregator.d.ts.map +1 -0
  452. package/dist/daemon/services/feedback-aggregator.js +415 -0
  453. package/dist/daemon/services/feedback-aggregator.js.map +1 -0
  454. package/dist/daemon/services/heartbeat-writer.d.ts +46 -0
  455. package/dist/daemon/services/heartbeat-writer.d.ts.map +1 -0
  456. package/dist/daemon/services/heartbeat-writer.js +82 -0
  457. package/dist/daemon/services/heartbeat-writer.js.map +1 -0
  458. package/dist/daemon/services/idle-session-sweeper.d.ts +61 -0
  459. package/dist/daemon/services/idle-session-sweeper.d.ts.map +1 -0
  460. package/dist/daemon/services/idle-session-sweeper.js +94 -0
  461. package/dist/daemon/services/idle-session-sweeper.js.map +1 -0
  462. package/dist/daemon/services/idle-task-budget.d.ts +50 -0
  463. package/dist/daemon/services/idle-task-budget.d.ts.map +1 -0
  464. package/dist/daemon/services/idle-task-budget.js +72 -0
  465. package/dist/daemon/services/idle-task-budget.js.map +1 -0
  466. package/dist/daemon/services/intercept-revive.d.ts +60 -0
  467. package/dist/daemon/services/intercept-revive.d.ts.map +1 -0
  468. package/dist/daemon/services/intercept-revive.js +86 -0
  469. package/dist/daemon/services/intercept-revive.js.map +1 -0
  470. package/dist/daemon/services/intercept-rollback-guard.d.ts +105 -0
  471. package/dist/daemon/services/intercept-rollback-guard.d.ts.map +1 -0
  472. package/dist/daemon/services/intercept-rollback-guard.js +152 -0
  473. package/dist/daemon/services/intercept-rollback-guard.js.map +1 -0
  474. package/dist/daemon/services/intercept-timeout-sweeper.d.ts +58 -0
  475. package/dist/daemon/services/intercept-timeout-sweeper.d.ts.map +1 -0
  476. package/dist/daemon/services/intercept-timeout-sweeper.js +83 -0
  477. package/dist/daemon/services/intercept-timeout-sweeper.js.map +1 -0
  478. package/dist/daemon/services/kb-injector.d.ts +57 -0
  479. package/dist/daemon/services/kb-injector.d.ts.map +1 -0
  480. package/dist/daemon/services/kb-injector.js +148 -0
  481. package/dist/daemon/services/kb-injector.js.map +1 -0
  482. package/dist/daemon/services/kb-rebuild-scheduler.d.ts +95 -0
  483. package/dist/daemon/services/kb-rebuild-scheduler.d.ts.map +1 -0
  484. package/dist/daemon/services/kb-rebuild-scheduler.js +149 -0
  485. package/dist/daemon/services/kb-rebuild-scheduler.js.map +1 -0
  486. package/dist/daemon/services/loop-hint.d.ts +139 -0
  487. package/dist/daemon/services/loop-hint.d.ts.map +1 -0
  488. package/dist/daemon/services/loop-hint.js +272 -0
  489. package/dist/daemon/services/loop-hint.js.map +1 -0
  490. package/dist/daemon/services/outcome-classification-service.d.ts +49 -0
  491. package/dist/daemon/services/outcome-classification-service.d.ts.map +1 -0
  492. package/dist/daemon/services/outcome-classification-service.js +214 -0
  493. package/dist/daemon/services/outcome-classification-service.js.map +1 -0
  494. package/dist/daemon/services/outcome-classifier.d.ts +136 -0
  495. package/dist/daemon/services/outcome-classifier.d.ts.map +1 -0
  496. package/dist/daemon/services/outcome-classifier.js +178 -0
  497. package/dist/daemon/services/outcome-classifier.js.map +1 -0
  498. package/dist/daemon/services/outcome-nudge.d.ts +107 -0
  499. package/dist/daemon/services/outcome-nudge.d.ts.map +1 -0
  500. package/dist/daemon/services/outcome-nudge.js +242 -0
  501. package/dist/daemon/services/outcome-nudge.js.map +1 -0
  502. package/dist/daemon/services/spec-approval.d.ts +127 -0
  503. package/dist/daemon/services/spec-approval.d.ts.map +1 -0
  504. package/dist/daemon/services/spec-approval.js +216 -0
  505. package/dist/daemon/services/spec-approval.js.map +1 -0
  506. package/dist/daemon/services/spec-gate.d.ts +54 -0
  507. package/dist/daemon/services/spec-gate.d.ts.map +1 -0
  508. package/dist/daemon/services/spec-gate.js +113 -0
  509. package/dist/daemon/services/spec-gate.js.map +1 -0
  510. package/dist/daemon/services/task-boundary-classifier.d.ts +78 -0
  511. package/dist/daemon/services/task-boundary-classifier.d.ts.map +1 -0
  512. package/dist/daemon/services/task-boundary-classifier.js +202 -0
  513. package/dist/daemon/services/task-boundary-classifier.js.map +1 -0
  514. package/dist/daemon/services/task-segmenter.d.ts +230 -1
  515. package/dist/daemon/services/task-segmenter.d.ts.map +1 -1
  516. package/dist/daemon/services/task-segmenter.js +527 -17
  517. package/dist/daemon/services/task-segmenter.js.map +1 -1
  518. package/dist/daemon/skill-sync.d.ts +7 -2
  519. package/dist/daemon/skill-sync.d.ts.map +1 -1
  520. package/dist/daemon/skill-sync.js +114 -9
  521. package/dist/daemon/skill-sync.js.map +1 -1
  522. package/dist/daemon/startup/maintenance-schedulers.d.ts +68 -0
  523. package/dist/daemon/startup/maintenance-schedulers.d.ts.map +1 -0
  524. package/dist/daemon/startup/maintenance-schedulers.js +294 -0
  525. package/dist/daemon/startup/maintenance-schedulers.js.map +1 -0
  526. package/dist/daemon/templates/agents/agent-retro-distiller.md +106 -0
  527. package/dist/daemon/templates/agents/claudemd-writer.md +102 -0
  528. package/dist/daemon/templates/agents/coder.md +262 -0
  529. package/dist/daemon/templates/agents/decision-maker.md +546 -0
  530. package/dist/daemon/templates/agents/doc-reviewer.md +118 -0
  531. package/dist/daemon/templates/agents/harness-debug-full.md +196 -0
  532. package/dist/daemon/templates/agents/knowledge-builder.md +120 -0
  533. package/dist/daemon/templates/agents/patch-applier.md +145 -0
  534. package/dist/daemon/templates/agents/planner.md +217 -0
  535. package/dist/daemon/templates/agents/safety-net-implementer.md +278 -0
  536. package/dist/daemon/templates/agents/skill-distiller.md +114 -0
  537. package/dist/daemon/templates/agents/task-boundary-classifier.md +65 -0
  538. package/dist/daemon/templates/agents/verify-agent.md +259 -0
  539. package/dist/daemon/utils/inject-block.d.ts +39 -0
  540. package/dist/daemon/utils/inject-block.d.ts.map +1 -0
  541. package/dist/daemon/utils/inject-block.js +25 -0
  542. package/dist/daemon/utils/inject-block.js.map +1 -0
  543. package/dist/hooks/hook-lib.sh +8 -0
  544. package/dist/hooks/notification.sh +19 -8
  545. package/dist/hooks/post-tool-use.sh +41 -23
  546. package/dist/hooks/pre-tool-use.sh +54 -23
  547. package/dist/hooks/session-start.sh +68 -0
  548. package/dist/hooks/stop.sh +31 -11
  549. package/dist/hooks/user-prompt-submit.sh +37 -21
  550. package/dist/knowledge/adapters/go-adapter.d.ts +65 -0
  551. package/dist/knowledge/adapters/go-adapter.d.ts.map +1 -0
  552. package/dist/knowledge/adapters/go-adapter.js +294 -0
  553. package/dist/knowledge/adapters/go-adapter.js.map +1 -0
  554. package/dist/knowledge/adapters/index.d.ts +41 -0
  555. package/dist/knowledge/adapters/index.d.ts.map +1 -0
  556. package/dist/knowledge/adapters/index.js +71 -0
  557. package/dist/knowledge/adapters/index.js.map +1 -0
  558. package/dist/knowledge/adapters/java-adapter.d.ts +66 -0
  559. package/dist/knowledge/adapters/java-adapter.d.ts.map +1 -0
  560. package/dist/knowledge/adapters/java-adapter.js +260 -0
  561. package/dist/knowledge/adapters/java-adapter.js.map +1 -0
  562. package/dist/knowledge/adapters/js-vue-adapter.d.ts +56 -0
  563. package/dist/knowledge/adapters/js-vue-adapter.d.ts.map +1 -0
  564. package/dist/knowledge/adapters/js-vue-adapter.js +203 -0
  565. package/dist/knowledge/adapters/js-vue-adapter.js.map +1 -0
  566. package/dist/knowledge/adapters/kotlin-adapter.d.ts +55 -0
  567. package/dist/knowledge/adapters/kotlin-adapter.d.ts.map +1 -0
  568. package/dist/knowledge/adapters/kotlin-adapter.js +209 -0
  569. package/dist/knowledge/adapters/kotlin-adapter.js.map +1 -0
  570. package/dist/knowledge/adapters/monorepo-adapter.d.ts +77 -0
  571. package/dist/knowledge/adapters/monorepo-adapter.d.ts.map +1 -0
  572. package/dist/knowledge/adapters/monorepo-adapter.js +170 -0
  573. package/dist/knowledge/adapters/monorepo-adapter.js.map +1 -0
  574. package/dist/knowledge/adapters/python-adapter.d.ts +89 -0
  575. package/dist/knowledge/adapters/python-adapter.d.ts.map +1 -0
  576. package/dist/knowledge/adapters/python-adapter.js +358 -0
  577. package/dist/knowledge/adapters/python-adapter.js.map +1 -0
  578. package/dist/knowledge/adapters/rust-adapter.d.ts +73 -0
  579. package/dist/knowledge/adapters/rust-adapter.d.ts.map +1 -0
  580. package/dist/knowledge/adapters/rust-adapter.js +329 -0
  581. package/dist/knowledge/adapters/rust-adapter.js.map +1 -0
  582. package/dist/knowledge/adapters/types.d.ts +99 -0
  583. package/dist/knowledge/adapters/types.d.ts.map +1 -0
  584. package/dist/knowledge/adapters/types.js +17 -0
  585. package/dist/knowledge/adapters/types.js.map +1 -0
  586. package/dist/knowledge/adapters/typescript-adapter.d.ts +57 -0
  587. package/dist/knowledge/adapters/typescript-adapter.d.ts.map +1 -0
  588. package/dist/knowledge/adapters/typescript-adapter.js +171 -0
  589. package/dist/knowledge/adapters/typescript-adapter.js.map +1 -0
  590. package/dist/knowledge/audit-applier.d.ts +70 -0
  591. package/dist/knowledge/audit-applier.d.ts.map +1 -0
  592. package/dist/knowledge/audit-applier.js +251 -0
  593. package/dist/knowledge/audit-applier.js.map +1 -0
  594. package/dist/knowledge/builder.d.ts +261 -0
  595. package/dist/knowledge/builder.d.ts.map +1 -0
  596. package/dist/knowledge/builder.js +966 -0
  597. package/dist/knowledge/builder.js.map +1 -0
  598. package/dist/knowledge/cli-provider.d.ts +151 -0
  599. package/dist/knowledge/cli-provider.d.ts.map +1 -0
  600. package/dist/knowledge/cli-provider.js +313 -0
  601. package/dist/knowledge/cli-provider.js.map +1 -0
  602. package/dist/knowledge/constants.d.ts +78 -0
  603. package/dist/knowledge/constants.d.ts.map +1 -0
  604. package/dist/knowledge/constants.js +98 -0
  605. package/dist/knowledge/constants.js.map +1 -0
  606. package/dist/knowledge/cross-module.d.ts +139 -0
  607. package/dist/knowledge/cross-module.d.ts.map +1 -0
  608. package/dist/knowledge/cross-module.js +370 -0
  609. package/dist/knowledge/cross-module.js.map +1 -0
  610. package/dist/knowledge/git-hooks.d.ts +67 -0
  611. package/dist/knowledge/git-hooks.d.ts.map +1 -0
  612. package/dist/knowledge/git-hooks.js +258 -0
  613. package/dist/knowledge/git-hooks.js.map +1 -0
  614. package/dist/knowledge/graph/edge-extractor.d.ts +45 -0
  615. package/dist/knowledge/graph/edge-extractor.d.ts.map +1 -0
  616. package/dist/knowledge/graph/edge-extractor.js +242 -0
  617. package/dist/knowledge/graph/edge-extractor.js.map +1 -0
  618. package/dist/knowledge/graph/impact.d.ts +73 -0
  619. package/dist/knowledge/graph/impact.d.ts.map +1 -0
  620. package/dist/knowledge/graph/impact.js +94 -0
  621. package/dist/knowledge/graph/impact.js.map +1 -0
  622. package/dist/knowledge/graph/types.d.ts +22 -0
  623. package/dist/knowledge/graph/types.d.ts.map +1 -0
  624. package/dist/knowledge/graph/types.js +13 -0
  625. package/dist/knowledge/graph/types.js.map +1 -0
  626. package/dist/knowledge/module-hash.d.ts +88 -0
  627. package/dist/knowledge/module-hash.d.ts.map +1 -0
  628. package/dist/knowledge/module-hash.js +162 -0
  629. package/dist/knowledge/module-hash.js.map +1 -0
  630. package/dist/knowledge/project-detector.d.ts +101 -0
  631. package/dist/knowledge/project-detector.d.ts.map +1 -0
  632. package/dist/knowledge/project-detector.js +223 -0
  633. package/dist/knowledge/project-detector.js.map +1 -0
  634. package/dist/knowledge/prompt.d.ts +237 -0
  635. package/dist/knowledge/prompt.d.ts.map +1 -0
  636. package/dist/knowledge/prompt.js +416 -0
  637. package/dist/knowledge/prompt.js.map +1 -0
  638. package/dist/knowledge/query.d.ts +118 -0
  639. package/dist/knowledge/query.d.ts.map +1 -0
  640. package/dist/knowledge/query.js +438 -0
  641. package/dist/knowledge/query.js.map +1 -0
  642. package/dist/knowledge/repo-map.d.ts +97 -0
  643. package/dist/knowledge/repo-map.d.ts.map +1 -0
  644. package/dist/knowledge/repo-map.js +447 -0
  645. package/dist/knowledge/repo-map.js.map +1 -0
  646. package/dist/knowledge/tools/index.d.ts +14 -0
  647. package/dist/knowledge/tools/index.d.ts.map +1 -0
  648. package/dist/knowledge/tools/index.js +11 -0
  649. package/dist/knowledge/tools/index.js.map +1 -0
  650. package/dist/knowledge/tools/knowledge-get-page.d.ts +46 -0
  651. package/dist/knowledge/tools/knowledge-get-page.d.ts.map +1 -0
  652. package/dist/knowledge/tools/knowledge-get-page.js +101 -0
  653. package/dist/knowledge/tools/knowledge-get-page.js.map +1 -0
  654. package/dist/knowledge/tools/knowledge-query.d.ts +77 -0
  655. package/dist/knowledge/tools/knowledge-query.d.ts.map +1 -0
  656. package/dist/knowledge/tools/knowledge-query.js +104 -0
  657. package/dist/knowledge/tools/knowledge-query.js.map +1 -0
  658. package/dist/knowledge/tools/repo-map-lookup.d.ts +45 -0
  659. package/dist/knowledge/tools/repo-map-lookup.d.ts.map +1 -0
  660. package/dist/knowledge/tools/repo-map-lookup.js +82 -0
  661. package/dist/knowledge/tools/repo-map-lookup.js.map +1 -0
  662. package/dist/knowledge/types.d.ts +269 -0
  663. package/dist/knowledge/types.d.ts.map +1 -0
  664. package/dist/knowledge/types.js +10 -0
  665. package/dist/knowledge/types.js.map +1 -0
  666. package/dist/knowledge/validator.d.ts +90 -0
  667. package/dist/knowledge/validator.d.ts.map +1 -0
  668. package/dist/knowledge/validator.js +355 -0
  669. package/dist/knowledge/validator.js.map +1 -0
  670. package/dist/mcp/server.d.ts +64 -8
  671. package/dist/mcp/server.d.ts.map +1 -1
  672. package/dist/mcp/server.js +448 -12
  673. package/dist/mcp/server.js.map +1 -1
  674. package/dist/skills/builtin-skills.d.ts +35 -0
  675. package/dist/skills/builtin-skills.d.ts.map +1 -0
  676. package/dist/skills/builtin-skills.js +68 -0
  677. package/dist/skills/builtin-skills.js.map +1 -0
  678. package/dist/skills/distill/attribution.d.ts +59 -0
  679. package/dist/skills/distill/attribution.d.ts.map +1 -0
  680. package/dist/skills/distill/attribution.js +101 -0
  681. package/dist/skills/distill/attribution.js.map +1 -0
  682. package/dist/skills/distill/distiller.d.ts +161 -0
  683. package/dist/skills/distill/distiller.d.ts.map +1 -0
  684. package/dist/skills/distill/distiller.js +461 -0
  685. package/dist/skills/distill/distiller.js.map +1 -0
  686. package/dist/skills/distill/index.d.ts +223 -0
  687. package/dist/skills/distill/index.d.ts.map +1 -0
  688. package/dist/skills/distill/index.js +466 -0
  689. package/dist/skills/distill/index.js.map +1 -0
  690. package/dist/skills/distill/project-anchor-guard.d.ts +116 -0
  691. package/dist/skills/distill/project-anchor-guard.d.ts.map +1 -0
  692. package/dist/skills/distill/project-anchor-guard.js +334 -0
  693. package/dist/skills/distill/project-anchor-guard.js.map +1 -0
  694. package/dist/skills/distill/topic-deduper.d.ts +77 -0
  695. package/dist/skills/distill/topic-deduper.d.ts.map +1 -0
  696. package/dist/skills/distill/topic-deduper.js +119 -0
  697. package/dist/skills/distill/topic-deduper.js.map +1 -0
  698. package/dist/skills/distill/upstream-fetcher.d.ts +71 -0
  699. package/dist/skills/distill/upstream-fetcher.d.ts.map +1 -0
  700. package/dist/skills/distill/upstream-fetcher.js +202 -0
  701. package/dist/skills/distill/upstream-fetcher.js.map +1 -0
  702. package/dist/skills/distilled/distilled-api-design.md +495 -0
  703. package/dist/skills/distilled/distilled-architecture-decision.md +173 -0
  704. package/dist/skills/distilled/distilled-brainstorming.md +79 -0
  705. package/dist/skills/distilled/distilled-brand-guidelines.md +86 -0
  706. package/dist/skills/distilled/distilled-canvas-design.md +128 -0
  707. package/dist/skills/distilled/distilled-claude-api.md +185 -0
  708. package/dist/skills/distilled/distilled-creator.md +181 -0
  709. package/dist/skills/distilled/distilled-db-schema-design.md +245 -0
  710. package/dist/skills/distilled/distilled-dispatching-parallel-agents.md +136 -0
  711. package/dist/skills/distilled/distilled-doc-coauthoring.md +144 -0
  712. package/dist/skills/distilled/distilled-docx.md +231 -0
  713. package/dist/skills/distilled/distilled-executing-plans.md +148 -0
  714. package/dist/skills/distilled/distilled-finishing-a-development-branch.md +213 -0
  715. package/dist/skills/distilled/distilled-frontend-design.md +118 -0
  716. package/dist/skills/distilled/distilled-harness-engineering.md +242 -0
  717. package/dist/skills/distilled/distilled-karpathy-guidelines.md +104 -0
  718. package/dist/skills/distilled/distilled-performance-optimization.md +175 -0
  719. package/dist/skills/distilled/distilled-receiving-code-review.md +185 -0
  720. package/dist/skills/distilled/distilled-spec-driven-design.md +193 -0
  721. package/dist/skills/distilled/distilled-subagent-driven-development.md +124 -0
  722. package/dist/skills/distilled/distilled-systematic-debugging.md +154 -0
  723. package/dist/skills/distilled/distilled-test-driven-development.md +432 -0
  724. package/dist/skills/distilled/distilled-using-superpowers.md +134 -0
  725. package/dist/skills/distilled/distilled-verification-before-completion.md +213 -0
  726. package/dist/skills/distilled/distilled-writing-skills.md +175 -0
  727. package/dist/skills/registry.d.ts +55 -51
  728. package/dist/skills/registry.d.ts.map +1 -1
  729. package/dist/skills/registry.js +82 -196
  730. package/dist/skills/registry.js.map +1 -1
  731. package/dist/skills/tools/pipeline-suggest.js +14 -14
  732. package/dist/skills/tools/pipeline-suggest.js.map +1 -1
  733. package/dist/skills/tools/skill-invoke.d.ts +3 -2
  734. package/dist/skills/tools/skill-invoke.d.ts.map +1 -1
  735. package/dist/skills/tools/skill-invoke.js +4 -2
  736. package/dist/skills/tools/skill-invoke.js.map +1 -1
  737. package/dist/web/analytics/anti-pattern-detector.d.ts.map +1 -1
  738. package/dist/web/analytics/anti-pattern-detector.js +6 -1
  739. package/dist/web/analytics/anti-pattern-detector.js.map +1 -1
  740. package/dist/web/analytics/drift-detector.d.ts +6 -0
  741. package/dist/web/analytics/drift-detector.d.ts.map +1 -1
  742. package/dist/web/analytics/drift-detector.js +15 -8
  743. package/dist/web/analytics/drift-detector.js.map +1 -1
  744. package/dist/web/analytics/weekly-report.d.ts +13 -0
  745. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  746. package/dist/web/analytics/weekly-report.js +17 -3
  747. package/dist/web/analytics/weekly-report.js.map +1 -1
  748. package/dist/web/routes/_helpers.d.ts +31 -0
  749. package/dist/web/routes/_helpers.d.ts.map +1 -1
  750. package/dist/web/routes/_helpers.js +33 -0
  751. package/dist/web/routes/_helpers.js.map +1 -1
  752. package/dist/web/routes/agent-content.d.ts +30 -0
  753. package/dist/web/routes/agent-content.d.ts.map +1 -0
  754. package/dist/web/routes/agent-content.js +139 -0
  755. package/dist/web/routes/agent-content.js.map +1 -0
  756. package/dist/web/routes/agent-distill.d.ts +49 -0
  757. package/dist/web/routes/agent-distill.d.ts.map +1 -0
  758. package/dist/web/routes/agent-distill.js +526 -0
  759. package/dist/web/routes/agent-distill.js.map +1 -0
  760. package/dist/web/routes/config.d.ts +56 -0
  761. package/dist/web/routes/config.d.ts.map +1 -0
  762. package/dist/web/routes/config.js +243 -0
  763. package/dist/web/routes/config.js.map +1 -0
  764. package/dist/web/routes/decisions.d.ts +15 -0
  765. package/dist/web/routes/decisions.d.ts.map +1 -0
  766. package/dist/web/routes/decisions.js +181 -0
  767. package/dist/web/routes/decisions.js.map +1 -0
  768. package/dist/web/routes/diagnostics.d.ts +61 -0
  769. package/dist/web/routes/diagnostics.d.ts.map +1 -0
  770. package/dist/web/routes/diagnostics.js +203 -0
  771. package/dist/web/routes/diagnostics.js.map +1 -0
  772. package/dist/web/routes/error-handler.d.ts +0 -4
  773. package/dist/web/routes/error-handler.d.ts.map +1 -1
  774. package/dist/web/routes/error-handler.js +0 -8
  775. package/dist/web/routes/error-handler.js.map +1 -1
  776. package/dist/web/routes/events.d.ts.map +1 -1
  777. package/dist/web/routes/events.js +26 -1
  778. package/dist/web/routes/events.js.map +1 -1
  779. package/dist/web/routes/health.d.ts +33 -0
  780. package/dist/web/routes/health.d.ts.map +1 -0
  781. package/dist/web/routes/health.js +37 -0
  782. package/dist/web/routes/health.js.map +1 -0
  783. package/dist/web/routes/insights.d.ts +0 -5
  784. package/dist/web/routes/insights.d.ts.map +1 -1
  785. package/dist/web/routes/insights.js +0 -0
  786. package/dist/web/routes/insights.js.map +1 -1
  787. package/dist/web/routes/knowledge.d.ts +57 -0
  788. package/dist/web/routes/knowledge.d.ts.map +1 -0
  789. package/dist/web/routes/knowledge.js +772 -0
  790. package/dist/web/routes/knowledge.js.map +1 -0
  791. package/dist/web/routes/patch.d.ts +60 -1
  792. package/dist/web/routes/patch.d.ts.map +1 -1
  793. package/dist/web/routes/patch.js +170 -64
  794. package/dist/web/routes/patch.js.map +1 -1
  795. package/dist/web/routes/pipeline.d.ts +28 -0
  796. package/dist/web/routes/pipeline.d.ts.map +1 -0
  797. package/dist/web/routes/pipeline.js +145 -0
  798. package/dist/web/routes/pipeline.js.map +1 -0
  799. package/dist/web/routes/rules.d.ts.map +1 -1
  800. package/dist/web/routes/rules.js +26 -7
  801. package/dist/web/routes/rules.js.map +1 -1
  802. package/dist/web/routes/sessions.d.ts.map +1 -1
  803. package/dist/web/routes/sessions.js +17 -8
  804. package/dist/web/routes/sessions.js.map +1 -1
  805. package/dist/web/routes/skill-content.d.ts +30 -0
  806. package/dist/web/routes/skill-content.d.ts.map +1 -0
  807. package/dist/web/routes/skill-content.js +117 -0
  808. package/dist/web/routes/skill-content.js.map +1 -0
  809. package/dist/web/routes/skill-stats.d.ts.map +1 -1
  810. package/dist/web/routes/skill-stats.js +153 -16
  811. package/dist/web/routes/skill-stats.js.map +1 -1
  812. package/dist/web/routes/skills-distill.d.ts +29 -0
  813. package/dist/web/routes/skills-distill.d.ts.map +1 -0
  814. package/dist/web/routes/skills-distill.js +552 -0
  815. package/dist/web/routes/skills-distill.js.map +1 -0
  816. package/dist/web/routes/skills.js +7 -7
  817. package/dist/web/routes/skills.js.map +1 -1
  818. package/dist/web/routes/stats.d.ts.map +1 -1
  819. package/dist/web/routes/stats.js +2 -1
  820. package/dist/web/routes/stats.js.map +1 -1
  821. package/dist/web/routes/task-timeline.d.ts +178 -0
  822. package/dist/web/routes/task-timeline.d.ts.map +1 -0
  823. package/dist/web/routes/task-timeline.js +530 -0
  824. package/dist/web/routes/task-timeline.js.map +1 -0
  825. package/dist/web/routes/tasks.d.ts.map +1 -1
  826. package/dist/web/routes/tasks.js +377 -8
  827. package/dist/web/routes/tasks.js.map +1 -1
  828. package/dist/web/routes/trace.d.ts.map +1 -1
  829. package/dist/web/routes/trace.js +3 -2
  830. package/dist/web/routes/trace.js.map +1 -1
  831. package/dist/web/routes/types.d.ts +0 -4
  832. package/dist/web/routes/types.d.ts.map +1 -1
  833. package/dist/web/routes/types.js +1 -1
  834. package/dist/web/routes/types.js.map +1 -1
  835. package/dist/web/routes/violations.d.ts +14 -0
  836. package/dist/web/routes/violations.d.ts.map +1 -0
  837. package/dist/web/routes/violations.js +112 -0
  838. package/dist/web/routes/violations.js.map +1 -0
  839. package/dist/web/server.d.ts.map +1 -1
  840. package/dist/web/server.js +99 -19
  841. package/dist/web/server.js.map +1 -1
  842. package/dist/web/services/agent-distill-manager.d.ts +122 -0
  843. package/dist/web/services/agent-distill-manager.d.ts.map +1 -0
  844. package/dist/web/services/agent-distill-manager.js +397 -0
  845. package/dist/web/services/agent-distill-manager.js.map +1 -0
  846. package/dist/web/services/build-manager.d.ts +72 -0
  847. package/dist/web/services/build-manager.d.ts.map +1 -0
  848. package/dist/web/services/build-manager.js +189 -0
  849. package/dist/web/services/build-manager.js.map +1 -0
  850. package/dist/web/services/distill-manager.d.ts +172 -0
  851. package/dist/web/services/distill-manager.d.ts.map +1 -0
  852. package/dist/web/services/distill-manager.js +411 -0
  853. package/dist/web/services/distill-manager.js.map +1 -0
  854. package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js +2 -0
  855. package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js.map +1 -0
  856. package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js +3 -0
  857. package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js.map +1 -0
  858. package/dist/web/static/assets/AgentsPage-Qd9FExLG.js +2 -0
  859. package/dist/web/static/assets/AgentsPage-Qd9FExLG.js.map +1 -0
  860. package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js +2 -0
  861. package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js.map +1 -0
  862. package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js +2 -0
  863. package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js.map +1 -0
  864. package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js +2 -0
  865. package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js.map +1 -0
  866. package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js +2 -0
  867. package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js.map +1 -0
  868. package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js +4 -0
  869. package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js.map +1 -0
  870. package/dist/web/static/assets/DistillPage-O7BHtRN8.js +2 -0
  871. package/dist/web/static/assets/DistillPage-O7BHtRN8.js.map +1 -0
  872. package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js +2 -0
  873. package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js.map +1 -0
  874. package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js +2 -0
  875. package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js.map +1 -0
  876. package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js +2 -0
  877. package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js.map +1 -0
  878. package/dist/web/static/assets/IssuesPage-SKmhlCrw.js +2 -0
  879. package/dist/web/static/assets/IssuesPage-SKmhlCrw.js.map +1 -0
  880. package/dist/web/static/assets/KbDetailPage-Yna86Na8.js +2 -0
  881. package/dist/web/static/assets/KbDetailPage-Yna86Na8.js.map +1 -0
  882. package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js +2 -0
  883. package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js.map +1 -0
  884. package/dist/web/static/assets/MarkdownRenderer-DlDQNihj.js +3 -0
  885. package/dist/web/static/assets/MarkdownRenderer-DlDQNihj.js.map +1 -0
  886. package/dist/web/static/assets/NotFound-LMzbP51V.js +2 -0
  887. package/dist/web/static/assets/NotFound-LMzbP51V.js.map +1 -0
  888. package/dist/web/static/assets/SettingsPage-DzoK4PKg.js +2 -0
  889. package/dist/web/static/assets/SettingsPage-DzoK4PKg.js.map +1 -0
  890. package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js +2 -0
  891. package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js.map +1 -0
  892. package/dist/web/static/assets/SkillsPage-aojkJpBc.js +2 -0
  893. package/dist/web/static/assets/SkillsPage-aojkJpBc.js.map +1 -0
  894. package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js +4 -0
  895. package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js.map +1 -0
  896. package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js +6 -0
  897. package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js.map +1 -0
  898. package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js +2 -0
  899. package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js.map +1 -0
  900. package/dist/web/static/assets/arco-DFQA6dO_.css +1 -0
  901. package/dist/web/static/assets/arco-DV6xCLhr.js +14 -0
  902. package/dist/web/static/assets/arco-DV6xCLhr.js.map +1 -0
  903. package/dist/web/static/assets/charts-BSV4cyC4.js +37 -0
  904. package/dist/web/static/assets/charts-BSV4cyC4.js.map +1 -0
  905. package/dist/web/static/assets/date-fns-sbWH3_uq.js +2 -0
  906. package/dist/web/static/assets/date-fns-sbWH3_uq.js.map +1 -0
  907. package/dist/web/static/assets/index-B_v_MKlb.css +1 -0
  908. package/dist/web/static/assets/index-DileOOE4.js +4 -0
  909. package/dist/web/static/assets/index-DileOOE4.js.map +1 -0
  910. package/dist/web/static/assets/lucide-CnlPQoG8.js +72 -0
  911. package/dist/web/static/assets/lucide-CnlPQoG8.js.map +1 -0
  912. package/dist/web/static/assets/markdown-CA7ePUts.js +30 -0
  913. package/dist/web/static/assets/markdown-CA7ePUts.js.map +1 -0
  914. package/dist/web/static/assets/outcome-BKGy9azt.js +2 -0
  915. package/dist/web/static/assets/outcome-BKGy9azt.js.map +1 -0
  916. package/dist/web/static/assets/query-CgCOpYWf.js +2 -0
  917. package/dist/web/static/assets/{query-C99w429o.js.map → query-CgCOpYWf.js.map} +1 -1
  918. package/dist/web/static/assets/{react-router-r79dBVy4.js → react-router-Cxmg8RuL.js} +3 -3
  919. package/dist/web/static/assets/{react-router-r79dBVy4.js.map → react-router-Cxmg8RuL.js.map} +1 -1
  920. package/dist/web/static/assets/react-vendor-tkvCrao7.js +57 -0
  921. package/dist/web/static/assets/react-vendor-tkvCrao7.js.map +1 -0
  922. package/dist/web/static/assets/syntax-highlighter-BDYycNja.js +6 -0
  923. package/dist/web/static/assets/syntax-highlighter-BDYycNja.js.map +1 -0
  924. package/dist/web/static/assets/useAgentStats-B-uTgqBd.js +2 -0
  925. package/dist/web/static/assets/useAgentStats-B-uTgqBd.js.map +1 -0
  926. package/dist/web/static/assets/useDecisions-D-G2Ft5T.js +2 -0
  927. package/dist/web/static/assets/useDecisions-D-G2Ft5T.js.map +1 -0
  928. package/dist/web/static/assets/useDistill-21dZkXlT.js +3 -0
  929. package/dist/web/static/assets/useDistill-21dZkXlT.js.map +1 -0
  930. package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js +2 -0
  931. package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js.map +1 -0
  932. package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js +2 -0
  933. package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js.map +1 -0
  934. package/dist/web/static/assets/useKbHits-xKXWgqh9.js +2 -0
  935. package/dist/web/static/assets/useKbHits-xKXWgqh9.js.map +1 -0
  936. package/dist/web/static/assets/useSkillStats-B5hbIwdf.js +2 -0
  937. package/dist/web/static/assets/useSkillStats-B5hbIwdf.js.map +1 -0
  938. package/dist/web/static/assets/vendor-DS-q4Eyc.js +36 -0
  939. package/dist/web/static/assets/vendor-DS-q4Eyc.js.map +1 -0
  940. package/dist/web/static/index.html +12 -8
  941. package/package.json +18 -5
  942. package/dist/core/ai/provider.d.ts +0 -63
  943. package/dist/core/ai/provider.d.ts.map +0 -1
  944. package/dist/core/ai/provider.js +0 -241
  945. package/dist/core/ai/provider.js.map +0 -1
  946. package/dist/core/ai/types.d.ts +0 -43
  947. package/dist/core/ai/types.d.ts.map +0 -1
  948. package/dist/core/ai/types.js +0 -5
  949. package/dist/core/ai/types.js.map +0 -1
  950. package/dist/core/storage/token-usage.d.ts +0 -36
  951. package/dist/core/storage/token-usage.d.ts.map +0 -1
  952. package/dist/core/storage/token-usage.js +0 -59
  953. package/dist/core/storage/token-usage.js.map +0 -1
  954. package/dist/core/utils/token-tracker.d.ts +0 -39
  955. package/dist/core/utils/token-tracker.d.ts.map +0 -1
  956. package/dist/core/utils/token-tracker.js +0 -69
  957. package/dist/core/utils/token-tracker.js.map +0 -1
  958. package/dist/skills/index.d.ts +0 -3
  959. package/dist/skills/index.d.ts.map +0 -1
  960. package/dist/skills/index.js +0 -3
  961. package/dist/skills/index.js.map +0 -1
  962. package/dist/skills/matcher.d.ts +0 -26
  963. package/dist/skills/matcher.d.ts.map +0 -1
  964. package/dist/skills/matcher.js +0 -113
  965. package/dist/skills/matcher.js.map +0 -1
  966. package/dist/skills/official/code-simplifier.md +0 -52
  967. package/dist/skills/official/find-skills.md +0 -142
  968. package/dist/skills/official/official-api-design.md +0 -30
  969. package/dist/skills/official/official-architecture-decision.md +0 -41
  970. package/dist/skills/official/official-bmad.md +0 -118
  971. package/dist/skills/official/official-db-schema-design.md +0 -34
  972. package/dist/skills/official/official-debug.md +0 -25
  973. package/dist/skills/official/official-doc-driven.md +0 -31
  974. package/dist/skills/official/official-harness-engineering.md +0 -108
  975. package/dist/skills/official/official-openspec.md +0 -89
  976. package/dist/skills/official/official-performance-optimization.md +0 -30
  977. package/dist/skills/official/official-pr-review.md +0 -35
  978. package/dist/skills/official/official-release-checklist.md +0 -30
  979. package/dist/skills/official/official-security-hardening.md +0 -32
  980. package/dist/skills/official/official-spec-driven-design.md +0 -31
  981. package/dist/skills/official/planning-with-files.md +0 -241
  982. package/dist/skills/official/ui-ux-pro-max.md +0 -105
  983. package/dist/skills/official/webapp-testing.md +0 -96
  984. package/dist/skills/official-skills.d.ts +0 -26
  985. package/dist/skills/official-skills.d.ts.map +0 -1
  986. package/dist/skills/official-skills.js +0 -74
  987. package/dist/skills/official-skills.js.map +0 -1
  988. package/dist/skills/semantic-matcher.d.ts +0 -60
  989. package/dist/skills/semantic-matcher.d.ts.map +0 -1
  990. package/dist/skills/semantic-matcher.js +0 -192
  991. package/dist/skills/semantic-matcher.js.map +0 -1
  992. package/dist/skills/upgrade-engine.d.ts +0 -93
  993. package/dist/skills/upgrade-engine.d.ts.map +0 -1
  994. package/dist/skills/upgrade-engine.js +0 -447
  995. package/dist/skills/upgrade-engine.js.map +0 -1
  996. package/dist/skills/upgrade-prompt.d.ts +0 -20
  997. package/dist/skills/upgrade-prompt.d.ts.map +0 -1
  998. package/dist/skills/upgrade-prompt.js +0 -75
  999. package/dist/skills/upgrade-prompt.js.map +0 -1
  1000. package/dist/web/routes/ai.d.ts +0 -10
  1001. package/dist/web/routes/ai.d.ts.map +0 -1
  1002. package/dist/web/routes/ai.js +0 -186
  1003. package/dist/web/routes/ai.js.map +0 -1
  1004. package/dist/web/routes/token-usage.d.ts +0 -7
  1005. package/dist/web/routes/token-usage.d.ts.map +0 -1
  1006. package/dist/web/routes/token-usage.js +0 -18
  1007. package/dist/web/routes/token-usage.js.map +0 -1
  1008. package/dist/web/ssrf-guard.d.ts +0 -35
  1009. package/dist/web/ssrf-guard.d.ts.map +0 -1
  1010. package/dist/web/ssrf-guard.js +0 -93
  1011. package/dist/web/ssrf-guard.js.map +0 -1
  1012. package/dist/web/static/assets/AIConfig-CdDWzJyO.js +0 -2
  1013. package/dist/web/static/assets/AIConfig-CdDWzJyO.js.map +0 -1
  1014. package/dist/web/static/assets/Dashboard-CoEmmIDt.js +0 -2
  1015. package/dist/web/static/assets/Dashboard-CoEmmIDt.js.map +0 -1
  1016. package/dist/web/static/assets/Drawer-DdRTzlLB.js +0 -2
  1017. package/dist/web/static/assets/Drawer-DdRTzlLB.js.map +0 -1
  1018. package/dist/web/static/assets/Events-DrIq1SUS.js +0 -2
  1019. package/dist/web/static/assets/Events-DrIq1SUS.js.map +0 -1
  1020. package/dist/web/static/assets/Reports-DFBM3MDK.js +0 -2
  1021. package/dist/web/static/assets/Reports-DFBM3MDK.js.map +0 -1
  1022. package/dist/web/static/assets/SearchInput-qCj_jAcf.js +0 -2
  1023. package/dist/web/static/assets/SearchInput-qCj_jAcf.js.map +0 -1
  1024. package/dist/web/static/assets/SessionDetail-CCzwdoT7.js +0 -2
  1025. package/dist/web/static/assets/SessionDetail-CCzwdoT7.js.map +0 -1
  1026. package/dist/web/static/assets/Sessions-FfLYkAw9.js +0 -2
  1027. package/dist/web/static/assets/Sessions-FfLYkAw9.js.map +0 -1
  1028. package/dist/web/static/assets/Skills-C8Gvs3Qa.js +0 -2
  1029. package/dist/web/static/assets/Skills-C8Gvs3Qa.js.map +0 -1
  1030. package/dist/web/static/assets/TaskDetail-BS8pYhaR.js +0 -2
  1031. package/dist/web/static/assets/TaskDetail-BS8pYhaR.js.map +0 -1
  1032. package/dist/web/static/assets/Tasks-CyuhizG8.js +0 -2
  1033. package/dist/web/static/assets/Tasks-CyuhizG8.js.map +0 -1
  1034. package/dist/web/static/assets/charts-CLrM0_uM.js +0 -37
  1035. package/dist/web/static/assets/charts-CLrM0_uM.js.map +0 -1
  1036. package/dist/web/static/assets/date-fns-CZ_bHujz.js +0 -2
  1037. package/dist/web/static/assets/date-fns-CZ_bHujz.js.map +0 -1
  1038. package/dist/web/static/assets/export-L_VBD2p1.js +0 -4
  1039. package/dist/web/static/assets/export-L_VBD2p1.js.map +0 -1
  1040. package/dist/web/static/assets/index-CBX47X8l.js +0 -3
  1041. package/dist/web/static/assets/index-CBX47X8l.js.map +0 -1
  1042. package/dist/web/static/assets/index-DjIoMdoR.css +0 -1
  1043. package/dist/web/static/assets/lucide-Bs_edTLa.js +0 -232
  1044. package/dist/web/static/assets/lucide-Bs_edTLa.js.map +0 -1
  1045. package/dist/web/static/assets/query-C99w429o.js +0 -2
  1046. package/dist/web/static/assets/react-vendor-CSp-GLFF.js +0 -49
  1047. package/dist/web/static/assets/react-vendor-CSp-GLFF.js.map +0 -1
  1048. package/dist/web/static/assets/syntax-highlighter-44FakypI.js +0 -9
  1049. package/dist/web/static/assets/syntax-highlighter-44FakypI.js.map +0 -1
  1050. package/dist/web/static/assets/time-Bxuk0M-C.js +0 -2
  1051. package/dist/web/static/assets/time-Bxuk0M-C.js.map +0 -1
  1052. package/dist/web/static/assets/vendor-CMMjVdZs.js +0 -64
  1053. package/dist/web/static/assets/vendor-CMMjVdZs.js.map +0 -1
@@ -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":"8pBAkUA,MAAMA,GAAe,CAAC,UAAW,SAAU,OAAQ,eAAgB,WAAY,UAAW,SAAU,QAAS,SAAS,EAQtH,SAASC,GAAgBC,EAA+B,CACtD,GAAI,OAAOA,GAAU,SACnB,OAAOA,EAAM,OAASA,EAAQ,KAEhC,GAAI,MAAM,QAAQA,CAAK,EAAG,CAExB,MAAMC,EAAkB,CAAA,EACxB,UAAWC,KAASF,EACd,OAAOE,GAAU,SACnBD,EAAM,KAAKC,CAAK,EACPA,GAAS,OAAOA,GAAU,UAAY,OAAQA,EAA6B,MAAS,UAC7FD,EAAM,KAAMC,EAA2B,IAAI,EAG/C,MAAMC,EAASF,EAAM,KAAK;AAAA;AAAA,CAAM,EAAE,KAAA,EAClC,OAAOE,GAAkB,IAC3B,CACA,OAAO,IACT,CAGA,SAASC,EAAWJ,EAAwB,CAC1C,GAAI,CACF,OAAO,KAAK,UAAUA,EAAO,KAAM,CAAC,CACtC,MAAQ,CACN,OAAO,OAAOA,CAAK,CACrB,CACF,CAgBO,SAASK,GAAiBC,EAAmD,CAClF,MAAMC,GAAQD,GAAO,IAAI,KAAA,EACzB,GAAI,CAACC,EAAM,MAAO,CAAE,KAAM,KAAM,SAAU,EAAA,EAK1C,GAAI,EADcA,EAAK,WAAW,GAAG,GAAKA,EAAK,WAAW,GAAG,GAE3D,MAAO,CAAE,KAAM,KAAM,SAAUA,CAAA,EAGjC,IAAIC,EACJ,GAAI,CACFA,EAAS,KAAK,MAAMD,CAAI,CAC1B,MAAQ,CAEN,MAAO,CAAE,KAAM,KAAM,SAAUA,CAAA,CACjC,CAGA,GAAIC,IAAW,MAAQ,OAAOA,GAAW,SACvC,MAAO,CAAE,KAAM,KAAM,SAAUD,CAAA,EAIjC,GAAI,CAAC,MAAM,QAAQC,CAAM,EAAG,CAC1B,MAAMC,EAAMD,EACZ,UAAWE,KAAOZ,GAChB,GAAIY,KAAOD,EAAK,CACd,MAAME,EAAOZ,GAAgBU,EAAIC,CAAG,CAAC,EACrC,GAAIC,EACF,MAAO,CAAE,KAAM,eAAgB,SAAUA,EAAM,KAAMH,EAAQ,OAAQJ,EAAWI,CAAM,EAAG,QAASE,CAAA,CAEtG,CAGF,MAAO,CAAE,KAAM,OAAQ,KAAMF,EAAQ,OAAQJ,EAAWI,CAAM,CAAA,CAChE,CAGA,MAAMI,EAAUb,GAAgBS,CAAM,EACtC,OAAII,EACK,CAAE,KAAM,eAAgB,SAAUA,EAAS,KAAMJ,EAAQ,OAAQJ,EAAWI,CAAM,EAAG,QAAS,SAAA,EAEhG,CAAE,KAAM,OAAQ,KAAMA,EAAQ,OAAQJ,EAAWI,CAAM,CAAA,CAChE,CAIA,MAAMK,GAAgB,IAAI,IAAI,CAAC,cAAc,CAAC,EAiBxCC,GAAkB,mDAYjB,SAASC,GAAmBC,EAAkD,CACnF,GAAI,CAACA,EAAQ,OAAO,KACpB,MAAMT,EAAOS,EAGb,IAAIC,EAAsB,KAC1BH,GAAgB,UAAY,EAC5B,IAAII,EACJ,MAAQA,EAAIJ,GAAgB,KAAKP,CAAI,KAAO,MAC1CU,EAAOC,EAAE,CAAC,EAAE,YAAA,EAEd,GAAID,EAAM,CACR,GAAIA,IAAS,QAAUA,IAAS,UAAW,MAAO,OAClD,GAAIA,IAAS,QAAUA,IAAS,OAAQ,MAAO,MACjD,CAGA,MAAI,uBAAuB,KAAKV,CAAI,EAAU,OAC1C,cAAc,KAAKA,CAAI,EAAU,UACjC,oBAAoB,KAAKA,CAAI,EAAU,OACpC,IACT,CAGO,SAASY,GAAiBC,EAAsC,CACrE,GAAI,CAACA,EAAc,MAAO,GAC1B,MAAM,EAAIA,EAAa,YAAA,EACvB,OACE,IAAM,SACN,EAAE,SAAS,aAAa,GACxB,EAAE,SAAS,YAAY,GACvB,EAAE,SAAS,mBAAmB,GAC9B,EAAE,SAAS,UAAU,GACrB,EAAE,SAAS,iBAAiB,GAC5B,EAAE,WAAW,UAAU,CAE3B,CAGO,SAASC,GAAgBD,EAAsC,CACpE,GAAI,CAACA,EAAc,MAAO,GAC1B,MAAM,EAAIA,EAAa,YAAA,EACvB,OAAO,IAAM,kBAAoB,EAAE,SAAS,SAAS,CACvD,CAGO,SAASE,GAAcF,EAAsC,CAClE,OAAKA,EACEP,GAAc,IAAIO,EAAa,YAAA,CAAa,EADzB,EAE5B,CAOO,SAASG,GAAkBH,EAGhC,CACA,OAAIC,GAAgBD,CAAY,EAAU,CAAE,KAAM,WAAY,SAAU,EAAA,EACpEE,GAAcF,CAAY,EAAU,CAAE,KAAM,SAAU,SAAU,EAAA,EAChED,GAAiBC,CAAY,EAAU,CAAE,KAAM,YAAa,SAAU,EAAA,EAEnE,CAAE,KAAM,YAAa,SAAU,EAAA,CACxC,CASA,MAAMI,GAAqB,IAErBC,EAAsC,CAC1C,SAAU,KACV,UAAW,KACX,OAAQ,KACR,OAAQ,IACV,EAyBA,SAASC,EAAQC,EAA+C,CAC9D,GAAI,CAACA,EAAK,OAAO,KACjB,MAAMC,EAAK,IAAI,KAAKD,CAAG,EAAE,QAAA,EACzB,OAAO,OAAO,SAASC,CAAE,EAAIA,EAAK,IACpC,CAOA,SAASC,GACPC,EACAC,EAC4B,CAC5B,MAAMC,GAAUF,EAAG,eAAiB,IAAI,YAAA,EAClCG,EAAOP,EAAQI,EAAG,EAAE,EAC1B,IAAII,EACAC,EAAY,OAAO,kBACvB,UAAWC,KAAKL,EAAQ,CACtB,IAAKK,EAAE,eAAiB,IAAI,YAAA,IAAkBJ,EAAQ,SACtD,MAAMK,EAAMX,EAAQU,EAAE,SAAS,EACzBE,EAAQL,IAAS,MAAQI,IAAQ,KAAO,KAAK,IAAIJ,EAAOI,CAAG,EAAI,OAAO,kBACxEC,EAAQH,IACVA,EAAYG,EACZJ,EAAOE,EAEX,CACA,OAAOF,CACT,CAGA,SAASK,GACPC,EACAV,EACe,CACf,GAAIU,EAAM,CACR,MAAMC,EAAIf,EAAQc,EAAK,SAAS,EAC1BE,EAAIhB,EAAQc,EAAK,aAAa,EACpC,GAAIC,IAAM,MAAQC,IAAM,MAAQA,GAAKD,SAAUC,EAAID,CACrD,CACA,OAAOX,GAAA,YAAAA,EAAI,cAAe,IAC5B,CAKA,SAASa,GACPH,EACAV,EACsE,CACtE,OAAIU,IAASA,EAAK,QAAUA,EAAK,QACxB,CAAE,OAAQA,EAAK,QAAU,KAAM,OAAQA,EAAK,QAAU,KAAM,UAAW,EAAA,EAE5EV,EACK,CACL,OAAQA,EAAG,gBAAkB,KAC7B,OAAQA,EAAG,gBAAkB,KAC7B,UAAW,EAAA,EAGR,CAAE,OAAQ,KAAM,OAAQ,KAAM,UAAW,EAAA,CAClD,CAGA,SAASc,GAAad,EAAqBe,EAA+BC,EAAmC,CAC3G,MAAMN,EAAOX,GAAWC,EAAIe,CAAW,EACjCE,EAAUJ,GAAYH,EAAMV,CAAE,EAC9BkB,EAAW1B,GAAcQ,EAAG,aAAa,EAGzCmB,GAAWT,GAAA,YAAAA,EAAM,UAAW,EAClC,MAAO,CACL,MAAOV,EAAG,eAAiB,YAC3B,GAAIA,EAAG,IAAM,KACb,WAAYS,GAAcC,EAAMV,CAAE,EAClC,WAAYiB,EAAQ,OACpB,WAAYA,EAAQ,OACpB,QAASC,EAAWjC,GAAmBgC,EAAQ,QAAUjB,EAAG,cAAc,EAAI,KAC9E,OAAQ,KACR,cAAe,KACf,UAAWiB,EAAQ,UACnB,SAAAD,EACA,SAAAG,EACA,WAAY,EAAA,CAEhB,CAEA,MAAMC,EAAQ,CAACT,EAA0BC,KACtChB,EAAQe,EAAE,EAAE,GAAK,IAAMf,EAAQgB,EAAE,EAAE,GAAK,GAGrCS,EAAiBC,GAA8BA,EAAQ,OAAOC,GAAK,CAACA,EAAE,QAAQ,EAAE,OAEhFC,EAAmBF,GAA8BA,EAAQ,OAAOC,GAAKA,EAAE,QAAQ,EAAE,OAWvF,SAASE,EAAeH,EAA0C,CAChE,MAAMI,EAASJ,EAAQ,OAAOC,GAAK,CAACA,EAAE,QAAQ,EAC9C,GAAIG,EAAO,SAAW,EAAG,OAAO,KAEhC,MAAMC,MAAY,IACZC,MAAa,IACnB,IAAIC,EAAM,EACV,UAAWN,KAAKG,EACTC,EAAM,IAAIJ,EAAE,KAAK,GAAGI,EAAM,IAAIJ,EAAE,MAAOM,GAAK,EACjDD,EAAO,IAAIL,EAAE,OAAQK,EAAO,IAAIL,EAAE,KAAK,GAAK,GAAK,CAAC,EAKpD,MAHc,CAAC,GAAGK,EAAO,SAAS,EAC/B,KAAK,CAACjB,EAAGC,IAAMA,EAAE,CAAC,EAAID,EAAE,CAAC,IAAMgB,EAAM,IAAIhB,EAAE,CAAC,CAAC,GAAK,IAAMgB,EAAM,IAAIf,EAAE,CAAC,CAAC,GAAK,EAAE,EAC7E,IAAI,CAAC,CAACkB,EAAOC,CAAC,IAAOA,EAAI,EAAI,GAAGD,CAAK,KAAKC,CAAC,GAAKD,CAAM,EAC5C,KAAK,KAAK,CACzB,CAuBO,SAASE,GACdC,EACAlB,EAAgC,GACnB,WACb,MAAMd,EAASgC,EAAO,OAAQV,GAA4BA,EAAE,OAAS,aAAa,EAC5EW,EAAYD,EAAO,OACtBV,GACCA,EAAE,OAAS,mBAAA,EAETY,EAAUF,EAAO,OACpBV,GAAuDA,EAAE,OAAS,QAAA,EAI/Da,EAAoC,CAAA,EACpCC,EAAqC,CAAA,EACrCC,EAAkC,CAAA,EACxC,UAAWtC,KAAMC,EAAQ,CACvB,KAAM,CAAE,KAAAsC,EAAM,SAAAvB,CAAA,EAAavB,GAAkBO,EAAG,aAAa,EACvDwC,EAAQ1B,GAAad,EAAIe,EAAaC,CAAQ,EAChDuB,IAAS,WAAYH,EAAgB,KAAKI,CAAK,EAC1CD,IAAS,SAAUD,EAAc,KAAKE,CAAK,EAC/CH,EAAiB,KAAKG,CAAK,CAClC,CACAJ,EAAgB,KAAKhB,CAAK,EAC1BiB,EAAiB,KAAKjB,CAAK,EAC3BkB,EAAc,KAAKlB,CAAK,EAMxB,MAAMqB,EAAkCN,EAAQ,IAAIO,GAAK,CACvD,MAAMC,EAAU,OAAOD,EAAE,cAAiB,SACpCE,GAAWD,EAAUD,EAAE,aAAeA,EAAE,kBAAoB,KAC5DG,EAAYF,EAAUD,EAAE,oBAAsB,GAAOA,EAAE,gBAAgB,QAAUhD,GACvF,MAAO,CACL,MAAO,SACP,GAAIgD,EAAE,IAAM,KACZ,WAAY,KACZ,WAAY,KACZ,WAAY,KACZ,QAAS,KACT,OAAQA,EAAE,KACV,cAAeE,EACf,UAAAC,EACA,SAAU,GACV,SAAU,GACV,WAAYH,EAAE,cAAgB,aAAA,CAElC,CAAC,EAEKI,EAAaZ,EAAU,CAAC,EACxBa,EAAaN,EAAcA,EAAc,OAAS,CAAC,EAGnDO,EAAkBZ,EAAgB,KAAKb,GAAKA,EAAE,MAAM,YAAA,IAAkB,gBAAgB,GACvFa,EAAgB,CAAC,EAChBa,GAAaH,GAAA,YAAAA,EAAY,MAAME,GAAA,YAAAA,EAAiB,KAAM,KACtDE,GAAgBF,GAAA,YAAAA,EAAiB,SAAUF,EAAa,iBAAmB,MAC3EK,EAAkBf,EAAgB,OAAS,GAAK,CAAC,CAACU,EAClDM,EAAiBC,GAAa,KAAMjB,EAAiB,CACzD,WAAAU,EACA,MAAO,2CAAA,CACR,EAGKQ,EAAmBjB,EAAiBA,EAAiB,OAAS,CAAC,EAC/DkB,EAAkBF,GAAa,KAAMhB,EAAkB,CAC3D,MAAO,oBAAA,CACR,EAGKmB,EAAgBlB,EAAcA,EAAc,OAAS,CAAC,EACtDmB,GAAUD,GAAA,YAAAA,EAAe,UAAW,KACpCE,EAAepB,EAAc,OAAS,EACxCA,EAAc,SAAW,EACvB,mBAAmBmB,GAAW,cAAc,aAC5C,GAAGnB,EAAc,MAAM,2BAA2BmB,GAAW,KAAK,aACpE,4BAGEE,EAAelB,EAAc,OAAS,EACxCA,EAAc,SAAW,EACvB,MAAMM,EAAW,MAAM,IACvB,GAAGN,EAAc,MAAM,WAAWM,EAAW,MAAM,WACrD,wBAEJ,MAAO,CACL,CACE,IAAK,WACL,MAAOpD,EAAW,SAClB,QAASyC,EACT,MAAOc,EACP,aAAczB,EAAeW,CAAe,EAC5C,GAAIa,EACJ,QAAS,KACT,OAAQ,KACR,QAASE,EACT,OAAQC,EACR,YAAYJ,GAAA,YAAAA,EAAiB,aAAc,KAC3C,YAAYA,GAAA,YAAAA,EAAiB,aAAc,KAC3C,YAAYA,GAAA,YAAAA,EAAiB,aAAc,KAC3C,YAAYF,GAAA,YAAAA,EAAY,cAAe,KACvC,gBAAgBA,GAAA,YAAAA,EAAY,SAAU,KACtC,cAAe,KACf,WAAWE,GAAA,YAAAA,EAAiB,YAAa,GACzC,WAAYZ,EAAgB,OAC5B,YAAaf,EAAce,CAAe,EAC1C,cAAeZ,EAAgBY,CAAe,CAAA,EAEhD,CACE,IAAK,YACL,MAAOzC,EAAW,UAClB,QAAS0C,EACT,OAAOiB,GAAA,YAAAA,EAAkB,QAAS,KAClC,aAAc7B,EAAeY,CAAgB,EAC7C,KAAIuB,EAAAvB,EAAiB,CAAC,IAAlB,YAAAuB,EAAqB,KAAM,KAC/B,QAAS,KACT,OAAQ,KACR,QAASvB,EAAiB,OAAS,EACnC,OAAQkB,EACR,YAAYD,GAAA,YAAAA,EAAkB,aAAc,KAC5C,YAAYA,GAAA,YAAAA,EAAkB,aAAc,KAC5C,YAAYA,GAAA,YAAAA,EAAkB,aAAc,KAC5C,WAAY,KACZ,eAAgB,KAChB,cAAe,KACf,WAAWA,GAAA,YAAAA,EAAkB,YAAa,GAC1C,WAAYjB,EAAiB,OAC7B,YAAahB,EAAcgB,CAAgB,EAC3C,cAAeb,EAAgBa,CAAgB,CAAA,EAEjD,CACE,IAAK,SACL,MAAO1C,EAAW,OAClB,QAAS2C,EACT,OAAOkB,GAAA,YAAAA,EAAe,QAAS,KAC/B,aAAc/B,EAAea,CAAa,EAC1C,KAAIuB,EAAAvB,EAAc,CAAC,IAAf,YAAAuB,EAAkB,KAAM,KAC5B,QAAAJ,EACA,OAAQ,KACR,QAASnB,EAAc,OAAS,EAChC,OAAQoB,EACR,YAAYF,GAAA,YAAAA,EAAe,aAAc,KACzC,YAAYA,GAAA,YAAAA,EAAe,aAAc,KACzC,YAAYA,GAAA,YAAAA,EAAe,aAAc,KACzC,WAAY,KACZ,eAAgB,KAChB,cAAe,KACf,WAAWA,GAAA,YAAAA,EAAe,YAAa,GACvC,WAAYlB,EAAc,OAC1B,YAAajB,EAAciB,CAAa,EACxC,cAAed,EAAgBc,CAAa,CAAA,EAE9C,CACE,IAAK,SACL,MAAO3C,EAAW,OAClB,QAAS8C,EACT,MAAOM,EAAa,SAAW,KAC/B,aAActB,EAAegB,CAAa,EAC1C,KAAIqB,EAAArB,EAAc,CAAC,IAAf,YAAAqB,EAAkB,KAAM,KAC5B,QAAS,KACT,QAAQf,GAAA,YAAAA,EAAY,SAAU,KAC9B,QAASN,EAAc,OAAS,EAChC,OAAQkB,EACR,WAAY,KACZ,WAAY,KACZ,WAAY,KACZ,WAAY,KACZ,eAAgB,KAChB,eAAeZ,GAAA,YAAAA,EAAY,gBAAiB,KAC5C,WAAWA,GAAA,YAAAA,EAAY,YAAa,GACpC,WAAYN,EAAc,OAC1B,YAAapB,EAAcoB,CAAa,EACxC,cAAejB,EAAgBiB,CAAa,CAAA,CAC9C,CAEJ,CAGA,SAASY,GACPU,EACAzC,EACA0C,EAIQ,CACR,GAAI1C,EAAQ,SAAW,EACrB,OAAI0C,EAAK,WAAmB,OAAOA,EAAK,WAAW,WAAW,MAAMA,EAAK,WAAW,MAAM,IACnFA,EAAK,MAGd,MAAMpC,MAAa,IACnB,UAAWL,KAAKD,EAASM,EAAO,IAAIL,EAAE,OAAQK,EAAO,IAAIL,EAAE,KAAK,GAAK,GAAK,CAAC,EAC3E,MAAMpD,EAAQ,CAAC,GAAGyD,EAAO,SAAS,EAAE,IAAI,CAAC,CAACjB,EAAGoB,CAAC,IAAOA,EAAI,EAAI,GAAGpB,CAAC,KAAKoB,CAAC,GAAKpB,CAAE,EACxEsD,EAASD,EAAK,WAAa,OAAOA,EAAK,WAAW,WAAW,MAAMA,EAAK,WAAW,MAAM,IAAM,GACrG,OAAI1C,EAAQ,SAAW,EACd,GAAG2C,CAAM,GAAG9F,EAAM,CAAC,CAAC,0BAEtB,GAAG8F,CAAM,GAAGF,CAAK,MAAMzC,EAAQ,MAAM,UAAUnD,EAAM,KAAK,GAAG,CAAC,UACvE,CAIA,MAAM+F,GAA6C,CACjD,OACA,OACA,YACA,WACA,SACF,EAGO,SAASC,GAAmBC,EAAuD,CACxF,GAAI,CAACA,EAAW,MAAO,CAAA,EACvB,MAAMC,EAAqB,CAAA,EAC3B,UAAWC,KAAUJ,GACnB,UAAWK,KAAQH,EAAUE,CAAM,GAAK,CAAA,EACtCD,EAAI,KAAK,CAAE,KAAAE,EAAM,OAAAD,CAAA,CAAQ,EAG7B,OAAOD,CACT,CAGO,SAASG,GAAcvC,EAAsC,CAClE,OAAOA,EACJ,OAAQV,GAAuDA,EAAE,OAAS,QAAQ,EAClF,IAAIA,IAAM,CAAE,KAAMA,EAAE,KAAM,QAASA,EAAE,iBAAkB,CAC5D,CAKO,SAASkD,GAAaxC,EAAqC,CAChE,OAAOA,EACJ,OACEV,GAA+DA,EAAE,OAAS,gBAAA,EAE5E,IAAI,CAACA,EAAGmD,KAAO,CACd,GAAI,GAAGnD,EAAE,EAAE,IAAIA,EAAE,OAAO,IAAImD,CAAC,GAC7B,QAASnD,EAAE,QACX,KAAMA,EAAE,KACR,SAAUA,EAAE,SACZ,KAAMA,EAAE,KACR,GAAIA,EAAE,EAAA,EACN,CACN,CAsDA,SAASoD,GAAkBC,EAAsD,CAC/E,GAAIA,GAAM,MAA2BA,IAAM,GAAI,OAAO,KACtD,GAAI,OAAOA,GAAM,SAAU,OAAOA,EAClC,MAAMtE,EAAI,OAAOsE,CAAC,EAAE,YAAA,EACpB,OAAItE,IAAM,SAAiB,EACvBA,IAAM,UAAkB,EACxBA,IAAM,iBAAyB,EAC5B,IACT,CAWO,SAASuE,GACdC,EACA/D,EACAgE,EACe,CACf,MAAMC,GAAuBF,GAAoB,CAAA,GAAI,IAAIxE,IAAM,CAC7D,SAAUA,EAAE,SACZ,OAAQA,EAAE,OACV,WAAYqE,GAAkBrE,EAAE,UAAU,CAAA,EAC1C,EACI2E,MAAe,IACrB,UAAWtE,KAAKI,GAAe,GACzBJ,EAAE,eAAesE,EAAS,IAAItE,EAAE,aAAa,EAQnD,MAAO,CAAE,SANiBoE,GAAW,CAAA,GAAI,IAAIG,IAAM,CACjD,KAAMA,EAAE,KACR,OAAQA,EAAE,QAAU,KACpB,WAAYP,GAAkBO,EAAE,UAAU,EAC1C,GAAI,OAAOA,EAAE,IAAO,SAAWA,EAAE,GAAK,IAAA,EACtC,EACoB,OAAAF,EAAQ,OAAQ,CAAC,GAAGC,CAAQ,CAAA,CACpD,CAsCO,SAASE,GAAuBlD,EAA4C,CACjF,MAAMmD,EAAUnD,EACb,OAAQV,GAA4DA,EAAE,OAAS,aAAa,EAC5F,MAAA,EACA,KAAK,CAACZ,EAAGC,IAAOD,EAAE,GAAKC,EAAE,GAAK,GAAKD,EAAE,GAAKC,EAAE,GAAK,EAAI,CAAE,EAEpDyE,MAAW,IACXhB,EAAyB,CAAA,EAC/B,IAAIiB,EAAe,EACnB,UAAW/D,KAAK6D,EAAS,CACvB,GAAI7D,EAAE,SAAU,CACd,GAAI8D,EAAK,IAAI9D,EAAE,QAAQ,EAAG,SAC1B8D,EAAK,IAAI9D,EAAE,QAAQ,CACrB,CACA,MAAMgE,EAAwBhE,EAAE,YAAc,OACxCiE,EAAUD,IAAS,OACzBlB,EAAI,KAAK,CACP,GAAI9C,EAAE,GACN,KAAMA,EAAE,KACR,QAAAiE,EACA,KAAAD,EACA,QAASC,EAAU,EAAEF,EAAe,KACpC,OAAQ/D,EAAE,SAAW,KACrB,QAASA,EAAE,UAAY,IAAA,CACxB,CACH,CACA,OAAO8C,CACT,CAQO,SAASoB,GAAwBxD,EAAwC,CAC9E,MAAMyD,EAAIzD,EAAO,KACdV,GACCA,EAAE,OAAS,mBAAA,EAEf,OAAOmE,GAAA,YAAAA,EAAG,cAAe,IAC3B,CAaO,SAASC,GAAmBC,EAUjC,CACA,MAAMC,EAAKD,GAAA,YAAAA,EAAU,SACrB,MAAI,CAACC,GAAM,CAACA,EAAG,WACN,CACL,WAAY,GACZ,UAAW,EACX,YAAYA,GAAA,YAAAA,EAAI,cAAe,KAC/B,QAAQA,GAAA,YAAAA,EAAI,SAAU,IAAA,EAGnB,CACL,WAAYA,EAAG,WAAa,EAC5B,UAAWA,EAAG,WACd,WAAYA,EAAG,YAGf,OAAQA,EAAG,SAAWA,EAAG,YAAc,cAAgB,cAAA,CAE3D,CASO,SAASC,GAAgCvD,EAA0B,CACxE,OACEA,EAAK,MAAQ,YACbA,EAAK,SACLA,EAAK,QAAQ,SAAW,GACxB,CAAC,CAACA,EAAK,UAEX,CAOO,SAASwD,GAAiBxD,EAAoC,CACnE,OAAOA,EAAK,QAAU,SAAW,MACnC,CAGO,SAASyD,GAAeC,EAAmBC,EAA4C,CAC5F,GAAI,CAACA,EAAS,MAAO,MACrB,MAAMpG,EAAK,IAAI,KAAKoG,CAAO,EAAE,QAAA,EAAY,IAAI,KAAKD,CAAS,EAAE,QAAA,EAC7D,GAAI,CAAC,OAAO,SAASnG,CAAE,GAAKA,EAAK,EAAG,MAAO,IAC3C,MAAMqG,EAAM,KAAK,MAAMrG,EAAK,GAAI,EAChC,GAAIqG,EAAM,GAAI,MAAO,GAAGA,CAAG,IAC3B,MAAM/G,EAAI,KAAK,MAAM+G,EAAM,EAAE,EACvB7F,EAAI6F,EAAM,GAChB,OAAI/G,EAAI,GAAWkB,EAAI,GAAGlB,CAAC,IAAIkB,CAAC,IAAM,GAAGlB,CAAC,IAEnC,GADG,KAAK,MAAMA,EAAI,EAAE,CAChB,IAAIA,EAAI,EAAE,GACvB,CCnpCA,eAAegH,GAAgBC,EAAyC,CACtE,MAAMC,EAAM,MAAM,MAAM,cAAcD,CAAM,EAAE,EAC9C,GAAI,CAACC,EAAI,GAAI,MAAM,IAAI,MAAM,gCAAgCA,EAAI,MAAM,GAAG,EAC1E,MAAM9H,EAAM,MAAM8H,EAAI,KAAA,EACtB,MAAO,CACL,GAAG9H,EAAI,KACP,YAAaA,EAAI,aAAe,CAAA,EAChC,WAAYA,EAAI,YAAc,CAAA,EAC9B,SAAUA,EAAI,UAAY,CAAA,EAC1B,iBAAkBA,EAAI,kBAAoB,CAAA,EAC1C,QAASA,EAAI,SAAW,CAAA,EACxB,UAAWA,EAAI,WAAa,CAAA,EAC5B,aAAcA,EAAI,cAAgB,CAAA,EAClC,YAAaA,EAAI,aAAe,CAAA,CAAC,CAErC,CAEA,eAAe+H,GAAkBF,EAA2C,CAC1E,MAAMC,EAAM,MAAM,MAAM,cAAcD,CAAM,WAAW,EACvD,GAAI,CAACC,EAAI,GAAI,MAAM,IAAI,MAAM,kCAAkCA,EAAI,MAAM,GAAG,EAC5E,OAAOA,EAAI,KAAA,CACb,CAsBO,SAASE,GAAcH,EAA4B,CACxD,MAAMI,EAAUC,EAAS,CACvB,SAAU,CAAC,mBAAoBL,CAAM,EACrC,QAAS,IAAMD,GAAgBC,CAAO,EACtC,QAAS,CAAC,CAACA,EACX,gBAAiB,IAAA,CAClB,EAEKM,EAAYD,EAAS,CACzB,SAAU,CAAC,uBAAwBL,CAAM,EACzC,QAAS,IAAME,GAAkBF,CAAO,EACxC,QAAS,CAAC,CAACA,EACX,gBAAiB,IAAA,CAClB,EAEKO,EAAYH,EAAQ,WAAaE,EAAU,UAC3CE,EAAQJ,EAAQ,OAASE,EAAU,MAEzC,IAAIG,EAAiC,KACrC,GAAIL,EAAQ,MAAQE,EAAU,KAAM,CAClC,MAAM1E,EAAS0E,EAAU,KAAK,OAC9BG,EAAK,CACH,OAAQL,EAAQ,KAChB,SAAUE,EAAU,KACpB,MAAO3E,GAAWC,EAAQwE,EAAQ,KAAK,WAAW,EAClD,aAActC,GAAmBwC,EAAU,KAAK,SAAS,EACzD,QAASnC,GAAcvC,CAAM,EAC7B,OAAQwC,GAAaxC,CAAM,EAC3B,KAAM4C,GAAoB4B,EAAQ,KAAK,iBAAkBA,EAAQ,KAAK,YAAaA,EAAQ,KAAK,OAAO,EACvG,iBAAkBtB,GAAuBlD,CAAM,EAC/C,kBAAmBwD,GAAwBxD,CAAM,EACjD,aAAc0D,GAAmBgB,EAAU,IAAI,CAAA,CAEnD,CAEA,MAAO,CACL,GAAAG,EACA,UAAAF,EACA,MAAAC,EACA,QAAS,IAAM,CACRJ,EAAQ,QAAA,EACRE,EAAU,QAAA,CACjB,CAAA,CAEJ,CC1DA,MAAMI,GAAMC,GAAK,IACXC,GAAMD,GAAK,IACXE,GAAOC,GAAM,KACbC,EAAeC,EAAS,KAG9B,SAASC,GAASxH,EAAkC,CAClD,GAAIA,IAAO,MAAQ,CAAC,OAAO,SAASA,CAAE,GAAKA,EAAK,EAAG,OAAO,KAC1D,GAAIA,EAAK,IAAM,MAAO,GAAGA,CAAE,KAC3B,MAAMqG,EAAMrG,EAAK,IACjB,GAAIqG,EAAM,GAAI,MAAO,GAAGA,EAAI,QAAQ,CAAC,CAAC,IACtC,MAAM/G,EAAI,KAAK,MAAM+G,EAAM,EAAE,EACvB7F,EAAI,KAAK,MAAM6F,EAAM,EAAE,EAC7B,OAAO7F,EAAI,GAAGlB,CAAC,IAAIkB,CAAC,IAAM,GAAGlB,CAAC,GAChC,CAYA,SAASmI,GAAY,CAAE,KAAA9I,EAAM,UAAA+I,EAAY,KAA6C,CACpF,OACEC,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,WAAY,sBACZ,OAAQ,kCACR,aAAc,EACd,QAAS,WACT,UAAAD,EACA,SAAU,OACV,UAAW,aACX,MAAO,qBAAA,EAGT,SAAAC,EAAAA,IAACC,EAAA,CAAiB,QAASjJ,CAAA,CAAM,CAAA,CAAA,CAGvC,CAaA,SAASkJ,GAAiB,CAAE,IAAAnJ,EAAK,UAAAgJ,EAAY,KAA4C,CACvF,MAAM9I,EAASH,GAAiBC,CAAG,EAE7BoJ,EAASC,GACbJ,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,WAAY,sBACZ,OAAQ,kCACR,aAAc,EACd,QAAS,WACT,UAAAD,EACA,SAAU,OACV,UAAW,aACX,MAAO,qBAAA,EAGR,SAAAK,CAAA,CAAA,EAIL,OAAInJ,EAAO,OAAS,KACXkJ,EAAMH,EAAAA,IAACC,EAAA,CAAiB,QAAShJ,EAAO,SAAU,CAAE,EAGzDA,EAAO,OAAS,OAEXkJ,QAAOF,EAAA,CAAiB,QAAS,YAAchJ,EAAO,OAAS,QAAS,CAAE,EAI5EkJ,EACLE,OAAAC,EAAAA,SAAA,CACE,SAAA,CAAAN,EAAAA,IAACC,EAAA,CAAiB,QAAShJ,EAAO,QAAA,CAAU,EAC5C+I,EAAAA,IAACJ,EAAA,CACC,SAAU,GACV,iBAAkB,CAAA,EAClB,MAAO,CAAE,WAAY,cAAe,UAAW,CAAA,EAE/C,SAAAI,EAAAA,IAACL,EAAA,CACC,KAAK,WACL,OACEU,EAAAA,KAACE,EAAA,CAAM,KAAM,EACX,SAAA,CAAAP,EAAAA,IAACQ,EAAA,EAAS,QACT,OAAA,CAAK,MAAO,CAAE,SAAU,EAAA,EAAM,SAAA,iBAAc,EAC7CH,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAM,SAAA,CAAA,QACnDxJ,EAAO,QAAQ,eAAA,CAAA,CACvB,CAAA,EACF,EAGF,eAACgJ,EAAA,CAAiB,QAAS,YAAchJ,EAAO,OAAS,OAAA,CAAS,CAAA,CAAA,CACpE,CAAA,CACF,CAAA,CACF,CAAA,CAEJ,CAIA,SAASyJ,GAAWC,EAAoC,CACtD,OAAIA,IAAY,gBAAmBC,EAAA,CAAI,MAAM,QAAQ,SAAA,KAAE,EACnDD,IAAY,gBAAmBC,EAAA,CAAI,MAAM,SAAS,SAAA,KAAE,EACpDD,IAAY,eAAkBC,EAAA,CAAI,MAAM,MAAM,SAAA,KAAE,EAChDD,IAAY,kBAAqBC,EAAA,CAAI,MAAM,OAAO,SAAA,KAAE,EACjD,IACT,CAEA,SAASC,GAAUC,EAAgB,CACjC,OAAIA,IAAW,kBAAqBF,EAAA,CAAI,MAAM,QAAQ,SAAA,MAAG,EACrDE,IAAW,eAAkBF,EAAA,CAAI,MAAM,WAAW,SAAA,MAAG,EACrDE,IAAW,kBAAqBF,EAAA,CAAI,MAAM,OAAO,SAAA,MAAG,EACjDZ,EAAAA,IAACY,GAAK,SAAAE,CAAA,CAAO,CACtB,CAEA,SAASC,EAAW/E,EAA6C,CAC/D,OAAIA,IAAY,OAAegE,EAAAA,IAACY,GAAI,MAAM,QAAQ,KAAK,QAAQ,SAAA,MAAA,CAAI,EAC/D5E,IAAY,OAAegE,EAAAA,IAACY,GAAI,MAAM,MAAM,KAAK,QAAQ,SAAA,MAAA,CAAI,EAC7D5E,IAAY,UAAkBgE,EAAAA,IAACY,GAAI,MAAM,SAAS,KAAK,QAAQ,SAAA,SAAA,CAAO,EACnE,IACT,CAEA,MAAMI,GAA8E,CAClF,KAAM,CAAE,MAAO,KAAM,MAAO,UAAA,EAC5B,KAAM,CAAE,MAAO,OAAQ,MAAO,QAAA,EAC9B,UAAW,CAAE,MAAO,YAAa,MAAO,OAAA,EACxC,SAAU,CAAE,MAAO,KAAM,MAAO,MAAA,EAChC,QAAS,CAAE,MAAO,KAAM,MAAO,MAAA,CACjC,EAEA,SAASC,GAAM,CAAE,GAA2B,CAC1C,GAAI,IAAM,KAAM,OAAO,KACvB,MAAMhI,EAAO,KAAK,MAAM,CAAC,EACzB,OACE+G,EAAAA,IAAC,QAAK,MAAO,CAAE,QAAS,cAAe,WAAY,SAAU,IAAK,CAAA,EAC/D,SAAA,MAAM,KAAK,CAAE,OAAQ,EAAG,EAAE,IAAI,CAACkB,EAAGjE,IACjC+C,EAAAA,IAACmB,GAAA,CAEC,MAAO,CAAE,SAAU,GAAI,MAAOlE,EAAIhE,EAAO,gCAAkC,8BAAA,CAA+B,EADrGgE,CAAA,CAGR,EACH,CAEJ,CAQA,SAASmE,GAAc,CACrB,QAAAC,EACA,MAAAtG,EACA,MAAAuG,EACA,MAAAC,CACF,EAKG,CACD,MAAMC,EAAe3B,GAAS9E,EAAM,UAAU,EACxC0G,EAAW1G,EAAM,QAAU,UAAYsG,IAAY,SACnDK,EAAcD,EAAW,iBAAmB,YAC5CE,EAAcN,IAAY,SAAW,eAAiB,gBACtDO,EAAaH,EAAW1G,EAAM,cAAgBA,EAAM,WACpD8G,EAAU,CAAC,EAAED,GAAe,CAACH,GAAY1G,EAAM,YAErD,OACEsF,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,OAAQ,kCACR,aAAc,EACd,QAAS,YACT,WAAY,mBAAA,EAId,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,aAAcwB,EAAU,EAAI,EAAG,SAAU,QACnG,SAAA,CAAAN,EAAQ,GACPlB,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,GAAI,WAAY,aAAe,SAAA,CAAA,IAChFa,EAAQ,EAAE,IAAEC,CAAA,EAChB,QAEDX,EAAA,CAAI,KAAK,QAAQ,MAAOa,EAAW,OAAS,WAAY,SAAQ,GAAC,KAAMA,QAAYK,EAAA,CAAA,CAAW,QAAMC,GAAA,CAAA,CAAU,EAC5G,WAAM,KAAA,CACT,EACChH,EAAM,UACLiF,MAACY,EAAA,CAAI,KAAK,QAAQ,MAAM,SAAS,SAAA,iBAAA,CAAe,EAEjD7F,EAAM,UACLiF,EAAAA,IAACY,EAAA,CAAI,KAAK,QAAQ,MAAM,OAAO,SAAQ,GAAC,SAAA,QAAA,CAAM,EAE/C7F,EAAM,IACLsF,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EACnD,SAAA,CAAAT,EAAAA,IAACgC,GAAA,CAAgB,MAAO,CAAE,YAAa,GAAK,EAC3CC,EAAOC,EAASnH,EAAM,EAAE,EAAG,UAAU,CAAA,EACxC,EAEDyG,GACCnB,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAM,SAAA,CAAA,MAAIe,CAAA,EAAa,EAE7EzG,EAAM,SAAWgG,EAAWhG,EAAM,OAAO,EACzCA,EAAM,QACLiF,EAAAA,IAACY,EAAA,CAAI,KAAK,QAAQ,WAAOkB,EAAA,CAAA,CAAW,EAAI,MAAO,CAAE,WAAY,aAC1D,SAAA/G,EAAM,OAAO,MAAM,EAAG,EAAE,EAC3B,EAEDA,EAAM,WACLiF,MAACY,EAAA,CAAI,KAAK,QAAQ,MAAM,SAAS,SAAA,SAAA,CAAO,EAIzCa,GAAY1G,EAAM,YACjBiF,EAAAA,IAACY,EAAA,CAAI,KAAK,QAAQ,MAAM,OAAO,SAAQ,GAAC,MAAM,4CAA4C,SAAA,iBAAA,CAE1F,CAAA,EAEJ,EAECiB,EACCxB,EAAAA,KAACT,EAAA,CACC,SAAU,GACV,iBAAkB2B,GAAS,EAAI,CAAC,QAAQ,EAAI,CAAA,EAC5C,MAAO,CAAE,WAAY,aAAA,EAEpB,SAAA,CAAAK,EACC5B,EAAAA,IAACL,EAAA,CACC,KAAK,SACL,OACEU,EAAAA,KAACE,EAAA,CAAM,KAAM,EACX,SAAA,CAAAP,EAAAA,IAACmC,EAAA,EAAS,EACVnC,EAAAA,IAAC,QAAK,MAAO,CAAE,SAAU,GAAI,WAAY,GAAA,EAAQ,SAAA0B,CAAA,CAAY,EAC7DrB,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAO,SAAA,CAAAmB,EAAW,OAAO,KAAA,CAAA,CAAG,CAAA,EACnF,EAGF,SAAA5B,EAAAA,IAACF,GAAA,CAAY,KAAM8B,CAAA,CAAY,CAAA,CAAA,EAE/B,KACH,CAACH,GAAY1G,EAAM,WAClBiF,EAAAA,IAACL,EAAA,CACC,KAAK,SACL,OACEU,EAAAA,KAACE,EAAA,CAAM,KAAM,EACX,SAAA,CAAAP,EAAAA,IAACQ,EAAA,EAAS,EACVR,EAAAA,IAAC,QAAK,MAAO,CAAE,SAAU,GAAI,WAAY,GAAA,EAAQ,SAAA2B,CAAA,CAAY,EAC7DtB,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAO,SAAA,CAAA1F,EAAM,WAAW,OAAO,KAAA,CAAA,CAAG,CAAA,EACzF,EAGF,SAAAiF,EAAAA,IAACE,GAAA,CAAiB,IAAKnF,EAAM,UAAA,CAAY,CAAA,CAAA,EAEzC,IAAA,CAAA,CAAA,EAEJ,IAAA,CAAA,CAAA,CAGV,CASA,SAASqH,GAAsB,CAC7B,WAAAC,EACA,OAAAvB,CACF,EAGG,CACD,OACET,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,OAAQ,kCACR,aAAc,EACd,QAAS,YACT,WAAY,oBACZ,QAAS,OACT,cAAe,SACf,IAAK,CAAA,EAGP,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,SAAU,MAAA,EACrE,SAAA,CAAAA,EAAAA,KAACO,EAAA,CAAI,KAAK,QAAQ,MAAM,QAAQ,SAAQ,GAAC,KAAMZ,EAAAA,IAACsC,GAAA,CAAA,CAAgB,EAAI,SAAA,CAAA,MAC9DxB,IAAW,WAAa,KAAQA,GAAU,IAAA,EAChD,EACAT,EAAAA,KAACI,EAAW,KAAX,CAAgB,MAAO,CAAE,SAAU,GAAI,MAAO,qBAAA,EAAyB,SAAA,CAAA,UAC9D4B,EAAW,6DAAA,CAAA,CACrB,CAAA,EACF,QACCE,EAAA,CAAK,GAAI,cAAcF,CAAU,GAChC,SAAArC,EAAAA,IAACwC,EAAA,CAAO,KAAK,UAAU,KAAK,QAAQ,WAAOC,EAAA,CAAA,CAAS,EAAI,sCAExD,CAAA,CACF,CAAA,CAAA,CAAA,CAGN,CAQA,SAASC,GAAgB,CAAE,OAAAC,EAAQ,KAAA7H,GAA6C,CAC9E,cACG,MAAA,CAEC,SAAA,CAAAuF,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,aAAc,GAAI,SAAU,QACvF,SAAA,CAAAA,EAAAA,KAACI,EAAW,KAAX,CAAgB,MAAO,CAAE,WAAY,IAAK,SAAU,EAAA,EAAM,SAAA,CAAA,KACtDkC,EAAO,QAAM7H,EAAK,KAAA,EACvB,EACCA,EAAK,YAAc,GAClBuF,EAAAA,KAACO,GAAI,KAAK,QAAQ,MAAM,WAAY,SAAA,CAAA9F,EAAK,YAAY,QAAA,EAAM,EAE5DA,EAAK,cAAgB,GACpBuF,EAAAA,KAACO,EAAA,CAAI,KAAK,QAAQ,MAAM,OAAO,SAAQ,GAAC,SAAA,CAAA,IAAE9F,EAAK,cAAc,OAAA,EAAK,EAEnEA,EAAK,MAAQ,UAAYiG,EAAWjG,EAAK,OAAO,EAChDA,EAAK,YACJkF,EAAAA,IAACuC,EAAA,CAAK,GAAI,cAAczH,EAAK,UAAU,GACrC,SAAAuF,EAAAA,KAACO,EAAA,CAAI,KAAK,QAAQ,MAAM,SAAS,KAAMZ,EAAAA,IAACyC,EAAA,CAAA,CAAS,EAAI,MAAO,CAAE,OAAQ,SAAA,EAAa,SAAA,CAAA,IAC/E3H,EAAK,WAAYA,EAAK,eAAiB,MAAMA,EAAK,cAAc,GAAK,EAAA,CAAA,CACzE,CAAA,CACF,CAAA,EAEJ,QAGC2F,EAAW,UAAX,CAAqB,MAAO,CAAE,SAAU,GAAI,OAAQ,WAAY,MAAO,sBAAuB,WAAY,UAAA,EACxG,WAAK,OACR,EAGC3F,EAAK,QAAQ,OAAS,QACpB,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,IAC1D,SAAAA,EAAK,QAAQ,IAAI,CAACC,EAAOkC,IACxB+C,EAAAA,IAACoB,GAAA,CAEC,QAAStG,EAAK,IACd,MAAAC,EACA,MAAOkC,EACP,MAAOnC,EAAK,QAAQ,MAAA,EAJf,GAAGC,EAAM,KAAK,IAAIA,EAAM,IAAMkC,CAAC,IAAIA,CAAC,EAAA,CAM5C,EACH,EAOAoB,GAAgCvD,CAAI,GAAKA,EAAK,WAC5CkF,EAAAA,IAACoC,GAAA,CAAsB,WAAYtH,EAAK,WAAY,OAAQA,EAAK,eAAgB,EAC/E,IAAA,EAER,CAEJ,CAQA,SAAS8H,GAAqB,CAC5B,OAAAC,EACA,SAAAtJ,CACF,EAGG,CACD,MAAMuJ,EAASD,EAAO,OAAQ,GAAM,EAAE,OAAO,EACvCE,EAAWF,EAAO,OAAQ,GAAM,CAAC,EAAE,OAAO,EAE1CG,EAASC,GAAe,CAC5B,GAAI,CACF,OAAOhB,EAAOC,EAASe,CAAE,EAAG,gBAAgB,CAC9C,MAAQ,CACN,OAAOA,CACT,CACF,EAEMC,EAAgBpF,GACpBA,IAAS,iBAAmB,uBAAyBA,IAAS,QAAU,OAAS,OAEnF,OACEuC,EAAAA,KAAC8C,EAAA,CACC,SAAQ,GACR,MACE9C,EAAAA,KAAC,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,QAAS,cAAe,WAAY,SAAU,IAAK,GAC/F,SAAA,CAAAL,EAAAA,IAACmC,EAAA,EAAS,EAAE,UAAA,EACd,EAEF,MACEW,EAAO,OAAS,SACbrC,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,IAAO,SAAA,CAAAqC,EAAO,OAAO,IAAA,CAAA,CAAE,EAC1E,KAGL,SAAA,CAAAA,EAAO,OAAS,EACf9C,MAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,IAC1D,SAAA8C,EAAO,IAAK,UACV,MAAA,CACC,SAAA,CAAAzC,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,aAAc,CAAA,EACzE,SAAA,CAAAA,EAAAA,KAACO,EAAA,CAAI,MAAM,WAAW,KAAK,QAAQ,SAAA,CAAA,KAAG,EAAE,QAAQ,IAAA,EAAE,EAClDZ,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAO,SAAAuC,EAAM,EAAE,EAAE,CAAA,CAAE,CAAA,EAC1E,EACAhD,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,WAAY,mCACZ,WAAY,sBACZ,QAAS,WACT,aAAc,cACd,MAAO,sBACP,UAAW,aACX,UAAW,IACX,SAAU,MAAA,EAGZ,SAAAA,EAAAA,IAACC,EAAA,CAAiB,QAAS,EAAE,IAAA,CAAM,CAAA,CAAA,CACrC,CAAA,EAlBQ,EAAE,SAAW,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAmB3C,CACD,CAAA,CACH,EACE1G,EAEFyG,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,WAAY,mCACZ,WAAY,sBACZ,QAAS,WACT,aAAc,cACd,MAAO,sBACP,UAAW,aACX,UAAW,IACX,SAAU,MAAA,EAGZ,SAAAA,EAAAA,IAACC,EAAA,CAAiB,QAAS1G,CAAA,CAAU,CAAA,CAAA,EAGvCyG,EAAAA,IAACoD,GAAA,CAAM,YAAY,eAAA,CAAgB,EAGpCL,EAAS,OAAS,GACjB/C,EAAAA,IAACJ,GAAS,MAAO,CAAE,UAAWkD,EAAO,OAAS,GAAKvJ,EAAW,GAAK,GACjE,SAAAyG,EAAAA,IAACL,EAAA,CACC,KAAK,kBACL,OACEU,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAClD,SAAA,CAAAsC,EAAS,OAAO,UAAQ,sBAAsB,WAAA,EACjD,EAGF,eAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,EAAA,EAC1D,SAAAA,EAAS,IAAI,CAAC,EAAG,WACf,MAAA,CACC,SAAA,CAAA1C,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,aAAc,CAAA,EACzE,SAAA,CAAAL,MAACY,EAAA,CAAI,MAAM,OAAO,KAAK,QAAQ,SAAA,OAAI,EACnCP,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAClD,SAAA,CAAAyC,EAAa,EAAE,IAAI,EAAE,MAAIF,EAAM,EAAE,EAAE,CAAA,CAAA,CACtC,CAAA,EACF,QACClD,GAAA,CAAY,KAAM,EAAE,KAAM,UAAW,GAAA,CAAK,CAAA,GAPnC,EAAE,SAAW,GAAG,EAAE,EAAE,IAAI,CAAC,EAQnC,CACD,CAAA,CACH,CAAA,CAAA,CACF,CACF,CAAA,CAAA,CAAA,CAIR,CAIA,SAAwBuD,IAAiB,SACvC,KAAM,CAAE,OAAAzE,CAAA,EAAW0E,GAAA,EACbC,EAAWC,GAAA,EACX,CAAE,GAAAnE,EAAI,UAAAF,EAAW,MAAAC,CAAA,EAAUL,GAAcH,CAAM,EAK/C,CAAC6E,EAAUC,CAAW,EAAIC,GAAAA,SAAwB,IAAI,EAE5D,GAAIxE,EACF,OACEa,MAAC,OAAI,MAAO,CAAE,QAAS,EAAA,EACrB,eAACmD,EAAA,CAAK,SAAQ,GACZ,SAAAnD,MAAC4D,GAAA,CAAS,UAAS,GAAC,KAAM,CAAE,KAAM,CAAA,EAAK,CAAA,CACzC,CAAA,CACF,EAIJ,GAAIxE,GAAS,CAACC,EACZ,aACG,MAAA,CAAI,MAAO,CAAE,QAAS,IACrB,SAAAW,EAAAA,IAAC6D,GAAA,CACC,OAAO,QACP,MAAM,WACN,UAAUzE,GAAA,YAAAA,EAAO,UAAW,cAC5B,MACEY,EAAAA,IAACwC,EAAA,CAAO,KAAK,UAAU,QAAS,IAAMe,EAAS,QAAQ,EAAG,SAAA,QAAA,CAE1D,CAAA,CAAA,EAGN,EAIJ,KAAM,CAAE,OAAAO,EAAQ,MAAAC,EAAO,aAAAC,EAAc,QAAAtJ,EAAS,OAAAuJ,EAAQ,KAAAC,EAAM,iBAAAC,EAAkB,kBAAAC,EAAmB,aAAAC,CAAA,EAAiBhF,EAC5GiF,EAAQC,GAAmBT,EAAO,OAAO3H,EAAA2H,EAAO,YAAY,CAAC,IAApB,YAAA3H,EAAuB,OAAO,EACvEqI,EAAWjG,GAAeuF,EAAO,WAAYA,EAAO,QAAQ,EAC5DW,EAAYxC,EAAOC,EAAS4B,EAAO,UAAU,EAAG,aAAa,EAG7DY,EAAcjB,IAAa,KAAOM,EAAMN,EAAW,CAAC,GAAK,KAAO,KAEtE,OACEpD,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,GAAI,QAAS,OAAQ,cAAe,SAAU,IAAK,EAAA,EAExE,SAAA,CAAAA,EAAAA,KAAC8C,EAAA,CAAK,SAAQ,GACZ,SAAA,CAAAnD,EAAAA,IAACwC,EAAA,CACC,KAAK,OACL,KAAK,QACL,WAAOmC,GAAA,EAAS,EAChB,MAAO,CAAE,aAAc,EAAG,YAAa,CAAA,EACvC,QAAS,IAAMpB,EAAS,QAAQ,EACjC,SAAA,MAAA,CAAA,EAGDvD,EAAAA,IAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,aAAc,eAAgB,gBAAiB,IAAK,GAAI,SAAU,QAC3G,SAAAK,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,SAAU,EAAG,KAAM,CAAA,EAC/B,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,GAAI,SAAU,MAAA,EACtE,SAAA,CAAAL,EAAAA,IAACS,EAAW,MAAX,CAAiB,QAAS,EAAG,MAAO,CAAE,OAAQ,CAAA,EAC5C,SAAA6D,CAAA,CACH,EACCzD,GAAUiD,EAAO,MAAM,EACvBpD,GAAWoD,EAAO,OAAO,CAAA,EAC5B,EACAzD,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,IAAK,GAAI,SAAU,OAAQ,UAAW,EAAG,WAAY,UAClF,SAAA,CAAAA,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,GAAI,QAAS,cAAe,WAAY,SAAU,IAAK,GAC1G,SAAA,CAAAT,EAAAA,IAACgC,GAAA,EAAgB,EAAE,OAAKwC,CAAA,EAC1B,EACAxE,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAO,SAAAgE,CAAA,CAAU,EACtEzE,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,GAAI,WAAY,WAAA,EAAe,MAAOqD,EAAO,GAC/F,SAAAA,EAAO,GAAG,OAAS,GAAK,GAAGA,EAAO,GAAG,MAAM,EAAG,EAAE,CAAC,IAAMA,EAAO,EAAA,CACjE,EACCM,GACCpE,EAAAA,IAACuC,EAAA,CAAK,GAAI,cAAc6B,CAAiB,GAAI,MAAO,CAAE,SAAU,EAAA,EAC9D,SAAA/D,EAAAA,KAACO,GAAI,MAAM,WAAW,SAAQ,GAAC,KAAMZ,EAAAA,IAACyC,EAAA,CAAA,CAAS,EAAI,MAAO,CAAE,OAAQ,SAAA,EAAa,SAAA,CAAA,IAC7E2B,CAAA,CAAA,CACJ,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EACF,EAGA/D,EAAAA,KAAC8C,EAAA,CACC,SAAQ,GACR,MACE9C,EAAAA,KAAC,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,QAAS,cAAe,WAAY,SAAU,IAAK,EAAG,SAAU,QAAU,SAAA,CAAA,OAMrHgE,EAAa,YACZhE,EAAAA,KAACO,EAAA,CAAI,MAAM,SAAS,SAAQ,GAAC,MAAO,CAAE,WAAY,GAAA,EAAO,SAAA,CAAA,KACpDyD,EAAa,UAAU,QACzBA,EAAa,SAAW,cACrB,cACAA,EAAa,WACX,gBAAgBA,EAAa,UAAU,OACvC,EAAA,EACR,EAEDA,EAAa,YAAcA,EAAa,SAAW,eAClDrE,MAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,GAAI,WAAY,GAAA,EAAO,SAAA,mCAAA,CAE5E,CAAA,EAEJ,EAEF,MAAOT,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAM,SAAA,SAAA,CAAO,EAEzE,SAAA,CAAAT,EAAAA,IAACN,GAAA,CACC,KAAK,QACL,QAAS+D,GAAY,GACrB,SAAWmB,GAAYlB,KAAqBmB,IAASD,EAAU,KAAOA,CAAQ,EAC9E,MAAO,CAAE,OAAQ,SAAA,EAEhB,SAAAb,EAAM,IAAKjJ,GACVkF,EAAAA,IAACP,GAAA,CAEC,MAAO3E,EAAK,MACZ,OAAQwD,GAAiBxD,CAAI,EAC7B,YACEuF,EAAAA,KAAC,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,QAAS,cAAe,WAAY,SAAU,IAAK,EAAG,SAAU,QAC1F,SAAA,CAAAvF,EAAK,MAAQ,UAAYA,EAAK,QAC7BiG,EAAWjG,EAAK,OAAO,EACrB,KACHA,EAAK,cAAgBA,EAAK,aACxB2F,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,IAIlD,SAAA,CAAA3F,EAAK,cAAgBA,EAAK,MAC1BA,EAAK,cAAgB,EAAI,MAAMA,EAAK,aAAa,IAAM,EAAA,EAC1D,EACEA,EAAK,MAAQ,UAAYA,EAAK,QAAU,KAC1CkF,MAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAM,SAAA,GAAA,CAAC,CAAA,CAAA,CAEhE,CAAA,EAnBG3F,EAAK,GAAA,CAsBb,CAAA,CAAA,EAEHkF,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,UAAW,GAAI,UAAW,kCAAmC,WAAY,EAAA,EACpF,SAAA0E,EACC1E,EAAAA,IAAC0C,IAAgB,OAAQe,GAAY,EAAG,KAAMiB,CAAA,CAAa,EAE3D1E,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAM,iEAE3D,CAAA,CAEJ,CAAA,CAAA,CAAA,EAIFJ,EAAAA,KAACf,GAAA,CAAI,OAAQ,GAAI,MAAM,QAErB,SAAA,CAAAU,EAAAA,IAACR,GAAA,CAAI,GAAI,GAAI,GAAI,GAAI,MAAO,CAAE,aAAc,IAC1C,gBAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,IAI3D,SAAA,CAAAQ,EAAAA,IAAC4C,GAAA,CAAqB,OAAQuB,EAAkB,UAAU/H,EAAA0H,EAAO,YAAY,CAAC,IAApB,YAAA1H,EAAuB,QAAS,EAG1FiE,EAAAA,KAAC8C,EAAA,CACC,SAAQ,GACR,MAAO9C,EAAAA,KAAC,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,QAAS,cAAe,WAAY,SAAU,IAAK,GAAK,SAAA,CAAAL,EAAAA,IAACQ,EAAA,EAAS,EAAE,gBAAA,EAAc,EACvI,MAAOH,EAAAA,KAACI,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAO,SAAA,CAAAuD,EAAa,OAAO,SAAOtJ,EAAQ,OAAO,SAAA,EAAO,EAEnH,SAAA,CAAAsJ,EAAa,OAAS,EACrBhE,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,UAC3C,SAAAgE,EAAa,IAAKc,GAAM,CACvB,MAAMC,EAAO/D,GAAW8D,EAAE,MAAM,EAChC,OACEzE,EAAAA,KAAC,MAAA,CAEC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,EACL,QAAS,QACT,aAAc,iCAAA,EAGhB,SAAA,CAAAL,MAACmC,GAAS,MAAO,CAAE,MAAO,sBAAuB,WAAY,GAAK,EAClEnC,MAACS,EAAW,KAAX,CAAgB,KAAI,GAAC,MAAO,CAAE,SAAU,GAAI,KAAM,EAAG,SAAU,GAAK,SAAQ,GAAC,MAAOqE,EAAE,KACpF,SAAAA,EAAE,KACL,EACA9E,EAAAA,IAACY,GAAI,KAAK,QAAQ,MAAOmE,EAAK,MAAQ,WAAK,KAAA,CAAM,CAAA,CAAA,EAb5CD,EAAE,IAAA,CAgBb,CAAC,CAAA,CACH,EAEA9E,EAAAA,IAACoD,GAAA,CAAM,YAAY,WAAW,QAG/B3C,EAAW,KAAX,CAAgB,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,MAAO,sBAAuB,QAAS,QAAS,UAAW,GAAI,aAAc,CAAA,EAAK,SAAA,UAE3I,EACC/F,EAAQ,OAAS,EAChBA,EAAQ,IAAI,CAACO,EAAGgC,IACdoD,EAAAA,KAAC,MAAA,CAA2B,MAAO,CAAE,QAAS,OAAQ,WAAY,aAAc,IAAK,EAAG,QAAS,QAAS,aAAc,iCAAA,EACtH,SAAA,CAAAL,EAAAA,IAAC8B,EAAA,CAAW,MAAO,CAAE,MAAO,sBAAuB,UAAW,EAAG,WAAY,CAAA,CAAE,CAAG,SACjF,MAAA,CAAI,MAAO,CAAE,SAAU,GACtB,SAAA,CAAA9B,MAACS,EAAW,KAAX,CAAgB,MAAO,CAAE,WAAY,YAAa,SAAU,GAAI,MAAO,0BACrE,SAAAxF,EAAE,KAAK,MAAM,EAAG,EAAE,EACrB,EACA+E,MAACS,EAAW,UAAX,CAAqB,MAAO,CAAE,SAAU,GAAI,OAAQ,UAAW,MAAO,uBAAyB,SAAU,CAAE,KAAM,GAC/G,SAAAxF,EAAE,SAAW,aAAA,CAChB,CAAA,CAAA,CACF,CAAA,GATQ,GAAGA,EAAE,IAAI,IAAIgC,CAAC,EAUxB,CACD,EAED+C,MAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAM,SAAA,sBAAA,CAE3D,CAAA,CAAA,CAAA,CAEJ,CAAA,CACF,CAAA,CACF,EAGAT,EAAAA,IAACR,IAAI,GAAI,GAAI,GAAI,EAAG,MAAO,CAAE,aAAc,IACzC,SAAAa,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,EAAA,EAE3D,SAAA,CAAAL,MAACmD,EAAA,CAAK,SAAQ,GAAC,YAAQ,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,WAAY,GAAA,EAAO,cAAE,EACtE,SAAAnD,EAAAA,IAACgF,GAAA,CACC,MAAM,KACN,KAAK,QACL,OAAQ,EACR,WAAY,CAAE,MAAO,GAAI,MAAO,qBAAA,EAChC,KAAM,CACJ,CAAE,MAAO,KAAM,MAAOnE,GAAUiD,EAAO,MAAM,CAAA,EAC7C,CAAE,MAAO,KAAM,MAAOpD,GAAWoD,EAAO,OAAO,GAAK9D,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,aAAC,CAAA,EACvF,CAAE,MAAO,KAAM,MAAO+D,CAAA,EACtB,CAAE,MAAO,MAAO,MAAOV,EAAO,WAAA,EAC9B,CAAE,MAAO,UAAW,MAAO9D,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAI,GAAC,MAAO,CAAE,SAAU,IAAO,SAAAqD,EAAO,GAAG,CAAA,EACrF,CACE,MAAO,OACP,MAAOM,EACH/D,EAAAA,KAACkC,EAAA,CAAK,GAAI,cAAc6B,CAAiB,GAAI,MAAO,CAAE,WAAY,WAAA,EAAe,SAAA,CAAA,IAAEA,CAAA,EAAkB,EACrGpE,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,SAAA,GAAA,CAAC,CAAA,CACzC,CACF,CAAA,EAEJ,EAGAJ,EAAAA,KAAC8C,EAAA,CAAK,SAAQ,GAAC,MAAOnD,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,WAAY,GAAA,EAAO,gBAAI,EACxE,SAAA,CAAAK,OAACI,EAAW,KAAX,CAAgB,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,MAAO,sBAAuB,QAAS,OAAQ,WAAY,SAAU,IAAK,GACjI,SAAA,CAAAT,EAAAA,IAACiF,GAAA,EAAS,EAAE,aAAA,EACd,EACCf,EAAK,QAAQ,OAAS,EACrBA,EAAK,QAAQ,IAAI,CAACzG,EAAGR,WAClB,MAAA,CAAmC,MAAO,CAAE,QAAS,SACpD,SAAA,CAAAoD,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,CAAA,EACxD,SAAA,CAAAL,EAAAA,IAACS,EAAW,KAAX,CAAgB,MAAO,CAAE,WAAY,YAAa,SAAU,EAAA,EAAO,SAAAhD,EAAE,IAAA,CAAK,EAC1EA,EAAE,aAAe,YAASwD,GAAA,CAAM,EAAGxD,EAAE,UAAA,CAAY,CAAA,EACpD,EACCA,EAAE,QAAUuC,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAO,WAAE,MAAA,CAAO,CAAA,CAAA,EAL1E,GAAGhD,EAAE,IAAI,IAAIA,EAAE,IAAMR,CAAC,EAMhC,CACD,EAED+C,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,GAAI,QAAS,QAAS,QAAS,OAAA,EAAW,SAAA,UAAA,CAAQ,EAGzGJ,EAAAA,KAACI,EAAW,KAAX,CAAgB,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,MAAO,sBAAuB,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,UAAW,GAAI,WAAY,EAAG,UAAW,iCAAA,EAC7K,SAAA,CAAAT,EAAAA,IAACmB,GAAA,EAAa,EAAE,gBAAA,EAClB,EACC+C,EAAK,OAAO,OAAS,EACpBA,EAAK,OAAO,IAAKrL,UACd,MAAA,CAAqB,MAAO,CAAE,QAAS,SACtC,SAAA,CAAAwH,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,CAAA,EACxD,SAAA,CAAAL,EAAAA,IAACS,EAAW,KAAX,CAAgB,MAAO,CAAE,WAAY,YAAa,SAAU,EAAA,EAAO,SAAA5H,EAAE,QAAA,CAAS,EAC/EmH,EAAAA,IAACiB,GAAA,CAAM,EAAGpI,EAAE,UAAA,CAAY,CAAA,EAC1B,EACAmH,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,EAAA,EAAO,SAAA5H,EAAE,MAAA,CAAO,CAAA,GAL7DA,EAAE,QAMZ,CACD,EAEDmH,EAAAA,IAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,GAAI,QAAS,QAAS,QAAS,OAAA,EAAW,SAAA,YAAS,EAG1GJ,EAAAA,KAACI,EAAW,KAAX,CAAgB,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,MAAO,sBAAuB,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,UAAW,GAAI,WAAY,EAAG,UAAW,iCAAA,EAC7K,SAAA,CAAAT,EAAAA,IAAC+B,GAAA,EAAU,EAAE,WAAA,EACf,QACC,MAAA,CAAI,MAAO,CAAE,UAAW,GACtB,SAAAmC,EAAK,OAAO,OAAS,EACpBA,EAAK,OAAO,IAAK,GACflE,EAAAA,IAACY,EAAA,CAAY,KAAK,QAAQ,MAAO,CAAE,YAAa,EAAG,aAAc,GAAM,YAA7D,CAA+D,CAC1E,EAEDZ,MAACS,EAAW,KAAX,CAAgB,KAAK,YAAY,MAAO,CAAE,SAAU,IAAM,aAAC,CAAA,CAEhE,CAAA,EACF,EAGAT,EAAAA,IAACmD,EAAA,CACC,SAAQ,GACR,MAAO9C,EAAAA,KAAC,OAAA,CAAK,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,QAAS,cAAe,WAAY,SAAU,IAAK,GAAK,SAAA,CAAAL,EAAAA,IAACkF,GAAA,CAAsB,MAAO,CAAE,MAAOjB,EAAO,OAAS,EAAI,gCAAkC,qBAAA,CAAsB,CAAG,EAAE,IAAA,EAAE,EACvO,MAAOA,EAAO,OAAS,SAAKxD,EAAW,KAAX,CAAgB,MAAO,CAAE,SAAU,GAAI,MAAO,qBAAwB,SAAA,CAAAwD,EAAO,OAAO,IAAA,CAAA,CAAE,EAAqB,OAEtI,SAAAA,EAAO,OAAS,EACfjE,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,EAAA,EAC1D,SAAAiE,EAAO,IAAKkB,GACX9E,EAAAA,KAAC,MAAA,CAAiB,MAAO,CAAE,OAAQ,kCAAmC,aAAc,EAAG,QAAS,EAAA,EAC9F,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,aAAc,CAAA,EACzE,SAAA,CAAAL,EAAAA,IAACY,EAAA,CAAI,KAAK,QAAQ,MAAOuE,EAAI,WAAa,OAAS,MAAQ,SAAW,SAAAA,EAAI,QAAA,CAAS,EACnFnF,EAAAA,IAACS,EAAW,KAAX,CAAgB,MAAO,CAAE,SAAU,GAAI,WAAY,GAAA,EAAQ,SAAA0E,EAAI,OAAA,CAAQ,EACxEnF,EAAAA,IAACY,EAAA,CAAI,KAAK,QAAS,WAAI,IAAA,CAAK,CAAA,EAC9B,EACCuE,EAAI,MACHnF,EAAAA,IAACS,EAAW,UAAX,CAAqB,MAAO,CAAE,SAAU,GAAI,OAAQ,EAAG,MAAO,uBAAyB,SAAU,CAAE,KAAM,CAAA,EACvG,SAAA0E,EAAI,KACP,EAEFnF,EAAAA,IAACuC,GAAK,GAAG,UAAU,MAAO,CAAE,SAAU,EAAA,EAAM,SAAA,UAAA,CAAQ,CAAA,GAX5C4C,EAAI,EAYd,CACD,EACH,EAEA9E,EAAAA,KAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,EAAG,SAAU,GAAI,MAAO,uBAChF,SAAA,CAAAL,EAAAA,IAACsC,GAAA,EAAgB,EAAE,kBAAA,CAAA,CAErB,CAAA,CAAA,CAEJ,CAAA,CACF,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,CAEJ"}
@@ -0,0 +1,6 @@
1
+ var xt=Object.defineProperty;var ut=(t,n,o)=>n in t?xt(t,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[n]=o;var Me=(t,n,o)=>ut(t,typeof n!="symbol"?n+"":n,o);import{j as e,r as T}from"./react-vendor-tkvCrao7.js";import{L as Re,a as we,u as ft}from"./react-router-Cxmg8RuL.js";import{a as De,c as fe,u as G,k as Be}from"./query-CgCOpYWf.js";import{J as z,b as m,T as i,ak as ke,al as gt,aa as Ae,t as ht,O as le,am as He,N as yt,_ as ie,h as Q,F as A,ad as _e,C as jt,ah as Oe,a2 as qe,a3 as K,an as bt,ao as Ke,ap as xe,y as Te,q as vt,d as re,a1 as St,$ as wt,E as se,Y as Fe,aq as ve,a8 as kt,x as _t,ar as Tt,as as Ee,v as zt,at as Ct,a as It,ai as $t,au as Mt,av as Bt,R as Se,z as Ft,aw as Et,I as Lt,ax as ee,ay as Wt}from"./arco-DV6xCLhr.js";import{p as E,f as Nt,c as Pt,a as Rt,u as Dt,r as At,l as Ht,k as Ot}from"./index-DileOOE4.js";import{n as qt}from"./task-title-BhOcemuR.js";import{a as Kt}from"./auth-Bnf8ZcqN.js";import{f as Z}from"./date-fns-sbWH3_uq.js";import{T as Ut}from"./vendor-DS-q4Eyc.js";import{c as Jt,F as Gt,G as Vt,M as Yt}from"./lucide-CnlPQoG8.js";import{b as Qt,o as Zt}from"./outcome-BKGy9azt.js";function Xt(t){switch(t){case"success":return e.jsx(le,{style:{color:"var(--cf-tag-green)"}});case"partial":return e.jsx(ht,{style:{color:"var(--cf-tag-orange)"}});case"failed":return e.jsx(Ae,{style:{color:"var(--cf-tag-red)"}});case"abandoned":return e.jsx(gt,{style:{color:"var(--color-text-3)"}});default:return e.jsx(ke,{style:{color:"var(--cf-tag-blue)"},spin:!0})}}function en(t){switch(t){case"success":return"green";case"partial":return"orange";case"failed":return"red";case"abandoned":return"gray";default:return"arcoblue"}}function tn({banner:t,taskId:n,startedAt:o}){const s=en(t.outcome);return e.jsx(z,{bordered:!0,"data-testid":"tier-banner",style:{marginBottom:10,background:"var(--cf-kpi-wash-purple, #FAF5FF)",borderColor:"var(--cf-tag-purple, #B37FEB)"},bodyStyle:{padding:"10px 14px"},children:e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap",fontSize:13},children:[e.jsx("span",{style:{fontSize:18,lineHeight:1,display:"inline-flex",alignItems:"center"},children:Xt(t.outcome)}),e.jsx(m,{color:s,size:"default","data-testid":"tier-banner-outcome",children:t.outcomeLabel}),e.jsx(i.Text,{style:{fontSize:12,color:"var(--color-text-2)"},children:t.pathLabel}),e.jsx(i.Text,{style:{fontSize:12,color:"var(--color-text-3)"},children:"·"}),e.jsxs(i.Text,{style:{fontSize:12},children:[t.fileCount," 文件"]}),e.jsx(i.Text,{style:{fontSize:12,color:"var(--color-text-3)"},children:"·"}),e.jsxs(i.Text,{style:{fontSize:12},children:[t.commitCount," commit"]}),e.jsx(i.Text,{style:{fontSize:12,color:"var(--color-text-3)"},children:"·"}),e.jsx(i.Text,{style:{fontSize:12},children:t.durationLabel}),t.agentSpawnCount>0&&e.jsxs(e.Fragment,{children:[e.jsx(i.Text,{style:{fontSize:12,color:"var(--color-text-3)"},children:"·"}),e.jsxs(i.Text,{style:{fontSize:12},children:[t.agentSpawnCount," agent spawn"]})]}),e.jsx("span",{style:{flex:1}}),e.jsxs(i.Text,{type:"secondary",style:{fontSize:11},title:n,children:[n.slice(0,8)," · ",o.slice(0,19).replace("T"," ")]})]})})}function ue({cardId:t,idx:n,title:o,oneLine:s,rightChip:r,expanded:a,onToggle:x,detail:c}){return e.jsxs(z,{bordered:!0,"data-testid":`decision-card-${t}`,"data-expanded":a?"1":"0",style:{marginBottom:8},bodyStyle:{padding:0},children:[e.jsxs("div",{role:"button",tabIndex:0,"aria-expanded":a,onClick:x,onKeyDown:u=>{(u.key==="Enter"||u.key===" ")&&(u.preventDefault(),x())},style:{cursor:"pointer",padding:"10px 14px",display:"flex",alignItems:"center",gap:10,userSelect:"none"},children:[e.jsx("span",{style:{color:"var(--color-text-3)",fontSize:14,lineHeight:1,display:"inline-flex"},children:a?e.jsx(He,{}):e.jsx(yt,{})}),e.jsx(i.Text,{style:{fontSize:12,color:"var(--color-text-3)",minWidth:14},children:n}),e.jsx(i.Text,{style:{fontSize:13,fontWeight:600,minWidth:92},children:o}),e.jsx(i.Text,{type:"secondary",style:{fontSize:12,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"var(--color-text-1)"},title:s,children:s}),r&&e.jsx("span",{style:{flexShrink:0},children:r})]}),a&&e.jsx("div",{"data-testid":`decision-card-detail-${t}`,style:{padding:"8px 14px 14px",borderTop:"1px solid var(--color-border-2)",background:"var(--color-fill-1)"},children:c})]})}function Le(t){if(!t)return null;try{return JSON.parse(t)}catch{return null}}function Ue(t){var N,P,L,B,H,q;const n=((P=(N=t.userPrompts[0])==null?void 0:N.content)==null?void 0:P.trim())||null,o=((L=t.userPrompts[0])==null?void 0:L.timestamp)??null,s=t.injections.find(y=>y.source_handler.includes(":intent"))??null,r=Le(s==null?void 0:s.metadata_json),a=r?{workflow_type:r.workflow_type,confidence:r.confidence,suggested_agent:r.suggested_agent,layer:r.layer,reasoning:r.reasoning}:null,x=t.injections.filter(y=>y.source_handler==="UserPromptSubmitHandler:kb"),c=new Map;for(const y of x){const S=Le(y.metadata_json);if(Array.isArray(S)){for(const w of S)if(w&&typeof w.name=="string"){const W=((B=c.get(w.name))==null?void 0:B.score)??0,_=typeof w.score=="number"?w.score:0;c.set(w.name,{score:Math.max(W,_),matched:Array.isArray(w.matched_keywords)?w.matched_keywords:void 0})}}}const u=Array.from(c.entries()).sort((y,S)=>S[1].score-y[1].score).slice(0,8).map(([y,S])=>({name:y,score:S.score||void 0,matched:S.matched})),h=t.skillInvocations.slice(0,16).map(y=>({skill_id:y.skill_id,reason:y.reason??""})),l=t.timeline.filter(y=>{var S;return y.is_agent_call&&((S=y.agent_detail)==null?void 0:S.subagent_type)}).map(y=>{var S,w,W,_;return{subagent_type:(S=y.agent_detail)==null?void 0:S.subagent_type,name:(w=y.agent_detail)==null?void 0:w.name,promptPreview:(_=(W=y.agent_detail)==null?void 0:W.prompt)==null?void 0:_.slice(0,200)}}),b=new Map;for(const y of t.timeline)if((y.tool_name==="Edit"||y.tool_name==="Write")&&((H=y.input)!=null&&H.file_path)){const S=y.input.file_path;b.set(S,(b.get(S)??0)+1)}const g=Array.from(b.entries()).sort((y,S)=>S[1]-y[1]).map(([y,S])=>({path:y,count:S})),k=g.length,f=[];for(const y of t.timeline){if(y.tool_name!=="Bash")continue;const S=(q=y.input)==null?void 0:q.command;if(S&&/\bgit\s+commit\b/.test(S)){const w=y.output,W=typeof w=="string"?w:(w==null?void 0:w.stdout)??(w==null?void 0:w.output)??JSON.stringify(w??{}),_=String(W).match(/\b[a-f0-9]{7,40}\b/);_?f.push(_[0]):f.push(`(commit @ ${y.timestamp.slice(11,19)})`)}}const M=t.outcome?{label:t.outcome,reason:t.outcome_reason,commit_count:t.commit_count}:null;return{prompt:n,promptTimestamp:o,intent:a,intentInj:s,kbHits:u,kbInjs:x,skills:h,spawned:l,filesChanged:k,fileList:g,commits:f,outcome:M,specs:t.pendingSpecs??[]}}function Je(t){const n=!t.intent&&t.kbHits.length===0,o=t.specs.length===0&&t.skills.length===0,s=t.spawned.length===0&&t.filesChanged===0;return n&&o&&s}function nn(t,n){var h,l,b;const o=t.specs.length>0;let s;if(o)s=`BMAD Spec (token=${t.specs[0].token})`;else{const g=((h=n.agentSpawns[0])==null?void 0:h.subagent_type)??null;s=cn(null,g)}const r=((l=t.outcome)==null?void 0:l.label)??"active",a=r==="success"?"成功":r==="partial"?"部分":r==="failed"?"失败":r==="abandoned"?"放弃":"进行中",x=t.filesChanged,c=(((b=t.outcome)==null?void 0:b.commit_count)??0)||t.commits.length;let u="-";if(n.start_time){const g=n.end_time?E(n.end_time).getTime():Date.now(),k=E(n.start_time).getTime(),f=Math.max(0,Math.round((g-k)/1e3));f<60?u=`${f}s`:f<3600?u=`${Math.floor(f/60)}m${f%60}s`:u=`${Math.floor(f/3600)}h${Math.floor(f%3600/60)}m`}return{outcome:r,outcomeLabel:a,pathLabel:s,fileCount:x,commitCount:c,durationLabel:u,agentSpawnCount:n.agentSpawns.length}}function sn(t,n){var q,y,S,w,W,_,C,U;const o=((q=t.intent)==null?void 0:q.workflow_type)??"?",s=((y=t.intent)==null?void 0:y.layer)??"-",r=typeof((S=t.intent)==null?void 0:S.confidence)=="number"?` conf=${t.intent.confidence.toFixed(2)}`:"",a=t.prompt?(t.prompt.length>30?t.prompt.slice(0,30)+"…":t.prompt).replace(/\n/g," "):"",x=`${o} · ${s}${r}${a?` · "${a}"`:""}`,c=t.specs.length,u=t.skills.length,h=[];c&&h.push(`spec×${c}`),u&&h.push(`skill×${u}`);const l=h.length===0?"自主决策(未走 daemon 推荐)":h.join(" · "),b=n.agentSpawns.length,g=t.filesChanged,k=Array.from(new Set(n.agentSpawns.map(V=>V.subagent_type??"?")));let f;b===0?f=g>0?`主线程直改 ${g} 文件 (0 spawn)`:"未触发":f=`spawn×${b} (${k.slice(0,2).join(", ")}${k.length>2?"…":""}) · file×${g}`;const M=((w=t.outcome)==null?void 0:w.label)==="success"?"成功":((W=t.outcome)==null?void 0:W.label)==="partial"?"部分":((_=t.outcome)==null?void 0:_.label)==="failed"?"失败":((C=t.outcome)==null?void 0:C.label)==="abandoned"?"放弃":"进行中",N=((U=t.outcome)==null?void 0:U.commit_count)??t.commits.length,P=n.reverted_commits??0,L=n.user_violation_count??0,B=[M];N>0&&B.push(`commit×${N}`),P>0&&B.push(`reverted×${P}`),L>0&&B.push(`violation×${L}`);const H=B.join(" · ");return{intent:x,decision:l,execution:f,outcome:H}}function on(t){return t.status==="approved"?{label:"已 approve",color:"green"}:t.status==="skipped"?{label:"已 skip",color:"gray"}:t.status==="modified"?{label:"已修改",color:"orange"}:t.status==="expired"?{label:"已过期",color:"gray"}:{label:"待 approve",color:"arcoblue"}}const oe={fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:11,lineHeight:1.55,color:"var(--color-text-2)",background:"var(--color-fill-1)",border:"1px solid var(--color-border-2)",borderRadius:4,padding:10,margin:0,whiteSpace:"pre-wrap",wordBreak:"break-word",maxHeight:280,overflowY:"auto"},rn={"bmad-question-default":"BMAD 默认路径(疑问句)","bmad-default":"BMAD 默认路径","task-question-needs-bmad":"任务问题需走 BMAD","decision-hint-pending":"待 decision-maker 介入","no-spawn":"主线程直接处理","harness-debug-full":"Harness 调试流程(未知 bug)","harness-hotfix":"Harness hotfix(已知 bug)","refactor-low-coverage":"重构低覆盖代码","hybrid-feature-with-safety":"新功能 + 改老代码(低覆盖)","workflow-recommendation-mismatch":"主线程未按推荐 spawn","workflow-rec":"Workflow 推荐命中","kb-injection":"知识库(KB)注入","spec-gate-block-mutation":"Spec gate 拦截 mutation","edit-multi-file-hard":"多文件 Edit 硬阈值","write-multi-file-hard":"多文件 Write 硬阈值","edit-multi-file-no-agent":"多文件 Edit 但未 spawn agent","write-multi-file-no-agent":"多文件 Write 但未 spawn agent","edit-hook-script-from-main":"主线程改 hook 脚本","write-hook-script-from-main":"主线程写 hook 脚本","bash-grep-multi-file":"主线程 bash grep 多文件","bash-find-source":"主线程 bash find 源码","bash-git-log-diff-no-file":"主线程 git log/diff 无文件","task-spawn-general-purpose-misuse":"spawn general-purpose(应用专门 agent)","inline-edit-no-spawn":"单文件 inline Edit 未 spawn","inline-write-no-spawn":"单文件 inline Write 未 spawn"};function ln(t){if(!t)return"未知";const n=rn[t];return n||(typeof console<"u"&&console.warn&&console.warn(`[reasonLabel] unknown enum: "${t}"`),t)}const We=/<!--\s*decision-id:\s*([a-f0-9]{4,40})\s*-->/gi;function an(t){if(!t)return{ids:[],cleanedPrompt:""};const n=[];let o=t;const s=new RegExp(We.source,"gi");let r;for(;(r=s.exec(t))!==null;)r[1]&&!n.includes(r[1])&&n.push(r[1]);return o=o.replace(new RegExp(We.source,"gi"),""),o=o.replace(/^[ \t]*\n+/,"").replace(/\n{3,}/g,`
2
+
3
+ `).trimStart(),{ids:n,cleanedPrompt:o}}function cn(t,n){const o=n||null;return o?`自主决策: spawn ${o}(无 daemon 推荐)`:"自主决策(未走 daemon 推荐)"}function dn({s:t}){return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("section",{children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["用户提问",t.prompt&&e.jsxs(m,{size:"small",color:"gray",style:{marginLeft:6},children:[t.prompt.length," chars"]})]}),t.prompt?e.jsxs(e.Fragment,{children:[t.promptTimestamp&&e.jsxs(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginBottom:4},children:["timestamp: ",e.jsx(i.Text,{code:!0,style:{fontSize:11},children:Nt(t.promptTimestamp,{includeSeconds:!0})})]}),e.jsx("pre",{style:oe,children:t.prompt})]}):e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未触发"})]}),e.jsxs("section",{children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["意图识别",t.intentInj&&e.jsx(m,{size:"small",color:"arcoblue",style:{marginLeft:6},children:"已注入"})]}),t.intent?e.jsxs("div",{style:{marginBottom:6,fontSize:12},children:[e.jsxs(i.Text,{code:!0,style:{fontSize:11},children:["workflow_type=",t.intent.workflow_type??"-"]}),typeof t.intent.confidence=="number"&&e.jsxs(i.Text,{type:"secondary",style:{fontSize:11,marginLeft:6},children:["· confidence=",(t.intent.confidence*100).toFixed(0),"%"]}),t.intent.layer&&e.jsxs(m,{size:"small",color:"gray",style:{marginLeft:6,fontSize:10},children:["layer=",t.intent.layer]}),t.intent.suggested_agent&&e.jsxs(m,{size:"small",color:"purple",style:{marginLeft:6,fontSize:10},children:["→ ",t.intent.suggested_agent]}),t.intent.reasoning&&e.jsx("div",{style:{marginTop:4,fontSize:11,color:"var(--color-text-2)"},children:t.intent.reasoning})]}):e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}),t.intentInj&&e.jsxs(e.Fragment,{children:[e.jsxs(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:4,marginBottom:4},children:["注入原文 (source: ",e.jsx(i.Text,{code:!0,style:{fontSize:11},children:t.intentInj.source_handler}),"):"]}),e.jsx("pre",{style:oe,children:t.intentInj.content})]})]}),e.jsxs("section",{children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["命中知识库",t.kbHits.length>0&&e.jsxs(m,{size:"small",color:"purple",style:{marginLeft:6},children:[t.kbHits.length," 命中"]})]}),t.kbHits.length===0?e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}):e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{display:"inline-flex",flexWrap:"wrap",gap:4,marginBottom:6},children:t.kbHits.map(n=>e.jsxs(m,{size:"small",color:"purple",style:{fontSize:10},children:[n.name,typeof n.score=="number"&&` · score ${Math.round(n.score)}`,n.matched&&n.matched.length>0&&` · [${n.matched.slice(0,3).join(", ")}]`]},n.name))}),t.kbInjs.map((n,o)=>e.jsxs("div",{style:{marginTop:6},children:[e.jsxs(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginBottom:4},children:["注入 #",o+1," (",n.content.length," chars):"]}),e.jsxs("pre",{style:oe,children:[n.content.slice(0,800),n.content.length>800&&`
4
+ …(truncated)`]})]},n.id))]})]})]})}function pn({s:t}){return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("section",{children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["Spec 生成 (Phase 2b)",t.specs.length>0&&e.jsxs(m,{size:"small",color:"purple",style:{marginLeft:6},children:[t.specs.length," 条"]})]}),t.specs.length===0?e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6},children:t.specs.map(n=>{var s;const o=on(n);return e.jsxs("div",{style:{padding:"6px 10px",background:"var(--color-bg-1)",border:"1px solid var(--color-border-2)",borderRadius:4,fontSize:11},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[e.jsxs(i.Text,{code:!0,style:{fontSize:11,color:"var(--cf-tag-purple)"},children:["token=",n.token]}),e.jsx(m,{size:"small",color:o.color,children:o.label}),((s=n.intent)==null?void 0:s.workflow_type)&&e.jsxs(m,{size:"small",color:"gray",style:{fontSize:10},children:[n.intent.workflow_type,n.intent.suggested_agent?` → ${n.intent.suggested_agent}`:""]}),e.jsx(i.Text,{type:"secondary",style:{fontSize:10},children:n.created_at.slice(11,19)})]}),e.jsxs("div",{style:{marginTop:4},children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"spec_path: "}),e.jsx(i.Text,{code:!0,style:{fontSize:10,wordBreak:"break-all"},children:n.spec_path})]}),n.approved_at&&e.jsxs("div",{style:{marginTop:2,color:"var(--color-text-2)"},children:["approved_at: ",e.jsx(i.Text,{code:!0,style:{fontSize:10},children:n.approved_at})]})]},n.id)})})]}),e.jsxs("section",{children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["匹配技能",t.skills.length>0&&e.jsxs(m,{size:"small",color:"arcoblue",style:{marginLeft:6},children:[t.skills.length," 个"]})]}),t.skills.length===0?e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6},children:t.skills.map((n,o)=>e.jsxs("div",{style:{padding:"6px 10px",background:"var(--color-bg-1)",border:"1px solid var(--color-border-2)",borderRadius:4,fontSize:11},children:[e.jsx(i.Text,{code:!0,style:{fontSize:11,color:"var(--cf-tag-purple)"},children:n.skill_id}),n.reason&&e.jsx("div",{style:{marginTop:4,color:"var(--color-text-2)"},children:n.reason})]},`${n.skill_id}-${o}`))})]})]})}function mn({s:t,data:n}){const o=t.fileList.reduce((s,r)=>s+r.count,0);return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("section",{children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["spawn Agent",n.agentSpawns.length>0&&e.jsxs(m,{size:"small",color:"arcoblue",style:{marginLeft:6},children:[n.agentSpawns.length," 次"]})]}),n.agentSpawns.length===0?e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未 spawn"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:8},children:n.agentSpawns.map((s,r)=>{var g;const a=s.end_timestamp?Math.max(0,Math.round((E(s.end_timestamp).getTime()-E(s.timestamp).getTime())/1e3)):null,x=a===null?"running":a<60?`${a}s`:`${Math.floor(a/60)}m${a%60}s`,c=s.timestamp,u=n.agentSpawns[r+1],h=(u==null?void 0:u.timestamp)??s.end_timestamp??new Date().toISOString(),l=new Map;for(const k of n.timeline){if(k.tool_name!=="Edit"&&k.tool_name!=="Write"||k.timestamp<c||k.timestamp>h)continue;const f=(g=k.input)==null?void 0:g.file_path;typeof f=="string"&&l.set(f,(l.get(f)??0)+1)}const b=Array.from(l.entries());return e.jsxs("div",{style:{padding:"8px 10px",background:"var(--color-bg-1)",border:"1px solid var(--color-border-2)",borderRadius:4,fontSize:11},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:4,flexWrap:"wrap"},children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,color:"var(--cf-tag-blue)"},children:["Spawn #",r+1]}),e.jsx(i.Text,{code:!0,style:{fontSize:11,color:"var(--cf-tag-blue)"},children:s.subagent_type??"(no type)"}),s.status==="completed"?e.jsx(m,{size:"small",color:"green",children:"completed"}):e.jsx(m,{size:"small",color:"arcoblue",children:"running"}),e.jsxs(i.Text,{type:"secondary",style:{fontSize:10},children:[s.timestamp.slice(11,19)," · ",x]})]}),s.description&&e.jsxs("div",{style:{marginTop:2},children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"描述: "}),e.jsx(i.Text,{style:{fontSize:11},children:s.description})]}),s.prompt&&e.jsxs("details",{style:{marginTop:4},children:[e.jsxs("summary",{style:{fontSize:11,color:"var(--color-text-3)",cursor:"pointer"},children:["完整 prompt (",s.prompt_length," chars)"]}),e.jsx("pre",{style:oe,children:s.prompt})]}),s.output&&e.jsxs("details",{style:{marginTop:4},children:[e.jsxs("summary",{style:{fontSize:11,color:"var(--color-text-3)",cursor:"pointer"},children:["输出预览 (",s.output_length," chars)"]}),e.jsxs("pre",{style:{...oe,maxHeight:160},children:[s.output.slice(0,1200),s.output.length>1200&&`
5
+ …(fold)`]})]}),e.jsxs("div",{style:{marginTop:6},children:[e.jsxs(i.Text,{type:"secondary",style:{fontSize:11},children:["期间产物 (",b.length," 文件):"]}),b.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:2,marginTop:4},children:b.map(([k,f])=>e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",fontSize:11},children:[e.jsx(ie,{style:{color:"var(--cf-tag-green)",flexShrink:0}}),e.jsx(i.Text,{code:!0,style:{fontSize:10,wordBreak:"break-all"},children:k}),e.jsxs(m,{size:"small",color:"gray",style:{fontSize:10},children:["×",f]})]},k))}):e.jsx(i.Text,{type:"secondary",style:{fontSize:11,marginLeft:4},children:"(无)"})]})]},r)})})]}),e.jsxs("section",{children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["改文件总览",t.filesChanged>0&&e.jsxs(m,{size:"small",color:"green",style:{marginLeft:6},children:[t.filesChanged," 文件 / ",o," 操作"]})]}),t.fileList.length===0?e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:t.fileList.map(s=>{var x,c;let r=-1;for(const u of n.timeline)if(!(u.tool_name!=="Edit"&&u.tool_name!=="Write")&&((x=u.input)==null?void 0:x.file_path)===s.path){for(let h=0;h<n.agentSpawns.length;h++){const l=n.agentSpawns[h],b=((c=n.agentSpawns[h+1])==null?void 0:c.timestamp)??l.end_timestamp??"9999";if(u.timestamp>=l.timestamp&&u.timestamp<=b){r=h;break}}if(r>=0)break}const a=r>=0?e.jsxs(m,{size:"small",color:"cyan",style:{fontSize:10},children:["by Spawn #",r+1]}):e.jsx(m,{size:"small",color:"gray",style:{fontSize:10},children:"by 主线程"});return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"4px 8px",background:"var(--color-bg-1)",border:"1px solid var(--color-border-2)",borderRadius:4},children:[e.jsx(ie,{style:{color:"var(--cf-tag-green)",flexShrink:0}}),e.jsx(i.Text,{code:!0,style:{fontSize:11,flex:1,wordBreak:"break-all"},title:s.path,children:s.path}),a,e.jsxs(m,{size:"small",color:"gray",style:{flexShrink:0,fontSize:10},children:["×",s.count]})]},s.path)})})]})]})}function xn(t){return t==="success"?e.jsx(m,{color:"green",size:"small",children:"成功"}):t==="partial"?e.jsx(m,{color:"orange",size:"small",children:"部分"}):t==="failed"?e.jsx(m,{color:"red",size:"small",children:"失败"}):t==="abandoned"?e.jsx(m,{color:"gray",size:"small",children:"放弃"}):e.jsx(m,{size:"small",children:t})}function un({s:t,data:n}){return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8,fontSize:12},children:[!t.outcome&&e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未分类 / 进行中"}),t.outcome&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"outcome: "}),xn(t.outcome.label)]}),t.outcome.reason&&e.jsxs("div",{children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"outcome_reason: "}),e.jsx(i.Text,{code:!0,style:{fontSize:11},children:t.outcome.reason})]}),typeof t.outcome.commit_count=="number"&&e.jsxs("div",{children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"commit_count: "}),e.jsx(i.Text,{style:{fontSize:11},children:t.outcome.commit_count})]})]}),typeof n.reverted_commits=="number"&&n.reverted_commits>0&&e.jsxs("div",{children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"reverted_commits: "}),e.jsx(m,{color:"red",size:"small",children:n.reverted_commits})]}),typeof n.user_violation_count=="number"&&n.user_violation_count>0&&e.jsxs("div",{children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"user_violation_count: "}),e.jsx(m,{color:"orange",size:"small",children:n.user_violation_count})]}),t.commits.length>0&&e.jsxs("div",{children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginBottom:4},children:"commits (best-effort grep from Bash):"}),e.jsx("div",{style:{display:"inline-flex",flexWrap:"wrap",gap:4},children:t.commits.map((o,s)=>e.jsx(m,{size:"small",color:"green",style:{fontSize:10,fontFamily:"monospace"},children:o},`${o}-${s}`))})]}),e.jsxs("div",{children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"event_count: "}),e.jsx(i.Text,{style:{fontSize:11},children:n.event_count})]})]})}async function ze(t,n){const o=await Kt(t,{method:"POST",headers:{"Content-Type":"application/json"},body:n?JSON.stringify(n):void 0});if(!o.ok){let s;try{const r=await o.json();s=(r==null?void 0:r.error)||(r==null?void 0:r.message)}catch{}throw new Error(`${o.status} ${s??o.statusText}`)}return o.json()}async function fn(t){return ze(`/api/tasks/${encodeURIComponent(t.taskId)}/approve-spec`)}async function gn(t){return ze(`/api/tasks/${encodeURIComponent(t.taskId)}/mark-abandoned`,{reason:t.reason??null})}async function Ge(t){return ze(`/api/tasks/${encodeURIComponent(t.taskId)}/rerun`)}function hn({taskId:t,outcome:n,pendingSpecs:o}){const s=Pt(),r=De(),[a,x]=T.useState(null),c=o.some(f=>f.status==="generated"),u=n==="abandoned",h=fe({mutationFn:()=>fn({taskId:t}),onSuccess:f=>{K.success(`已 approve ${f.approved} spec`),r.invalidateQueries({queryKey:["task-detail",t]})},onError:f=>{K.error(`Approve 失败:${f.message}`)}}),l=fe({mutationFn:f=>gn({taskId:t,reason:f}),onSuccess:()=>{K.success("已标记 abandoned"),r.invalidateQueries({queryKey:["task-detail",t]})},onError:f=>{K.error(`标记失败:${f.message}`)}}),b=fe({mutationFn:()=>Ge({taskId:t}),onSuccess:f=>{x(f)},onError:f=>{K.error(`Re-run 取 prompt 失败:${f.message}`)}}),g=async()=>{await s({title:"标记任务为 abandoned",message:"此操作会把该任务的 outcome 置为 abandoned。可以稍后再点击 Re-run 用同意图重跑。是否继续?",confirmText:"标记 abandoned",variant:"warning"})&&l.mutate(void 0)},k=async()=>{if(a!=null&&a.prompt)try{await navigator.clipboard.writeText(a.prompt),K.success("已复制到剪贴板")}catch{K.warning("复制失败(请手动选取文本)")}};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{"data-testid":"action-rail",style:{display:"flex",flexWrap:"wrap",gap:8,padding:"10px 14px",border:"1px dashed var(--color-border-2)",borderRadius:4,marginTop:4,marginBottom:16,background:"var(--color-bg-1)"},children:[e.jsx(Q,{content:c?"把待审 spec 标记为 approved(不重启 daemon)":"该任务没有 pending spec",children:e.jsxs(A,{type:"primary",size:"small",icon:e.jsx(le,{}),disabled:!c||h.isPending,loading:h.isPending,onClick:()=>h.mutate(),"data-testid":"action-approve-spec",children:["Approve spec",o.length>0&&` (${o.filter(f=>f.status==="generated").length})`]})}),e.jsx(Q,{content:u?"该任务已是 abandoned":"把任务标记为 abandoned(不影响已写文件)",children:e.jsx(A,{status:"warning",size:"small",icon:e.jsx(Ae,{}),disabled:u||l.isPending,loading:l.isPending,onClick:g,"data-testid":"action-mark-abandoned",children:"标记 abandoned"})}),e.jsx(Q,{content:"打开原 prompt 文本,复制后粘贴到 Claude Code 继续",children:e.jsx(A,{size:"small",icon:e.jsx(_e,{}),loading:b.isPending,onClick:()=>b.mutate(),"data-testid":"action-rerun",children:"Re-run (复制原 prompt)"})}),e.jsx(Q,{content:"MVP 后续(需要 cross-task 相似性查询)",children:e.jsx(A,{size:"small",icon:e.jsx(jt,{}),disabled:!0,"data-testid":"action-compare",children:"对比上周同类任务"})})]}),e.jsx(Oe,{title:"Re-run — 复制原 prompt",visible:!!a,onCancel:()=>x(null),footer:e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:8},children:[e.jsx(A,{onClick:()=>x(null),size:"small",children:"完成"}),e.jsx(A,{type:"primary",size:"small",icon:e.jsx(qe,{}),onClick:k,disabled:!(a!=null&&a.prompt),children:"复制到剪贴板"})]}),style:{width:720},children:e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[(a==null?void 0:a.workflow_type)&&e.jsxs("div",{style:{fontSize:12},children:[e.jsx(i.Text,{type:"secondary",children:"workflow_type:"})," ",e.jsx(i.Text,{code:!0,children:a.workflow_type}),a.suggested_agent&&e.jsxs(e.Fragment,{children:[" ",e.jsx(i.Text,{type:"secondary",children:"→"})," ",e.jsx(i.Text,{code:!0,children:a.suggested_agent})]})]}),a!=null&&a.prompt?e.jsx("pre",{"data-testid":"rerun-prompt-text",style:{fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:12,lineHeight:1.55,background:"var(--color-fill-1)",border:"1px solid var(--color-border-2)",borderRadius:4,padding:12,maxHeight:360,overflowY:"auto",whiteSpace:"pre-wrap",wordBreak:"break-word",margin:0},children:a.prompt}):e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"该任务没有可恢复的原 prompt(events 表未记录 UserPromptSubmit)。"}),e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"MVP 工作流:复制后回到 Claude Code 中粘贴提交。后续会有 daemon-driven spawn-same-agent 模式。"})]})})]})}function yn(t,n){const o=E(t).getTime(),s=n?E(n).getTime():Date.now(),r=Math.max(0,Math.round((s-o)/1e3));return r<60?`${r}s`:r<3600?`${Math.floor(r/60)}m${r%60}s`:`${Math.floor(r/3600)}h${Math.floor(r%3600/60)}m`}function jn(t,n=32){if(!t)return"(无 prompt)";const o=t.replace(/\n/g," ").trim();return o.length>n?o.slice(0,n)+"…":o}function bn({data:t,summary:n}){var b;const[o,s]=T.useState(!1),[r,a]=T.useState(null),x=((b=n.outcome)==null?void 0:b.commit_count)??n.commits.length,c=yn(t.start_time,t.end_time),u=jn(n.prompt),h=fe({mutationFn:()=>Ge({taskId:t.id}),onSuccess:g=>a(g),onError:g=>K.error(`Re-run 取 prompt 失败:${g.message}`)}),l=async()=>{if(r!=null&&r.prompt)try{await navigator.clipboard.writeText(r.prompt),K.success("已复制到剪贴板")}catch{K.warning("复制失败(请手动选取文本)")}};return e.jsxs(z,{bordered:!0,style:{marginBottom:16,background:"var(--cf-kpi-wash-blue, #F2F9FF)"},"data-testid":"trivial-card",children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap",cursor:"pointer"},onClick:()=>s(g=>!g),"data-testid":"trivial-card-header",children:[e.jsx(le,{style:{color:"var(--cf-tag-green, #00B42A)",fontSize:16}}),e.jsxs(i.Text,{style:{fontSize:13,fontWeight:500},children:["“",u,"”"]}),e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsxs(i.Text,{style:{fontSize:12},children:[x," commit",x===1?"":"s"]}),e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsx(i.Text,{style:{fontSize:12},children:c}),e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"daemon 未介入"}),e.jsx("span",{style:{flex:1}}),e.jsx(A,{size:"mini",type:"text",icon:o?e.jsx(bt,{}):e.jsx(He,{}),onClick:g=>{g.stopPropagation(),s(k=>!k)},"data-testid":"trivial-card-toggle",children:o?"收起":"展开"})]}),o&&e.jsxs("div",{style:{marginTop:12,paddingTop:12,borderTop:"1px solid var(--color-border-2)",display:"flex",flexDirection:"column",gap:6},"data-testid":"trivial-card-detail",children:[e.jsxs("div",{style:{display:"flex",gap:12,fontSize:12,flexWrap:"wrap"},children:[e.jsx(i.Text,{type:"secondary",children:"时间"}),e.jsx(i.Text,{code:!0,children:Z(E(t.start_time),"yyyy-MM-dd HH:mm:ss")})]}),e.jsxs("div",{style:{display:"flex",gap:12,fontSize:12,flexWrap:"wrap"},children:[e.jsx(i.Text,{type:"secondary",children:"Task ID"}),e.jsx(i.Text,{code:!0,children:t.id.slice(0,12)})]}),n.commits.length>0&&e.jsxs("div",{style:{display:"flex",gap:12,fontSize:12,flexWrap:"wrap"},children:[e.jsx(i.Text,{type:"secondary",children:"Commit"}),e.jsx(i.Text,{code:!0,children:n.commits.join(", ")})]}),e.jsx("div",{style:{display:"flex",gap:8,marginTop:4},children:e.jsx(A,{size:"small",icon:e.jsx(_e,{}),loading:h.isPending,onClick:()=>h.mutate(),"data-testid":"trivial-card-rerun",children:"Re-run"})})]}),e.jsx(Oe,{title:"Re-run — 复制原 prompt",visible:!!r,onCancel:()=>a(null),footer:e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:8},children:[e.jsx(A,{onClick:()=>a(null),size:"small",children:"完成"}),e.jsx(A,{type:"primary",size:"small",icon:e.jsx(qe,{}),onClick:l,disabled:!(r!=null&&r.prompt),children:"复制到剪贴板"})]}),style:{width:720},children:r!=null&&r.prompt?e.jsx("pre",{style:{fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:12,lineHeight:1.55,background:"var(--color-fill-1)",border:"1px solid var(--color-border-2)",borderRadius:4,padding:12,maxHeight:360,overflowY:"auto",whiteSpace:"pre-wrap",wordBreak:"break-word",margin:0},children:r.prompt}):e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"该任务没有可恢复的原 prompt(events 表未记录 UserPromptSubmit)。"})})]})}const te={fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:11,lineHeight:1.55,color:"var(--color-text-2)",background:"var(--color-fill-1)",border:"1px solid var(--color-border-2)",borderRadius:4,padding:10,margin:0,whiteSpace:"pre-wrap",wordBreak:"break-word",maxHeight:240,overflowY:"auto"};function ne({title:t,children:n,testId:o}){return e.jsxs("div",{"data-testid":o,style:{marginBottom:16},children:[e.jsx(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:6},children:t}),n]})}function vn({data:t,timeline:n,visible:o,onClose:s}){const r=Ue(t),a=Je(r),x=t.injections.find(u=>u.source_handler.includes(":intent"));let c=null;try{c=x!=null&&x.metadata_json?JSON.parse(x.metadata_json):null}catch{c=null}return e.jsxs(Ke,{visible:o,onCancel:s,onOk:s,title:"高级调试信息(仅故障排查时使用)",width:560,placement:"right","data-testid":"debug-drawer",footer:null,children:[e.jsx(ne,{title:"① intent_engine 输出",testId:"debug-section-intent",children:c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{display:"flex",gap:6,marginBottom:6,flexWrap:"wrap"},children:[typeof c.workflow_type=="string"&&e.jsxs(m,{size:"small",color:"arcoblue",children:["workflow_type=",c.workflow_type]}),typeof c.confidence=="number"&&e.jsxs(m,{size:"small",color:"gray",children:["conf=",c.confidence.toFixed(2)]}),typeof c.layer=="string"&&e.jsxs(m,{size:"small",color:"gray",children:["layer=",c.layer]}),typeof c.suggested_agent=="string"&&e.jsxs(m,{size:"small",color:"purple",children:["agent=",c.suggested_agent]})]}),e.jsx("pre",{style:te,children:JSON.stringify(c,null,2)})]}):e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"未触发 intent injection"})}),e.jsx(xe,{style:{margin:"12px 0"}}),e.jsxs(ne,{title:"② daemon config flags(最新值)",testId:"debug-section-config",children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:"下列标志通过 daemon `config-store` 控制(实时值需后端补 endpoint; 目前显示最近一次注入的快照):"}),e.jsx("pre",{style:te,children:JSON.stringify({"auto_spec_generation.enabled":"(see /api/health for live value)","dedup_guard.enabled":"(see /api/health for live value)","active_pending.window_min":"(see /api/health for live value)","feedback_loop.enabled":"(see /api/health for live value)"},null,2)})]}),e.jsx(xe,{style:{margin:"12px 0"}}),e.jsxs(ne,{title:"③ trivial_filter 决策",testId:"debug-section-trivial",children:[e.jsx("div",{style:{display:"flex",gap:6,marginBottom:6,flexWrap:"wrap"},children:e.jsxs(m,{size:"small",color:a?"green":"orange",children:["isTrivialPath=",String(a)]})}),e.jsx("pre",{style:te,children:JSON.stringify({intentEmpty:!r.intent&&r.kbHits.length===0,decisionEmpty:r.specs.length===0&&r.skills.length===0,executionEmpty:r.spawned.length===0&&r.filesChanged===0,counters:{specs:r.specs.length,skills:r.skills.length,spawned:r.spawned.length,filesChanged:r.filesChanged,kbHits:r.kbHits.length,commits:r.commits.length}},null,2)})]}),e.jsx(xe,{style:{margin:"12px 0"}}),e.jsxs(ne,{title:"④ 原始事件(timeline 端点返回)",testId:"debug-section-raw",children:[n?e.jsxs(e.Fragment,{children:[e.jsxs(i.Text,{type:"secondary",style:{fontSize:11},children:["events: ",n.events.length," · artifacts: spec=",n.artifacts.spec.length," archive=",n.artifacts.archive.length," ","changelog=",n.artifacts.changelog.length," template=",n.artifacts.template.length," code=",n.artifacts.code.length]}),e.jsx("pre",{style:te,children:JSON.stringify(n,null,2)})]}):e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"timeline 端点未返回(loading 或 error)"}),e.jsx(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:8},children:t.agentSpawns.length>0?`agent_spawn 共 ${t.agentSpawns.length} 个,prompt/output 全文见 task detail JSON: GET /api/tasks/${t.id}`:"无 agent spawn"})]}),e.jsx(xe,{style:{margin:"12px 0"}}),e.jsx(ne,{title:"⑤ daemon 注入(additionalContext / systemMessage)",testId:"debug-section-injections",children:t.injections.length===0?e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"本任务无注入事件"}):e.jsxs(e.Fragment,{children:[e.jsxs(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginBottom:6},children:["共 ",t.injections.length," 条注入"]}),t.injections.map(u=>e.jsxs("div",{style:{marginBottom:8},children:[e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",marginBottom:4,flexWrap:"wrap"},children:[e.jsx(m,{size:"small",color:u.injection_type==="systemMessage"?"arcoblue":"orange",children:u.injection_type}),e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:u.source_handler})]}),e.jsx("pre",{style:te,children:u.content})]},u.id))]})})]})}async function Sn(t){const n=await fetch(`/api/tasks/${encodeURIComponent(t)}/timeline`);if(!n.ok)throw new Error(`timeline HTTP ${n.status}`);return n.json()}function wn(t){try{return Z(E(t),"HH:mm:ss")}catch{return t.slice(11,19)}}function kn(t,n){if(t===null||t<0)return n==="task_end"?"进行中":"未知";if(t===0&&n!=="paired")return"未知";const o=(()=>{if(t<1e3)return`${t}ms`;const s=Math.round(t/1e3);return s<60?`${s}s`:`${Math.floor(s/60)}m${s%60}s`})();return n==="task_end"?`进行中 (≈${o})`:o}const Ve='"Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", sans-serif',_n={user_prompt:{icon:"👤",color:"gray",label:"用户"},daemon_enforce:{icon:"🚫",color:"red",label:"daemon 拦截"},agent_spawn:{icon:"🤝",color:"arcoblue",label:"agent spawn"},commit:{icon:"💾",color:"green",label:"commit"},decision_resolved:{icon:"✅",color:"green",label:"决策闭环"}};function Tn({ev:t}){const n=_n[t.kind];return e.jsxs("div",{"data-testid":`timeline-event-${t.kind}`,style:{display:"flex",alignItems:"flex-start",gap:12,padding:"8px 4px",borderBottom:"1px solid var(--color-border-2)"},children:[e.jsx(i.Text,{code:!0,type:"secondary",style:{fontSize:11,minWidth:70,fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace"},children:wn(t.at)}),e.jsx("span",{style:{fontSize:14,minWidth:24,fontFamily:Ve,fontVariantEmoji:"emoji"},children:n.icon}),e.jsx("div",{style:{flex:1,minWidth:0},children:e.jsx(zn,{ev:t})})]})}function zn({ev:t}){switch(t.kind){case"user_prompt":return e.jsxs("div",{children:[e.jsx(i.Text,{style:{fontSize:12,fontWeight:500},children:"用户"}),e.jsxs(i.Paragraph,{style:{fontSize:12,color:"var(--color-text-2)",margin:"4px 0 0",whiteSpace:"pre-wrap"},ellipsis:{rows:3,expandable:!0},children:['"',t.text,'"']})]});case"daemon_enforce":return e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap"},children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:500},children:[t.decision==="deny"?"daemon 拒绝":"daemon 警告"," ",t.tool]}),e.jsx(m,{size:"small",color:t.decision==="deny"?"red":"orange",children:ln(t.rule_id)})]}),t.hint&&e.jsx(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:2},children:t.hint.slice(0,200)})]});case"agent_spawn":{const{ids:n,cleanedPrompt:o}=an(t.prompt_preview);return e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap"},children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:500},children:["主线程 spawn ",t.subagent_type??"?"]}),e.jsxs(i.Text,{type:"secondary",style:{fontSize:11},children:["(",kn(t.duration_ms,t.duration_source),")"]}),n.map(s=>e.jsx(Re,{to:`/decisions/${s}`,style:{textDecoration:"none"},title:`查看决策 ${s}`,children:e.jsxs(m,{size:"small",color:"purple",style:{cursor:"pointer"},children:[e.jsx("span",{style:{fontFamily:Ve},children:"📋"})," ","决策 ",s.slice(0,8)]})},s))]}),e.jsxs("div",{style:{marginTop:4,marginLeft:12,fontSize:11,color:"var(--color-text-3)"},children:[e.jsx("span",{children:"└─ "}),e.jsxs(i.Text,{type:"secondary",style:{fontSize:11},children:["prompt ",t.prompt_length," chars · output ",t.output_length," chars"]})]}),o&&e.jsx(i.Paragraph,{style:{fontSize:11,color:"var(--color-text-3)",margin:"4px 0 0 24px",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",whiteSpace:"pre-wrap"},ellipsis:{rows:2,expandable:!0},children:o})]})}case"commit":return e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap"},children:[e.jsx(i.Text,{style:{fontSize:12,fontWeight:500},children:"提交"}),e.jsx(i.Text,{code:!0,style:{fontSize:11,color:"var(--cf-tag-green)"},children:t.hash})]}),t.message_preview&&e.jsx(i.Text,{style:{fontSize:11,display:"block",marginTop:2},children:t.message_preview})]});case"decision_resolved":return e.jsx("div",{children:e.jsxs(i.Text,{style:{fontSize:12,fontWeight:500},children:["决策闭环"," ",e.jsx(i.Text,{code:!0,style:{fontSize:11},children:t.decision_id})]})});default:return null}}function Cn({artifacts:t}){const n=Object.keys(t).map(o=>({key:o,label:o==="spec"?"📄 spec":o==="archive"?"📦 归档":o==="changelog"?"📝 changelog":o==="template"?"🧱 模板":"⚙ 代码",count:t[o].length,example:t[o][0]??"-"})).filter(o=>o.count>0);return e.jsxs("div",{"data-testid":"artifacts-table",style:{marginTop:16},children:[e.jsx(i.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:6},children:"产物总览"}),n.length===0?e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"(本任务无产物)"}):e.jsx(St,{size:"small",pagination:!1,data:n,columns:[{title:"类型",dataIndex:"label",width:120},{title:"数量",dataIndex:"count",width:80},{title:"示例路径",dataIndex:"example",render:o=>e.jsx(i.Text,{code:!0,style:{fontSize:11,wordBreak:"break-all"},children:o})}]})]})}function In({data:t}){const[n,o]=T.useState(!1),{data:s,isLoading:r,isError:a}=G({queryKey:["task-timeline",t.id],queryFn:()=>Sn(t.id),staleTime:3e4,retry:1});if(a)throw new Error("timeline fetch failed");return e.jsxs(z,{bordered:!0,style:{marginBottom:16,background:"var(--cf-kpi-wash-blue, #F2F9FF)"},"data-testid":"task-timeline-view",children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:8},children:[e.jsxs(i.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx(Te,{style:{color:"var(--cf-tag-blue)"}}),"任务详情 · 时间线"]}),e.jsx(A,{size:"mini",type:"text",icon:e.jsx(vt,{}),onClick:()=>o(!0),"data-testid":"debug-drawer-toggle",title:"高级调试信息(仅故障排查时使用)",children:"调试"})]}),r&&e.jsx("div",{"data-testid":"task-timeline-loading",children:e.jsx(re,{animation:!0,text:{rows:6}})}),s&&e.jsxs(e.Fragment,{children:[e.jsx("div",{"data-testid":"task-timeline-events",children:s.events.length===0?e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"(时间线无事件)"}):s.events.map((x,c)=>e.jsx(Tn,{ev:x},`${x.at}-${x.kind}-${c}`))}),e.jsx(Cn,{artifacts:s.artifacts})]}),e.jsx(vn,{data:t,timeline:s??null,visible:n,onClose:()=>o(!1)})]})}function $n(t){return!t||t==="success"?new Set:t==="failed"||t==="partial"?new Set(["execution"]):t==="abandoned"?new Set(["outcome"]):new Set}function Mn(t){const n=t.get("expand");if(!n)return new Set;const o=new Set;for(const s of n.split(",")){const r=s.trim();(r==="intent"||r==="decision"||r==="execution"||r==="outcome")&&o.add(r)}return o}function Bn(t){return["intent","decision","execution","outcome"].filter(o=>t.has(o)).join(",")}class Fn extends T.Component{constructor(){super(...arguments);Me(this,"state",{errored:!1})}static getDerivedStateFromError(){return{errored:!0}}componentDidCatch(o,s){console.warn("[TaskTimelineView] fallback to 4-card; error:",o.message,s)}render(){return this.state.errored?this.props.fallback:this.props.children}}function En({data:t}){const[n,o]=we(),s=T.useMemo(()=>{const l=Mn(n);return l.size>0?l:$n(t.outcome)},[n,t.outcome]),r=T.useCallback(l=>{const b=new Set(s);b.has(l)?b.delete(l):b.add(l);const g=Bn(b),k=new URLSearchParams(n);g?k.set("expand",g):k.delete("expand"),o(k,{replace:!0})},[s,n,o]),a=T.useMemo(()=>Ue(t),[t]),x=T.useMemo(()=>nn(a,t),[a,t]),c=T.useMemo(()=>sn(a,t),[a,t]);if(T.useMemo(()=>Je(a),[a]))return e.jsx(bn,{data:t,summary:a});const h=e.jsxs(z,{bordered:!0,style:{marginBottom:16,background:"var(--cf-kpi-wash-blue, #F2F9FF)"},"data-testid":"tier-container",children:[e.jsxs(i.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6,marginBottom:8},children:[e.jsx(Te,{style:{color:"var(--cf-tag-blue)"}}),"任务详情"]}),e.jsx(tn,{banner:x,taskId:t.id,startedAt:t.start_time}),e.jsx(ue,{cardId:"intent",idx:1,title:"用户意图",oneLine:c.intent,expanded:s.has("intent"),onToggle:()=>r("intent"),detail:e.jsx(dn,{s:a})}),e.jsx(ue,{cardId:"decision",idx:2,title:"系统决策",oneLine:c.decision,expanded:s.has("decision"),onToggle:()=>r("decision"),detail:e.jsx(pn,{s:a})}),e.jsx(ue,{cardId:"execution",idx:3,title:"执行",oneLine:c.execution,expanded:s.has("execution"),onToggle:()=>r("execution"),detail:e.jsx(mn,{s:a,data:t})}),e.jsx(ue,{cardId:"outcome",idx:4,title:"结果",oneLine:c.outcome,expanded:s.has("outcome"),onToggle:()=>r("outcome"),detail:e.jsx(un,{s:a,data:t})}),e.jsx(hn,{taskId:t.id,outcome:t.outcome??null,pendingSpecs:t.pendingSpecs})]});return e.jsx(Fn,{fallback:h,children:e.jsx(In,{data:t})})}async function Ln(){const t=await fetch("/api/insights/badge?days=7");if(!t.ok)throw new Error(`badge HTTP ${t.status}`);return t.json()}function Wn({slot:t}={}){const{data:n,isLoading:o,isError:s}=G({queryKey:["daemon-observer-badge"],queryFn:Ln,refetchInterval:6e4,retry:1});if(o)return e.jsx("div",{"data-testid":"daemon-observer-badge-loading",style:{marginBottom:12},children:e.jsx(re,{animation:!0,text:{rows:1,width:360}})});if(s||!n)return null;const r=n.denied_7d??0,a=n.hinted_7d??0,x=n.trivial_passed_7d??0;return e.jsxs("div",{"data-testid":"daemon-observer-badge",style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap",padding:"6px 10px",marginBottom:12,border:"1px solid var(--color-border-2)",borderRadius:4,background:"var(--color-bg-1)",fontSize:12},children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"本周 daemon:"}),e.jsxs(m,{size:"small",color:"red","data-testid":"daemon-observer-denied",children:["🚫 拒 ",r," 次"]}),e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsxs(m,{size:"small",color:"orange","data-testid":"daemon-observer-hinted",children:["⚡ hint ",a," 次"]}),e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsxs(m,{size:"small",color:"green","data-testid":"daemon-observer-trivial",children:["✓ 通过 ",x," 个 trivial"]})]})}async function Nn(t){const n=await fetch(`/api/tasks/${t}`);if(!n.ok)throw new Error("Failed to fetch task detail");const o=await n.json();return{...o.task,userPrompts:o.userPrompts??[],injections:(o.injections??[]).map(s=>({id:s.id,timestamp:s.timestamp,source_handler:s.source_handler,injection_type:s.injection_type,content:s.content,metadata_json:s.metadata_json??null})),timeline:(o.timeline??[]).map((s,r)=>({id:`${s.timestamp}-${s.tool_name??s.kind}-${r}`,timestamp:s.timestamp,kind:s.kind??"tool",tool_name:s.tool_name??null,hook_type:s.hook_type,input:s.input,output:s.output,is_agent_call:s.is_agent_call,agent_detail:s.agent_detail,notification:s.notification})),skillInvocations:o.skillInvocations??[],artifacts:o.artifacts??[],pendingSpecs:o.pendingSpecs??[],agentSpawns:o.agentSpawns??[]}}function Pn(t){switch(t){case"Read":return e.jsx(Bt,{style:{color:"var(--color-text-3)"}});case"Edit":return e.jsx(Mt,{style:{color:"var(--cf-tag-orange)"}});case"Write":return e.jsx(ie,{style:{color:"var(--cf-tag-green)"}});case"Bash":return e.jsx($t,{style:{color:"var(--cf-tag-orange)"}});case"Agent":case"Task":return e.jsx(Te,{style:{color:"var(--cf-tag-blue)"}});case"Grep":case"Glob":return e.jsx(It,{style:{color:"var(--cf-tag-purple)"}});case"WebSearch":case"WebFetch":return e.jsx(Ct,{style:{color:"#14C9C9"}});default:return e.jsx(zt,{style:{color:"var(--color-text-3)"}})}}function Ne(t,n){const o=E(t).getTime()-E(n).getTime();return o<1e3?"+0s":o<6e4?`+${Math.floor(o/1e3)}s`:o<36e5?`+${Math.floor(o/6e4)}m${Math.floor(o%6e4/1e3)}s`:`+${Math.floor(o/36e5)}h${Math.floor(o%36e5/6e4)}m`}function Rn(t){return t==="completed"?e.jsx(m,{color:"green",icon:e.jsx(le,{}),children:"已完成"}):t==="active"?e.jsx(m,{color:"arcoblue",icon:e.jsx(ke,{spin:!0}),children:"进行中"}):t==="abandoned"?e.jsx(m,{color:"gray",children:"已放弃"}):e.jsx(m,{color:"gray",children:t})}function Pe(t){return t==="success"?e.jsx(m,{color:"green",size:"small",children:"成功"}):t==="partial"?e.jsx(m,{color:"orange",size:"small",children:"部分"}):t==="failed"?e.jsx(m,{color:"red",size:"small",children:"失败"}):t==="abandoned"?e.jsx(m,{color:"gray",size:"small",children:"放弃"}):e.jsx(m,{size:"small",children:t})}function Dn({taskId:t}){var h;const[n,o]=T.useState(new Set),{data:s,isLoading:r,error:a}=G({queryKey:["task-detail",t],queryFn:()=>Nn(t),enabled:!!t,refetchInterval:1e4});if(r)return e.jsx(z,{bordered:!0,children:e.jsx(re,{animation:!0,text:{rows:6}})});if(a||!s)return e.jsx(z,{bordered:!0,children:e.jsxs(i.Text,{type:"error",children:["加载失败: ",(a==null?void 0:a.message)||"未知错误"]})});const x=l=>{o(b=>{const g=new Set(b);return g.has(l)?g.delete(l):g.add(l),g})},c=s.end_time?`${Math.round((E(s.end_time).getTime()-E(s.start_time).getTime())/1e3)}s`:"进行中",u=s.userPrompts.length===0&&s.injections.length===0&&s.timeline.length===0&&s.skillInvocations.length===0&&s.artifacts.length===0;return e.jsxs("div",{children:[e.jsxs(z,{bordered:!0,style:{marginBottom:16},children:[e.jsxs("div",{style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:12,marginBottom:16},children:[e.jsx(i.Title,{heading:6,style:{margin:0},children:qt(s.title,(h=s.userPrompts[0])==null?void 0:h.content)}),e.jsxs("span",{style:{display:"inline-flex",gap:6},children:[Rn(s.status),s.outcome&&Pe(s.outcome)]})]}),e.jsx(wt,{colon:" :",size:"small",column:2,data:[{label:"开始时间",value:Z(E(s.start_time),"MM-dd HH:mm:ss")},{label:"结束时间",value:s.end_time?Z(E(s.end_time),"MM-dd HH:mm:ss"):"-"},{label:"持续时间",value:c},{label:"事件数",value:s.event_count},...s.outcome?[{label:"结果",value:e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[Pe(s.outcome),s.outcome_reason&&e.jsx(i.Text,{type:"secondary",style:{fontSize:11},children:s.outcome_reason})]})}]:[],...typeof s.commit_count=="number"?[{label:"提交数",value:e.jsxs("span",{children:[s.commit_count,typeof s.reverted_commits=="number"&&s.reverted_commits>0&&e.jsxs(i.Text,{type:"secondary",style:{fontSize:11,marginLeft:4},children:["(",s.reverted_commits," reverted)"]})]})}]:[]]})]}),e.jsx(Wn,{slot:"task-detail"}),e.jsx(En,{data:s}),u&&e.jsx(z,{bordered:!0,children:e.jsx(se,{icon:e.jsx(Fe,{style:{fontSize:32,color:"var(--color-text-4)"}}),description:e.jsxs("div",{children:[e.jsx("div",{style:{fontWeight:500},children:"该任务暂无可展示的执行内容"}),e.jsx("div",{style:{fontSize:12,color:"var(--color-text-3)",marginTop:4},children:"事件可能仍在记录中,稍后刷新查看"})]})})}),s.timeline.length>0&&e.jsxs(z,{bordered:!0,style:{marginBottom:16},children:[e.jsxs(i.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6,marginBottom:16},children:[e.jsx(Fe,{style:{color:"var(--color-text-3)"}}),"执行时间线",e.jsx(m,{size:"small",color:"gray",children:s.timeline.length})]}),e.jsx(ve,{children:s.timeline.map((l,b)=>{var y,S,w,W,_,C,U,V,ae;if(l.kind==="notification"){const R=((y=l.notification)==null?void 0:y.message)??"通知",j=((S=l.notification)==null?void 0:S.notification_type)??null;return e.jsx(ve.Item,{dot:e.jsx(kt,{style:{color:"var(--cf-tag-orange)"}}),label:Ne(l.timestamp,s.start_time),labelPosition:"relative",dotType:"hollow",children:e.jsxs("div",{style:{padding:4},"data-testid":"timeline-notification",children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[e.jsx(i.Text,{style:{fontSize:13,fontWeight:500,color:"var(--cf-tag-orange)"},children:"通知"}),j&&e.jsx(m,{size:"small",color:"orange",children:j})]}),e.jsx(i.Text,{type:"secondary",style:{fontSize:12,display:"block",marginTop:2},children:R})]})},l.id||b)}const g=l.is_agent_call,k=l.tool_name==="Edit"||l.tool_name==="Write",f=n.has(b),M=l.input,N=M==null?void 0:M.file_path,P=(M==null?void 0:M.description)||(M==null?void 0:M.command),L=(w=l.agent_detail)==null?void 0:w.status,B=((W=l.agent_detail)==null?void 0:W.changed_files)??[],H=g?s.agentSpawns.find(R=>{var j;return R.timestamp===l.timestamp&&(R.subagent_type??void 0)===((j=l.agent_detail)==null?void 0:j.subagent_type)})??s.agentSpawns.find(R=>R.timestamp===l.timestamp):void 0,q=g?L==="running"?e.jsx(ke,{spin:!0,style:{color:"var(--cf-tag-orange)"}}):e.jsx(le,{style:{color:"var(--cf-tag-green)"}}):Pn(l.tool_name);return e.jsx(ve.Item,{dot:q,label:Ne(l.timestamp,s.start_time),labelPosition:"relative",dotType:"hollow",children:e.jsxs("div",{onClick:()=>x(b),style:{cursor:"pointer",padding:4,borderRadius:4},"data-testid":g?"timeline-agent-call":void 0,children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[g?e.jsx(i.Text,{style:{fontSize:13,fontWeight:600,color:L==="running"?"var(--cf-tag-orange)":"var(--cf-tag-green)"},children:L==="running"?`⏳ ${((_=l.agent_detail)==null?void 0:_.subagent_type)??"子 agent"} 进行中`:`✅ ${((C=l.agent_detail)==null?void 0:C.subagent_type)??"子 agent"} 完成`}):e.jsx(i.Text,{style:{fontSize:13,fontWeight:500,color:"var(--color-text-1)"},children:l.tool_name}),g&&B.length>0&&e.jsxs(m,{size:"small",color:"green",children:[B.length," 文件"]}),!g&&((U=l.agent_detail)==null?void 0:U.subagent_type)&&e.jsx(m,{size:"small",color:"arcoblue",children:l.agent_detail.subagent_type}),((V=l.agent_detail)==null?void 0:V.name)&&e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:l.agent_detail.name})]}),g&&!f&&((ae=l.agent_detail)==null?void 0:ae.description)&&e.jsx(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:l.agent_detail.description}),!f&&k&&N&&e.jsx(i.Text,{style:{fontSize:11,fontFamily:"monospace",color:"var(--cf-tag-green)",display:"block",marginTop:2},title:N,children:N}),!f&&!k&&P&&e.jsx(i.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:P}),f&&e.jsxs("div",{onClick:R=>R.stopPropagation(),style:{marginTop:8,display:"flex",flexDirection:"column",gap:8},children:[g&&l.agent_detail&&e.jsxs(z,{size:"small",bordered:!0,style:{background:"var(--cf-kpi-wash-blue, #E8F3FF)"},children:[l.agent_detail.subagent_type&&e.jsxs("div",{style:{fontSize:12,marginBottom:4},children:[e.jsx(i.Text,{type:"secondary",children:"subagent_type:"})," ",e.jsx(i.Text,{code:!0,children:l.agent_detail.subagent_type})]}),l.agent_detail.name&&e.jsxs("div",{style:{fontSize:12,marginBottom:4},children:[e.jsx(i.Text,{type:"secondary",children:"name:"})," ",e.jsx(i.Text,{code:!0,children:l.agent_detail.name})]}),l.agent_detail.prompt&&e.jsxs("div",{children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"prompt:"}),e.jsx("pre",{style:{fontSize:11,background:"#fff",border:"1px solid var(--color-border-2)",borderRadius:4,padding:8,marginTop:4,maxHeight:200,overflow:"auto",whiteSpace:"pre-wrap"},children:l.agent_detail.prompt})]}),B.length>0&&e.jsxs("div",{style:{marginTop:8},"data-testid":"agent-changed-files",children:[e.jsxs(i.Text,{type:"secondary",style:{fontSize:12},children:["改动文件 (",B.length,"):"]}),e.jsx("div",{style:{marginTop:4,display:"flex",flexDirection:"column",gap:2},children:B.map(R=>e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx(ie,{style:{color:"var(--cf-tag-green)"}}),e.jsx(i.Text,{code:!0,style:{fontSize:11},title:R,children:R})]},R))})]}),(H==null?void 0:H.output)&&e.jsxs("div",{style:{marginTop:8},children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"报告全文:"}),e.jsx("pre",{style:{fontSize:11,background:"#fff",border:"1px solid var(--color-border-2)",borderRadius:4,padding:8,marginTop:4,maxHeight:320,overflow:"auto",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:H.output})]}),L==="running"&&e.jsx(i.Text,{type:"secondary",style:{fontSize:12,display:"block",marginTop:8},children:"⏳ 子 agent 仍在执行,报告尚未返回"})]}),k&&N&&e.jsxs(z,{size:"small",bordered:!0,children:[e.jsx(i.Text,{type:"secondary",style:{fontSize:12},children:"file:"})," ",e.jsx(i.Text,{code:!0,style:{color:"var(--cf-tag-green)"},children:N})]}),!g&&P&&e.jsx(z,{size:"small",bordered:!0,children:e.jsx("pre",{style:{fontSize:11,color:"var(--color-text-2)",margin:0,whiteSpace:"pre-wrap",wordBreak:"break-word",maxHeight:160,overflow:"auto"},children:P})})]})]})},l.id||b)})})]}),s.skillInvocations.length>0&&e.jsxs(z,{bordered:!0,style:{marginBottom:16},children:[e.jsxs(i.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6,marginBottom:12},children:[e.jsx(_t,{style:{color:"var(--cf-tag-purple)"}}),"Skill 调用",e.jsx(m,{size:"small",color:"gray",children:s.skillInvocations.length})]}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:8},children:s.skillInvocations.map(l=>e.jsxs(z,{size:"small",bordered:!0,style:{borderColor:"var(--cf-tag-purple)",background:"var(--cf-kpi-wash-purple, #F5E8FF)"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap",marginBottom:4},children:[e.jsx(i.Text,{style:{fontFamily:"monospace",fontSize:13,fontWeight:500,color:"var(--cf-tag-purple)"},children:l.skill_id}),l.workflow&&e.jsx(m,{size:"small",color:"purple",children:l.workflow}),l.phase&&e.jsxs(m,{size:"small",color:"purple",children:["phase: ",l.phase]})]}),e.jsx(i.Text,{style:{fontSize:12,color:"var(--color-text-2)"},children:l.reason})]},l.id))})]}),s.artifacts.length>0&&e.jsxs(z,{bordered:!0,children:[e.jsxs(i.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6,marginBottom:12},children:[e.jsx(Tt,{style:{color:"var(--cf-tag-green)"}}),"产物",e.jsxs(m,{size:"small",color:"gray",children:[s.artifacts.length," 个文件"]})]}),e.jsx(Ee,{size:"small",dataSource:s.artifacts,render:l=>e.jsx(Ee.Item,{style:{padding:"6px 12px"},children:e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:8},children:[e.jsx(ie,{style:{color:"var(--cf-tag-green)"}}),e.jsx(i.Text,{code:!0,style:{fontSize:12},title:l,children:l})]})},l)})]})]})}async function An(t){const n=await fetch(`/api/sessions/${t}/detail`);if(!n.ok)throw new Error("Failed to fetch session detail");return n.json()}function Hn({sessionId:t}){const{data:n,isLoading:o,error:s}=G({queryKey:["session-detail",t],queryFn:()=>An(t),enabled:!!t});return o?e.jsx("div",{className:"p-6 text-gray-500",children:"加载中..."}):s||!n?e.jsx("div",{className:"p-6 text-red-600",children:"加载失败"}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500 mb-1",children:"Session ID"}),e.jsx("div",{className:"text-sm font-mono text-gray-900 break-all",children:n.session.session_id})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-4 pb-4 border-b border-gray-200",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500",children:"事件数"}),e.jsx("div",{className:"text-lg font-semibold",children:n.session.event_count})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500",children:"任务数"}),e.jsx("div",{className:"text-lg font-semibold",children:n.tasks.length})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500",children:"开始时间"}),e.jsx("div",{className:"text-sm",children:n.session.start_time?Z(E(n.session.start_time),"MM-dd HH:mm:ss"):"-"})]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-700 mb-3",children:"任务列表"}),e.jsx("div",{className:"space-y-3",children:n.tasks.map(r=>e.jsxs("div",{className:"border border-gray-200 rounded-lg p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h4",{className:"text-sm font-semibold text-gray-900 flex-1 mr-2",children:r.title}),e.jsx("span",{className:Ut("px-2 py-0.5 text-xs font-medium rounded-full whitespace-nowrap",r.status==="completed"&&"bg-green-100 text-green-700",r.status==="active"&&"bg-blue-100 text-blue-700",r.status==="abandoned"&&"bg-gray-100 text-gray-600"),children:r.status})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-3 mb-3 text-xs",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"text-gray-500 mb-1 flex items-center gap-1",children:[e.jsx(Jt,{className:"h-3 w-3"}),"工具使用"]}),e.jsx("div",{className:"space-y-0.5",children:Object.entries(r.summary.toolUsage).slice(0,4).map(([a,x])=>e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:a}),e.jsx("span",{className:"font-mono text-gray-900",children:x})]},a))})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"text-gray-500 mb-1 flex items-center gap-1",children:[e.jsx(Gt,{className:"h-3 w-3"}),"文件变更"]}),e.jsxs("div",{className:"text-gray-700",children:[r.summary.filesChanged.length," 个"]}),r.summary.filesChanged.slice(0,3).map(a=>e.jsx("div",{className:"text-gray-500 truncate text-[10px]",title:a,children:a.split("/").pop()},a))]}),e.jsxs("div",{children:[e.jsxs("div",{className:"text-gray-500 mb-1 flex items-center gap-1",children:[e.jsx(Vt,{className:"h-3 w-3"}),"提交"]}),e.jsxs("div",{className:"text-gray-700",children:[r.summary.commits.length," 次"]})]})]}),r.prompts.length>0&&e.jsxs("div",{className:"border-t border-gray-100 pt-3",children:[e.jsxs("div",{className:"text-xs text-gray-500 mb-2 flex items-center gap-1",children:[e.jsx(Yt,{className:"h-3 w-3"}),"用户提示 (",r.prompts.length,")"]}),e.jsxs("div",{className:"space-y-1.5",children:[r.prompts.slice(0,3).map((a,x)=>e.jsx("div",{className:"text-xs bg-gray-50 rounded p-2",children:e.jsx("p",{className:"text-gray-700 line-clamp-2",children:a.content})},x)),r.prompts.length>3&&e.jsxs("div",{className:"text-xs text-gray-400",children:["还有 ",r.prompts.length-3," 条..."]})]})]})]},r.id))})]})]})}const On=720;function qn(t){const n=t.get("task");if(n)return{kind:"task",id:n,paramKey:"task"};const o=t.get("session");return o?{kind:"session",id:o,paramKey:"session"}:null}function Kn(t){switch(t.kind){case"session":return`会话: ${t.id.slice(0,8)}...`;case"task":return`任务: ${t.id.slice(0,8)}...`}}function Un(){const[t,n]=we(),o=T.useMemo(()=>qn(t),[t]),s=()=>{if(!o)return;const a=new URLSearchParams(t);a.delete(o.paramKey),n(a,{replace:!1})},r=!!o;return e.jsx(Ke,{title:o?Kn(o):"",width:On,placement:"right",visible:r,onCancel:s,footer:null,maskClosable:!0,unmountOnExit:!0,children:o?e.jsx(Jn,{target:o}):null})}function Jn({target:t}){return t.kind==="session"?e.jsx(Hn,{sessionId:t.id}):e.jsx(Dn,{taskId:t.id})}const Gn=[{key:"all",label:"全部",color:"gray"},{key:"success",label:"✅ 成功",color:"green"},{key:"partial",label:"⚠️ 部分",color:"orange"},{key:"failed",label:"❌ 失败",color:"red"},{key:"abandoned",label:"🛑 放弃",color:"gray"},{key:"none",label:"🔄 进行中",color:"arcoblue",hideWhenZero:!0},{key:"answered",label:"💬 已答复",color:"cyan",hideWhenZero:!0}];function Vn({active:t,counts:n,onChange:o}){return e.jsx("div",{style:{display:"inline-flex",gap:6,flexWrap:"wrap",alignItems:"center"},children:Gn.map(s=>{const r=s.key===t,a=n[s.key]??0;return s.hideWhenZero&&a===0&&!r?null:e.jsxs(m,{checkable:!0,checked:r,onCheck:()=>o(s.key),color:r?s.color:void 0,style:{cursor:"pointer",fontSize:12,fontWeight:r?600:400,borderColor:r?void 0:"var(--color-border-2)"},children:[s.label," ",e.jsxs("span",{style:{opacity:.7,marginLeft:2},children:["(",a,")"]})]},s.key)})})}async function Yn(t,n={}){const o=new URLSearchParams;o.set("window",String(n.windowDays??30)),t&&o.set("project",t),n.limit!=null&&o.set("limit",String(n.limit)),n.offset!=null&&o.set("offset",String(n.offset)),n.includeSystem&&o.set("include_kinds","user,agent-callback,image,system");const s=await fetch(`/api/insights/agent-board?${o.toString()}`);if(!s.ok)throw new Error(`API ${s.status}`);return s.json()}async function Qn(t,n={}){const o=new URLSearchParams;o.set("window",String(n.windowDays??30)),o.set("rows","prompt"),t&&o.set("project",t),n.limit!=null&&o.set("limit",String(n.limit)),n.offset!=null&&o.set("offset",String(n.offset)),n.includeSystem&&o.set("include_kinds","user,agent-callback,image,system"),n.outcome&&n.outcome!=="all"&&o.set("outcome",n.outcome);const s=(n.search??"").trim();s&&o.set("search",s);const r=await fetch(`/api/insights/agent-board?${o.toString()}`);if(!r.ok)throw new Error(`API ${r.status}`);return r.json()}function Zn(t){try{return Z(E(t),"MM-dd HH:mm")}catch{return t}}function Ye(t){if(t==null)return"—";if(t<60)return`${t}s`;if(t<3600)return`${Math.round(t/60)}m`;const n=Math.floor(t/3600),o=Math.round(t%3600/60);return o>0?`${n}h ${o}m`:`${n}h`}function Qe(t){const n=Date.now()-E(t).getTime();return n<6e4?"刚刚":n<36e5?`${Math.round(n/6e4)}m 前`:n<864e5?`${Math.round(n/36e5)}h 前`:`${Math.round(n/864e5)}d 前`}function Xn(t){switch(t){case"agent-callback":return"回调";case"image":return"图片";case"system":return"系统";case"user":default:return""}}function es(t){return t!=="user"}const Ze={pending:{text:"待处理",color:"gray"},active:{text:"进行中",color:"arcoblue"},abandoned:{text:"中断",color:"orange"},completed:{text:"完成",color:"green"}};function ts({row:t,group:n,onOpen:o}){const s=t.prompt_text||"(空 prompt)",r=s.length>160?`${s.slice(0,160)}…`:s,a=(n==null?void 0:n.lane)??"active",x=Ze[a];return e.jsx(z,{bordered:!0,hoverable:!0,onClick:()=>o(t.group_id),"data-prompt-row":t.event_id,"data-group-id":t.group_id,style:{marginBottom:8,background:"var(--color-bg-1)",borderLeft:"3px solid var(--color-border-2)",cursor:"pointer"},bodyStyle:{padding:"10px 14px"},children:e.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:12},children:[e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsx(Q,{content:s,children:e.jsxs(i.Text,{style:{fontSize:13,color:"var(--color-text-1)"},children:["💬 ",r]})}),e.jsxs("div",{style:{display:"flex",gap:8,fontSize:11,color:"var(--color-text-3)",flexWrap:"wrap",alignItems:"center",marginTop:4},children:[e.jsx("span",{style:{fontFamily:"monospace"},children:t.event_id.slice(0,8)}),e.jsx("span",{children:"·"}),e.jsx("span",{children:Qe(t.prompt_ts)}),e.jsx("span",{children:"·"}),e.jsx("span",{children:Zn(t.prompt_ts)})]})]}),e.jsx("div",{style:{flexShrink:0},children:n!=null&&n.outcome?e.jsx(Qt,{value:n.outcome}):e.jsx(m,{color:x.color,size:"small",children:x.text})})]})})}const ns=[{key:"pending",emoji:"🆕",title:"待处理",bg:"#f5f6f7",border:"#dadce0"},{key:"active",emoji:"🔄",title:"进行中",bg:"#eaf2ff",border:"#bcd2ff"},{key:"abandoned",emoji:"⏸",title:"中断",bg:"#fff5e8",border:"#ffd591"},{key:"failed",emoji:"❌",title:"失败",bg:"#fff1f0",border:"#ffccc7"},{key:"done",emoji:"✅",title:"完成",bg:"#e8faef",border:"#b8e8ca"}];function ss({def:t,cards:n,onOpen:o,limit:s,onLoadMore:r}){const a=n.slice(0,s),x=Math.max(0,n.length-a.length);return e.jsxs("div",{"data-lane":t.key,style:{flex:1,minWidth:240,background:t.bg,border:`1px solid ${t.border}`,borderRadius:8,padding:12,display:"flex",flexDirection:"column"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:8},children:[e.jsx("span",{style:{fontSize:16},children:t.emoji}),e.jsx(i.Text,{style:{fontSize:13,fontWeight:600},children:t.title}),e.jsx(m,{size:"small",style:{marginLeft:"auto"},children:n.length})]}),e.jsxs("div",{style:{flex:1,maxHeight:"calc(100vh - 300px)",overflowY:"auto",paddingRight:4},children:[n.length===0?e.jsx("div",{style:{padding:"16px 0",display:"flex",justifyContent:"center",opacity:.6},children:e.jsx(se,{description:"无任务"})}):a.map(c=>{const u=es(c.task_kind),h=u?"var(--color-fill-4)":c.status==="completed"?Zt(c.outcome):"var(--color-border-2)";return e.jsxs(z,{bordered:!0,size:"small",hoverable:!0,onClick:()=>o(c.task_id),"data-task-kind":c.task_kind,style:{marginBottom:8,background:u?"var(--color-fill-1)":"var(--color-bg-1)",borderLeft:`4px solid ${h}`,cursor:"pointer",opacity:u?.78:1},bodyStyle:{padding:"8px 10px"},children:[u&&e.jsx("div",{style:{marginBottom:4},children:e.jsx(m,{color:"gray",size:"small",style:{fontSize:10},children:Xn(c.task_kind)})}),e.jsx(i.Paragraph,{style:{margin:0,marginBottom:4,fontSize:12,fontWeight:600,lineHeight:1.35,wordBreak:"break-word",color:u?"var(--color-text-3)":void 0},children:c.title?c.title.length>80?c.title.slice(0,80)+"…":c.title:"(空 title)"}),e.jsxs("div",{style:{display:"flex",gap:4,fontSize:10.5,color:"var(--color-text-3)",flexWrap:"wrap"},children:[e.jsx("span",{children:Qe(c.start_time)}),c.duration_sec!==null&&e.jsxs("span",{children:["· ",Ye(c.duration_sec)]}),c.files_changed>0&&e.jsxs("span",{children:["· ",c.files_changed," files"]}),c.kb_pages.length>0&&e.jsxs("span",{children:["· ",c.kb_pages.length," KB"]})]})]},c.task_id)}),x>0&&e.jsx("div",{style:{paddingTop:4},children:e.jsxs(A,{size:"mini",long:!0,type:"text",onClick:r,style:{fontSize:11,color:"var(--color-text-3)"},children:["再看 30 条(剩 ",x,")"]})})]})]})}function gs(){const[t,n]=we(),o=ft(),{data:s}=G({queryKey:Ot(),queryFn:Ht,staleTime:3e4}),{project:r}=Rt(),a=(s==null?void 0:s.current)??"",x=At(r,a),c=t.get("outcome")??"all",u=t.get("view")==="kanban"?"kanban":"list",h=t.get("q")??"",{window:l}=Dt(),b=t.get("sys")==="1",g=[20,40,80],k=40,f=300,M=parseInt(t.get("page")??"1",10),N=parseInt(t.get("pageSize")??String(k),10),P=Number.isFinite(M)&&M>0?M:1,L=g.includes(N)?N:k,B=30,[H,q]=T.useState(B);T.useEffect(()=>{q(B)},[c,h,l]);const y=T.useRef(l);T.useEffect(()=>{if(y.current!==l&&(y.current=l,t.get("page")||t.get("pageSize"))){const p=new URLSearchParams(t);p.delete("page"),p.delete("pageSize"),n(p,{replace:!0})}},[l,t,n]);const S=u==="list"?L:f,w=u==="list"?(P-1)*L:0,W=De(),_=u==="list",{data:C,isLoading:U,isError:V,refetch:ae,isFetching:R}=G({queryKey:["tasks-hub",x,"kanban",S,w,b,l],queryFn:()=>Yn(x,{limit:S,offset:w,includeSystem:b,windowDays:l}),enabled:!_,refetchInterval:3e4,refetchIntervalInBackground:!1,placeholderData:Be}),{data:j,isLoading:Xe,isError:et,refetch:tt,isFetching:nt}=G({queryKey:["tasks-hub",x,"prompt",S,w,b,l,c,h],queryFn:()=>Qn(x,{limit:S,offset:w,includeSystem:b,windowDays:l,outcome:c,search:h}),enabled:_,refetchInterval:3e4,refetchIntervalInBackground:!1,placeholderData:Be}),[ge,he]=T.useState(!1);T.useEffect(()=>{if(typeof EventSource>"u")return;const p=x?`/api/events/stream?project=${encodeURIComponent(x)}`:"/api/events/stream",d=new EventSource(p);let v=null;const O=()=>{v&&clearTimeout(v),v=setTimeout(()=>{W.invalidateQueries({queryKey:["tasks-hub"]})},700)};return d.onopen=()=>he(!0),d.onmessage=F=>{try{const $=JSON.parse(F.data||"{}");if(($==null?void 0:$.type)==="connected"){he(!0);return}}catch{}O()},d.onerror=()=>{he(!1)},()=>{v&&clearTimeout(v),d.close()}},[x,W]);const ce=T.useMemo(()=>C?[...C.lanes.pending,...C.lanes.active,...C.lanes.abandoned,...C.lanes.completed]:[],[C]),st=T.useMemo(()=>{if(_){const v=j==null?void 0:j.window_aggregates;if(v)return{all:v.task_total,success:v.by_outcome.success,partial:v.by_outcome.partial,failed:v.by_outcome.failed,abandoned:v.by_outcome.abandoned,answered:v.by_outcome.answered,none:v.by_outcome.none};const O=j?Object.values(j.groups).filter($=>$.task_kind==="user"):[],F={all:O.length,success:0,partial:0,failed:0,abandoned:0,answered:0,none:0};for(const $ of O)$.outcome==="success"||$.outcome==="partial"||$.outcome==="failed"||$.outcome==="abandoned"?F[$.outcome]++:$.status==="abandoned"?F.abandoned++:F.none++;return F}const p=ce.filter(v=>v.task_kind==="user"),d={all:p.length,success:0,partial:0,failed:0,abandoned:0,answered:0,none:0};for(const v of p)v.outcome==="success"||v.outcome==="partial"||v.outcome==="failed"||v.outcome==="abandoned"?d[v.outcome]++:v.status==="abandoned"?d.abandoned++:d.none++;return d},[_,j,ce]),ot=T.useMemo(()=>{if(!C)return{pending:[],active:[],abandoned:[],failed:[],done:[]};const p=h.trim().toLowerCase(),d=$=>p?$.filter(I=>[I.title,...I.top_tools.map(me=>me.tool),...I.kb_pages.map(me=>me.name)].join(" ").toLowerCase().includes(p)):$,v=d(C.lanes.completed),O=v.filter($=>$.outcome==="failed"),F=v.filter($=>$.outcome!=="failed");return{pending:d(C.lanes.pending),active:d(C.lanes.active),abandoned:d(C.lanes.abandoned),failed:O,done:F}},[C,h]),J=T.useMemo(()=>{if(_){const I=j==null?void 0:j.window_aggregates,X=(j==null?void 0:j.total_in_window)??0;if(I){const D=I.task_total;return{total:D,failed:I.by_outcome.failed,intercepted:0,avgSec:I.avg_duration_sec??0,promptTotal:X,groupCount:D}}const je=(j?Object.values(j.groups):[]).filter(D=>D.task_kind==="user"),$e=je.length,dt=je.filter(D=>D.outcome==="failed").length,be=je.map(D=>D.duration_sec).filter(D=>typeof D=="number"&&D>0),pt=be.length>0?Math.round(be.reduce((D,mt)=>D+mt,0)/be.length):0;return{total:$e,failed:dt,intercepted:0,avgSec:pt,promptTotal:X,groupCount:$e}}const p=ce.filter(I=>I.task_kind==="user"),d=(C==null?void 0:C.total_in_window)??p.length,v=p.filter(I=>I.outcome==="failed").length,O=p.filter(I=>I.intercepts.deny+I.intercepts.warn>0).length,F=p.map(I=>I.duration_sec).filter(I=>typeof I=="number"&&I>0),$=F.length>0?Math.round(F.reduce((I,X)=>I+X,0)/F.length):0;return{total:d,failed:v,intercepted:O,avgSec:$,promptTotal:0,groupCount:d}},[_,j,ce,C]),de=T.useMemo(()=>j?j.rows:[],[j]),it=T.useMemo(()=>{const p=[],d=new Set;for(const v of de)d.has(v.group_id)||(d.add(v.group_id),p.push(v.group_id));return p},[de]),Y=p=>n(p,{replace:!1}),pe=p=>{p.delete("page"),p.delete("pageSize")},Ce=p=>{const d=new URLSearchParams(t);p==="all"?d.delete("outcome"):d.set("outcome",p),pe(d),Y(d)},rt=p=>{const d=new URLSearchParams(t);p==="list"?d.delete("view"):d.set("view",p),pe(d),Y(d)},lt=p=>{const d=new URLSearchParams(t);p?d.set("q",p):d.delete("q"),pe(d),Y(d)},at=p=>{const d=new URLSearchParams(t);p?d.set("sys","1"):d.delete("sys"),pe(d),Y(d)},ye=p=>{o(`/tasks/${p}`)},ct=p=>{const d=new URLSearchParams(t);p<=1?d.delete("page"):d.set("page",String(p)),Y(d)},Ie=p=>{const d=new URLSearchParams(t);p===k?d.delete("pageSize"):d.set("pageSize",String(p)),d.delete("page"),Y(d)};return e.jsxs("div",{style:{padding:16,display:"flex",flexDirection:"column",gap:12,height:"100%"},children:[e.jsxs(z,{bordered:!1,bodyStyle:{padding:"12px 16px"},style:{background:"var(--color-bg-1)"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,flexWrap:"wrap",marginBottom:12},children:[e.jsx(i.Title,{heading:5,style:{margin:0},children:"我的任务"}),e.jsxs(i.Text,{type:"secondary",style:{fontSize:12},children:["近 ",l,"d · ",_?"每行 = 1 条 user prompt(按任务分组)· 点行看执行链路":"看板按任务卡 · 点卡片看详情"]}),e.jsxs("div",{style:{marginLeft:"auto",display:"flex",gap:8,alignItems:"center"},children:[e.jsx(Q,{content:ge?"实时已连接(SSE)":"离线 · 30s 轮询兜底",children:e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4,fontSize:12,color:"var(--color-text-3)"},children:[e.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:ge?"var(--cf-tag-green, #00B42A)":"var(--color-text-4, #C9CDD4)",display:"inline-block"}}),ge?"实时":"离线"]})}),e.jsxs(Se.Group,{type:"button",size:"small",value:u,onChange:p=>rt(p),children:[e.jsxs(Se,{value:"list",children:[e.jsx(Ft,{})," 列表"]}),e.jsxs(Se,{value:"kanban",children:[e.jsx(Et,{})," 看板"]})]}),e.jsx(A,{size:"small",icon:e.jsx(_e,{}),loading:_?nt:R,onClick:()=>_?tt():ae(),children:"刷新"})]})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,flexWrap:"wrap"},children:[e.jsx(Vn,{active:c,counts:st,onChange:Ce}),e.jsx(m,{checkable:!0,checked:b,onCheck:p=>at(p),size:"small",color:b?"arcoblue":void 0,"data-testid":"sys-toggle",children:"含系统任务"}),e.jsx(Lt.Search,{size:"small",placeholder:"搜索 title / tool / KB / file...",style:{width:280,marginLeft:"auto"},value:h,onChange:p=>lt(p),allowClear:!0})]})]}),e.jsx(z,{bordered:!0,bodyStyle:{padding:"12px 16px"},children:e.jsxs("div",{style:{display:"flex",gap:24,flexWrap:"wrap"},children:[e.jsx(ee,{title:e.jsxs("span",{style:{fontSize:12,color:"var(--color-text-3)"},children:["总任务数 (",l,"d)"]}),value:J.total,groupSeparator:!0}),_&&e.jsx(ee,{title:e.jsxs("span",{style:{fontSize:12,color:"var(--color-text-3)"},children:["prompt 数 (",l,"d)"]}),value:J.promptTotal,groupSeparator:!0}),e.jsx("div",{style:{cursor:"pointer"},onClick:()=>Ce("failed"),title:"点击筛选失败任务",children:e.jsx(ee,{title:e.jsx("span",{style:{fontSize:12,color:"#f44336"},children:"失败 (可点击 →)"}),value:J.failed,styleValue:{color:J.failed>0?"#f44336":void 0}})}),!_&&e.jsx(ee,{title:e.jsx("span",{style:{fontSize:12,color:"var(--color-text-3)"},children:"被拦截"}),value:J.intercepted,styleValue:{color:J.intercepted>0?"#ff9800":void 0}}),e.jsx(ee,{title:e.jsx("span",{style:{fontSize:12,color:"var(--color-text-3)"},children:"平均时长"}),value:Ye(J.avgSec)})]})}),_?et?e.jsx(z,{bordered:!0,children:e.jsx(se,{description:"加载失败"})}):Xe||!j?e.jsx(z,{bordered:!0,children:e.jsx(re,{animation:!0,text:{rows:6}})}):e.jsxs("div",{style:{flex:1,minHeight:0,overflowY:"auto",display:"flex",flexDirection:"column"},children:[de.length===0?e.jsxs(z,{bordered:!0,children:[e.jsx(se,{description:h.length>0?`近 ${l}d 无匹配「${h}」的 prompt(整窗)`:c!=="all"?`近 ${l}d 无 ${c} 任务`:`近 ${l}d 无 prompt(或被过滤掉)`}),(c!=="all"||h.length>0)&&e.jsxs(i.Text,{type:"secondary",style:{fontSize:11,display:"block",textAlign:"center",padding:12},children:["整窗无匹配;清空筛选/搜索 (",e.jsx(Re,{to:"?",children:"重置"}),")"]})]}):e.jsx("div",{style:{flex:1},children:it.map(p=>{const d=j.groups[p],v=de.filter(F=>F.group_id===p),O=Ze[(d==null?void 0:d.lane)??"active"];return e.jsxs("div",{style:{marginBottom:14},"data-group-section":p,children:[e.jsxs("div",{style:{position:"sticky",top:0,zIndex:1,display:"flex",alignItems:"center",gap:8,padding:"6px 10px",marginBottom:6,background:"var(--color-fill-1)",borderRadius:6,flexWrap:"wrap"},children:[e.jsxs(i.Text,{style:{fontSize:12,fontWeight:600,cursor:"pointer"},onClick:()=>ye(p),children:["🎯 ",(d==null?void 0:d.title)||"(空 title)"]}),e.jsx(m,{size:"small",color:O.color,children:O.text}),e.jsx(m,{size:"small",style:{fontFamily:"monospace"},children:p.slice(0,8)}),e.jsxs(i.Text,{type:"secondary",style:{fontSize:11},children:[(d==null?void 0:d.prompt_count)??v.length," 条 prompt"]})]}),v.map(F=>e.jsx(ts,{row:F,group:d,onOpen:ye},F.event_id))]},p)})}),((j==null?void 0:j.total_in_window)??0)>0&&e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"12px 4px",gap:12,flexWrap:"wrap",borderTop:"1px solid var(--color-border-2)",marginTop:8},children:[e.jsxs(i.Text,{type:"secondary",style:{fontSize:11},children:["近 ",l,"d 共 ",(j==null?void 0:j.total_in_window)??0," 条 prompt(",(j==null?void 0:j.summary.total_groups)??0," 个分组)· 第 ",P," / ",Math.max(1,Math.ceil(((j==null?void 0:j.total_in_window)??0)/L))," 页",c!=="all"&&e.jsxs("span",{style:{marginLeft:8},children:["· 已筛选「",c,"」(整窗)"]}),h.length>0&&e.jsxs("span",{style:{marginLeft:8},children:["· 已搜索「",h,"」(整窗)"]})]}),e.jsx(Wt,{current:P,total:(j==null?void 0:j.total_in_window)??0,pageSize:L,sizeOptions:[...g],sizeCanChange:!0,showJumper:!0,size:"small",onChange:(p,d)=>{d!==L?Ie(d):ct(p)},onPageSizeChange:p=>Ie(p)})]})]}):V?e.jsx(z,{bordered:!0,children:e.jsx(se,{description:"加载失败"})}):U||!C?e.jsx(z,{bordered:!0,children:e.jsx(re,{animation:!0,text:{rows:6}})}):e.jsx("div",{style:{display:"flex",gap:12,flex:1,minHeight:0,overflowX:"auto"},children:ns.map(p=>e.jsx(ss,{def:p,cards:ot[p.key]??[],onOpen:ye,limit:H,onLoadMore:()=>q(d=>d+B)},p.key))}),e.jsx(Un,{})]})}export{gs as default};
6
+ //# sourceMappingURL=TasksHubPage-C2PLh3eg.js.map