@winspan/claude-forge 8.54.3 → 9.2.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.
- package/DEVELOPMENT.md +649 -33
- package/README.md +155 -17
- package/dist/catalogs/agents.json +72 -0
- package/dist/catalogs/skills.json +194 -0
- package/dist/claudemd/claudemd-generator.d.ts +45 -45
- package/dist/claudemd/claudemd-generator.d.ts.map +1 -1
- package/dist/claudemd/claudemd-generator.js +128 -449
- package/dist/claudemd/claudemd-generator.js.map +1 -1
- package/dist/claudemd/index.d.ts +14 -4
- package/dist/claudemd/index.d.ts.map +1 -1
- package/dist/claudemd/index.js +15 -4
- package/dist/claudemd/index.js.map +1 -1
- package/dist/claudemd/resume-manager.d.ts.map +1 -1
- package/dist/claudemd/resume-manager.js +37 -9
- package/dist/claudemd/resume-manager.js.map +1 -1
- package/dist/claudemd/templates/swarm-protocol.md +35 -186
- package/dist/claudemd/violations-manager.d.ts +40 -0
- package/dist/claudemd/violations-manager.d.ts.map +1 -0
- package/dist/claudemd/violations-manager.js +106 -0
- package/dist/claudemd/violations-manager.js.map +1 -0
- package/dist/cli/commands/admin.d.ts +15 -0
- package/dist/cli/commands/admin.d.ts.map +1 -0
- package/dist/cli/commands/admin.js +177 -0
- package/dist/cli/commands/admin.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +18 -0
- package/dist/cli/commands/agents.d.ts.map +1 -0
- package/dist/cli/commands/agents.js +160 -0
- package/dist/cli/commands/agents.js.map +1 -0
- package/dist/cli/commands/bypass.d.ts +18 -0
- package/dist/cli/commands/bypass.d.ts.map +1 -0
- package/dist/cli/commands/bypass.js +87 -0
- package/dist/cli/commands/bypass.js.map +1 -0
- package/dist/cli/commands/claudemd.d.ts +60 -0
- package/dist/cli/commands/claudemd.d.ts.map +1 -1
- package/dist/cli/commands/claudemd.js +174 -37
- package/dist/cli/commands/claudemd.js.map +1 -1
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +94 -1
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/daemon.d.ts +39 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/daemon.js +167 -20
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/cli/commands/decisions.d.ts +129 -0
- package/dist/cli/commands/decisions.d.ts.map +1 -0
- package/dist/cli/commands/decisions.js +669 -0
- package/dist/cli/commands/decisions.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +29 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +124 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/entropy.d.ts +35 -0
- package/dist/cli/commands/entropy.d.ts.map +1 -0
- package/dist/cli/commands/entropy.js +121 -0
- package/dist/cli/commands/entropy.js.map +1 -0
- package/dist/cli/commands/executions.d.ts +1 -0
- package/dist/cli/commands/executions.d.ts.map +1 -1
- package/dist/cli/commands/executions.js +10 -1
- package/dist/cli/commands/executions.js.map +1 -1
- package/dist/cli/commands/fix.d.ts +31 -0
- package/dist/cli/commands/fix.d.ts.map +1 -0
- package/dist/cli/commands/fix.js +108 -0
- package/dist/cli/commands/fix.js.map +1 -0
- package/dist/cli/commands/governance.d.ts +21 -0
- package/dist/cli/commands/governance.d.ts.map +1 -0
- package/dist/cli/commands/governance.js +60 -0
- package/dist/cli/commands/governance.js.map +1 -0
- package/dist/cli/commands/init.d.ts +27 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +158 -146
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/insights-goal-check.d.ts +50 -0
- package/dist/cli/commands/insights-goal-check.d.ts.map +1 -0
- package/dist/cli/commands/insights-goal-check.js +318 -0
- package/dist/cli/commands/insights-goal-check.js.map +1 -0
- package/dist/cli/commands/insights.d.ts +15 -0
- package/dist/cli/commands/insights.d.ts.map +1 -0
- package/dist/cli/commands/insights.js +127 -0
- package/dist/cli/commands/insights.js.map +1 -0
- package/dist/cli/commands/knowledge.d.ts +66 -0
- package/dist/cli/commands/knowledge.d.ts.map +1 -0
- package/dist/cli/commands/knowledge.js +897 -0
- package/dist/cli/commands/knowledge.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +0 -12
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +11 -5
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/menu.d.ts.map +1 -1
- package/dist/cli/commands/menu.js +10 -184
- package/dist/cli/commands/menu.js.map +1 -1
- package/dist/cli/commands/project.d.ts +98 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +382 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/commands/skills.d.ts.map +1 -1
- package/dist/cli/commands/skills.js +14 -128
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/spec.d.ts +40 -0
- package/dist/cli/commands/spec.d.ts.map +1 -0
- package/dist/cli/commands/spec.js +49 -0
- package/dist/cli/commands/spec.js.map +1 -0
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +3 -2
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +17 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/trace.d.ts.map +1 -1
- package/dist/cli/commands/trace.js +4 -9
- package/dist/cli/commands/trace.js.map +1 -1
- package/dist/cli/commands/violations.d.ts +14 -0
- package/dist/cli/commands/violations.d.ts.map +1 -0
- package/dist/cli/commands/violations.js +43 -0
- package/dist/cli/commands/violations.js.map +1 -0
- package/dist/cli/index.js +26 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/hook-manager.d.ts +1 -1
- package/dist/cli/init/hook-manager.d.ts.map +1 -1
- package/dist/cli/init/hook-manager.js +6 -0
- package/dist/cli/init/hook-manager.js.map +1 -1
- package/dist/cli/utils/resolve-session.d.ts +32 -0
- package/dist/cli/utils/resolve-session.d.ts.map +1 -0
- package/dist/cli/utils/resolve-session.js +39 -0
- package/dist/cli/utils/resolve-session.js.map +1 -0
- package/dist/core/config.d.ts +4 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +11 -23
- package/dist/core/config.js.map +1 -1
- package/dist/core/constants.d.ts +14 -13
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +20 -13
- package/dist/core/constants.js.map +1 -1
- package/dist/core/diagnostics/checks.d.ts +151 -0
- package/dist/core/diagnostics/checks.d.ts.map +1 -0
- package/dist/core/diagnostics/checks.js +765 -0
- package/dist/core/diagnostics/checks.js.map +1 -0
- package/dist/core/diagnostics/daemon-status.d.ts +77 -0
- package/dist/core/diagnostics/daemon-status.d.ts.map +1 -0
- package/dist/core/diagnostics/daemon-status.js +113 -0
- package/dist/core/diagnostics/daemon-status.js.map +1 -0
- package/dist/core/diagnostics/entropy-checks.d.ts +82 -0
- package/dist/core/diagnostics/entropy-checks.d.ts.map +1 -0
- package/dist/core/diagnostics/entropy-checks.js +395 -0
- package/dist/core/diagnostics/entropy-checks.js.map +1 -0
- package/dist/core/diagnostics/fix-runner.d.ts +54 -0
- package/dist/core/diagnostics/fix-runner.d.ts.map +1 -0
- package/dist/core/diagnostics/fix-runner.js +90 -0
- package/dist/core/diagnostics/fix-runner.js.map +1 -0
- package/dist/core/diagnostics/knip-runner.d.ts +49 -0
- package/dist/core/diagnostics/knip-runner.d.ts.map +1 -0
- package/dist/core/diagnostics/knip-runner.js +100 -0
- package/dist/core/diagnostics/knip-runner.js.map +1 -0
- package/dist/core/diagnostics/markers.d.ts +96 -0
- package/dist/core/diagnostics/markers.d.ts.map +1 -0
- package/dist/core/diagnostics/markers.js +153 -0
- package/dist/core/diagnostics/markers.js.map +1 -0
- package/dist/core/governance/global-inject.d.ts +60 -0
- package/dist/core/governance/global-inject.d.ts.map +1 -0
- package/dist/core/governance/global-inject.js +129 -0
- package/dist/core/governance/global-inject.js.map +1 -0
- package/dist/core/queue/index.d.ts +16 -3
- package/dist/core/queue/index.d.ts.map +1 -1
- package/dist/core/queue/index.js +14 -3
- package/dist/core/queue/index.js.map +1 -1
- package/dist/core/storage/base.d.ts +158 -0
- package/dist/core/storage/base.d.ts.map +1 -1
- package/dist/core/storage/base.js +570 -0
- package/dist/core/storage/base.js.map +1 -1
- package/dist/core/storage/codec/tool-input-codec.d.ts +93 -0
- package/dist/core/storage/codec/tool-input-codec.d.ts.map +1 -0
- package/dist/core/storage/codec/tool-input-codec.js +159 -0
- package/dist/core/storage/codec/tool-input-codec.js.map +1 -0
- package/dist/core/storage/decisions.d.ts +362 -0
- package/dist/core/storage/decisions.d.ts.map +1 -0
- package/dist/core/storage/decisions.js +502 -0
- package/dist/core/storage/decisions.js.map +1 -0
- package/dist/core/storage/events.d.ts +112 -8
- package/dist/core/storage/events.d.ts.map +1 -1
- package/dist/core/storage/events.js +390 -39
- package/dist/core/storage/events.js.map +1 -1
- package/dist/core/storage/feedback.d.ts +131 -0
- package/dist/core/storage/feedback.d.ts.map +1 -0
- package/dist/core/storage/feedback.js +187 -0
- package/dist/core/storage/feedback.js.map +1 -0
- package/dist/core/storage/forge-config.d.ts +40 -0
- package/dist/core/storage/forge-config.d.ts.map +1 -0
- package/dist/core/storage/forge-config.js +65 -0
- package/dist/core/storage/forge-config.js.map +1 -0
- package/dist/core/storage/injections.d.ts +28 -0
- package/dist/core/storage/injections.d.ts.map +1 -1
- package/dist/core/storage/injections.js +62 -5
- package/dist/core/storage/injections.js.map +1 -1
- package/dist/core/storage/knowledge.d.ts +106 -0
- package/dist/core/storage/knowledge.d.ts.map +1 -0
- package/dist/core/storage/knowledge.js +202 -0
- package/dist/core/storage/knowledge.js.map +1 -0
- package/dist/core/storage/maintenance.d.ts +36 -9
- package/dist/core/storage/maintenance.d.ts.map +1 -1
- package/dist/core/storage/maintenance.js +56 -24
- package/dist/core/storage/maintenance.js.map +1 -1
- package/dist/core/storage/pipeline-rollup.d.ts +117 -0
- package/dist/core/storage/pipeline-rollup.d.ts.map +1 -0
- package/dist/core/storage/pipeline-rollup.js +471 -0
- package/dist/core/storage/pipeline-rollup.js.map +1 -0
- package/dist/core/storage/routing.d.ts +16 -3
- package/dist/core/storage/routing.d.ts.map +1 -1
- package/dist/core/storage/routing.js +39 -8
- package/dist/core/storage/routing.js.map +1 -1
- package/dist/core/storage/rows.d.ts +50 -7
- package/dist/core/storage/rows.d.ts.map +1 -1
- package/dist/core/storage/schema.sql +302 -23
- package/dist/core/storage/sessions.d.ts +136 -0
- package/dist/core/storage/sessions.d.ts.map +1 -1
- package/dist/core/storage/sessions.js +351 -15
- package/dist/core/storage/sessions.js.map +1 -1
- package/dist/core/storage/skills.d.ts +1 -0
- package/dist/core/storage/skills.d.ts.map +1 -1
- package/dist/core/storage/skills.js +21 -6
- package/dist/core/storage/skills.js.map +1 -1
- package/dist/core/storage/sqlite.d.ts +253 -20
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +425 -16
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts +474 -2
- package/dist/core/storage/tasks.d.ts.map +1 -1
- package/dist/core/storage/tasks.js +1213 -18
- package/dist/core/storage/tasks.js.map +1 -1
- package/dist/core/storage/tool-intercepts.d.ts +69 -0
- package/dist/core/storage/tool-intercepts.d.ts.map +1 -0
- package/dist/core/storage/tool-intercepts.js +116 -0
- package/dist/core/storage/tool-intercepts.js.map +1 -0
- package/dist/core/storage/workflow-recommendations.d.ts +124 -0
- package/dist/core/storage/workflow-recommendations.d.ts.map +1 -0
- package/dist/core/storage/workflow-recommendations.js +274 -0
- package/dist/core/storage/workflow-recommendations.js.map +1 -0
- package/dist/core/types.d.ts +112 -17
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +12 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/backup.d.ts +81 -0
- package/dist/core/utils/backup.d.ts.map +1 -0
- package/dist/core/utils/backup.js +98 -0
- package/dist/core/utils/backup.js.map +1 -0
- package/dist/core/utils/binary-paths.d.ts +92 -0
- package/dist/core/utils/binary-paths.d.ts.map +1 -0
- package/dist/core/utils/binary-paths.js +166 -0
- package/dist/core/utils/binary-paths.js.map +1 -0
- package/dist/core/utils/bypass-token.d.ts +75 -0
- package/dist/core/utils/bypass-token.d.ts.map +1 -0
- package/dist/core/utils/bypass-token.js +133 -0
- package/dist/core/utils/bypass-token.js.map +1 -0
- package/dist/core/utils/cc-builtin-agents.d.ts +3 -0
- package/dist/core/utils/cc-builtin-agents.d.ts.map +1 -0
- package/dist/core/utils/cc-builtin-agents.js +29 -0
- package/dist/core/utils/cc-builtin-agents.js.map +1 -0
- package/dist/core/utils/claude-cli-spawn.d.ts +106 -0
- package/dist/core/utils/claude-cli-spawn.d.ts.map +1 -0
- package/dist/core/utils/claude-cli-spawn.js +219 -0
- package/dist/core/utils/claude-cli-spawn.js.map +1 -0
- package/dist/core/utils/forge-resume-block.d.ts.map +1 -1
- package/dist/core/utils/forge-resume-block.js +3 -2
- package/dist/core/utils/forge-resume-block.js.map +1 -1
- package/dist/core/utils/logger.d.ts +15 -3
- package/dist/core/utils/logger.d.ts.map +1 -1
- package/dist/core/utils/logger.js +20 -2
- package/dist/core/utils/logger.js.map +1 -1
- package/dist/core/utils/noise-prompt.d.ts +97 -0
- package/dist/core/utils/noise-prompt.d.ts.map +1 -0
- package/dist/core/utils/noise-prompt.js +127 -0
- package/dist/core/utils/noise-prompt.js.map +1 -0
- package/dist/core/utils/path.d.ts +0 -4
- package/dist/core/utils/path.d.ts.map +1 -1
- package/dist/core/utils/path.js +0 -7
- package/dist/core/utils/path.js.map +1 -1
- package/dist/core/utils/time.d.ts +41 -0
- package/dist/core/utils/time.d.ts.map +1 -1
- package/dist/core/utils/time.js +114 -0
- package/dist/core/utils/time.js.map +1 -1
- package/dist/daemon/agent-sync.d.ts +24 -0
- package/dist/daemon/agent-sync.d.ts.map +1 -0
- package/dist/daemon/agent-sync.js +114 -0
- package/dist/daemon/agent-sync.js.map +1 -0
- package/dist/daemon/config-store.d.ts +55 -0
- package/dist/daemon/config-store.d.ts.map +1 -0
- package/dist/daemon/config-store.js +137 -0
- package/dist/daemon/config-store.js.map +1 -0
- package/dist/daemon/event-parser.d.ts +22 -0
- package/dist/daemon/event-parser.d.ts.map +1 -1
- package/dist/daemon/event-parser.js +49 -3
- package/dist/daemon/event-parser.js.map +1 -1
- package/dist/daemon/handlers/history-exporter.d.ts.map +1 -1
- package/dist/daemon/handlers/history-exporter.js +9 -8
- package/dist/daemon/handlers/history-exporter.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts +58 -4
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +261 -8
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/pre-tool-use.d.ts +156 -0
- package/dist/daemon/handlers/pre-tool-use.d.ts.map +1 -0
- package/dist/daemon/handlers/pre-tool-use.js +585 -0
- package/dist/daemon/handlers/pre-tool-use.js.map +1 -0
- package/dist/daemon/handlers/stop.d.ts +35 -7
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +157 -8
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts +36 -14
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +135 -48
- package/dist/daemon/handlers/user-prompt.js.map +1 -1
- package/dist/daemon/hook-sync.d.ts.map +1 -1
- package/dist/daemon/hook-sync.js +2 -1
- package/dist/daemon/hook-sync.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +471 -43
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/lifecycle.d.ts +48 -1
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +98 -2
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/router.d.ts +4 -1
- package/dist/daemon/router.d.ts.map +1 -1
- package/dist/daemon/router.js +4 -2
- package/dist/daemon/router.js.map +1 -1
- package/dist/daemon/rules/defaults.d.ts +20 -0
- package/dist/daemon/rules/defaults.d.ts.map +1 -0
- package/dist/daemon/rules/defaults.js +692 -0
- package/dist/daemon/rules/defaults.js.map +1 -0
- package/dist/daemon/rules/registry.d.ts +47 -0
- package/dist/daemon/rules/registry.d.ts.map +1 -0
- package/dist/daemon/rules/registry.js +84 -0
- package/dist/daemon/rules/registry.js.map +1 -0
- package/dist/daemon/rules/types.d.ts +170 -0
- package/dist/daemon/rules/types.d.ts.map +1 -0
- package/dist/daemon/rules/types.js +15 -0
- package/dist/daemon/rules/types.js.map +1 -0
- package/dist/daemon/rules/whitelist.d.ts +101 -0
- package/dist/daemon/rules/whitelist.d.ts.map +1 -0
- package/dist/daemon/rules/whitelist.js +210 -0
- package/dist/daemon/rules/whitelist.js.map +1 -0
- package/dist/daemon/rules/workflow-defaults.d.ts +52 -0
- package/dist/daemon/rules/workflow-defaults.d.ts.map +1 -0
- package/dist/daemon/rules/workflow-defaults.js +521 -0
- package/dist/daemon/rules/workflow-defaults.js.map +1 -0
- package/dist/daemon/server.d.ts +11 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +7 -1
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/services/context-injector.d.ts +34 -0
- package/dist/daemon/services/context-injector.d.ts.map +1 -0
- package/dist/daemon/services/context-injector.js +61 -0
- package/dist/daemon/services/context-injector.js.map +1 -0
- package/dist/daemon/services/decision-hint.d.ts +203 -0
- package/dist/daemon/services/decision-hint.d.ts.map +1 -0
- package/dist/daemon/services/decision-hint.js +487 -0
- package/dist/daemon/services/decision-hint.js.map +1 -0
- package/dist/daemon/services/event-ttl-sweep.d.ts +86 -0
- package/dist/daemon/services/event-ttl-sweep.d.ts.map +1 -0
- package/dist/daemon/services/event-ttl-sweep.js +123 -0
- package/dist/daemon/services/event-ttl-sweep.js.map +1 -0
- package/dist/daemon/services/experience-extractor.d.ts +67 -0
- package/dist/daemon/services/experience-extractor.d.ts.map +1 -0
- package/dist/daemon/services/experience-extractor.js +323 -0
- package/dist/daemon/services/experience-extractor.js.map +1 -0
- package/dist/daemon/services/feedback-aggregator.d.ts +179 -0
- package/dist/daemon/services/feedback-aggregator.d.ts.map +1 -0
- package/dist/daemon/services/feedback-aggregator.js +455 -0
- package/dist/daemon/services/feedback-aggregator.js.map +1 -0
- package/dist/daemon/services/heartbeat-writer.d.ts +55 -0
- package/dist/daemon/services/heartbeat-writer.d.ts.map +1 -0
- package/dist/daemon/services/heartbeat-writer.js +111 -0
- package/dist/daemon/services/heartbeat-writer.js.map +1 -0
- package/dist/daemon/services/idle-session-sweeper.d.ts +61 -0
- package/dist/daemon/services/idle-session-sweeper.d.ts.map +1 -0
- package/dist/daemon/services/idle-session-sweeper.js +94 -0
- package/dist/daemon/services/idle-session-sweeper.js.map +1 -0
- package/dist/daemon/services/idle-task-budget.d.ts +50 -0
- package/dist/daemon/services/idle-task-budget.d.ts.map +1 -0
- package/dist/daemon/services/idle-task-budget.js +72 -0
- package/dist/daemon/services/idle-task-budget.js.map +1 -0
- package/dist/daemon/services/intercept-revive.d.ts +60 -0
- package/dist/daemon/services/intercept-revive.d.ts.map +1 -0
- package/dist/daemon/services/intercept-revive.js +86 -0
- package/dist/daemon/services/intercept-revive.js.map +1 -0
- package/dist/daemon/services/intercept-rollback-guard.d.ts +105 -0
- package/dist/daemon/services/intercept-rollback-guard.d.ts.map +1 -0
- package/dist/daemon/services/intercept-rollback-guard.js +152 -0
- package/dist/daemon/services/intercept-rollback-guard.js.map +1 -0
- package/dist/daemon/services/intercept-timeout-sweeper.d.ts +58 -0
- package/dist/daemon/services/intercept-timeout-sweeper.d.ts.map +1 -0
- package/dist/daemon/services/intercept-timeout-sweeper.js +83 -0
- package/dist/daemon/services/intercept-timeout-sweeper.js.map +1 -0
- package/dist/daemon/services/kb-injector.d.ts +57 -0
- package/dist/daemon/services/kb-injector.d.ts.map +1 -0
- package/dist/daemon/services/kb-injector.js +140 -0
- package/dist/daemon/services/kb-injector.js.map +1 -0
- package/dist/daemon/services/outcome-classification-service.d.ts +49 -0
- package/dist/daemon/services/outcome-classification-service.d.ts.map +1 -0
- package/dist/daemon/services/outcome-classification-service.js +214 -0
- package/dist/daemon/services/outcome-classification-service.js.map +1 -0
- package/dist/daemon/services/outcome-classifier.d.ts +136 -0
- package/dist/daemon/services/outcome-classifier.d.ts.map +1 -0
- package/dist/daemon/services/outcome-classifier.js +178 -0
- package/dist/daemon/services/outcome-classifier.js.map +1 -0
- package/dist/daemon/services/outcome-nudge.d.ts +107 -0
- package/dist/daemon/services/outcome-nudge.d.ts.map +1 -0
- package/dist/daemon/services/outcome-nudge.js +242 -0
- package/dist/daemon/services/outcome-nudge.js.map +1 -0
- package/dist/daemon/services/spec-approval.d.ts +127 -0
- package/dist/daemon/services/spec-approval.d.ts.map +1 -0
- package/dist/daemon/services/spec-approval.js +216 -0
- package/dist/daemon/services/spec-approval.js.map +1 -0
- package/dist/daemon/services/spec-gate.d.ts +54 -0
- package/dist/daemon/services/spec-gate.d.ts.map +1 -0
- package/dist/daemon/services/spec-gate.js +113 -0
- package/dist/daemon/services/spec-gate.js.map +1 -0
- package/dist/daemon/services/task-boundary-classifier.d.ts +78 -0
- package/dist/daemon/services/task-boundary-classifier.d.ts.map +1 -0
- package/dist/daemon/services/task-boundary-classifier.js +202 -0
- package/dist/daemon/services/task-boundary-classifier.js.map +1 -0
- package/dist/daemon/services/task-segmenter.d.ts +219 -1
- package/dist/daemon/services/task-segmenter.d.ts.map +1 -1
- package/dist/daemon/services/task-segmenter.js +481 -17
- package/dist/daemon/services/task-segmenter.js.map +1 -1
- package/dist/daemon/services/violation-reporter.d.ts +130 -0
- package/dist/daemon/services/violation-reporter.d.ts.map +1 -0
- package/dist/daemon/services/violation-reporter.js +339 -0
- package/dist/daemon/services/violation-reporter.js.map +1 -0
- package/dist/daemon/skill-sync.d.ts +7 -2
- package/dist/daemon/skill-sync.d.ts.map +1 -1
- package/dist/daemon/skill-sync.js +114 -9
- package/dist/daemon/skill-sync.js.map +1 -1
- package/dist/daemon/templates/agents/claudemd-writer.md +101 -0
- package/dist/daemon/templates/agents/coder.md +105 -0
- package/dist/daemon/templates/agents/decision-maker.md +460 -0
- package/dist/daemon/templates/agents/doc-reviewer.md +115 -0
- package/dist/daemon/templates/agents/harness-debug-full.md +114 -0
- package/dist/daemon/templates/agents/harness-hotfix.md +99 -0
- package/dist/daemon/templates/agents/hybrid-feature-with-safety.md +104 -0
- package/dist/daemon/templates/agents/knowledge-builder.md +119 -0
- package/dist/daemon/templates/agents/patch-applier.md +144 -0
- package/dist/daemon/templates/agents/planner.md +165 -0
- package/dist/daemon/templates/agents/refactor-specialist.md +98 -0
- package/dist/daemon/templates/agents/skill-distiller.md +113 -0
- package/dist/daemon/templates/agents/task-boundary-classifier.md +64 -0
- package/dist/daemon/templates/agents/verify-agent.md +136 -0
- package/dist/daemon/utils/inject-block.d.ts +39 -0
- package/dist/daemon/utils/inject-block.d.ts.map +1 -0
- package/dist/daemon/utils/inject-block.js +25 -0
- package/dist/daemon/utils/inject-block.js.map +1 -0
- package/dist/hooks/hook-lib.sh +8 -0
- package/dist/hooks/notification.sh +19 -8
- package/dist/hooks/post-tool-use.sh +41 -23
- package/dist/hooks/pre-tool-use.sh +54 -23
- package/dist/hooks/session-start.sh +68 -0
- package/dist/hooks/stop.sh +24 -10
- package/dist/hooks/user-prompt-submit.sh +37 -21
- package/dist/knowledge/adapters/go-adapter.d.ts +65 -0
- package/dist/knowledge/adapters/go-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/go-adapter.js +294 -0
- package/dist/knowledge/adapters/go-adapter.js.map +1 -0
- package/dist/knowledge/adapters/index.d.ts +41 -0
- package/dist/knowledge/adapters/index.d.ts.map +1 -0
- package/dist/knowledge/adapters/index.js +71 -0
- package/dist/knowledge/adapters/index.js.map +1 -0
- package/dist/knowledge/adapters/java-adapter.d.ts +66 -0
- package/dist/knowledge/adapters/java-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/java-adapter.js +260 -0
- package/dist/knowledge/adapters/java-adapter.js.map +1 -0
- package/dist/knowledge/adapters/js-vue-adapter.d.ts +56 -0
- package/dist/knowledge/adapters/js-vue-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/js-vue-adapter.js +203 -0
- package/dist/knowledge/adapters/js-vue-adapter.js.map +1 -0
- package/dist/knowledge/adapters/kotlin-adapter.d.ts +55 -0
- package/dist/knowledge/adapters/kotlin-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/kotlin-adapter.js +209 -0
- package/dist/knowledge/adapters/kotlin-adapter.js.map +1 -0
- package/dist/knowledge/adapters/monorepo-adapter.d.ts +77 -0
- package/dist/knowledge/adapters/monorepo-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/monorepo-adapter.js +170 -0
- package/dist/knowledge/adapters/monorepo-adapter.js.map +1 -0
- package/dist/knowledge/adapters/python-adapter.d.ts +89 -0
- package/dist/knowledge/adapters/python-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/python-adapter.js +358 -0
- package/dist/knowledge/adapters/python-adapter.js.map +1 -0
- package/dist/knowledge/adapters/rust-adapter.d.ts +73 -0
- package/dist/knowledge/adapters/rust-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/rust-adapter.js +329 -0
- package/dist/knowledge/adapters/rust-adapter.js.map +1 -0
- package/dist/knowledge/adapters/types.d.ts +99 -0
- package/dist/knowledge/adapters/types.d.ts.map +1 -0
- package/dist/knowledge/adapters/types.js +17 -0
- package/dist/knowledge/adapters/types.js.map +1 -0
- package/dist/knowledge/adapters/typescript-adapter.d.ts +57 -0
- package/dist/knowledge/adapters/typescript-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/typescript-adapter.js +171 -0
- package/dist/knowledge/adapters/typescript-adapter.js.map +1 -0
- package/dist/knowledge/audit-applier.d.ts +70 -0
- package/dist/knowledge/audit-applier.d.ts.map +1 -0
- package/dist/knowledge/audit-applier.js +251 -0
- package/dist/knowledge/audit-applier.js.map +1 -0
- package/dist/knowledge/builder.d.ts +261 -0
- package/dist/knowledge/builder.d.ts.map +1 -0
- package/dist/knowledge/builder.js +937 -0
- package/dist/knowledge/builder.js.map +1 -0
- package/dist/knowledge/cli-provider.d.ts +151 -0
- package/dist/knowledge/cli-provider.d.ts.map +1 -0
- package/dist/knowledge/cli-provider.js +313 -0
- package/dist/knowledge/cli-provider.js.map +1 -0
- package/dist/knowledge/constants.d.ts +73 -0
- package/dist/knowledge/constants.d.ts.map +1 -0
- package/dist/knowledge/constants.js +93 -0
- package/dist/knowledge/constants.js.map +1 -0
- package/dist/knowledge/cross-module.d.ts +139 -0
- package/dist/knowledge/cross-module.d.ts.map +1 -0
- package/dist/knowledge/cross-module.js +370 -0
- package/dist/knowledge/cross-module.js.map +1 -0
- package/dist/knowledge/git-hooks.d.ts +67 -0
- package/dist/knowledge/git-hooks.d.ts.map +1 -0
- package/dist/knowledge/git-hooks.js +258 -0
- package/dist/knowledge/git-hooks.js.map +1 -0
- package/dist/knowledge/module-hash.d.ts +88 -0
- package/dist/knowledge/module-hash.d.ts.map +1 -0
- package/dist/knowledge/module-hash.js +162 -0
- package/dist/knowledge/module-hash.js.map +1 -0
- package/dist/knowledge/project-detector.d.ts +101 -0
- package/dist/knowledge/project-detector.d.ts.map +1 -0
- package/dist/knowledge/project-detector.js +223 -0
- package/dist/knowledge/project-detector.js.map +1 -0
- package/dist/knowledge/prompt.d.ts +228 -0
- package/dist/knowledge/prompt.d.ts.map +1 -0
- package/dist/knowledge/prompt.js +404 -0
- package/dist/knowledge/prompt.js.map +1 -0
- package/dist/knowledge/query.d.ts +105 -0
- package/dist/knowledge/query.d.ts.map +1 -0
- package/dist/knowledge/query.js +341 -0
- package/dist/knowledge/query.js.map +1 -0
- package/dist/knowledge/repo-map.d.ts +91 -0
- package/dist/knowledge/repo-map.d.ts.map +1 -0
- package/dist/knowledge/repo-map.js +408 -0
- package/dist/knowledge/repo-map.js.map +1 -0
- package/dist/knowledge/tools/index.d.ts +14 -0
- package/dist/knowledge/tools/index.d.ts.map +1 -0
- package/dist/knowledge/tools/index.js +11 -0
- package/dist/knowledge/tools/index.js.map +1 -0
- package/dist/knowledge/tools/knowledge-get-page.d.ts +46 -0
- package/dist/knowledge/tools/knowledge-get-page.d.ts.map +1 -0
- package/dist/knowledge/tools/knowledge-get-page.js +101 -0
- package/dist/knowledge/tools/knowledge-get-page.js.map +1 -0
- package/dist/knowledge/tools/knowledge-query.d.ts +77 -0
- package/dist/knowledge/tools/knowledge-query.d.ts.map +1 -0
- package/dist/knowledge/tools/knowledge-query.js +104 -0
- package/dist/knowledge/tools/knowledge-query.js.map +1 -0
- package/dist/knowledge/tools/repo-map-lookup.d.ts +45 -0
- package/dist/knowledge/tools/repo-map-lookup.d.ts.map +1 -0
- package/dist/knowledge/tools/repo-map-lookup.js +82 -0
- package/dist/knowledge/tools/repo-map-lookup.js.map +1 -0
- package/dist/knowledge/types.d.ts +269 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +10 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/knowledge/validator.d.ts +90 -0
- package/dist/knowledge/validator.d.ts.map +1 -0
- package/dist/knowledge/validator.js +288 -0
- package/dist/knowledge/validator.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +222 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/skills/builtin-skills.d.ts +35 -0
- package/dist/skills/builtin-skills.d.ts.map +1 -0
- package/dist/skills/builtin-skills.js +68 -0
- package/dist/skills/builtin-skills.js.map +1 -0
- package/dist/skills/distill/attribution.d.ts +59 -0
- package/dist/skills/distill/attribution.d.ts.map +1 -0
- package/dist/skills/distill/attribution.js +101 -0
- package/dist/skills/distill/attribution.js.map +1 -0
- package/dist/skills/distill/claude-cli-resolver.d.ts +26 -0
- package/dist/skills/distill/claude-cli-resolver.d.ts.map +1 -0
- package/dist/skills/distill/claude-cli-resolver.js +115 -0
- package/dist/skills/distill/claude-cli-resolver.js.map +1 -0
- package/dist/skills/distill/distiller.d.ts +161 -0
- package/dist/skills/distill/distiller.d.ts.map +1 -0
- package/dist/skills/distill/distiller.js +461 -0
- package/dist/skills/distill/distiller.js.map +1 -0
- package/dist/skills/distill/index.d.ts +223 -0
- package/dist/skills/distill/index.d.ts.map +1 -0
- package/dist/skills/distill/index.js +466 -0
- package/dist/skills/distill/index.js.map +1 -0
- package/dist/skills/distill/project-anchor-guard.d.ts +116 -0
- package/dist/skills/distill/project-anchor-guard.d.ts.map +1 -0
- package/dist/skills/distill/project-anchor-guard.js +334 -0
- package/dist/skills/distill/project-anchor-guard.js.map +1 -0
- package/dist/skills/distill/topic-deduper.d.ts +77 -0
- package/dist/skills/distill/topic-deduper.d.ts.map +1 -0
- package/dist/skills/distill/topic-deduper.js +119 -0
- package/dist/skills/distill/topic-deduper.js.map +1 -0
- package/dist/skills/distill/upstream-fetcher.d.ts +71 -0
- package/dist/skills/distill/upstream-fetcher.d.ts.map +1 -0
- package/dist/skills/distill/upstream-fetcher.js +202 -0
- package/dist/skills/distill/upstream-fetcher.js.map +1 -0
- package/dist/skills/distilled/distilled-api-design.md +491 -0
- package/dist/skills/distilled/distilled-architecture-decision.md +173 -0
- package/dist/skills/distilled/distilled-creator.md +178 -0
- package/dist/skills/distilled/distilled-db-schema-design.md +245 -0
- package/dist/skills/distilled/distilled-defi-amm-security.md +293 -0
- package/dist/skills/distilled/distilled-executing-plans.md +113 -0
- package/dist/skills/distilled/distilled-harness-engineering.md +242 -0
- package/dist/skills/distilled/distilled-karpathy-guidelines.md +104 -0
- package/dist/skills/distilled/distilled-performance-optimization.md +175 -0
- package/dist/skills/distilled/distilled-spec-driven-design.md +193 -0
- package/dist/skills/distilled/distilled-systematic-debugging.md +306 -0
- package/dist/skills/distilled/distilled-verification-before-completion.md +203 -0
- package/dist/skills/keyword-score.d.ts +29 -0
- package/dist/skills/keyword-score.d.ts.map +1 -0
- package/dist/skills/keyword-score.js +54 -0
- package/dist/skills/keyword-score.js.map +1 -0
- package/dist/skills/registry.d.ts +64 -20
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +102 -105
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/tools/pipeline-suggest.js +14 -14
- package/dist/skills/tools/skill-invoke.d.ts +1 -1
- package/dist/skills/tools/skill-invoke.js +1 -1
- package/dist/web/routes/agent-content.d.ts +30 -0
- package/dist/web/routes/agent-content.d.ts.map +1 -0
- package/dist/web/routes/agent-content.js +139 -0
- package/dist/web/routes/agent-content.js.map +1 -0
- package/dist/web/routes/decisions.d.ts +15 -0
- package/dist/web/routes/decisions.d.ts.map +1 -0
- package/dist/web/routes/decisions.js +181 -0
- package/dist/web/routes/decisions.js.map +1 -0
- package/dist/web/routes/diagnostics.d.ts +61 -0
- package/dist/web/routes/diagnostics.d.ts.map +1 -0
- package/dist/web/routes/diagnostics.js +203 -0
- package/dist/web/routes/diagnostics.js.map +1 -0
- package/dist/web/routes/events.d.ts.map +1 -1
- package/dist/web/routes/events.js +24 -0
- package/dist/web/routes/events.js.map +1 -1
- package/dist/web/routes/health.d.ts +33 -0
- package/dist/web/routes/health.d.ts.map +1 -0
- package/dist/web/routes/health.js +37 -0
- package/dist/web/routes/health.js.map +1 -0
- package/dist/web/routes/insights.d.ts +0 -5
- package/dist/web/routes/insights.d.ts.map +1 -1
- package/dist/web/routes/insights.js +783 -2
- package/dist/web/routes/insights.js.map +1 -1
- package/dist/web/routes/knowledge.d.ts +16 -0
- package/dist/web/routes/knowledge.d.ts.map +1 -0
- package/dist/web/routes/knowledge.js +661 -0
- package/dist/web/routes/knowledge.js.map +1 -0
- package/dist/web/routes/patch.d.ts +60 -1
- package/dist/web/routes/patch.d.ts.map +1 -1
- package/dist/web/routes/patch.js +170 -64
- package/dist/web/routes/patch.js.map +1 -1
- package/dist/web/routes/pipeline.d.ts +37 -0
- package/dist/web/routes/pipeline.d.ts.map +1 -0
- package/dist/web/routes/pipeline.js +149 -0
- package/dist/web/routes/pipeline.js.map +1 -0
- package/dist/web/routes/rules.d.ts.map +1 -1
- package/dist/web/routes/rules.js +6 -1
- package/dist/web/routes/rules.js.map +1 -1
- package/dist/web/routes/sessions.d.ts.map +1 -1
- package/dist/web/routes/sessions.js +9 -1
- package/dist/web/routes/sessions.js.map +1 -1
- package/dist/web/routes/skill-content.d.ts +30 -0
- package/dist/web/routes/skill-content.d.ts.map +1 -0
- package/dist/web/routes/skill-content.js +117 -0
- package/dist/web/routes/skill-content.js.map +1 -0
- package/dist/web/routes/skills-distill.d.ts +29 -0
- package/dist/web/routes/skills-distill.d.ts.map +1 -0
- package/dist/web/routes/skills-distill.js +552 -0
- package/dist/web/routes/skills-distill.js.map +1 -0
- package/dist/web/routes/skills.js +7 -7
- package/dist/web/routes/skills.js.map +1 -1
- package/dist/web/routes/task-timeline.d.ts +102 -0
- package/dist/web/routes/task-timeline.d.ts.map +1 -0
- package/dist/web/routes/task-timeline.js +274 -0
- package/dist/web/routes/task-timeline.js.map +1 -0
- package/dist/web/routes/tasks.d.ts.map +1 -1
- package/dist/web/routes/tasks.js +355 -8
- package/dist/web/routes/tasks.js.map +1 -1
- package/dist/web/routes/trace.d.ts.map +1 -1
- package/dist/web/routes/trace.js +3 -2
- package/dist/web/routes/trace.js.map +1 -1
- package/dist/web/routes/types.d.ts +0 -4
- package/dist/web/routes/types.d.ts.map +1 -1
- package/dist/web/routes/types.js +1 -1
- package/dist/web/routes/types.js.map +1 -1
- package/dist/web/routes/violations.d.ts +14 -0
- package/dist/web/routes/violations.d.ts.map +1 -0
- package/dist/web/routes/violations.js +111 -0
- package/dist/web/routes/violations.js.map +1 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +79 -19
- package/dist/web/server.js.map +1 -1
- package/dist/web/services/build-manager.d.ts +72 -0
- package/dist/web/services/build-manager.d.ts.map +1 -0
- package/dist/web/services/build-manager.js +189 -0
- package/dist/web/services/build-manager.js.map +1 -0
- package/dist/web/services/distill-manager.d.ts +125 -0
- package/dist/web/services/distill-manager.d.ts.map +1 -0
- package/dist/web/services/distill-manager.js +308 -0
- package/dist/web/services/distill-manager.js.map +1 -0
- package/dist/web/static/assets/AgentContentPage-DkeRNxok.js +2 -0
- package/dist/web/static/assets/AgentContentPage-DkeRNxok.js.map +1 -0
- package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js +2 -0
- package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js.map +1 -0
- package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js +3 -0
- package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js.map +1 -0
- package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js +2 -0
- package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js.map +1 -0
- package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js +2 -0
- package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js.map +1 -0
- package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js +2 -0
- package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js.map +1 -0
- package/dist/web/static/assets/DriftTab-DqpepOhI.js +2 -0
- package/dist/web/static/assets/DriftTab-DqpepOhI.js.map +1 -0
- package/dist/web/static/assets/HealthHomePage-CN6zNIie.js +3 -0
- package/dist/web/static/assets/HealthHomePage-CN6zNIie.js.map +1 -0
- package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js +2 -0
- package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js.map +1 -0
- package/dist/web/static/assets/MarkdownRenderer-DZmTl-8J.js +3 -0
- package/dist/web/static/assets/MarkdownRenderer-DZmTl-8J.js.map +1 -0
- package/dist/web/static/assets/NotFound-BQPh0vaF.js +2 -0
- package/dist/web/static/assets/NotFound-BQPh0vaF.js.map +1 -0
- package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js +2 -0
- package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js.map +1 -0
- package/dist/web/static/assets/SettingsPage-oLJBNzQj.js +2 -0
- package/dist/web/static/assets/SettingsPage-oLJBNzQj.js.map +1 -0
- package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js +2 -0
- package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js.map +1 -0
- package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js +2 -0
- package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js.map +1 -0
- package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js +2 -0
- package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js.map +1 -0
- package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js +6 -0
- package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js.map +1 -0
- package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js +3 -0
- package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js.map +1 -0
- package/dist/web/static/assets/arco-Bhi3a6Qp.js +14 -0
- package/dist/web/static/assets/arco-Bhi3a6Qp.js.map +1 -0
- package/dist/web/static/assets/arco-DFQA6dO_.css +1 -0
- package/dist/web/static/assets/charts-BuHQWDbQ.js +37 -0
- package/dist/web/static/assets/charts-BuHQWDbQ.js.map +1 -0
- package/dist/web/static/assets/date-fns-sbWH3_uq.js +2 -0
- package/dist/web/static/assets/date-fns-sbWH3_uq.js.map +1 -0
- package/dist/web/static/assets/index-7bl3kbcx.css +1 -0
- package/dist/web/static/assets/index-BIYnq1Dx.js +4 -0
- package/dist/web/static/assets/index-BIYnq1Dx.js.map +1 -0
- package/dist/web/static/assets/lucide-CnlPQoG8.js +72 -0
- package/dist/web/static/assets/lucide-CnlPQoG8.js.map +1 -0
- package/dist/web/static/assets/outcome-DUn1NjlC.js +2 -0
- package/dist/web/static/assets/outcome-DUn1NjlC.js.map +1 -0
- package/dist/web/static/assets/query-S6X1S7K9.js +2 -0
- package/dist/web/static/assets/{query-C99w429o.js.map → query-S6X1S7K9.js.map} +1 -1
- package/dist/web/static/assets/{react-router-r79dBVy4.js → react-router-JVUrkhdd.js} +3 -3
- package/dist/web/static/assets/{react-router-r79dBVy4.js.map → react-router-JVUrkhdd.js.map} +1 -1
- package/dist/web/static/assets/react-vendor-tkvCrao7.js +57 -0
- package/dist/web/static/assets/react-vendor-tkvCrao7.js.map +1 -0
- package/dist/web/static/assets/syntax-highlighter-BkZfCDsz.js +6 -0
- package/dist/web/static/assets/syntax-highlighter-BkZfCDsz.js.map +1 -0
- package/dist/web/static/assets/useTabsParam-k8qte_0C.js +2 -0
- package/dist/web/static/assets/useTabsParam-k8qte_0C.js.map +1 -0
- package/dist/web/static/assets/vendor-DWgdB1eY.js +65 -0
- package/dist/web/static/assets/vendor-DWgdB1eY.js.map +1 -0
- package/dist/web/static/index.html +12 -8
- package/package.json +14 -3
- package/dist/core/ai/provider.d.ts +0 -63
- package/dist/core/ai/provider.d.ts.map +0 -1
- package/dist/core/ai/provider.js +0 -241
- package/dist/core/ai/provider.js.map +0 -1
- package/dist/core/ai/types.d.ts +0 -43
- package/dist/core/ai/types.d.ts.map +0 -1
- package/dist/core/ai/types.js +0 -5
- package/dist/core/ai/types.js.map +0 -1
- package/dist/core/storage/token-usage.d.ts +0 -36
- package/dist/core/storage/token-usage.d.ts.map +0 -1
- package/dist/core/storage/token-usage.js +0 -59
- package/dist/core/storage/token-usage.js.map +0 -1
- package/dist/core/utils/token-tracker.d.ts +0 -39
- package/dist/core/utils/token-tracker.d.ts.map +0 -1
- package/dist/core/utils/token-tracker.js +0 -69
- package/dist/core/utils/token-tracker.js.map +0 -1
- package/dist/skills/index.d.ts +0 -3
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js +0 -3
- package/dist/skills/index.js.map +0 -1
- package/dist/skills/matcher.d.ts +0 -26
- package/dist/skills/matcher.d.ts.map +0 -1
- package/dist/skills/matcher.js +0 -113
- package/dist/skills/matcher.js.map +0 -1
- package/dist/skills/official/code-simplifier.md +0 -52
- package/dist/skills/official/find-skills.md +0 -142
- package/dist/skills/official/official-api-design.md +0 -30
- package/dist/skills/official/official-architecture-decision.md +0 -41
- package/dist/skills/official/official-bmad.md +0 -118
- package/dist/skills/official/official-db-schema-design.md +0 -34
- package/dist/skills/official/official-debug.md +0 -25
- package/dist/skills/official/official-doc-driven.md +0 -31
- package/dist/skills/official/official-harness-engineering.md +0 -108
- package/dist/skills/official/official-performance-optimization.md +0 -30
- package/dist/skills/official/official-pr-review.md +0 -35
- package/dist/skills/official/official-release-checklist.md +0 -30
- package/dist/skills/official/official-security-hardening.md +0 -32
- package/dist/skills/official/official-spec-driven-design.md +0 -31
- package/dist/skills/official/planning-with-files.md +0 -241
- package/dist/skills/official/ui-ux-pro-max.md +0 -105
- package/dist/skills/official/webapp-testing.md +0 -96
- package/dist/skills/official-skills.d.ts +0 -26
- package/dist/skills/official-skills.d.ts.map +0 -1
- package/dist/skills/official-skills.js +0 -73
- package/dist/skills/official-skills.js.map +0 -1
- package/dist/skills/semantic-matcher.d.ts +0 -60
- package/dist/skills/semantic-matcher.d.ts.map +0 -1
- package/dist/skills/semantic-matcher.js +0 -192
- package/dist/skills/semantic-matcher.js.map +0 -1
- package/dist/skills/upgrade-engine.d.ts +0 -93
- package/dist/skills/upgrade-engine.d.ts.map +0 -1
- package/dist/skills/upgrade-engine.js +0 -447
- package/dist/skills/upgrade-engine.js.map +0 -1
- package/dist/skills/upgrade-prompt.d.ts +0 -20
- package/dist/skills/upgrade-prompt.d.ts.map +0 -1
- package/dist/skills/upgrade-prompt.js +0 -75
- package/dist/skills/upgrade-prompt.js.map +0 -1
- package/dist/web/routes/ai.d.ts +0 -10
- package/dist/web/routes/ai.d.ts.map +0 -1
- package/dist/web/routes/ai.js +0 -186
- package/dist/web/routes/ai.js.map +0 -1
- package/dist/web/routes/token-usage.d.ts +0 -7
- package/dist/web/routes/token-usage.d.ts.map +0 -1
- package/dist/web/routes/token-usage.js +0 -18
- package/dist/web/routes/token-usage.js.map +0 -1
- package/dist/web/ssrf-guard.d.ts +0 -35
- package/dist/web/ssrf-guard.d.ts.map +0 -1
- package/dist/web/ssrf-guard.js +0 -93
- package/dist/web/ssrf-guard.js.map +0 -1
- package/dist/web/static/assets/AIConfig-CdDWzJyO.js +0 -2
- package/dist/web/static/assets/AIConfig-CdDWzJyO.js.map +0 -1
- package/dist/web/static/assets/Dashboard-CoEmmIDt.js +0 -2
- package/dist/web/static/assets/Dashboard-CoEmmIDt.js.map +0 -1
- package/dist/web/static/assets/Drawer-DdRTzlLB.js +0 -2
- package/dist/web/static/assets/Drawer-DdRTzlLB.js.map +0 -1
- package/dist/web/static/assets/Events-DrIq1SUS.js +0 -2
- package/dist/web/static/assets/Events-DrIq1SUS.js.map +0 -1
- package/dist/web/static/assets/Reports-DFBM3MDK.js +0 -2
- package/dist/web/static/assets/Reports-DFBM3MDK.js.map +0 -1
- package/dist/web/static/assets/SearchInput-qCj_jAcf.js +0 -2
- package/dist/web/static/assets/SearchInput-qCj_jAcf.js.map +0 -1
- package/dist/web/static/assets/SessionDetail-CCzwdoT7.js +0 -2
- package/dist/web/static/assets/SessionDetail-CCzwdoT7.js.map +0 -1
- package/dist/web/static/assets/Sessions-FfLYkAw9.js +0 -2
- package/dist/web/static/assets/Sessions-FfLYkAw9.js.map +0 -1
- package/dist/web/static/assets/Skills-C8Gvs3Qa.js +0 -2
- package/dist/web/static/assets/Skills-C8Gvs3Qa.js.map +0 -1
- package/dist/web/static/assets/TaskDetail-BS8pYhaR.js +0 -2
- package/dist/web/static/assets/TaskDetail-BS8pYhaR.js.map +0 -1
- package/dist/web/static/assets/Tasks-CyuhizG8.js +0 -2
- package/dist/web/static/assets/Tasks-CyuhizG8.js.map +0 -1
- package/dist/web/static/assets/charts-CLrM0_uM.js +0 -37
- package/dist/web/static/assets/charts-CLrM0_uM.js.map +0 -1
- package/dist/web/static/assets/date-fns-CZ_bHujz.js +0 -2
- package/dist/web/static/assets/date-fns-CZ_bHujz.js.map +0 -1
- package/dist/web/static/assets/export-L_VBD2p1.js +0 -4
- package/dist/web/static/assets/export-L_VBD2p1.js.map +0 -1
- package/dist/web/static/assets/index-CBX47X8l.js +0 -3
- package/dist/web/static/assets/index-CBX47X8l.js.map +0 -1
- package/dist/web/static/assets/index-DjIoMdoR.css +0 -1
- package/dist/web/static/assets/lucide-Bs_edTLa.js +0 -232
- package/dist/web/static/assets/lucide-Bs_edTLa.js.map +0 -1
- package/dist/web/static/assets/query-C99w429o.js +0 -2
- package/dist/web/static/assets/react-vendor-CSp-GLFF.js +0 -49
- package/dist/web/static/assets/react-vendor-CSp-GLFF.js.map +0 -1
- package/dist/web/static/assets/syntax-highlighter-44FakypI.js +0 -9
- package/dist/web/static/assets/syntax-highlighter-44FakypI.js.map +0 -1
- package/dist/web/static/assets/task-title-BhOcemuR.js +0 -2
- package/dist/web/static/assets/task-title-BhOcemuR.js.map +0 -1
- package/dist/web/static/assets/time-Bxuk0M-C.js +0 -2
- package/dist/web/static/assets/time-Bxuk0M-C.js.map +0 -1
- package/dist/web/static/assets/vendor-CMMjVdZs.js +0 -64
- package/dist/web/static/assets/vendor-CMMjVdZs.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as e}from"./react-vendor-tkvCrao7.js";import{b as m,L as p}from"./react-router-JVUrkhdd.js";import{u as x}from"./query-S6X1S7K9.js";import{m as s,u,T as i,d as y,E as a,Y as f,b as o}from"./arco-Bhi3a6Qp.js";import{M as j}from"./MarkdownRenderer-DZmTl-8J.js";import"./vendor-DWgdB1eY.js";import"./syntax-highlighter-BkZfCDsz.js";const h=["name","description","tools","model","version","spawn_agent","tags"];function g(t){if(t==null)return"-";if(Array.isArray(t))return t.join(", ");if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return String(t)}}function T(t){return t==="official"?e.jsx(o,{color:"arcoblue",children:"official"}):t==="distilled"?e.jsx(o,{color:"purple",children:"distilled"}):e.jsx(o,{color:"gray",children:"missing"})}function E(){const{id:t}=m(),{data:r,isLoading:l,isError:c,error:d}=x({queryKey:["skill-content-page",t],enabled:!!t,queryFn:async()=>{const n=await fetch(`/api/skills/${encodeURIComponent(t)}/content`);if(!n.ok)throw new Error(`HTTP ${n.status}`);return n.json()},staleTime:5*6e4});return e.jsxs("div",{style:{padding:16,display:"flex",flexDirection:"column",gap:12},children:[e.jsxs(s,{children:[e.jsx(s.Item,{children:e.jsx(p,{to:"/context?tab=skills",children:"/context"})}),e.jsx(s.Item,{children:"skill"}),e.jsx(s.Item,{children:e.jsx("span",{style:{fontFamily:"monospace"},children:t})})]}),e.jsxs(u,{bordered:!0,children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:12},children:[e.jsx(i.Title,{heading:5,style:{margin:0,fontFamily:"monospace"},children:t}),r&&T(r.source)]}),l&&e.jsx(y,{animation:!0,text:{rows:10}}),c&&e.jsx(a,{description:e.jsxs(i.Text,{type:"error",children:["加载失败: ",String(d)]})}),r&&!r.exists&&e.jsx(a,{description:e.jsxs("span",{children:["未找到 ",e.jsxs("code",{style:{fontFamily:"monospace"},children:[t,".md"]}),"。 可能不是一个真实文件(hit-rate 列出的 keyword id 没有对应 markdown)。"]})}),r&&r.exists&&e.jsxs(e.Fragment,{children:[e.jsx(f,{colon:" :",size:"small",column:2,title:e.jsx(i.Text,{style:{fontSize:13},children:"Frontmatter"}),data:h.map(n=>({label:n,value:g(r.frontmatter[n])})),style:{marginBottom:16}}),e.jsxs(i.Text,{type:"secondary",style:{fontSize:12},children:["path: ",r.path," · ",r.bytes," bytes"]}),e.jsx("div",{style:{marginTop:12},children:e.jsx(j,{content:r.body})})]})]})]})}export{E as default};
|
|
2
|
+
//# sourceMappingURL=SkillContentPage-DK5rgfgw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillContentPage-DK5rgfgw.js","sources":["../../src/pages/SkillContentPage.tsx"],"sourcesContent":["/**\n * /context/skill/:id — full-page view of a skill's markdown.\n *\n * Standalone fallback for long skills (e.g. official-spec-driven-design.md\n * with 600+ LOC) where the 760px drawer feels cramped. Linked from\n * SkillContentDrawer's \"Open in full page\" anchor.\n *\n * Breadcrumb: /context → /context/skill/:id\n */\nimport { useParams, Link } from 'react-router-dom'\nimport { useQuery } from '@tanstack/react-query'\nimport Breadcrumb from '@arco-design/web-react/es/Breadcrumb'\nimport Card from '@arco-design/web-react/es/Card'\nimport Descriptions from '@arco-design/web-react/es/Descriptions'\nimport Empty from '@arco-design/web-react/es/Empty'\nimport Skeleton from '@arco-design/web-react/es/Skeleton'\nimport Tag from '@arco-design/web-react/es/Tag'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport MarkdownRenderer from '../components/MarkdownRenderer'\n\ninterface SkillContentResponse {\n id: string\n source: 'official' | 'distilled' | 'missing'\n exists: boolean\n path: string | null\n bytes: number\n body: string\n frontmatter: Record<string, unknown>\n}\n\nconst WHITELIST: ReadonlyArray<string> = [\n 'name',\n 'description',\n 'tools',\n 'model',\n 'version',\n 'spawn_agent',\n 'tags',\n]\n\nfunction renderFmValue(v: unknown): string {\n if (v == null) return '-'\n if (Array.isArray(v)) return v.join(', ')\n if (typeof v === 'string') return v\n if (typeof v === 'number' || typeof v === 'boolean') return String(v)\n try {\n return JSON.stringify(v)\n } catch {\n return String(v)\n }\n}\n\nfunction sourceTag(source: 'official' | 'distilled' | 'missing') {\n if (source === 'official') return <Tag color=\"arcoblue\">official</Tag>\n if (source === 'distilled') return <Tag color=\"purple\">distilled</Tag>\n return <Tag color=\"gray\">missing</Tag>\n}\n\nexport default function SkillContentPage() {\n const { id } = useParams<{ id: string }>()\n const { data, isLoading, isError, error } = useQuery<SkillContentResponse>({\n queryKey: ['skill-content-page', id],\n enabled: !!id,\n queryFn: async () => {\n const r = await fetch(`/api/skills/${encodeURIComponent(id!)}/content`)\n if (!r.ok) throw new Error(`HTTP ${r.status}`)\n return r.json()\n },\n staleTime: 5 * 60_000,\n })\n\n return (\n <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 12 }}>\n <Breadcrumb>\n <Breadcrumb.Item>\n <Link to=\"/context?tab=skills\">/context</Link>\n </Breadcrumb.Item>\n <Breadcrumb.Item>skill</Breadcrumb.Item>\n <Breadcrumb.Item>\n <span style={{ fontFamily: 'monospace' }}>{id}</span>\n </Breadcrumb.Item>\n </Breadcrumb>\n\n <Card bordered>\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>\n <Typography.Title heading={5} style={{ margin: 0, fontFamily: 'monospace' }}>{id}</Typography.Title>\n {data && sourceTag(data.source)}\n </div>\n\n {isLoading && <Skeleton animation text={{ rows: 10 }} />}\n {isError && (\n <Empty description={<Typography.Text type=\"error\">加载失败: {String(error)}</Typography.Text>} />\n )}\n {data && !data.exists && (\n <Empty\n description={\n <span>\n 未找到 <code style={{ fontFamily: 'monospace' }}>{id}.md</code>。\n 可能不是一个真实文件(hit-rate 列出的 keyword id 没有对应 markdown)。\n </span>\n }\n />\n )}\n {data && data.exists && (\n <>\n <Descriptions\n colon=\" :\"\n size=\"small\"\n column={2}\n title={<Typography.Text style={{ fontSize: 13 }}>Frontmatter</Typography.Text>}\n data={WHITELIST.map((key) => ({\n label: key,\n value: renderFmValue(data.frontmatter[key]),\n }))}\n style={{ marginBottom: 16 }}\n />\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n path: {data.path} · {data.bytes} bytes\n </Typography.Text>\n <div style={{ marginTop: 12 }}>\n <MarkdownRenderer content={data.body} />\n </div>\n </>\n )}\n </Card>\n </div>\n )\n}\n"],"names":["WHITELIST","renderFmValue","v","sourceTag","source","Tag","jsx","SkillContentPage","id","useParams","data","isLoading","isError","error","useQuery","r","jsxs","Breadcrumb","Link","Card","Typography","Skeleton","Empty","Fragment","Descriptions","key","MarkdownRenderer"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as e,r as y}from"./react-vendor-tkvCrao7.js";import{u as j}from"./query-S6X1S7K9.js";import{ai as w,U as v,Y as h,d as g,E as m,T as a,b as c,X as T}from"./arco-Bhi3a6Qp.js";import{M as k}from"./MarkdownRenderer-DZmTl-8J.js";import"./vendor-DWgdB1eY.js";import"./syntax-highlighter-BkZfCDsz.js";const z=["name","description","tools","model","version","spawn_agent","tags"];function S(r){if(r==null)return"-";if(Array.isArray(r))return r.join(", ");if(typeof r=="string")return r;if(typeof r=="number"||typeof r=="boolean")return String(r);try{return JSON.stringify(r)}catch{return String(r)}}function b(r){return r==="official"?e.jsx(c,{color:"arcoblue",size:"small",children:"official"}):r==="distilled"?e.jsx(c,{color:"purple",size:"small",children:"distilled"}):e.jsx(c,{color:"gray",size:"small",children:"missing"})}function _({open:r,skillId:o,stats:s,onClose:d}){const{data:l,isLoading:x,isError:u,error:p}=j({queryKey:["skill-content",o],enabled:!!o&&r,queryFn:async()=>{const i=await fetch(`/api/skills/${encodeURIComponent(o)}/content`);if(!i.ok)throw new Error(`HTTP ${i.status}`);return i.json()},staleTime:3e5}),t=e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,flexWrap:"wrap"},children:[e.jsx("span",{style:{fontFamily:"monospace",fontSize:13},children:o??"-"}),l&&b(l.source),o&&e.jsxs("a",{href:`/context/skill/${encodeURIComponent(o)}`,target:"_blank",rel:"noopener noreferrer",style:{marginLeft:"auto",fontSize:12,display:"inline-flex",alignItems:"center",gap:4},children:[e.jsx(w,{})," Open in full page"]})]});return e.jsxs(v,{visible:r,onCancel:d,onOk:d,title:t,width:760,footer:null,unmountOnExit:!0,children:[s&&e.jsx(h,{colon:" :",size:"small",column:4,data:[{label:"invocations",value:s.invocations},{label:"success",value:s.success},{label:"failed",value:s.failed},{label:"rate",value:s.rate}],style:{marginBottom:12}}),x&&e.jsx(g,{animation:!0,text:{rows:6}}),u&&e.jsx(m,{description:e.jsxs(a.Text,{type:"error",children:["加载失败: ",String(p)]})}),l&&!l.exists&&e.jsx(m,{description:e.jsxs("span",{children:["未找到 ",e.jsxs("code",{style:{fontFamily:"monospace"},children:[o,".md"]}),"。",e.jsx("br",{}),"hit-rate 表中的 id 可能没有对应文件(如未蒸馏的 keyword)。"]})}),l&&l.exists&&e.jsxs(e.Fragment,{children:[e.jsx(h,{colon:" :",size:"mini",column:2,title:e.jsx(a.Text,{style:{fontSize:13},children:"Frontmatter"}),data:z.map(i=>({label:String(i),value:S(l.frontmatter[i])})),style:{marginBottom:16}}),e.jsx(a.Text,{style:{fontSize:13,fontWeight:600},children:"Body"}),e.jsx("div",{style:{marginTop:8,maxHeight:"calc(100vh - 360px)",overflow:"auto",border:"1px solid var(--color-border-2)",borderRadius:4,padding:12},children:e.jsx(k,{content:l.body})})]})]})}function O(){const[r,o]=y.useState(null),{data:s,isLoading:d,isError:l,error:x}=j({queryKey:["ctx-skill-hit-rate"],queryFn:async()=>{const t=await fetch("/api/rules/hit-rate?days=7");if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.json()},staleTime:6e4}),u=y.useMemo(()=>{if(!s)return[];const t=s.skills.map(n=>({skill_id:n.skill_id,invocations:n.total,success:n.success,failed:n.failed,success_rate:n.total>0?n.success/n.total:0,rate:n.rate})),i=s.neverTriggered.map(n=>({skill_id:n,invocations:0,success:0,failed:0,success_rate:0,rate:"0%"}));return[...t,...i].sort((n,f)=>f.invocations-n.invocations)},[s]);if(l)return e.jsx(m,{description:e.jsxs(a.Text,{type:"error",children:["加载失败: ",String(x)]})});if(d||!s)return e.jsx(g,{animation:!0,text:{rows:8}});const p=[{title:"skill_id",dataIndex:"skill_id",render:t=>e.jsx("span",{style:{fontFamily:"monospace",fontSize:12},children:t})},{title:"invocations (7d)",dataIndex:"invocations",width:150,sorter:(t,i)=>t.invocations-i.invocations,render:t=>t===0?e.jsx(c,{color:"red",size:"small",children:"未触发"}):e.jsx("span",{style:{fontFamily:"monospace",fontWeight:600},children:t})},{title:"success_rate",dataIndex:"success_rate",width:140,render:(t,i)=>{if(i.invocations===0)return e.jsx(a.Text,{type:"secondary",style:{fontSize:12},children:"—"});const n=Math.round(t*1e3)/10,f=n>=90?"green":n>=70?"orange":"red";return e.jsxs("span",{children:[e.jsxs(c,{color:f,size:"small",children:[n,"%"]}),e.jsxs(a.Text,{type:"secondary",style:{fontSize:11,marginLeft:6},children:["(",i.success,"✓/",i.failed,"✗)"]})]})}},{title:"rate (vs 全部 prompt)",dataIndex:"rate",width:160,render:t=>e.jsx(a.Text,{style:{fontSize:12},children:t})},{title:"状态",dataIndex:"invocations",key:"status",width:110,render:t=>t===0?e.jsx(c,{color:"red",size:"small",children:"zero-call"}):t<3?e.jsx(c,{color:"orange",size:"small",children:"low"}):e.jsx(c,{color:"green",size:"small",children:"active"})}];return e.jsxs("div",{children:[e.jsx("div",{style:{marginBottom:12},children:e.jsxs(a.Text,{style:{fontSize:13,color:"var(--color-text-3)"},children:["近 7d · 总 invocation ",s.summary.skillInvocations," / ",s.summary.totalPrompts," prompts · skill rate ",s.summary.skillRate," · 共 ",u.length," 个 skill · 未触发 ",s.neverTriggered.length," 个"]})}),e.jsx(T,{rowKey:"skill_id",data:u,columns:p,pagination:{pageSize:20,showTotal:!0},size:"small",border:{wrapper:!0,cell:!0},onRow:t=>({onClick:()=>o(t),style:{cursor:"pointer"}}),noDataElement:e.jsx(m,{description:"无 skill 数据"})}),e.jsx(_,{open:r!==null,skillId:(r==null?void 0:r.skill_id)??null,stats:r,onClose:()=>o(null)})]})}export{O as default};
|
|
2
|
+
//# sourceMappingURL=SkillStatsTable-DYMzjEUV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillStatsTable-DYMzjEUV.js","sources":["../../src/components/context/SkillContentDrawer.tsx","../../src/components/context/SkillStatsTable.tsx"],"sourcesContent":["/**\n * SkillContentDrawer — right-side Arco Drawer that shows a skill's full\n * markdown (frontmatter + body) when a row in SkillStatsTable is clicked.\n *\n * Spec: docs/design/2026-05-26/2029-skill-agent-content-viewer-spec.md (Phase F)\n *\n * Layout:\n * - Header: title (skill_id) + \"Open in full page\" link → /context/skill/:id\n * - Top: stats descriptions (invocations / success / rate / 状态), driven by\n * the row props (no extra fetch — same data the table already has).\n * - Mid: frontmatter (whitelist 7 fields: name/description/tools/model/\n * version/spawn_agent/tags) rendered as Arco Descriptions mini column=2.\n * - Bottom: markdown body in scrollable container (MarkdownRenderer + Prism).\n *\n * Empty handling:\n * - exists=false (e.g. virtual `general-purpose` or hit-rate id without a\n * backing .md file) → friendly Empty.\n */\nimport { useQuery } from '@tanstack/react-query'\nimport Drawer from '@arco-design/web-react/es/Drawer'\nimport Descriptions from '@arco-design/web-react/es/Descriptions'\nimport Empty from '@arco-design/web-react/es/Empty'\nimport Skeleton from '@arco-design/web-react/es/Skeleton'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport Tag from '@arco-design/web-react/es/Tag'\nimport { IconLaunch } from '@arco-design/web-react/icon'\nimport MarkdownRenderer from '../MarkdownRenderer'\n\nexport interface SkillRowStats {\n skill_id: string\n invocations: number\n success: number\n failed: number\n success_rate: number\n rate: string\n}\n\ninterface SkillContentResponse {\n id: string\n source: 'official' | 'distilled' | 'missing'\n exists: boolean\n path: string | null\n bytes: number\n body: string\n frontmatter: Record<string, unknown>\n}\n\ninterface Props {\n open: boolean\n skillId: string | null\n stats?: SkillRowStats | null\n onClose: () => void\n}\n\nconst WHITELIST: ReadonlyArray<keyof Record<string, unknown>> = [\n 'name',\n 'description',\n 'tools',\n 'model',\n 'version',\n 'spawn_agent',\n 'tags',\n]\n\nfunction renderFmValue(v: unknown): string {\n if (v == null) return '-'\n if (Array.isArray(v)) return v.join(', ')\n if (typeof v === 'string') return v\n if (typeof v === 'number' || typeof v === 'boolean') return String(v)\n try {\n return JSON.stringify(v)\n } catch {\n return String(v)\n }\n}\n\nfunction sourceTag(source: 'official' | 'distilled' | 'missing') {\n if (source === 'official') return <Tag color=\"arcoblue\" size=\"small\">official</Tag>\n if (source === 'distilled') return <Tag color=\"purple\" size=\"small\">distilled</Tag>\n return <Tag color=\"gray\" size=\"small\">missing</Tag>\n}\n\nexport default function SkillContentDrawer({ open, skillId, stats, onClose }: Props) {\n const { data, isLoading, isError, error } = useQuery<SkillContentResponse>({\n queryKey: ['skill-content', skillId],\n enabled: !!skillId && open,\n queryFn: async () => {\n const r = await fetch(`/api/skills/${encodeURIComponent(skillId!)}/content`)\n if (!r.ok) throw new Error(`HTTP ${r.status}`)\n return r.json()\n },\n staleTime: 5 * 60_000,\n })\n\n const title = (\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>\n <span style={{ fontFamily: 'monospace', fontSize: 13 }}>{skillId ?? '-'}</span>\n {data && sourceTag(data.source)}\n {skillId && (\n <a\n href={`/context/skill/${encodeURIComponent(skillId)}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ marginLeft: 'auto', fontSize: 12, display: 'inline-flex', alignItems: 'center', gap: 4 }}\n >\n <IconLaunch /> Open in full page\n </a>\n )}\n </div>\n )\n\n return (\n <Drawer\n visible={open}\n onCancel={onClose}\n onOk={onClose}\n title={title}\n width={760}\n footer={null}\n unmountOnExit\n >\n {/* Stats from the row (no extra fetch) */}\n {stats && (\n <Descriptions\n colon=\" :\"\n size=\"small\"\n column={4}\n data={[\n { label: 'invocations', value: stats.invocations },\n { label: 'success', value: stats.success },\n { label: 'failed', value: stats.failed },\n { label: 'rate', value: stats.rate },\n ]}\n style={{ marginBottom: 12 }}\n />\n )}\n\n {isLoading && <Skeleton animation text={{ rows: 6 }} />}\n {isError && (\n <Empty description={<Typography.Text type=\"error\">加载失败: {String(error)}</Typography.Text>} />\n )}\n\n {data && !data.exists && (\n <Empty\n description={\n <span>\n 未找到 <code style={{ fontFamily: 'monospace' }}>{skillId}.md</code>。\n <br />\n hit-rate 表中的 id 可能没有对应文件(如未蒸馏的 keyword)。\n </span>\n }\n />\n )}\n\n {data && data.exists && (\n <>\n <Descriptions\n colon=\" :\"\n size=\"mini\"\n column={2}\n title={<Typography.Text style={{ fontSize: 13 }}>Frontmatter</Typography.Text>}\n data={WHITELIST.map((key) => ({\n label: String(key),\n value: renderFmValue(data.frontmatter[key as string]),\n }))}\n style={{ marginBottom: 16 }}\n />\n <Typography.Text style={{ fontSize: 13, fontWeight: 600 }}>Body</Typography.Text>\n <div\n style={{\n marginTop: 8,\n maxHeight: 'calc(100vh - 360px)',\n overflow: 'auto',\n border: '1px solid var(--color-border-2)',\n borderRadius: 4,\n padding: 12,\n }}\n >\n <MarkdownRenderer content={data.body} />\n </div>\n </>\n )}\n </Drawer>\n )\n}\n","/**\n * SkillStatsTable — Tab 2 of /context (🔧 Skill 调用).\n *\n * 数据: GET /api/rules/hit-rate?days=7 — 返回 summary + skills[] (含\n * total/success/failed/rate) + neverTriggered[]. 0 改后端.\n *\n * 列: skill_id | invocations_7d | success_rate | 状态 chip (含 zero-result 标记).\n */\nimport { useMemo, useState } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport Table from '@arco-design/web-react/es/Table'\nimport Tag from '@arco-design/web-react/es/Tag'\nimport Empty from '@arco-design/web-react/es/Empty'\nimport Skeleton from '@arco-design/web-react/es/Skeleton'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport SkillContentDrawer, { type SkillRowStats } from './SkillContentDrawer'\n\ninterface SkillRow {\n skill_id: string\n total: number\n success: number\n failed: number\n rate: string // e.g. \"13.1%\"\n}\ninterface HitRateResponse {\n summary: { totalPrompts: number; skillInvocations: number; skillRate: string }\n skills: SkillRow[]\n neverTriggered: string[]\n}\n\nexport default function SkillStatsTable() {\n const [openSkill, setOpenSkill] = useState<SkillRowStats | null>(null)\n const { data, isLoading, isError, error } = useQuery<HitRateResponse>({\n queryKey: ['ctx-skill-hit-rate'],\n queryFn: async () => {\n const r = await fetch('/api/rules/hit-rate?days=7')\n if (!r.ok) throw new Error(`HTTP ${r.status}`)\n return r.json()\n },\n staleTime: 60_000,\n })\n\n // Merge invoked skills + never-triggered (cited 0 → highlight in red).\n const rows = useMemo(() => {\n if (!data) return []\n const invoked = data.skills.map((s) => ({\n skill_id: s.skill_id,\n invocations: s.total,\n success: s.success,\n failed: s.failed,\n success_rate: s.total > 0 ? s.success / s.total : 0,\n rate: s.rate,\n }))\n const neverRows = data.neverTriggered.map((id) => ({\n skill_id: id,\n invocations: 0,\n success: 0,\n failed: 0,\n success_rate: 0,\n rate: '0%',\n }))\n return [...invoked, ...neverRows].sort((a, b) => b.invocations - a.invocations)\n }, [data])\n\n if (isError) return <Empty description={<Typography.Text type=\"error\">加载失败: {String(error)}</Typography.Text>} />\n if (isLoading || !data) return <Skeleton animation text={{ rows: 8 }} />\n\n const columns = [\n {\n title: 'skill_id',\n dataIndex: 'skill_id',\n render: (id: string) => <span style={{ fontFamily: 'monospace', fontSize: 12 }}>{id}</span>,\n },\n {\n title: 'invocations (7d)',\n dataIndex: 'invocations',\n width: 150,\n sorter: (a: { invocations: number }, b: { invocations: number }) => a.invocations - b.invocations,\n render: (n: number) => (\n n === 0\n ? <Tag color=\"red\" size=\"small\">未触发</Tag>\n : <span style={{ fontFamily: 'monospace', fontWeight: 600 }}>{n}</span>\n ),\n },\n {\n title: 'success_rate',\n dataIndex: 'success_rate',\n width: 140,\n render: (rate: number, r: { invocations: number; success: number; failed: number }) => {\n if (r.invocations === 0) return <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>—</Typography.Text>\n const pct = Math.round(rate * 1000) / 10\n const color = pct >= 90 ? 'green' : pct >= 70 ? 'orange' : 'red'\n return (\n <span>\n <Tag color={color} size=\"small\">{pct}%</Tag>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, marginLeft: 6 }}>\n ({r.success}✓/{r.failed}✗)\n </Typography.Text>\n </span>\n )\n },\n },\n {\n title: 'rate (vs 全部 prompt)',\n dataIndex: 'rate',\n width: 160,\n render: (s: string) => <Typography.Text style={{ fontSize: 12 }}>{s}</Typography.Text>,\n },\n {\n title: '状态',\n dataIndex: 'invocations',\n key: 'status',\n width: 110,\n render: (n: number) => (\n n === 0 ? <Tag color=\"red\" size=\"small\">zero-call</Tag> :\n n < 3 ? <Tag color=\"orange\" size=\"small\">low</Tag> :\n <Tag color=\"green\" size=\"small\">active</Tag>\n ),\n },\n ]\n\n return (\n <div>\n <div style={{ marginBottom: 12 }}>\n <Typography.Text style={{ fontSize: 13, color: 'var(--color-text-3)' }}>\n 近 7d · 总 invocation {data.summary.skillInvocations} / {data.summary.totalPrompts} prompts ·\n skill rate {data.summary.skillRate} · 共 {rows.length} 个 skill ·\n 未触发 {data.neverTriggered.length} 个\n </Typography.Text>\n </div>\n <Table\n rowKey=\"skill_id\"\n data={rows}\n columns={columns}\n pagination={{ pageSize: 20, showTotal: true }}\n size=\"small\"\n border={{ wrapper: true, cell: true }}\n onRow={(record) => ({\n onClick: () => setOpenSkill(record as SkillRowStats),\n style: { cursor: 'pointer' },\n })}\n noDataElement={<Empty description=\"无 skill 数据\" />}\n />\n <SkillContentDrawer\n open={openSkill !== null}\n skillId={openSkill?.skill_id ?? null}\n stats={openSkill}\n onClose={() => setOpenSkill(null)}\n />\n </div>\n )\n}\n"],"names":["WHITELIST","renderFmValue","v","sourceTag","source","jsx","Tag","SkillContentDrawer","open","skillId","stats","onClose","data","isLoading","isError","error","useQuery","r","title","jsxs","IconLaunch","Drawer","Descriptions","Skeleton","Empty","Typography","Fragment","key","MarkdownRenderer","SkillStatsTable","openSkill","setOpenSkill","useState","rows","useMemo","invoked","s","neverRows","id","a","b","columns","n","rate","pct","color","Table","record"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as l,j as e}from"./react-vendor-tkvCrao7.js";import{u as $,b as Y}from"./query-S6X1S7K9.js";import{K as H,d as M,T as a,u as C,b as m,t as L,aj as P,ak as W,al as V,am as Z,I as X,an as ee}from"./arco-Bhi3a6Qp.js";import{a as A}from"./auth-Bnf8ZcqN.js";import{ai as te}from"./vendor-DWgdB1eY.js";import{R as se,g as ne,h as ie,i as re,j as le,k as ae}from"./charts-BuHQWDbQ.js";async function oe(){const t=await fetch("/api/skills/distill/status");if(!t.ok)throw new Error(`status failed: ${t.status}`);return t.json()}async function de(t=4){const s=await fetch(`/api/skills/distill/cost-estimate?topicCap=${t}`);if(!s.ok)throw new Error(`cost-estimate failed: ${s.status}`);return s.json()}async function ce(){const t=await fetch("/api/skills/distill/review");if(!t.ok)throw new Error(`review failed: ${t.status}`);return t.json()}async function ue(t){const s=await fetch(`/api/skills/distill/review/${encodeURIComponent(t)}/diff`);if(s.status===404)throw new Error("distilled_file_not_found");if(!s.ok)throw new Error(`diff failed: ${s.status}`);return s.json()}async function pe(t){const s=await A("/api/skills/distill/run",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(s.status===409)throw new Error("distill_in_progress");if(!s.ok)throw new Error(`run failed: ${s.status}`);return s.json()}async function he(){const t=await A("/api/skills/distill/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})});if(t.status===409)throw new Error("distill_in_progress");if(!t.ok)throw new Error(`refresh failed: ${t.status}`);return t.json()}async function fe(t){const s=await A(`/api/skills/distill/apply/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})});if(!s.ok)throw new Error(`apply failed: ${s.status}`);return s.json()}async function ye(t){const s=await A(`/api/skills/distill/cancel/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})});if(!s.ok)throw new Error(`cancel failed: ${s.status}`)}const ge=["connected","start","progress","phase-changed","skill-distilled","done","cancelled","error"];function xe(t,s){const i=new EventSource(`/api/skills/distill/run/${encodeURIComponent(t)}/stream`),o=r=>h=>{var p;let u={};try{u=JSON.parse(h.data||"{}")}catch{}const f={...u,type:r};s.onEvent(f),(r==="done"||r==="error"||r==="cancelled")&&((p=s.onTerminal)==null||p.call(s,f),i.close())};for(const r of ge)i.addEventListener(r,o(r));return()=>i.close()}function me(t){if(!t)return"蒸馏失败,未知错误";const s=t.trim();return s==="distill_in_progress"?"已有蒸馏在进行中,请稍后再试":s.startsWith("run failed: 401")||s==="unauthorized"?"未授权:请检查 daemon token":s.startsWith("run failed: 403")?"无权限触发蒸馏(403,loopback only)":s.startsWith("run failed: 500")?"后端蒸馏出错(500),请查看 daemon 日志":s.toLowerCase().includes("failed to fetch")?"无法连接 daemon,请确认服务已启动":s}function je({open:t,topicCap:s,onConfirm:i,onCancel:o}){const[r,h]=l.useState(null),[u,f]=l.useState(!1),[p,b]=l.useState(null);l.useEffect(()=>{t&&(f(!0),b(null),de(s).then(h).catch(w=>b(String(w))).finally(()=>f(!1)))},[t,s]);const S=w=>w.toLocaleString("en-US");return e.jsxs(H,{visible:t,title:"确认蒸馏成本",onOk:i,onCancel:o,okText:u?"加载中…":"开始蒸馏",cancelText:"取消",okButtonProps:{disabled:u||p!==null},children:[u&&e.jsx(M,{animation:!0,text:{rows:3}}),p&&e.jsxs(a.Text,{type:"error",style:{fontSize:13},children:["无法获取成本估算:",p]}),!u&&!p&&r&&e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[e.jsxs(a.Text,{style:{fontSize:13},children:["将对 ",e.jsx("b",{children:r.candidateCount})," 个上游 skill 进行评分(Haiku),并蒸馏 最多 ",e.jsx("b",{children:Math.min(r.candidateCount,r.topicCap)})," 个 topic(Sonnet)。"]}),e.jsxs("div",{style:{padding:12,background:"var(--color-fill-2)",borderRadius:4,display:"grid",gridTemplateColumns:"1fr auto",rowGap:4,fontSize:12,fontFamily:"monospace"},children:[e.jsx("span",{children:"评分输入 (Haiku)"}),e.jsxs("span",{children:[S(r.scorerInputTokens)," tok"]}),e.jsx("span",{children:"评分输出 (Haiku)"}),e.jsxs("span",{children:[S(r.scorerOutputTokens)," tok"]}),e.jsx("span",{children:"蒸馏输入 (Sonnet)"}),e.jsxs("span",{children:[S(r.distillerInputTokens)," tok"]}),e.jsx("span",{children:"蒸馏输出 (Sonnet)"}),e.jsxs("span",{children:[S(r.distillerOutputTokens)," tok"]}),e.jsx("span",{style:{fontWeight:700,borderTop:"1px solid var(--color-border-1)",paddingTop:4,marginTop:4},children:"总计"}),e.jsxs("span",{style:{fontWeight:700,borderTop:"1px solid var(--color-border-1)",paddingTop:4,marginTop:4},children:[S(r.total)," tok"]})]}),e.jsx(a.Text,{type:"secondary",style:{fontSize:12},children:"实际成本取决于 LLM 提供商定价。请确认配置的 base_url 与计费模式。"}),e.jsx(a.Text,{type:"secondary",style:{fontSize:12},children:"Sample-approve gate 在前 2 个蒸馏完成后暂停,等待 review 后再继续。"})]})]})}function Se(t){switch(t){case"idle":return"gray";case"running":return"arcoblue";case"done":return"green";case"error":return"red";case"init":return"gray";case"scoring":return"blue";case"distilling":return"arcoblue";case"review_required":return"orange";default:return"gray"}}function be(t){switch(t){case"start":return{color:"arcoblue",label:"START"};case"progress":return{color:"gray",label:"PROGRESS"};case"phase-changed":return{color:"blue",label:"PHASE"};case"skill-distilled":return{color:"green",label:"DISTILLED"};case"done":return{color:"green",label:"DONE"};case"cancelled":return{color:"red",label:"CANCELLED"};case"error":return{color:"red",label:"ERROR"};default:return{color:"gray",label:t.toUpperCase()}}}const we={idle:"空闲",running:"正在蒸馏 (R-A stub; R-B 接 claude CLI)…",done:"完成",error:"出错",init:"已初始化候选清单",scoring:"正在评分 (legacy phase)",distilling:"正在蒸馏 (legacy phase)",review_required:"已暂停 (legacy phase, R-A 已移除 gate)"};function ke(t){return t?we[t]??t:"准备启动…"}function ve({runId:t,onTerminal:s}){const[i,o]=l.useState([]),[r,h]=l.useState(null),[u,f]=l.useState(!1),[p,b]=l.useState(()=>Date.now()),[S,w]=l.useState(()=>Date.now()),g=l.useRef(s);l.useEffect(()=>{g.current=s},[s]),l.useEffect(()=>{o([]),h(null),b(Date.now());const n=xe(t,{onEvent:c=>o(j=>[...j,c]),onTerminal:c=>{var j;h(c),(j=g.current)==null||j.call(g,c)}});return()=>n()},[t]),l.useEffect(()=>{if(r)return;const n=setInterval(()=>w(Date.now()),1e3);return()=>clearInterval(n)},[r]);const z=async()=>{f(!0);try{await ye(t)}catch{}finally{f(!1)}},k=[...i].reverse().find(n=>n.phase),v=k==null?void 0:k.phase,y=i.filter(n=>n.type==="skill-distilled"),E=Math.max(0,Math.floor((S-p)/1e3)),_=i.length>0&&i[i.length-1].at?new Date(i[i.length-1].at).getTime():p,I=Math.max(0,Math.floor((S-_)/1e3)),T=[...i].reverse().find(n=>n.type==="progress"),D=T==null?void 0:T.topicId,R=(()=>{var c;const n=(c=T==null?void 0:T.message)==null?void 0:c.match(/chars=(\d+)/);return n?parseInt(n[1],10):null})();return e.jsxs(C,{bordered:!0,bodyStyle:{padding:16},"data-testid":"distill-progress",children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:12,flexWrap:"wrap"},children:[e.jsx(a.Title,{heading:6,style:{margin:0},children:"蒸馏进度"}),e.jsxs(m,{color:Se(v),size:"small",children:["phase: ",v??"starting"]}),e.jsx(m,{size:"small",style:{fontFamily:"monospace"},children:t}),!r&&e.jsxs(m,{size:"small",color:"gray",children:["已运行 ",E,"s",I>5&&` · 自上次事件 ${I}s`]}),e.jsx("div",{style:{marginLeft:"auto"},children:!r&&e.jsx(L,{size:"small",status:"danger",loading:u,onClick:z,children:"取消"})})]}),!r&&e.jsx("div",{style:{marginBottom:12,padding:"8px 12px",background:"var(--color-fill-1)",borderRadius:4},children:e.jsxs(a.Text,{style:{fontSize:13},children:[e.jsx("span",{style:{display:"inline-block",width:8,height:8,borderRadius:"50%",background:"#3491fa",marginRight:8,animation:"pulse 1.5s ease-in-out infinite"}}),ke(v),D&&e.jsxs(m,{size:"small",color:"arcoblue",style:{marginLeft:8},children:["topic: ",D]}),R!=null&&e.jsxs(m,{size:"small",color:"gray",style:{marginLeft:4},children:[R.toLocaleString()," chars"]}),I>30&&e.jsx(a.Text,{type:"secondary",style:{fontSize:11,marginLeft:8},children:"(LLM 调用可能需要 30-90s 完成,请耐心等待)"})]})}),y.length>0&&e.jsxs("div",{style:{marginBottom:12},children:[e.jsxs(a.Text,{type:"secondary",style:{fontSize:12},children:["已蒸馏 ",y.length," 个 skill:"]}),e.jsx("ul",{style:{margin:"4px 0 0 0",paddingLeft:20,fontSize:13},children:y.map((n,c)=>e.jsx("li",{style:{fontFamily:"monospace"},children:n.topicId},c))})]}),e.jsxs("div",{style:{maxHeight:240,overflowY:"auto",fontSize:12,fontFamily:"monospace",background:"var(--color-fill-1)",padding:8,borderRadius:4},children:[i.length===0&&e.jsx(a.Text,{type:"secondary",children:"等待第一个 SSE 事件…(init/scoring 阶段无 state 变更则没有事件,phase 变化会立刻 push)"}),i.map((n,c)=>{const j=be(n.type);return e.jsxs("div",{style:{display:"flex",gap:8,lineHeight:"20px"},children:[e.jsx(m,{color:j.color,size:"small",style:{minWidth:78,textAlign:"center"},children:j.label}),e.jsxs("span",{style:{flex:1},children:[n.topicId?`${n.topicId} `:"",n.message??"",n.errorMessage?` — ${n.errorMessage}`:"",n.completed!=null?` (completed=${n.completed}, pending=${n.pending??"?"})`:""]})]},c)})]})]})}function Te({score:t}){let s="gray";return t>=4?s="green":t>=3?s="arcoblue":s="orange",e.jsxs(m,{color:s,size:"medium",style:{fontSize:14,fontWeight:700},children:[t.toFixed(1)," / 5"]})}function Ce({dims:t}){const s=[{axis:"D1 多语言",value:t.d1},{axis:"D2 SDLC",value:t.d2},{axis:"D3 抽象层",value:t.d3},{axis:"D4 contextfit",value:t.d4},{axis:"D5 可注入",value:t.d5}];return e.jsx("div",{style:{width:220,height:180},children:e.jsx(se,{children:e.jsxs(ne,{data:s,outerRadius:"70%",children:[e.jsx(ie,{}),e.jsx(re,{dataKey:"axis",tick:{fontSize:10}}),e.jsx(le,{angle:90,domain:[0,1],tick:{fontSize:9}}),e.jsx(ae,{name:"score",dataKey:"value",stroke:"#165dff",fill:"#165dff",fillOpacity:.4})]})})})}function ze({left:t,right:s}){const i=te(t,s);return e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8,maxHeight:360,overflowY:"auto",fontFamily:"monospace",fontSize:11,lineHeight:"16px",background:"var(--color-fill-1)",padding:8,borderRadius:4},children:[e.jsxs("div",{children:[e.jsx(a.Text,{type:"secondary",style:{fontSize:11,display:"block",marginBottom:4},children:"Upstream (原始)"}),e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap",wordBreak:"break-word"},children:i.map((o,r)=>{if(o.added)return null;const h=o.removed?"rgba(245, 63, 63, 0.12)":"transparent";return e.jsx("span",{style:{background:h,display:"block"},children:o.value},r)})})]}),e.jsxs("div",{children:[e.jsx(a.Text,{type:"secondary",style:{fontSize:11,display:"block",marginBottom:4},children:"Distilled (蒸馏后)"}),e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap",wordBreak:"break-word"},children:i.map((o,r)=>{if(o.removed)return null;const h=o.added?"rgba(0, 180, 42, 0.12)":"transparent";return e.jsx("span",{style:{background:h,display:"block"},children:o.value},r)})})]})]})}function Ee({file:t,onReject:s}){const[i,o]=l.useState(null),[r,h]=l.useState(!1),u=t.id.replace(/^distilled-/,""),{data:f,isLoading:p,isError:b,error:S}=$({queryKey:["distill-diff",t.id],queryFn:()=>ue(u),staleTime:6e4}),w=async()=>{h(!0);try{const y=await fe(u);o({open:!0,status:y.gitStatus,hint:y.hint})}catch(y){o({open:!0,status:"error",hint:String(y)})}finally{h(!1)}};if(p)return e.jsx(C,{bordered:!0,children:e.jsx(M,{animation:!0,text:{rows:5}})});if(b||!f)return e.jsx(C,{bordered:!0,children:e.jsxs(a.Text,{type:"error",children:["加载 diff 失败: ",String(S)]})});const g=f.frontmatter,z=g.it_universal_dims??{d1:0,d2:0,d3:0,d4:0,d5:0},k=f.upstreams.find(y=>y.content),v=(k==null?void 0:k.content)??"(upstream cache 不可读)";return e.jsxs(C,{bordered:!0,bodyStyle:{padding:16},"data-testid":"distill-review-card","data-topic-id":t.id,children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,flexWrap:"wrap",marginBottom:12},children:[e.jsx(a.Title,{heading:6,style:{margin:0,fontFamily:"monospace"},children:t.id}),e.jsx(Te,{score:t.itScore}),t.realDistillation?e.jsx(m,{color:"green",size:"small",children:"real distill"}):e.jsx(m,{color:"orange",size:"small",children:"stub — needs real distillation"})]}),e.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap",marginBottom:12},children:[(g.distilled_from??[]).map((y,E)=>e.jsxs(m,{bordered:!0,size:"small",style:{fontFamily:"monospace",fontSize:10},children:[y.upstream," · ",y.license??"?"," @",(y.commit??"").slice(0,7)||"unknown"]},E)),g.distilled_by&&e.jsxs(m,{size:"small",color:"arcoblue",children:["by: ",g.distilled_by]})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:16,marginBottom:12},children:[e.jsx(Ce,{dims:z}),e.jsxs("div",{style:{minWidth:0},children:[g.it_universal_rationale&&e.jsxs(a.Text,{type:"secondary",style:{fontSize:12,display:"block",marginBottom:8},children:[e.jsx("b",{children:"评分 rationale:"})," ",g.it_universal_rationale]}),g.description&&e.jsx(a.Text,{style:{fontSize:12,display:"block",marginBottom:4},children:g.description})]})]}),e.jsx(ze,{left:v,right:f.distilledMarkdown}),e.jsxs("div",{style:{display:"flex",gap:8,marginTop:12},children:[e.jsx(L,{type:"primary",size:"small",loading:r,onClick:w,children:"查看 git status (Apply)"}),e.jsx(L,{size:"small",status:"warning",onClick:()=>s==null?void 0:s(t.id),children:"隐藏 (Reject)"}),e.jsx(a.Text,{type:"secondary",style:{fontSize:11,marginLeft:"auto",alignSelf:"center"},children:t.path})]}),e.jsxs(H,{visible:(i==null?void 0:i.open)===!0,title:"git status",onCancel:()=>o(null),onOk:()=>o(null),okText:"知道了",cancelText:"关闭",children:[e.jsx("pre",{style:{fontFamily:"monospace",fontSize:12,background:"var(--color-fill-2)",padding:8,borderRadius:4,whiteSpace:"pre-wrap"},children:i==null?void 0:i.status}),e.jsx(a.Text,{type:"secondary",style:{fontSize:12},children:i==null?void 0:i.hint})]})]})}function Oe(){var F;const t=Y(),[s,i]=l.useState(null),[o,r]=l.useState(!1),[h,u]=l.useState(null),[f,p]=l.useState(null),[b,S]=l.useState(new Set),[w,g]=l.useState(!1),[z,k]=l.useState(3),[v,y]=l.useState(4),[E,_]=l.useState(""),[I,T]=l.useState(!1),D=$({queryKey:["distill-status"],queryFn:oe,refetchInterval:s?4e3:3e4,staleTime:2e3}),R=$({queryKey:["distill-review"],queryFn:ce,staleTime:1e4}),n=D.data,c=(n==null?void 0:n.isBusy)??!1,j=(n==null?void 0:n.claudeCliAvailable)??!1,N=(n==null?void 0:n.claudeCliPath)??null,O=((F=n==null?void 0:n.state)==null?void 0:F.phase)??null,B=l.useMemo(()=>{var x;return(((x=R.data)==null?void 0:x.distilledFiles)??[]).filter(G=>!b.has(G.id))},[R.data,b]);l.useEffect(()=>{c&&(n!=null&&n.currentRunId)&&!s&&i(n.currentRunId)},[c,n==null?void 0:n.currentRunId,s]);const q=()=>{p(null),u("run"),r(!0)},K=()=>{p(null),u("refresh"),r(!0)},U=async()=>{if(r(!1),!!h)try{const d=E.split(/[,\s]+/).map(x=>x.trim()).filter(x=>/^[a-z0-9][a-z0-9-]*$/.test(x));if(h==="run"){const x=await pe({threshold:z,topicCap:v,skip:d.length>0?d:void 0,regenerateAll:I});i(x.runId)}else{const x=await he();i(x.runId)}}catch(d){p(me(d instanceof Error?d.message:String(d)))}finally{u(null)}},Q=d=>{t.invalidateQueries({queryKey:["distill-status"]}),t.invalidateQueries({queryKey:["distill-review"]}),setTimeout(()=>i(null),1500)},J=d=>{S(x=>new Set(x).add(d))};return D.isLoading?e.jsx(M,{animation:!0,text:{rows:4}}):e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsx(C,{bordered:!0,bodyStyle:{padding:12},children:e.jsxs("div",{style:{display:"flex",gap:12,flexWrap:"wrap",alignItems:"center"},children:[e.jsx(a.Title,{heading:6,style:{margin:0},children:"蒸馏状态"}),e.jsxs(m,{color:j?"green":"red",size:"small",children:["claude CLI: ",j?`✓ ${N??"available"}`:"✗ not found"]}),O&&e.jsxs(m,{size:"small",color:"arcoblue",children:["phase: ",O]}),c&&e.jsx(m,{color:"orange",size:"small",children:"running"}),(n==null?void 0:n.state)&&e.jsxs(a.Text,{type:"secondary",style:{fontSize:12},children:["completed: ",n.state.completed.length," / skipped: ",n.state.skipped.length]})]})}),e.jsxs(C,{bordered:!0,bodyStyle:{padding:16},children:[e.jsxs("div",{style:{display:"flex",gap:12,alignItems:"center",flexWrap:"wrap"},children:[e.jsx(L,{type:"primary",size:"large",disabled:c||!j,onClick:q,"data-testid":"distill-now-button",children:c?"蒸馏运行中…":"开始蒸馏 (Distill now)"}),e.jsx(L,{size:"default",disabled:c||!j,onClick:K,children:"重新拉取 + 蒸馏 (Refresh)"}),!j&&e.jsx(P,{type:"warning",showIcon:!0,style:{width:"100%",marginTop:4},content:e.jsxs("span",{children:[e.jsx("strong",{children:"claude CLI 未安装"})," —— 蒸馏走 ",e.jsx("code",{children:"child_process.spawn('claude', ['-p', '--agent', 'skill-distiller', ...])"}),"需要本机有 ",e.jsx("code",{children:"claude"})," binary。安装:",e.jsx("code",{style:{marginLeft:4},children:"brew install claude"})," 或",e.jsx("code",{style:{marginLeft:4},children:"npm i -g @anthropic-ai/claude-code"})]})}),e.jsx(a.Text,{type:"secondary",style:{fontSize:12,marginLeft:"auto"},children:"从 obra-superpowers / anthropics-skills / ECC 蒸馏 IT 通用 skill"})]}),e.jsx(W,{bordered:!1,activeKey:w?["adv"]:[],onChange:d=>g(x=>!x),style:{marginTop:12},children:e.jsx(W.Item,{header:"高级选项",name:"adv",children:e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"200px 1fr",gap:12,alignItems:"center"},children:[e.jsx(a.Text,{style:{fontSize:12},children:"评分阈值 (D1-D5 总分 ≥)"}),e.jsx("div",{style:{width:280},children:e.jsx(V,{value:z,onChange:d=>k(Array.isArray(d)?d[0]:d),min:0,max:5,step:.5,marks:{0:"0",3:"3.0",5:"5"}})}),e.jsx(a.Text,{style:{fontSize:12},children:"topic 上限 (本次)"}),e.jsx(Z,{value:v,onChange:d=>y(typeof d=="number"?d:4),min:1,max:50,style:{width:120}}),e.jsx(a.Text,{style:{fontSize:12},children:"跳过 topic id"}),e.jsx(X,{value:E,onChange:_,placeholder:"逗号或空格分隔,如 debug,test",style:{maxWidth:360}}),e.jsx(a.Text,{style:{fontSize:12},children:"重新生成全部"}),e.jsx("div",{children:e.jsx(ee,{checked:I,onChange:T})})]})})}),f&&e.jsx(P,{type:"error",content:f,style:{marginTop:12},closable:!0,onClose:()=>p(null)})]}),s&&e.jsx(ve,{runId:s,onTerminal:Q}),O==="done"&&B.length>0&&e.jsxs(C,{bordered:!0,bodyStyle:{padding:12},children:[e.jsxs(a.Title,{heading:6,style:{margin:"0 0 8px 0"},children:["蒸馏 review (",B.length,")"]}),e.jsxs(a.Text,{type:"secondary",style:{fontSize:12,display:"block",marginBottom:12},children:["对每张卡片:查看 diff + 评分 → 满意点 [Apply] 看 git status,不满意点 [Reject] 隐藏。 提交由你在终端 ",e.jsx("code",{children:"git add"})," + ",e.jsx("code",{children:"git commit"})," 完成。"]}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:12},children:B.map(d=>e.jsx(Ee,{file:d,onReject:J},d.id))})]}),e.jsx(je,{open:o,topicCap:v,onConfirm:U,onCancel:()=>{r(!1),u(null)}})]})}export{Oe as default};
|
|
2
|
+
//# sourceMappingURL=SkillsDistillTab-C7qaG8q3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillsDistillTab-C7qaG8q3.js","sources":["../../src/utils/distillApi.ts","../../src/components/distill/CostConfirmModal.tsx","../../src/components/distill/DistillProgress.tsx","../../src/components/distill/ReviewCard.tsx","../../src/components/distill/SkillsDistillTab.tsx"],"sourcesContent":["/**\n * Distill-related fetch helpers for the dashboard SPA.\n *\n * Mirrors the kbApi.ts pattern: read endpoints use plain fetch, write endpoints\n * use authFetch. All endpoints are loopback-only on the daemon side.\n */\n\nimport { authFetch } from './auth'\n\n// ── Status / cost-estimate ─────────────────────────────────────────────────\n\nexport interface DistillState {\n // R-A (spec 1851 §2.5): phase simplified to { idle | running | done | error }.\n // Legacy on-disk schemas with init/scoring/distilling/review_required are\n // normalised on the backend before returning here.\n phase: 'idle' | 'running' | 'done' | 'error'\n cacheRoot: string\n upstreamCommits: Record<string, string>\n // R-A: `pending` is deprecated and always empty; kept optional for\n // backwards-compat with state files written by pre-R-A daemons.\n pending?: string[]\n completed: string[]\n skipped: string[]\n rejected?: string[]\n lastRunAt?: string\n updatedAt: string\n}\n\nexport interface DistillStatusResponse {\n stateFileExists: boolean\n state: DistillState | null\n isBusy: boolean\n currentRunId: string | null\n lastRunId: string | null\n /**\n * spec 1851 R-A: claude CLI availability. R-A always returns false; R-B\n * adds real PATH detection via claude-cli-resolver.ts. UI gates the\n * \"开始蒸馏\" button on this flag once R-B lands.\n */\n claudeCliAvailable: boolean\n}\n\nexport async function getDistillStatus(): Promise<DistillStatusResponse> {\n const r = await fetch('/api/skills/distill/status')\n if (!r.ok) throw new Error(`status failed: ${r.status}`)\n return r.json()\n}\n\nexport interface DistillCostEstimate {\n candidateCount: number\n topicCap: number\n scorerInputTokens: number\n scorerOutputTokens: number\n distillerInputTokens: number\n distillerOutputTokens: number\n total: number\n}\n\nexport async function getDistillCostEstimate(topicCap = 4): Promise<DistillCostEstimate> {\n const r = await fetch(`/api/skills/distill/cost-estimate?topicCap=${topicCap}`)\n if (!r.ok) throw new Error(`cost-estimate failed: ${r.status}`)\n return r.json()\n}\n\n// ── Review ────────────────────────────────────────────────────────────────\n\nexport interface DistilledFile {\n id: string\n path: string\n itScore: number\n realDistillation: boolean\n}\n\nexport interface DistillReviewResponse {\n distilledFiles: DistilledFile[]\n pending: string[]\n state: DistillState | null\n}\n\nexport async function getDistillReview(): Promise<DistillReviewResponse> {\n const r = await fetch('/api/skills/distill/review')\n if (!r.ok) throw new Error(`review failed: ${r.status}`)\n return r.json()\n}\n\nexport interface DistillDiffResponse {\n topicId: string\n filePath: string\n distilledMarkdown: string\n frontmatter: {\n name?: string\n version?: string\n description?: string\n keywords?: string[]\n distilled_by?: string\n distilled_at?: string\n distilled_from?: Array<{\n upstream: string\n license?: string\n commit?: string\n paths?: string[]\n }>\n it_universal_score?: number\n it_universal_dims?: { d1: number; d2: number; d3: number; d4: number; d5: number }\n it_universal_rationale?: string\n [key: string]: unknown\n }\n upstreams: Array<{\n upstream: string\n path: string\n content: string | null\n }>\n}\n\nexport async function getDistillDiff(topicId: string): Promise<DistillDiffResponse> {\n const r = await fetch(`/api/skills/distill/review/${encodeURIComponent(topicId)}/diff`)\n if (r.status === 404) throw new Error('distilled_file_not_found')\n if (!r.ok) throw new Error(`diff failed: ${r.status}`)\n return r.json()\n}\n\n// ── Mutations ─────────────────────────────────────────────────────────────\n\nexport interface DistillRunBody {\n threshold?: number\n topicCap?: number\n skip?: string[]\n regenerateAll?: boolean\n}\n\nexport interface DistillRunResponse {\n runId: string\n streamUrl: string\n}\n\nexport async function startDistillInit(skipFetch = false): Promise<{ fetchResults: unknown[]; noticeWritten: boolean; catalogWritten: boolean }> {\n const r = await authFetch('/api/skills/distill/init', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ skipFetch }),\n })\n if (!r.ok) throw new Error(`init failed: ${r.status}`)\n return r.json()\n}\n\nexport async function startDistillRun(body: DistillRunBody): Promise<DistillRunResponse> {\n const r = await authFetch('/api/skills/distill/run', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n if (r.status === 409) throw new Error('distill_in_progress')\n if (!r.ok) throw new Error(`run failed: ${r.status}`)\n return r.json()\n}\n\nexport async function continueDistillRun(\n priorRunId: string,\n): Promise<DistillRunResponse> {\n const r = await authFetch(`/api/skills/distill/run/${encodeURIComponent(priorRunId)}/continue`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({}),\n })\n if (r.status === 409) throw new Error('distill_in_progress')\n if (!r.ok) throw new Error(`continue failed: ${r.status}`)\n return r.json()\n}\n\nexport async function refreshDistill(): Promise<DistillRunResponse> {\n const r = await authFetch('/api/skills/distill/refresh', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({}),\n })\n if (r.status === 409) throw new Error('distill_in_progress')\n if (!r.ok) throw new Error(`refresh failed: ${r.status}`)\n return r.json()\n}\n\nexport async function applyDistill(topicId: string): Promise<{ topicId: string; filePath: string; gitStatus: string; hint: string }> {\n const r = await authFetch(`/api/skills/distill/apply/${encodeURIComponent(topicId)}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({}),\n })\n if (!r.ok) throw new Error(`apply failed: ${r.status}`)\n return r.json()\n}\n\nexport async function cancelDistill(runId: string): Promise<void> {\n const r = await authFetch(`/api/skills/distill/cancel/${encodeURIComponent(runId)}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({}),\n })\n if (!r.ok) throw new Error(`cancel failed: ${r.status}`)\n}\n\n// ── SSE subscription ──────────────────────────────────────────────────────\n\n// R-D: `gate-paused` removed (R-B has no sample-approve gate)\nexport type DistillEventType =\n | 'connected'\n | 'start'\n | 'progress'\n | 'phase-changed'\n | 'skill-distilled'\n | 'done'\n | 'cancelled'\n | 'error'\n\nexport interface DistillEvent {\n type: DistillEventType\n at?: string\n message?: string\n phase?: DistillState['phase']\n completed?: number\n pending?: number\n skipped?: number\n topicId?: string\n distilledCount?: number\n pausedAtGate?: boolean\n errorMessage?: string\n runId?: string\n}\n\nconst DISTILL_EVENT_TYPES: DistillEventType[] = [\n 'connected',\n 'start',\n 'progress',\n 'phase-changed',\n 'skill-distilled',\n 'done',\n 'cancelled',\n 'error',\n]\n\nexport function subscribeDistill(\n runId: string,\n handlers: {\n onEvent: (ev: DistillEvent) => void\n onTerminal?: (ev: DistillEvent) => void\n },\n): () => void {\n const es = new EventSource(`/api/skills/distill/run/${encodeURIComponent(runId)}/stream`)\n const dispatch = (type: DistillEventType) => (msg: MessageEvent) => {\n let data: any = {}\n try {\n data = JSON.parse(msg.data || '{}')\n } catch {\n // ignore malformed\n }\n const ev: DistillEvent = { ...data, type }\n handlers.onEvent(ev)\n if (\n type === 'done' ||\n type === 'error' ||\n type === 'cancelled'\n ) {\n handlers.onTerminal?.(ev)\n es.close()\n }\n }\n for (const t of DISTILL_EVENT_TYPES) {\n es.addEventListener(t, dispatch(t))\n }\n return () => es.close()\n}\n\nexport function friendlyDistillError(message: string | undefined): string {\n if (!message) return '蒸馏失败,未知错误'\n const m = message.trim()\n if (m === 'distill_in_progress') return '已有蒸馏在进行中,请稍后再试'\n if (m.startsWith('run failed: 401') || m === 'unauthorized') return '未授权:请检查 daemon token'\n if (m.startsWith('run failed: 403')) return '无权限触发蒸馏(403,loopback only)'\n if (m.startsWith('run failed: 500')) return '后端蒸馏出错(500),请查看 daemon 日志'\n if (m.toLowerCase().includes('failed to fetch')) return '无法连接 daemon,请确认服务已启动'\n return m\n}\n","/**\n * CostConfirmModal — pre-flight cost estimate shown before kicking off a\n * distill run. Per spec Q3, displays estimated tokens (more honest than a\n * hard-coded $1.50). User must confirm to proceed.\n */\nimport { useEffect, useState } from 'react'\nimport Modal from '@arco-design/web-react/es/Modal'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport Skeleton from '@arco-design/web-react/es/Skeleton'\nimport { getDistillCostEstimate, type DistillCostEstimate } from '../../utils/distillApi'\n\ninterface Props {\n open: boolean\n topicCap: number\n onConfirm: () => void\n onCancel: () => void\n}\n\nexport default function CostConfirmModal({ open, topicCap, onConfirm, onCancel }: Props) {\n const [estimate, setEstimate] = useState<DistillCostEstimate | null>(null)\n const [loading, setLoading] = useState(false)\n const [err, setErr] = useState<string | null>(null)\n\n useEffect(() => {\n if (!open) return\n setLoading(true)\n setErr(null)\n getDistillCostEstimate(topicCap)\n .then(setEstimate)\n .catch((e) => setErr(String(e)))\n .finally(() => setLoading(false))\n }, [open, topicCap])\n\n const fmt = (n: number) => n.toLocaleString('en-US')\n\n return (\n <Modal\n visible={open}\n title=\"确认蒸馏成本\"\n onOk={onConfirm}\n onCancel={onCancel}\n okText={loading ? '加载中…' : '开始蒸馏'}\n cancelText=\"取消\"\n okButtonProps={{ disabled: loading || err !== null }}\n >\n {loading && <Skeleton animation text={{ rows: 3 }} />}\n {err && (\n <Typography.Text type=\"error\" style={{ fontSize: 13 }}>\n 无法获取成本估算:{err}\n </Typography.Text>\n )}\n {!loading && !err && estimate && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n <Typography.Text style={{ fontSize: 13 }}>\n 将对 <b>{estimate.candidateCount}</b> 个上游 skill 进行评分(Haiku),并蒸馏\n 最多 <b>{Math.min(estimate.candidateCount, estimate.topicCap)}</b> 个 topic(Sonnet)。\n </Typography.Text>\n <div\n style={{\n padding: 12,\n background: 'var(--color-fill-2)',\n borderRadius: 4,\n display: 'grid',\n gridTemplateColumns: '1fr auto',\n rowGap: 4,\n fontSize: 12,\n fontFamily: 'monospace',\n }}\n >\n <span>评分输入 (Haiku)</span>\n <span>{fmt(estimate.scorerInputTokens)} tok</span>\n <span>评分输出 (Haiku)</span>\n <span>{fmt(estimate.scorerOutputTokens)} tok</span>\n <span>蒸馏输入 (Sonnet)</span>\n <span>{fmt(estimate.distillerInputTokens)} tok</span>\n <span>蒸馏输出 (Sonnet)</span>\n <span>{fmt(estimate.distillerOutputTokens)} tok</span>\n <span style={{ fontWeight: 700, borderTop: '1px solid var(--color-border-1)', paddingTop: 4, marginTop: 4 }}>\n 总计\n </span>\n <span style={{ fontWeight: 700, borderTop: '1px solid var(--color-border-1)', paddingTop: 4, marginTop: 4 }}>\n {fmt(estimate.total)} tok\n </span>\n </div>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 实际成本取决于 LLM 提供商定价。请确认配置的 base_url 与计费模式。\n </Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n Sample-approve gate 在前 2 个蒸馏完成后暂停,等待 review 后再继续。\n </Typography.Text>\n </div>\n )}\n </Modal>\n )\n}\n","/**\n * DistillProgress — SSE-driven progress UI. Subscribes to\n * /api/skills/distill/run/:runId/stream and renders an event-by-event log\n * with phase + per-skill rows.\n */\nimport { useEffect, useRef, useState } from 'react'\nimport Card from '@arco-design/web-react/es/Card'\nimport Tag from '@arco-design/web-react/es/Tag'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport Button from '@arco-design/web-react/es/Button'\nimport { subscribeDistill, cancelDistill, type DistillEvent } from '../../utils/distillApi'\n\ninterface Props {\n runId: string\n onTerminal?: (ev: DistillEvent) => void\n}\n\nfunction phaseColor(phase?: string): string {\n // R-A (spec 1851 §2.5): phase simplified. Legacy values still possible if\n // an old on-disk state file slips through the normaliser; keep them mapped\n // for visual back-compat.\n switch (phase) {\n case 'idle': return 'gray'\n case 'running': return 'arcoblue'\n case 'done': return 'green'\n case 'error': return 'red'\n // legacy values still possible from stale state files\n case 'init': return 'gray'\n case 'scoring': return 'blue'\n case 'distilling': return 'arcoblue'\n case 'review_required': return 'orange'\n default: return 'gray'\n }\n}\n\nfunction eventBadge(type: DistillEvent['type']): { color: string; label: string } {\n switch (type) {\n case 'start': return { color: 'arcoblue', label: 'START' }\n case 'progress': return { color: 'gray', label: 'PROGRESS' }\n case 'phase-changed': return { color: 'blue', label: 'PHASE' }\n case 'skill-distilled': return { color: 'green', label: 'DISTILLED' }\n case 'done': return { color: 'green', label: 'DONE' }\n case 'cancelled': return { color: 'red', label: 'CANCELLED' }\n case 'error': return { color: 'red', label: 'ERROR' }\n default: return { color: 'gray', label: type.toUpperCase() }\n }\n}\n\nconst PHASE_HUMAN_ZH: Record<string, string> = {\n // R-A: simplified phases.\n idle: '空闲',\n running: '正在蒸馏 (R-A stub; R-B 接 claude CLI)…',\n done: '完成',\n error: '出错',\n // legacy back-compat\n init: '已初始化候选清单',\n scoring: '正在评分 (legacy phase)',\n distilling: '正在蒸馏 (legacy phase)',\n review_required: '已暂停 (legacy phase, R-A 已移除 gate)',\n}\n\nfunction phaseHuman(phase?: string): string {\n if (!phase) return '准备启动…'\n return PHASE_HUMAN_ZH[phase] ?? phase\n}\n\nexport default function DistillProgress({ runId, onTerminal }: Props) {\n const [events, setEvents] = useState<DistillEvent[]>([])\n const [terminal, setTerminal] = useState<DistillEvent | null>(null)\n const [cancelling, setCancelling] = useState(false)\n const [startedAt, setStartedAt] = useState<number>(() => Date.now())\n const [now, setNow] = useState<number>(() => Date.now())\n const onTerminalRef = useRef(onTerminal)\n\n useEffect(() => {\n onTerminalRef.current = onTerminal\n }, [onTerminal])\n\n useEffect(() => {\n setEvents([])\n setTerminal(null)\n setStartedAt(Date.now())\n const unsubscribe = subscribeDistill(runId, {\n onEvent: (ev) => setEvents((prev) => [...prev, ev]),\n onTerminal: (ev) => {\n setTerminal(ev)\n onTerminalRef.current?.(ev)\n },\n })\n return () => unsubscribe()\n }, [runId])\n\n // Tick every 1s while the run is in flight so 已运行 / 自上次事件 计时器\n // refresh smoothly. Stop ticking after terminal event to save CPU.\n useEffect(() => {\n if (terminal) return\n const interval = setInterval(() => setNow(Date.now()), 1000)\n return () => clearInterval(interval)\n }, [terminal])\n\n const handleCancel = async () => {\n setCancelling(true)\n try {\n await cancelDistill(runId)\n } catch {\n // best-effort\n } finally {\n setCancelling(false)\n }\n }\n\n const lastPhaseEvent = [...events].reverse().find((e) => e.phase)\n const lastPhase = lastPhaseEvent?.phase\n\n const skills = events.filter((e) => e.type === 'skill-distilled')\n\n const elapsedSec = Math.max(0, Math.floor((now - startedAt) / 1000))\n const lastEventAt = events.length > 0 && events[events.length - 1].at\n ? new Date(events[events.length - 1].at!).getTime()\n : startedAt\n const sinceLastEventSec = Math.max(0, Math.floor((now - lastEventAt) / 1000))\n\n // R-C: progress events carry `message: \"chars=N\"` and optional `topicId`.\n // Show the current chars accumulator + which topic the agent is on, so the\n // user sees real motion even mid-LLM-stream.\n const lastProgressEvent = [...events].reverse().find((e) => e.type === 'progress')\n const currentTopicId = lastProgressEvent?.topicId\n const currentCharCount = (() => {\n const m = lastProgressEvent?.message?.match(/chars=(\\d+)/)\n return m ? parseInt(m[1], 10) : null\n })()\n\n return (\n <Card\n bordered\n bodyStyle={{ padding: 16 }}\n data-testid=\"distill-progress\"\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12, flexWrap: 'wrap' }}>\n <Typography.Title heading={6} style={{ margin: 0 }}>蒸馏进度</Typography.Title>\n <Tag color={phaseColor(lastPhase)} size=\"small\">phase: {lastPhase ?? 'starting'}</Tag>\n <Tag size=\"small\" style={{ fontFamily: 'monospace' }}>{runId}</Tag>\n {!terminal && (\n <Tag size=\"small\" color=\"gray\">\n 已运行 {elapsedSec}s\n {sinceLastEventSec > 5 && ` · 自上次事件 ${sinceLastEventSec}s`}\n </Tag>\n )}\n <div style={{ marginLeft: 'auto' }}>\n {!terminal && (\n <Button\n size=\"small\"\n status=\"danger\"\n loading={cancelling}\n onClick={handleCancel}\n >\n 取消\n </Button>\n )}\n </div>\n </div>\n\n {/* Phase-aware status line (always visible while running) */}\n {!terminal && (\n <div style={{ marginBottom: 12, padding: '8px 12px', background: 'var(--color-fill-1)', borderRadius: 4 }}>\n <Typography.Text style={{ fontSize: 13 }}>\n <span style={{ display: 'inline-block', width: 8, height: 8, borderRadius: '50%', background: '#3491fa', marginRight: 8, animation: 'pulse 1.5s ease-in-out infinite' }} />\n {phaseHuman(lastPhase)}\n {currentTopicId && (\n <Tag size=\"small\" color=\"arcoblue\" style={{ marginLeft: 8 }}>\n topic: {currentTopicId}\n </Tag>\n )}\n {currentCharCount != null && (\n <Tag size=\"small\" color=\"gray\" style={{ marginLeft: 4 }}>\n {currentCharCount.toLocaleString()} chars\n </Tag>\n )}\n {sinceLastEventSec > 30 && (\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, marginLeft: 8 }}>\n (LLM 调用可能需要 30-90s 完成,请耐心等待)\n </Typography.Text>\n )}\n </Typography.Text>\n </div>\n )}\n\n {skills.length > 0 && (\n <div style={{ marginBottom: 12 }}>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 已蒸馏 {skills.length} 个 skill:\n </Typography.Text>\n <ul style={{ margin: '4px 0 0 0', paddingLeft: 20, fontSize: 13 }}>\n {skills.map((ev, i) => (\n <li key={i} style={{ fontFamily: 'monospace' }}>{ev.topicId}</li>\n ))}\n </ul>\n </div>\n )}\n\n <div\n style={{\n maxHeight: 240,\n overflowY: 'auto',\n fontSize: 12,\n fontFamily: 'monospace',\n background: 'var(--color-fill-1)',\n padding: 8,\n borderRadius: 4,\n }}\n >\n {events.length === 0 && (\n <Typography.Text type=\"secondary\">\n 等待第一个 SSE 事件…(init/scoring 阶段无 state 变更则没有事件,phase 变化会立刻 push)\n </Typography.Text>\n )}\n {events.map((ev, i) => {\n const badge = eventBadge(ev.type)\n return (\n <div key={i} style={{ display: 'flex', gap: 8, lineHeight: '20px' }}>\n <Tag color={badge.color} size=\"small\" style={{ minWidth: 78, textAlign: 'center' }}>\n {badge.label}\n </Tag>\n <span style={{ flex: 1 }}>\n {ev.topicId ? `${ev.topicId} ` : ''}\n {ev.message ?? ''}\n {ev.errorMessage ? ` — ${ev.errorMessage}` : ''}\n {ev.completed != null ? ` (completed=${ev.completed}, pending=${ev.pending ?? '?'})` : ''}\n </span>\n </div>\n )\n })}\n </div>\n </Card>\n )\n}\n","/**\n * ReviewCard — one card per distilled skill. Shows:\n * - Header: topic id, IT-universal score (large), realDistillation badge\n * - 5-axis Radar chart (D1-D5 dims)\n * - Side-by-side line diff: upstream original (left) vs distilled (right)\n * - Attribution chips: upstream URLs + license + commit\n * - Actions: [Apply] (view git status) [Reject] (local-only: hide row)\n *\n * Diff library: jsdiff (`diff` package, ~30 kB gz).\n */\nimport { useState } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport Card from '@arco-design/web-react/es/Card'\nimport Tag from '@arco-design/web-react/es/Tag'\nimport Button from '@arco-design/web-react/es/Button'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport Skeleton from '@arco-design/web-react/es/Skeleton'\nimport Modal from '@arco-design/web-react/es/Modal'\nimport { Radar, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, ResponsiveContainer } from 'recharts'\nimport { diffLines, type Change } from 'diff'\nimport {\n getDistillDiff,\n applyDistill,\n type DistilledFile,\n type DistillDiffResponse,\n} from '../../utils/distillApi'\n\ninterface Props {\n file: DistilledFile\n onReject?: (id: string) => void\n}\n\nfunction ScoreBadge({ score }: { score: number }) {\n let color = 'gray'\n if (score >= 4.0) color = 'green'\n else if (score >= 3.0) color = 'arcoblue'\n else color = 'orange'\n return (\n <Tag color={color} size=\"medium\" style={{ fontSize: 14, fontWeight: 700 }}>\n {score.toFixed(1)} / 5\n </Tag>\n )\n}\n\nfunction DimRadar({ dims }: { dims: { d1: number; d2: number; d3: number; d4: number; d5: number } }) {\n const data = [\n { axis: 'D1 多语言', value: dims.d1 },\n { axis: 'D2 SDLC', value: dims.d2 },\n { axis: 'D3 抽象层', value: dims.d3 },\n { axis: 'D4 contextfit', value: dims.d4 },\n { axis: 'D5 可注入', value: dims.d5 },\n ]\n return (\n <div style={{ width: 220, height: 180 }}>\n <ResponsiveContainer>\n <RadarChart data={data} outerRadius=\"70%\">\n <PolarGrid />\n <PolarAngleAxis dataKey=\"axis\" tick={{ fontSize: 10 }} />\n <PolarRadiusAxis angle={90} domain={[0, 1]} tick={{ fontSize: 9 }} />\n <Radar name=\"score\" dataKey=\"value\" stroke=\"#165dff\" fill=\"#165dff\" fillOpacity={0.4} />\n </RadarChart>\n </ResponsiveContainer>\n </div>\n )\n}\n\nfunction DiffPane({ left, right }: { left: string; right: string }) {\n const changes: Change[] = diffLines(left, right)\n\n return (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: 8,\n maxHeight: 360,\n overflowY: 'auto',\n fontFamily: 'monospace',\n fontSize: 11,\n lineHeight: '16px',\n background: 'var(--color-fill-1)',\n padding: 8,\n borderRadius: 4,\n }}\n >\n <div>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginBottom: 4 }}>\n Upstream (原始)\n </Typography.Text>\n <pre style={{ margin: 0, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n {changes.map((c, i) => {\n if (c.added) return null\n const bg = c.removed ? 'rgba(245, 63, 63, 0.12)' : 'transparent'\n return (\n <span key={i} style={{ background: bg, display: 'block' }}>{c.value}</span>\n )\n })}\n </pre>\n </div>\n <div>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, display: 'block', marginBottom: 4 }}>\n Distilled (蒸馏后)\n </Typography.Text>\n <pre style={{ margin: 0, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n {changes.map((c, i) => {\n if (c.removed) return null\n const bg = c.added ? 'rgba(0, 180, 42, 0.12)' : 'transparent'\n return (\n <span key={i} style={{ background: bg, display: 'block' }}>{c.value}</span>\n )\n })}\n </pre>\n </div>\n </div>\n )\n}\n\nexport default function ReviewCard({ file, onReject }: Props) {\n const [applyResult, setApplyResult] = useState<{ open: boolean; status: string; hint: string } | null>(null)\n const [applying, setApplying] = useState(false)\n\n // Use bare topicId (strip 'distilled-' prefix) for the API path.\n const topicId = file.id.replace(/^distilled-/, '')\n\n const { data, isLoading, isError, error } = useQuery<DistillDiffResponse>({\n queryKey: ['distill-diff', file.id],\n queryFn: () => getDistillDiff(topicId),\n staleTime: 60_000,\n })\n\n const handleApply = async () => {\n setApplying(true)\n try {\n const r = await applyDistill(topicId)\n setApplyResult({ open: true, status: r.gitStatus, hint: r.hint })\n } catch (e) {\n setApplyResult({ open: true, status: 'error', hint: String(e) })\n } finally {\n setApplying(false)\n }\n }\n\n if (isLoading) {\n return (\n <Card bordered>\n <Skeleton animation text={{ rows: 5 }} />\n </Card>\n )\n }\n if (isError || !data) {\n return (\n <Card bordered>\n <Typography.Text type=\"error\">加载 diff 失败: {String(error)}</Typography.Text>\n </Card>\n )\n }\n\n const fm = data.frontmatter\n const dims = fm.it_universal_dims ?? { d1: 0, d2: 0, d3: 0, d4: 0, d5: 0 }\n const primaryUpstream = data.upstreams.find((u) => u.content)\n const upstreamContent = primaryUpstream?.content ?? '(upstream cache 不可读)'\n\n return (\n <Card\n bordered\n bodyStyle={{ padding: 16 }}\n data-testid=\"distill-review-card\"\n data-topic-id={file.id}\n >\n {/* Header */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap', marginBottom: 12 }}>\n <Typography.Title heading={6} style={{ margin: 0, fontFamily: 'monospace' }}>{file.id}</Typography.Title>\n <ScoreBadge score={file.itScore} />\n {file.realDistillation ? (\n <Tag color=\"green\" size=\"small\">real distill</Tag>\n ) : (\n <Tag color=\"orange\" size=\"small\">stub — needs real distillation</Tag>\n )}\n </div>\n\n {/* Attribution chips */}\n <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 12 }}>\n {(fm.distilled_from ?? []).map((src, i) => (\n <Tag key={i} bordered size=\"small\" style={{ fontFamily: 'monospace', fontSize: 10 }}>\n {src.upstream} · {src.license ?? '?'} @{(src.commit ?? '').slice(0, 7) || 'unknown'}\n </Tag>\n ))}\n {fm.distilled_by && (\n <Tag size=\"small\" color=\"arcoblue\">by: {fm.distilled_by}</Tag>\n )}\n </div>\n\n {/* Radar + diff side by side */}\n <div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: 16, marginBottom: 12 }}>\n <DimRadar dims={dims} />\n <div style={{ minWidth: 0 }}>\n {fm.it_universal_rationale && (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 8 }}>\n <b>评分 rationale:</b> {fm.it_universal_rationale}\n </Typography.Text>\n )}\n {fm.description && (\n <Typography.Text style={{ fontSize: 12, display: 'block', marginBottom: 4 }}>\n {fm.description}\n </Typography.Text>\n )}\n </div>\n </div>\n\n {/* Diff */}\n <DiffPane left={upstreamContent} right={data.distilledMarkdown} />\n\n {/* Actions */}\n <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>\n <Button type=\"primary\" size=\"small\" loading={applying} onClick={handleApply}>\n 查看 git status (Apply)\n </Button>\n <Button size=\"small\" status=\"warning\" onClick={() => onReject?.(file.id)}>\n 隐藏 (Reject)\n </Button>\n <Typography.Text type=\"secondary\" style={{ fontSize: 11, marginLeft: 'auto', alignSelf: 'center' }}>\n {file.path}\n </Typography.Text>\n </div>\n\n <Modal\n visible={applyResult?.open === true}\n title=\"git status\"\n onCancel={() => setApplyResult(null)}\n onOk={() => setApplyResult(null)}\n okText=\"知道了\"\n cancelText=\"关闭\"\n >\n <pre\n style={{\n fontFamily: 'monospace',\n fontSize: 12,\n background: 'var(--color-fill-2)',\n padding: 8,\n borderRadius: 4,\n whiteSpace: 'pre-wrap',\n }}\n >\n {applyResult?.status}\n </pre>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n {applyResult?.hint}\n </Typography.Text>\n </Modal>\n </Card>\n )\n}\n","/**\n * SkillsDistillTab — primary content of /context?tab=distill.\n *\n * R-A simplification (spec 1851):\n * - Removed API key + useAgent state (no provider; no env toggle).\n * - Replaced `apiKeyConfigured` UI with `claudeCliAvailable` (R-A\n * hard-codes false from backend; R-B turns it into a real probe).\n * - Removed \"继续蒸馏\" (Continue past gate) button — no sample-approve gate.\n */\nimport { useState, useMemo, useEffect } from 'react'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport Card from '@arco-design/web-react/es/Card'\nimport Button from '@arco-design/web-react/es/Button'\nimport Tag from '@arco-design/web-react/es/Tag'\nimport Typography from '@arco-design/web-react/es/Typography'\nimport Input from '@arco-design/web-react/es/Input'\nimport Slider from '@arco-design/web-react/es/Slider'\nimport InputNumber from '@arco-design/web-react/es/InputNumber'\nimport Switch from '@arco-design/web-react/es/Switch'\nimport Skeleton from '@arco-design/web-react/es/Skeleton'\nimport Alert from '@arco-design/web-react/es/Alert'\nimport Collapse from '@arco-design/web-react/es/Collapse'\nimport {\n getDistillStatus,\n getDistillReview,\n startDistillRun,\n refreshDistill,\n friendlyDistillError,\n type DistillEvent,\n} from '../../utils/distillApi'\nimport CostConfirmModal from './CostConfirmModal'\nimport DistillProgress from './DistillProgress'\nimport ReviewCard from './ReviewCard'\n\nexport default function SkillsDistillTab() {\n const queryClient = useQueryClient()\n const [activeRunId, setActiveRunId] = useState<string | null>(null)\n const [costModalOpen, setCostModalOpen] = useState(false)\n const [pendingAction, setPendingAction] = useState<'run' | 'refresh' | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [rejectedIds, setRejectedIds] = useState<Set<string>>(new Set())\n\n // Advanced options\n const [advancedOpen, setAdvancedOpen] = useState(false)\n const [threshold, setThreshold] = useState(3.0)\n const [topicCap, setTopicCap] = useState(4)\n const [skipText, setSkipText] = useState('')\n const [regenerateAll, setRegenerateAll] = useState(false)\n\n const statusQuery = useQuery({\n queryKey: ['distill-status'],\n queryFn: getDistillStatus,\n refetchInterval: activeRunId ? 4_000 : 30_000,\n staleTime: 2_000,\n })\n\n const reviewQuery = useQuery({\n queryKey: ['distill-review'],\n queryFn: getDistillReview,\n staleTime: 10_000,\n })\n\n const status = statusQuery.data\n const isBusy = status?.isBusy ?? false\n const claudeCliAvailable = status?.claudeCliAvailable ?? false\n const claudeCliPath = (status as { claudeCliPath?: string | null } | undefined)?.claudeCliPath ?? null\n const phase = status?.state?.phase ?? null\n\n const reviewFiles = useMemo(() => {\n const files = reviewQuery.data?.distilledFiles ?? []\n return files.filter((f) => !rejectedIds.has(f.id))\n }, [reviewQuery.data, rejectedIds])\n\n // If status reports a busy job but we have no activeRunId, adopt it\n // (e.g. page reload mid-run).\n useEffect(() => {\n if (isBusy && status?.currentRunId && !activeRunId) {\n setActiveRunId(status.currentRunId)\n }\n }, [isBusy, status?.currentRunId, activeRunId])\n\n const handleDistillNowClick = () => {\n setError(null)\n setPendingAction('run')\n setCostModalOpen(true)\n }\n\n const handleRefreshClick = () => {\n setError(null)\n setPendingAction('refresh')\n setCostModalOpen(true)\n }\n\n const handleCostConfirm = async () => {\n setCostModalOpen(false)\n if (!pendingAction) return\n try {\n const skipList = skipText\n .split(/[,\\s]+/)\n .map((s) => s.trim())\n .filter((s) => /^[a-z0-9][a-z0-9-]*$/.test(s))\n if (pendingAction === 'run') {\n const r = await startDistillRun({\n threshold,\n topicCap,\n skip: skipList.length > 0 ? skipList : undefined,\n regenerateAll,\n })\n setActiveRunId(r.runId)\n } else {\n const r = await refreshDistill()\n setActiveRunId(r.runId)\n }\n } catch (e) {\n setError(friendlyDistillError(e instanceof Error ? e.message : String(e)))\n } finally {\n setPendingAction(null)\n }\n }\n\n const handleTerminal = (_ev: DistillEvent) => {\n // Refresh status + review after terminal event. R-D: gate-paused removed,\n // so all terminal events (done/error/cancelled) unconditionally clear\n // activeRunId.\n queryClient.invalidateQueries({ queryKey: ['distill-status'] })\n queryClient.invalidateQueries({ queryKey: ['distill-review'] })\n setTimeout(() => setActiveRunId(null), 1500)\n }\n\n const handleReject = (id: string) => {\n setRejectedIds((prev) => new Set(prev).add(id))\n }\n\n if (statusQuery.isLoading) {\n return <Skeleton animation text={{ rows: 4 }} />\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {/* Status card */}\n <Card bordered bodyStyle={{ padding: 12 }}>\n <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>\n <Typography.Title heading={6} style={{ margin: 0 }}>蒸馏状态</Typography.Title>\n <Tag color={claudeCliAvailable ? 'green' : 'red'} size=\"small\">\n claude CLI: {claudeCliAvailable ? `✓ ${claudeCliPath ?? 'available'}` : '✗ not found'}\n </Tag>\n {phase && (\n <Tag size=\"small\" color=\"arcoblue\">phase: {phase}</Tag>\n )}\n {isBusy && <Tag color=\"orange\" size=\"small\">running</Tag>}\n {status?.state && (\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n completed: {status.state.completed.length} / skipped: {status.state.skipped.length}\n </Typography.Text>\n )}\n </div>\n </Card>\n\n {/* Primary action card */}\n <Card bordered bodyStyle={{ padding: 16 }}>\n <div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>\n <Button\n type=\"primary\"\n size=\"large\"\n disabled={isBusy || !claudeCliAvailable}\n onClick={handleDistillNowClick}\n data-testid=\"distill-now-button\"\n >\n {isBusy ? '蒸馏运行中…' : '开始蒸馏 (Distill now)'}\n </Button>\n <Button\n size=\"default\"\n disabled={isBusy || !claudeCliAvailable}\n onClick={handleRefreshClick}\n >\n 重新拉取 + 蒸馏 (Refresh)\n </Button>\n {!claudeCliAvailable && (\n <Alert\n type=\"warning\"\n showIcon\n style={{ width: '100%', marginTop: 4 }}\n content={\n <span>\n <strong>claude CLI 未安装</strong> ——\n 蒸馏走 <code>child_process.spawn('claude', ['-p', '--agent', 'skill-distiller', ...])</code>\n 需要本机有 <code>claude</code> binary。安装:\n <code style={{ marginLeft: 4 }}>brew install claude</code> 或\n <code style={{ marginLeft: 4 }}>npm i -g @anthropic-ai/claude-code</code>\n </span>\n }\n />\n )}\n <Typography.Text type=\"secondary\" style={{ fontSize: 12, marginLeft: 'auto' }}>\n 从 obra-superpowers / anthropics-skills / ECC 蒸馏 IT 通用 skill\n </Typography.Text>\n </div>\n\n {/* Advanced disclosure */}\n <Collapse\n bordered={false}\n activeKey={advancedOpen ? ['adv'] : []}\n onChange={(_keys) => setAdvancedOpen((v) => !v)}\n style={{ marginTop: 12 }}\n >\n <Collapse.Item header=\"高级选项\" name=\"adv\">\n <div style={{ display: 'grid', gridTemplateColumns: '200px 1fr', gap: 12, alignItems: 'center' }}>\n <Typography.Text style={{ fontSize: 12 }}>评分阈值 (D1-D5 总分 ≥)</Typography.Text>\n <div style={{ width: 280 }}>\n <Slider\n value={threshold}\n onChange={(v) => setThreshold(Array.isArray(v) ? v[0] : v)}\n min={0}\n max={5}\n step={0.5}\n marks={{ 0: '0', 3: '3.0', 5: '5' }}\n />\n </div>\n\n <Typography.Text style={{ fontSize: 12 }}>topic 上限 (本次)</Typography.Text>\n <InputNumber\n value={topicCap}\n onChange={(v) => setTopicCap(typeof v === 'number' ? v : 4)}\n min={1}\n max={50}\n style={{ width: 120 }}\n />\n\n <Typography.Text style={{ fontSize: 12 }}>跳过 topic id</Typography.Text>\n <Input\n value={skipText}\n onChange={setSkipText}\n placeholder=\"逗号或空格分隔,如 debug,test\"\n style={{ maxWidth: 360 }}\n />\n\n <Typography.Text style={{ fontSize: 12 }}>重新生成全部</Typography.Text>\n <div>\n <Switch checked={regenerateAll} onChange={setRegenerateAll} />\n </div>\n </div>\n </Collapse.Item>\n </Collapse>\n\n {error && (\n <Alert type=\"error\" content={error} style={{ marginTop: 12 }} closable onClose={() => setError(null)} />\n )}\n </Card>\n\n {/* Active progress */}\n {activeRunId && (\n <DistillProgress runId={activeRunId} onTerminal={handleTerminal} />\n )}\n\n {/* Review cards */}\n {phase === 'done' && reviewFiles.length > 0 && (\n <Card bordered bodyStyle={{ padding: 12 }}>\n <Typography.Title heading={6} style={{ margin: '0 0 8px 0' }}>\n 蒸馏 review ({reviewFiles.length})\n </Typography.Title>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12, display: 'block', marginBottom: 12 }}>\n 对每张卡片:查看 diff + 评分 → 满意点 [Apply] 看 git status,不满意点 [Reject] 隐藏。\n 提交由你在终端 <code>git add</code> + <code>git commit</code> 完成。\n </Typography.Text>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {reviewFiles.map((f) => (\n <ReviewCard key={f.id} file={f} onReject={handleReject} />\n ))}\n </div>\n </Card>\n )}\n\n {/* Cost confirm */}\n <CostConfirmModal\n open={costModalOpen}\n topicCap={topicCap}\n onConfirm={handleCostConfirm}\n onCancel={() => {\n setCostModalOpen(false)\n setPendingAction(null)\n }}\n />\n </div>\n )\n}\n"],"names":["getDistillStatus","r","getDistillCostEstimate","topicCap","getDistillReview","getDistillDiff","topicId","startDistillRun","body","authFetch","refreshDistill","applyDistill","cancelDistill","runId","DISTILL_EVENT_TYPES","subscribeDistill","handlers","es","dispatch","type","msg","data","ev","_a","t","friendlyDistillError","message","m","CostConfirmModal","open","onConfirm","onCancel","estimate","setEstimate","useState","loading","setLoading","err","setErr","useEffect","e","fmt","n","jsxs","Modal","jsx","Skeleton","Typography","phaseColor","phase","eventBadge","PHASE_HUMAN_ZH","phaseHuman","DistillProgress","onTerminal","events","setEvents","terminal","setTerminal","cancelling","setCancelling","startedAt","setStartedAt","now","setNow","onTerminalRef","useRef","unsubscribe","prev","interval","handleCancel","lastPhaseEvent","lastPhase","skills","elapsedSec","lastEventAt","sinceLastEventSec","lastProgressEvent","currentTopicId","currentCharCount","Card","Tag","Button","i","badge","ScoreBadge","score","color","DimRadar","dims","ResponsiveContainer","RadarChart","PolarGrid","PolarAngleAxis","PolarRadiusAxis","Radar","DiffPane","left","right","changes","diffLines","c","bg","ReviewCard","file","onReject","applyResult","setApplyResult","applying","setApplying","isLoading","isError","error","useQuery","handleApply","fm","primaryUpstream","u","upstreamContent","src","SkillsDistillTab","queryClient","useQueryClient","activeRunId","setActiveRunId","costModalOpen","setCostModalOpen","pendingAction","setPendingAction","setError","rejectedIds","setRejectedIds","advancedOpen","setAdvancedOpen","threshold","setThreshold","setTopicCap","skipText","setSkipText","regenerateAll","setRegenerateAll","statusQuery","reviewQuery","status","isBusy","claudeCliAvailable","claudeCliPath","reviewFiles","useMemo","f","handleDistillNowClick","handleRefreshClick","handleCostConfirm","skipList","s","handleTerminal","_ev","handleReject","id","Alert","Collapse","_keys","v","Slider","InputNumber","Input","Switch"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
var ut=Object.defineProperty;var ft=(t,s,r)=>s in t?ut(t,s,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[s]=r;var Fe=(t,s,r)=>ft(t,typeof s!="symbol"?s+"":s,r);import{j as e,r as I}from"./react-vendor-tkvCrao7.js";import{L as De,d as ze}from"./react-router-JVUrkhdd.js";import{b as Ae,c as he,u as ne,k as Le}from"./query-S6X1S7K9.js";import{u as z,b as p,T as o,v as Te,w as gt,x as He,r as ht,y as xe,D as Oe,F as yt,H as pe,e as ee,t as D,J as Ce,n as jt,K as Ue,N as qe,O as K,Q as bt,U as Ke,V as fe,W as Ie,s as vt,d as me,X as wt,Y as St,E as de,Z as Ee,_ as we,$ as _t,p as kt,a0 as zt,a1 as We,a2 as Tt,a3 as Ct,a as It,a4 as $t,a5 as Mt,a6 as Bt,R as ie,o as Ft,a7 as Lt,I as Et,a8 as le,a9 as Wt}from"./arco-Bhi3a6Qp.js";import{a as L,f as Je,u as Rt}from"./index-BIYnq1Dx.js";import{P as Nt}from"./ProjectSwitcher-D3lZMFd3.js";import{a as Pt}from"./auth-Bnf8ZcqN.js";import{f as se}from"./date-fns-sbWH3_uq.js";import{N as Dt}from"./vendor-DWgdB1eY.js";import{c as At,F as Ht,G as Ot,M as Ut}from"./lucide-CnlPQoG8.js";import{b as qt,o as Kt}from"./outcome-DUn1NjlC.js";const X=80;function Jt(t,s){if(!(t!=null&&t.trim()))return"(无标题)";const r=t.trim();if(r.startsWith("<task-notification>")){const n=r.match(/<summary>([\s\S]*?)<\/summary>/);if(n&&n[1].trim()){const i=n[1].trim();return i.length>X?i.slice(0,X)+"…":i}if(s){const i=s.match(/<summary>([\s\S]*?)<\/summary>/);if(i&&i[1].trim()){const x=i[1].trim();return x.length>X?x.slice(0,X)+"…":x}return`(子任务回调) — ${s.trim().slice(0,60).replace(/\s+/g," ")}${s.trim().length>60?"…":""}`}return"(子任务回调)"}return r.length>X?r.slice(0,X)+"…":r}function Gt(t){switch(t){case"success":return e.jsx(xe,{style:{color:"var(--cf-tag-green)"}});case"partial":return e.jsx(ht,{style:{color:"var(--cf-tag-orange)"}});case"failed":return e.jsx(He,{style:{color:"var(--cf-tag-red)"}});case"abandoned":return e.jsx(gt,{style:{color:"var(--color-text-3)"}});default:return e.jsx(Te,{style:{color:"var(--cf-tag-blue)"},spin:!0})}}function Vt(t){switch(t){case"success":return"green";case"partial":return"orange";case"failed":return"red";case"abandoned":return"gray";default:return"arcoblue"}}function Qt({banner:t,taskId:s,startedAt:r}){const n=Vt(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:Gt(t.outcome)}),e.jsx(p,{color:n,size:"default","data-testid":"tier-banner-outcome",children:t.outcomeLabel}),e.jsx(o.Text,{style:{fontSize:12,color:"var(--color-text-2)"},children:t.pathLabel}),e.jsx(o.Text,{style:{fontSize:12,color:"var(--color-text-3)"},children:"·"}),e.jsxs(o.Text,{style:{fontSize:12},children:[t.fileCount," 文件"]}),e.jsx(o.Text,{style:{fontSize:12,color:"var(--color-text-3)"},children:"·"}),e.jsxs(o.Text,{style:{fontSize:12},children:[t.commitCount," commit"]}),e.jsx(o.Text,{style:{fontSize:12,color:"var(--color-text-3)"},children:"·"}),e.jsx(o.Text,{style:{fontSize:12},children:t.durationLabel}),t.agentSpawnCount>0&&e.jsxs(e.Fragment,{children:[e.jsx(o.Text,{style:{fontSize:12,color:"var(--color-text-3)"},children:"·"}),e.jsxs(o.Text,{style:{fontSize:12},children:[t.agentSpawnCount," agent spawn"]})]}),e.jsx("span",{style:{flex:1}}),e.jsxs(o.Text,{type:"secondary",style:{fontSize:11},title:s,children:[s.slice(0,8)," · ",r.slice(0,19).replace("T"," ")]})]})})}function ge({cardId:t,idx:s,title:r,oneLine:n,rightChip:i,expanded:l,onToggle:x,detail:m}){return e.jsxs(z,{bordered:!0,"data-testid":`decision-card-${t}`,"data-expanded":l?"1":"0",style:{marginBottom:8},bodyStyle:{padding:0},children:[e.jsxs("div",{role:"button",tabIndex:0,"aria-expanded":l,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:l?e.jsx(Oe,{}):e.jsx(yt,{})}),e.jsx(o.Text,{style:{fontSize:12,color:"var(--color-text-3)",minWidth:14},children:s}),e.jsx(o.Text,{style:{fontSize:13,fontWeight:600,minWidth:92},children:r}),e.jsx(o.Text,{type:"secondary",style:{fontSize:12,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"var(--color-text-1)"},title:n,children:n}),i&&e.jsx("span",{style:{flexShrink:0},children:i})]}),l&&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:m})]})}function Se(t){if(!t)return null;try{return JSON.parse(t)}catch{return null}}function Ge(t){var W,F,O,U,$,k;const s=((F=(W=t.userPrompts[0])==null?void 0:W.content)==null?void 0:F.trim())||null,r=((O=t.userPrompts[0])==null?void 0:O.timestamp)??null,n=t.injections.find(h=>h.source_handler.includes(":intent"))??null,i=Se(n==null?void 0:n.metadata_json),l=i?{workflow_type:i.workflow_type,confidence:i.confidence,suggested_agent:i.suggested_agent,layer:i.layer,reasoning:i.reasoning}:null,x=t.injections.find(h=>h.source_handler==="UserPromptSubmitHandler:workflow_rec")??null,m=Se(x==null?void 0:x.metadata_json),u=m?{rule_id:m.rule_id,recommended_workflow:m.recommended_workflow,recommended_agent_type:m.recommended_agent_type,matched_keywords:Array.isArray(m.matched_keywords)?m.matched_keywords:void 0}:null,b=t.injections.filter(h=>h.source_handler==="UserPromptSubmitHandler:kb"),a=new Map;for(const h of b){const S=Se(h.metadata_json);if(Array.isArray(S)){for(const _ of S)if(_&&typeof _.name=="string"){const R=((U=a.get(_.name))==null?void 0:U.score)??0,f=typeof _.score=="number"?_.score:0;a.set(_.name,{score:Math.max(R,f),matched:Array.isArray(_.matched_keywords)?_.matched_keywords:void 0})}}}const v=Array.from(a.entries()).sort((h,S)=>S[1].score-h[1].score).slice(0,8).map(([h,S])=>({name:h,score:S.score||void 0,matched:S.matched})),y=t.skillInvocations.slice(0,16).map(h=>({skill_id:h.skill_id,reason:h.reason??""})),w=t.timeline.filter(h=>{var S;return h.is_agent_call&&((S=h.agent_detail)==null?void 0:S.subagent_type)}).map(h=>{var S,_,R,f;return{subagent_type:(S=h.agent_detail)==null?void 0:S.subagent_type,name:(_=h.agent_detail)==null?void 0:_.name,promptPreview:(f=(R=h.agent_detail)==null?void 0:R.prompt)==null?void 0:f.slice(0,200)}}),g=new Map;for(const h of t.timeline)if((h.tool_name==="Edit"||h.tool_name==="Write")&&(($=h.input)!=null&&$.file_path)){const S=h.input.file_path;g.set(S,(g.get(S)??0)+1)}const T=Array.from(g.entries()).sort((h,S)=>S[1]-h[1]).map(([h,S])=>({path:h,count:S})),C=T.length,E=[];for(const h of t.timeline){if(h.tool_name!=="Bash")continue;const S=(k=h.input)==null?void 0:k.command;if(S&&/\bgit\s+commit\b/.test(S)){const _=h.output,R=typeof _=="string"?_:(_==null?void 0:_.stdout)??(_==null?void 0:_.output)??JSON.stringify(_??{}),f=String(R).match(/\b[a-f0-9]{7,40}\b/);f?E.push(f[0]):E.push(`(commit @ ${h.timestamp.slice(11,19)})`)}}const H=t.outcome?{label:t.outcome,reason:t.outcome_reason,commit_count:t.commit_count}:null;return{prompt:s,promptTimestamp:r,intent:l,intentInj:n,workflowRec:u,workflowRecInj:x,recs:t.workflowRecommendations,kbHits:v,kbInjs:b,skills:y,spawned:w,filesChanged:C,fileList:T,commits:E,outcome:H,specs:t.pendingSpecs??[]}}function Ve(t){const s=!t.intent&&t.kbHits.length===0,r=t.recs.length===0&&t.specs.length===0&&t.skills.length===0,n=t.spawned.length===0&&t.filesChanged===0;return s&&r&&n}function Yt(t,s){var a,v,y,w;const r=t.specs.length>0,n=t.recs.length>0;let i;if(r)i=`BMAD Spec (token=${t.specs[0].token})`;else if(n){const g=t.recs[0].recommended_agent_type,T=((a=s.agentSpawns[0])==null?void 0:a.subagent_type)??null;i=ke(g,T)}else{const g=((v=s.agentSpawns[0])==null?void 0:v.subagent_type)??null;i=ke(null,g)}const l=((y=t.outcome)==null?void 0:y.label)??"active",x=l==="success"?"成功":l==="partial"?"部分":l==="failed"?"失败":l==="abandoned"?"放弃":"进行中",m=t.filesChanged,u=(((w=t.outcome)==null?void 0:w.commit_count)??0)||t.commits.length;let b="-";if(s.start_time){const g=s.end_time?L(s.end_time).getTime():Date.now(),T=L(s.start_time).getTime(),C=Math.max(0,Math.round((g-T)/1e3));C<60?b=`${C}s`:C<3600?b=`${Math.floor(C/60)}m${C%60}s`:b=`${Math.floor(C/3600)}h${Math.floor(C%3600/60)}m`}return{outcome:l,outcomeLabel:x,pathLabel:i,fileCount:m,commitCount:u,durationLabel:b,agentSpawnCount:s.agentSpawns.length}}function Zt(t,s){var U,$,k,h,S,_,R,f;const r=((U=t.intent)==null?void 0:U.workflow_type)??"?",n=(($=t.intent)==null?void 0:$.layer)??"-",i=typeof((k=t.intent)==null?void 0:k.confidence)=="number"?` conf=${t.intent.confidence.toFixed(2)}`:"",l=t.prompt?(t.prompt.length>30?t.prompt.slice(0,30)+"…":t.prompt).replace(/\n/g," "):"",x=`${r} · ${n}${i}${l?` · "${l}"`:""}`,m=t.recs.length,u=t.specs.length,b=t.skills.length,a=[];m&&a.push(`rec×${m}`),u&&a.push(`spec×${u}`),b&&a.push(`skill×${b}`);const v=a.length===0?"自主决策(未走 daemon 推荐)":a.join(" · "),y=s.agentSpawns.length,w=t.filesChanged,g=Array.from(new Set(s.agentSpawns.map(Q=>Q.subagent_type??"?")));let T;y===0?T=w>0?`主线程直改 ${w} 文件 (0 spawn)`:"未触发":T=`spawn×${y} (${g.slice(0,2).join(", ")}${g.length>2?"…":""}) · file×${w}`;const C=((h=t.outcome)==null?void 0:h.label)==="success"?"成功":((S=t.outcome)==null?void 0:S.label)==="partial"?"部分":((_=t.outcome)==null?void 0:_.label)==="failed"?"失败":((R=t.outcome)==null?void 0:R.label)==="abandoned"?"放弃":"进行中",E=((f=t.outcome)==null?void 0:f.commit_count)??t.commits.length,H=s.reverted_commits??0,W=s.user_violation_count??0,F=[C];E>0&&F.push(`commit×${E}`),H>0&&F.push(`reverted×${H}`),W>0&&F.push(`violation×${W}`);const O=F.join(" · ");return{intent:x,decision:v,execution:T,outcome:O}}function Xt(t){switch(t){case"accepted":return{label:"遵守",color:"green"};case"partial_accepted":return{label:"部分遵守",color:"orange"};case"bypassed":return{label:"明示绕过",color:"purple"};case"rejected":return{label:"拒绝",color:"red"};case"ignored":return{label:"未采纳",color:"red"};case"pending":return{label:"待决",color:"gray"};default:return{label:"无状态",color:"gray"}}}function en(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 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:280,overflowY:"auto"},tn={"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)"};function _e(t){if(!t)return"未知";const s=tn[t];return s||(typeof console<"u"&&console.warn&&console.warn(`[reasonLabel] unknown enum: "${t}"`),t)}const Re=/<!--\s*decision-id:\s*([a-f0-9]{4,40})\s*-->/gi;function nn(t){if(!t)return{ids:[],cleanedPrompt:""};const s=[];let r=t;const n=new RegExp(Re.source,"gi");let i;for(;(i=n.exec(t))!==null;)i[1]&&!s.includes(i[1])&&s.push(i[1]);return r=r.replace(new RegExp(Re.source,"gi"),""),r=r.replace(/^[ \t]*\n+/,"").replace(/\n{3,}/g,`
|
|
2
|
+
|
|
3
|
+
`).trimStart(),{ids:s,cleanedPrompt:r}}function ke(t,s){const r=t||null,n=s||null;return!r&&!n?"自主决策(未走 daemon 推荐)":r&&n&&r===n?`daemon 推荐: ${r}`:r&&n&&r!==n?`daemon 推荐 ${r}(主线程选 ${n})`:r&&!n?`daemon 推荐: ${r}(未 spawn)`:`自主决策: spawn ${n}(无 daemon 推荐)`}function sn({s:t}){return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("section",{children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["用户提问",t.prompt&&e.jsxs(p,{size:"small",color:"gray",style:{marginLeft:6},children:[t.prompt.length," chars"]})]}),t.prompt?e.jsxs(e.Fragment,{children:[t.promptTimestamp&&e.jsxs(o.Text,{type:"secondary",style:{fontSize:11,display:"block",marginBottom:4},children:["timestamp: ",e.jsx(o.Text,{code:!0,style:{fontSize:11},children:Je(t.promptTimestamp,{includeSeconds:!0})})]}),e.jsx("pre",{style:te,children:t.prompt})]}):e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"未触发"})]}),e.jsxs("section",{children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["意图识别",t.intentInj&&e.jsx(p,{size:"small",color:"arcoblue",style:{marginLeft:6},children:"已注入"})]}),t.intent?e.jsxs("div",{style:{marginBottom:6,fontSize:12},children:[e.jsxs(o.Text,{code:!0,style:{fontSize:11},children:["workflow_type=",t.intent.workflow_type??"-"]}),typeof t.intent.confidence=="number"&&e.jsxs(o.Text,{type:"secondary",style:{fontSize:11,marginLeft:6},children:["· confidence=",(t.intent.confidence*100).toFixed(0),"%"]}),t.intent.layer&&e.jsxs(p,{size:"small",color:"gray",style:{marginLeft:6,fontSize:10},children:["layer=",t.intent.layer]}),t.intent.suggested_agent&&e.jsxs(p,{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(o.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}),t.intentInj&&e.jsxs(e.Fragment,{children:[e.jsxs(o.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:4,marginBottom:4},children:["注入原文 (source: ",e.jsx(o.Text,{code:!0,style:{fontSize:11},children:t.intentInj.source_handler}),"):"]}),e.jsx("pre",{style:te,children:t.intentInj.content})]})]}),e.jsxs("section",{children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["命中知识库",t.kbHits.length>0&&e.jsxs(p,{size:"small",color:"purple",style:{marginLeft:6},children:[t.kbHits.length," 命中"]})]}),t.kbHits.length===0?e.jsx(o.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(s=>e.jsxs(p,{size:"small",color:"purple",style:{fontSize:10},children:[s.name,typeof s.score=="number"&&` · score ${Math.round(s.score)}`,s.matched&&s.matched.length>0&&` · [${s.matched.slice(0,3).join(", ")}]`]},s.name))}),t.kbInjs.map((s,r)=>e.jsxs("div",{style:{marginTop:6},children:[e.jsxs(o.Text,{type:"secondary",style:{fontSize:11,display:"block",marginBottom:4},children:["注入 #",r+1," (",s.content.length," chars):"]}),e.jsxs("pre",{style:te,children:[s.content.slice(0,800),s.content.length>800&&`
|
|
4
|
+
…(truncated)`]})]},s.id))]})]})]})}function rn(t){const s=Xt(t);return e.jsx(p,{size:"small",color:s.color,children:s.label})}function on({s:t,data:s}){return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("section",{children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["推荐方法论 (workflow_rec)",t.recs.length>0&&e.jsxs(p,{size:"small",color:"arcoblue",style:{marginLeft:6},children:[t.recs.length," 条"]})]}),t.workflowRecInj&&e.jsxs("details",{style:{marginBottom:6},children:[e.jsxs("summary",{style:{fontSize:11,color:"var(--color-text-3)",cursor:"pointer"},children:["展开注入原文 (",t.workflowRecInj.content.length," chars)"]}),e.jsx("pre",{style:te,children:t.workflowRecInj.content})]}),t.recs.length===0&&!t.workflowRecInj&&e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}),t.recs.length>0&&e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:t.recs.map(r=>{const n=r.recommended_agent_type,i=s.agentSpawns.find(x=>x.timestamp>=r.timestamp);let l;return r.outcome==="bypassed"?l=e.jsx(p,{size:"small",color:"purple",children:"显式 bypass"}):(i==null?void 0:i.subagent_type)===n?l=e.jsxs(p,{size:"small",color:"green",children:["已采纳 (spawn ",n,")"]}):i?l=e.jsxs(p,{size:"small",color:"orange",children:["未采纳, 实际 ",i.subagent_type??"?"]}):s.agentSpawns.length===0?l=e.jsx(p,{size:"small",color:"gray",children:"主线程未 spawn"}):l=rn(r.outcome),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,fontSize:11,flexWrap:"wrap"},children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:10,minWidth:60},children:Je(r.timestamp,{includeSeconds:!0,tzSuffix:""}).slice(11,19)}),e.jsx(p,{size:"small",color:"orange",title:r.rule_id,children:_e(r.rule_id)}),e.jsx(o.Text,{style:{fontSize:11,color:"var(--color-text-2)"},children:"→"}),e.jsx(o.Text,{code:!0,style:{fontSize:10},children:n}),e.jsx("span",{style:{flex:1}}),l]},r.id)})})]}),e.jsxs("section",{children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["Spec 生成 (Phase 2b)",t.specs.length>0&&e.jsxs(p,{size:"small",color:"purple",style:{marginLeft:6},children:[t.specs.length," 条"]})]}),t.specs.length===0?e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6},children:t.specs.map(r=>{var i;const n=en(r);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(o.Text,{code:!0,style:{fontSize:11,color:"var(--cf-tag-purple)"},children:["token=",r.token]}),e.jsx(p,{size:"small",color:n.color,children:n.label}),((i=r.intent)==null?void 0:i.workflow_type)&&e.jsxs(p,{size:"small",color:"gray",style:{fontSize:10},children:[r.intent.workflow_type,r.intent.suggested_agent?` → ${r.intent.suggested_agent}`:""]}),e.jsx(o.Text,{type:"secondary",style:{fontSize:10},children:r.created_at.slice(11,19)})]}),e.jsxs("div",{style:{marginTop:4},children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"spec_path: "}),e.jsx(o.Text,{code:!0,style:{fontSize:10,wordBreak:"break-all"},children:r.spec_path})]}),r.approved_at&&e.jsxs("div",{style:{marginTop:2,color:"var(--color-text-2)"},children:["approved_at: ",e.jsx(o.Text,{code:!0,style:{fontSize:10},children:r.approved_at})]})]},r.id)})})]}),e.jsxs("section",{children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["匹配技能",t.skills.length>0&&e.jsxs(p,{size:"small",color:"arcoblue",style:{marginLeft:6},children:[t.skills.length," 个"]})]}),t.skills.length===0?e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6},children:t.skills.map((r,n)=>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(o.Text,{code:!0,style:{fontSize:11,color:"var(--cf-tag-purple)"},children:r.skill_id}),r.reason&&e.jsx("div",{style:{marginTop:4,color:"var(--color-text-2)"},children:r.reason})]},`${r.skill_id}-${n}`))})]})]})}function ln({s:t,data:s}){const r=t.fileList.reduce((n,i)=>n+i.count,0);return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("section",{children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["spawn Agent",s.agentSpawns.length>0&&e.jsxs(p,{size:"small",color:"arcoblue",style:{marginLeft:6},children:[s.agentSpawns.length," 次"]})]}),s.agentSpawns.length===0?t.recs.length>0?e.jsxs(o.Text,{type:"secondary",style:{fontSize:12},children:["推荐 ",t.recs.length," 次但主线程未 spawn"]}):e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"未 spawn"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:8},children:s.agentSpawns.map((n,i)=>{var y;const l=n.end_timestamp?Math.max(0,Math.round((L(n.end_timestamp).getTime()-L(n.timestamp).getTime())/1e3)):null,x=l===null?"running":l<60?`${l}s`:`${Math.floor(l/60)}m${l%60}s`,m=n.timestamp,u=s.agentSpawns[i+1],b=(u==null?void 0:u.timestamp)??n.end_timestamp??new Date().toISOString(),a=new Map;for(const w of s.timeline){if(w.tool_name!=="Edit"&&w.tool_name!=="Write"||w.timestamp<m||w.timestamp>b)continue;const g=(y=w.input)==null?void 0:y.file_path;typeof g=="string"&&a.set(g,(a.get(g)??0)+1)}const v=Array.from(a.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(o.Text,{style:{fontSize:12,fontWeight:600,color:"var(--cf-tag-blue)"},children:["Spawn #",i+1]}),e.jsx(o.Text,{code:!0,style:{fontSize:11,color:"var(--cf-tag-blue)"},children:n.subagent_type??"(no type)"}),n.status==="completed"?e.jsx(p,{size:"small",color:"green",children:"completed"}):e.jsx(p,{size:"small",color:"arcoblue",children:"running"}),e.jsxs(o.Text,{type:"secondary",style:{fontSize:10},children:[n.timestamp.slice(11,19)," · ",x]})]}),n.description&&e.jsxs("div",{style:{marginTop:2},children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"描述: "}),e.jsx(o.Text,{style:{fontSize:11},children:n.description})]}),n.prompt&&e.jsxs("details",{style:{marginTop:4},children:[e.jsxs("summary",{style:{fontSize:11,color:"var(--color-text-3)",cursor:"pointer"},children:["完整 prompt (",n.prompt_length," chars)"]}),e.jsx("pre",{style:te,children:n.prompt})]}),n.output&&e.jsxs("details",{style:{marginTop:4},children:[e.jsxs("summary",{style:{fontSize:11,color:"var(--color-text-3)",cursor:"pointer"},children:["输出预览 (",n.output_length," chars)"]}),e.jsxs("pre",{style:{...te,maxHeight:160},children:[n.output.slice(0,1200),n.output.length>1200&&`
|
|
5
|
+
…(fold)`]})]}),e.jsxs("div",{style:{marginTop:6},children:[e.jsxs(o.Text,{type:"secondary",style:{fontSize:11},children:["期间产物 (",v.length," 文件):"]}),v.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:2,marginTop:4},children:v.map(([w,g])=>e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",fontSize:11},children:[e.jsx(pe,{style:{color:"var(--cf-tag-green)",flexShrink:0}}),e.jsx(o.Text,{code:!0,style:{fontSize:10,wordBreak:"break-all"},children:w}),e.jsxs(p,{size:"small",color:"gray",style:{fontSize:10},children:["×",g]})]},w))}):e.jsx(o.Text,{type:"secondary",style:{fontSize:11,marginLeft:4},children:"(无)"})]})]},i)})})]}),e.jsxs("section",{children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:4},children:["改文件总览",t.filesChanged>0&&e.jsxs(p,{size:"small",color:"green",style:{marginLeft:6},children:[t.filesChanged," 文件 / ",r," 操作"]})]}),t.fileList.length===0?e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"未触发"}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:t.fileList.map(n=>{var x,m;let i=-1;for(const u of s.timeline)if(!(u.tool_name!=="Edit"&&u.tool_name!=="Write")&&((x=u.input)==null?void 0:x.file_path)===n.path){for(let b=0;b<s.agentSpawns.length;b++){const a=s.agentSpawns[b],v=((m=s.agentSpawns[b+1])==null?void 0:m.timestamp)??a.end_timestamp??"9999";if(u.timestamp>=a.timestamp&&u.timestamp<=v){i=b;break}}if(i>=0)break}const l=i>=0?e.jsxs(p,{size:"small",color:"cyan",style:{fontSize:10},children:["by Spawn #",i+1]}):e.jsx(p,{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(pe,{style:{color:"var(--cf-tag-green)",flexShrink:0}}),e.jsx(o.Text,{code:!0,style:{fontSize:11,flex:1,wordBreak:"break-all"},title:n.path,children:n.path}),l,e.jsxs(p,{size:"small",color:"gray",style:{flexShrink:0,fontSize:10},children:["×",n.count]})]},n.path)})})]})]})}function an(t){return t==="success"?e.jsx(p,{color:"green",size:"small",children:"成功"}):t==="partial"?e.jsx(p,{color:"orange",size:"small",children:"部分"}):t==="failed"?e.jsx(p,{color:"red",size:"small",children:"失败"}):t==="abandoned"?e.jsx(p,{color:"gray",size:"small",children:"放弃"}):e.jsx(p,{size:"small",children:t})}function cn({s:t,data:s}){return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8,fontSize:12},children:[!t.outcome&&e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"未分类 / 进行中"}),t.outcome&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"outcome: "}),an(t.outcome.label)]}),t.outcome.reason&&e.jsxs("div",{children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"outcome_reason: "}),e.jsx(o.Text,{code:!0,style:{fontSize:11},children:t.outcome.reason})]}),typeof t.outcome.commit_count=="number"&&e.jsxs("div",{children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"commit_count: "}),e.jsx(o.Text,{style:{fontSize:11},children:t.outcome.commit_count})]})]}),typeof s.reverted_commits=="number"&&s.reverted_commits>0&&e.jsxs("div",{children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"reverted_commits: "}),e.jsx(p,{color:"red",size:"small",children:s.reverted_commits})]}),typeof s.user_violation_count=="number"&&s.user_violation_count>0&&e.jsxs("div",{children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"user_violation_count: "}),e.jsx(p,{color:"orange",size:"small",children:s.user_violation_count})]}),t.commits.length>0&&e.jsxs("div",{children:[e.jsx(o.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((r,n)=>e.jsx(p,{size:"small",color:"green",style:{fontSize:10,fontFamily:"monospace"},children:r},`${r}-${n}`))})]}),e.jsxs("div",{children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"event_count: "}),e.jsx(o.Text,{style:{fontSize:11},children:s.event_count})]})]})}async function $e(t,s){const r=await Pt(t,{method:"POST",headers:{"Content-Type":"application/json"},body:s?JSON.stringify(s):void 0});if(!r.ok){let n;try{const i=await r.json();n=(i==null?void 0:i.error)||(i==null?void 0:i.message)}catch{}throw new Error(`${r.status} ${n??r.statusText}`)}return r.json()}async function dn(t){return $e(`/api/tasks/${encodeURIComponent(t.taskId)}/approve-spec`)}async function pn(t){return $e(`/api/tasks/${encodeURIComponent(t.taskId)}/mark-abandoned`,{reason:t.reason??null})}async function Qe(t){return $e(`/api/tasks/${encodeURIComponent(t.taskId)}/rerun`)}function mn({taskId:t,outcome:s,pendingSpecs:r}){const n=Rt(),i=Ae(),[l,x]=I.useState(null),m=r.some(g=>g.status==="generated"),u=s==="abandoned",b=he({mutationFn:()=>dn({taskId:t}),onSuccess:g=>{K.success(`已 approve ${g.approved} spec`),i.invalidateQueries({queryKey:["task-detail",t]})},onError:g=>{K.error(`Approve 失败:${g.message}`)}}),a=he({mutationFn:g=>pn({taskId:t,reason:g}),onSuccess:()=>{K.success("已标记 abandoned"),i.invalidateQueries({queryKey:["task-detail",t]})},onError:g=>{K.error(`标记失败:${g.message}`)}}),v=he({mutationFn:()=>Qe({taskId:t}),onSuccess:g=>{x(g)},onError:g=>{K.error(`Re-run 取 prompt 失败:${g.message}`)}}),y=async()=>{await n({title:"标记任务为 abandoned",message:"此操作会把该任务的 outcome 置为 abandoned。可以稍后再点击 Re-run 用同意图重跑。是否继续?",confirmText:"标记 abandoned",variant:"warning"})&&a.mutate(void 0)},w=async()=>{if(l!=null&&l.prompt)try{await navigator.clipboard.writeText(l.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(ee,{content:m?"把待审 spec 标记为 approved(不重启 daemon)":"该任务没有 pending spec",children:e.jsxs(D,{type:"primary",size:"small",icon:e.jsx(xe,{}),disabled:!m||b.isPending,loading:b.isPending,onClick:()=>b.mutate(),"data-testid":"action-approve-spec",children:["Approve spec",r.length>0&&` (${r.filter(g=>g.status==="generated").length})`]})}),e.jsx(ee,{content:u?"该任务已是 abandoned":"把任务标记为 abandoned(不影响已写文件)",children:e.jsx(D,{status:"warning",size:"small",icon:e.jsx(He,{}),disabled:u||a.isPending,loading:a.isPending,onClick:y,"data-testid":"action-mark-abandoned",children:"标记 abandoned"})}),e.jsx(ee,{content:"打开原 prompt 文本,复制后粘贴到 Claude Code 继续",children:e.jsx(D,{size:"small",icon:e.jsx(Ce,{}),loading:v.isPending,onClick:()=>v.mutate(),"data-testid":"action-rerun",children:"Re-run (复制原 prompt)"})}),e.jsx(ee,{content:"MVP 后续(需要 cross-task 相似性查询)",children:e.jsx(D,{size:"small",icon:e.jsx(jt,{}),disabled:!0,"data-testid":"action-compare",children:"对比上周同类任务"})})]}),e.jsx(Ue,{title:"Re-run — 复制原 prompt",visible:!!l,onCancel:()=>x(null),footer:e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:8},children:[e.jsx(D,{onClick:()=>x(null),size:"small",children:"完成"}),e.jsx(D,{type:"primary",size:"small",icon:e.jsx(qe,{}),onClick:w,disabled:!(l!=null&&l.prompt),children:"复制到剪贴板"})]}),style:{width:720},children:e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[(l==null?void 0:l.workflow_type)&&e.jsxs("div",{style:{fontSize:12},children:[e.jsx(o.Text,{type:"secondary",children:"workflow_type:"})," ",e.jsx(o.Text,{code:!0,children:l.workflow_type}),l.suggested_agent&&e.jsxs(e.Fragment,{children:[" ",e.jsx(o.Text,{type:"secondary",children:"→"})," ",e.jsx(o.Text,{code:!0,children:l.suggested_agent})]})]}),l!=null&&l.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:l.prompt}):e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"该任务没有可恢复的原 prompt(events 表未记录 UserPromptSubmit)。"}),e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"MVP 工作流:复制后回到 Claude Code 中粘贴提交。后续会有 daemon-driven spawn-same-agent 模式。"})]})})]})}function xn(t,s){const r=L(t).getTime(),n=s?L(s).getTime():Date.now(),i=Math.max(0,Math.round((n-r)/1e3));return i<60?`${i}s`:i<3600?`${Math.floor(i/60)}m${i%60}s`:`${Math.floor(i/3600)}h${Math.floor(i%3600/60)}m`}function un(t,s=32){if(!t)return"(无 prompt)";const r=t.replace(/\n/g," ").trim();return r.length>s?r.slice(0,s)+"…":r}function fn({data:t,summary:s}){var v;const[r,n]=I.useState(!1),[i,l]=I.useState(null),x=((v=s.outcome)==null?void 0:v.commit_count)??s.commits.length,m=xn(t.start_time,t.end_time),u=un(s.prompt),b=he({mutationFn:()=>Qe({taskId:t.id}),onSuccess:y=>l(y),onError:y=>K.error(`Re-run 取 prompt 失败:${y.message}`)}),a=async()=>{if(i!=null&&i.prompt)try{await navigator.clipboard.writeText(i.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:()=>n(y=>!y),"data-testid":"trivial-card-header",children:[e.jsx(xe,{style:{color:"var(--cf-tag-green, #00B42A)",fontSize:16}}),e.jsxs(o.Text,{style:{fontSize:13,fontWeight:500},children:["“",u,"”"]}),e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsxs(o.Text,{style:{fontSize:12},children:[x," commit",x===1?"":"s"]}),e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsx(o.Text,{style:{fontSize:12},children:m}),e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"daemon 未介入"}),e.jsx("span",{style:{flex:1}}),e.jsx(D,{size:"mini",type:"text",icon:r?e.jsx(bt,{}):e.jsx(Oe,{}),onClick:y=>{y.stopPropagation(),n(w=>!w)},"data-testid":"trivial-card-toggle",children:r?"收起":"展开"})]}),r&&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(o.Text,{type:"secondary",children:"时间"}),e.jsx(o.Text,{code:!0,children:se(L(t.start_time),"yyyy-MM-dd HH:mm:ss")})]}),e.jsxs("div",{style:{display:"flex",gap:12,fontSize:12,flexWrap:"wrap"},children:[e.jsx(o.Text,{type:"secondary",children:"Task ID"}),e.jsx(o.Text,{code:!0,children:t.id.slice(0,12)})]}),s.commits.length>0&&e.jsxs("div",{style:{display:"flex",gap:12,fontSize:12,flexWrap:"wrap"},children:[e.jsx(o.Text,{type:"secondary",children:"Commit"}),e.jsx(o.Text,{code:!0,children:s.commits.join(", ")})]}),e.jsx("div",{style:{display:"flex",gap:8,marginTop:4},children:e.jsx(D,{size:"small",icon:e.jsx(Ce,{}),loading:b.isPending,onClick:()=>b.mutate(),"data-testid":"trivial-card-rerun",children:"Re-run"})})]}),e.jsx(Ue,{title:"Re-run — 复制原 prompt",visible:!!i,onCancel:()=>l(null),footer:e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:8},children:[e.jsx(D,{onClick:()=>l(null),size:"small",children:"完成"}),e.jsx(D,{type:"primary",size:"small",icon:e.jsx(qe,{}),onClick:a,disabled:!(i!=null&&i.prompt),children:"复制到剪贴板"})]}),style:{width:720},children:i!=null&&i.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:i.prompt}):e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"该任务没有可恢复的原 prompt(events 表未记录 UserPromptSubmit)。"})})]})}const ae={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 ce({title:t,children:s,testId:r}){return e.jsxs("div",{"data-testid":r,style:{marginBottom:16},children:[e.jsx(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:6},children:t}),s]})}function gn({data:t,timeline:s,visible:r,onClose:n}){const i=Ge(t),l=Ve(i),x=t.injections.find(u=>u.source_handler.includes(":intent"));let m=null;try{m=x!=null&&x.metadata_json?JSON.parse(x.metadata_json):null}catch{m=null}return e.jsxs(Ke,{visible:r,onCancel:n,onOk:n,title:"高级调试信息(仅故障排查时使用)",width:560,placement:"right","data-testid":"debug-drawer",footer:null,children:[e.jsx(ce,{title:"① intent_engine 输出",testId:"debug-section-intent",children:m?e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{display:"flex",gap:6,marginBottom:6,flexWrap:"wrap"},children:[typeof m.workflow_type=="string"&&e.jsxs(p,{size:"small",color:"arcoblue",children:["workflow_type=",m.workflow_type]}),typeof m.confidence=="number"&&e.jsxs(p,{size:"small",color:"gray",children:["conf=",m.confidence.toFixed(2)]}),typeof m.layer=="string"&&e.jsxs(p,{size:"small",color:"gray",children:["layer=",m.layer]}),typeof m.suggested_agent=="string"&&e.jsxs(p,{size:"small",color:"purple",children:["agent=",m.suggested_agent]})]}),e.jsx("pre",{style:ae,children:JSON.stringify(m,null,2)})]}):e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"未触发 intent injection"})}),e.jsx(fe,{style:{margin:"12px 0"}}),e.jsxs(ce,{title:"② daemon config flags(最新值)",testId:"debug-section-config",children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:"下列标志通过 daemon `config-store` 控制(实时值需后端补 endpoint; 目前显示最近一次注入的快照):"}),e.jsx("pre",{style:ae,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(fe,{style:{margin:"12px 0"}}),e.jsxs(ce,{title:"③ trivial_filter 决策",testId:"debug-section-trivial",children:[e.jsx("div",{style:{display:"flex",gap:6,marginBottom:6,flexWrap:"wrap"},children:e.jsxs(p,{size:"small",color:l?"green":"orange",children:["isTrivialPath=",String(l)]})}),e.jsx("pre",{style:ae,children:JSON.stringify({intentEmpty:!i.intent&&i.kbHits.length===0,decisionEmpty:i.recs.length===0&&i.specs.length===0&&i.skills.length===0,executionEmpty:i.spawned.length===0&&i.filesChanged===0,counters:{recs:i.recs.length,specs:i.specs.length,skills:i.skills.length,spawned:i.spawned.length,filesChanged:i.filesChanged,kbHits:i.kbHits.length,commits:i.commits.length}},null,2)})]}),e.jsx(fe,{style:{margin:"12px 0"}}),e.jsxs(ce,{title:"④ 原始事件(timeline 端点返回)",testId:"debug-section-raw",children:[s?e.jsxs(e.Fragment,{children:[e.jsxs(o.Text,{type:"secondary",style:{fontSize:11},children:["events: ",s.events.length," · artifacts: spec=",s.artifacts.spec.length," archive=",s.artifacts.archive.length," ","changelog=",s.artifacts.changelog.length," template=",s.artifacts.template.length," code=",s.artifacts.code.length]}),e.jsx("pre",{style:ae,children:JSON.stringify(s,null,2)})]}):e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"timeline 端点未返回(loading 或 error)"}),e.jsx(o.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(fe,{style:{margin:"12px 0"}}),e.jsx(ce,{title:"⑤ daemon 注入(additionalContext / systemMessage)",testId:"debug-section-injections",children:t.injections.length===0?e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"本任务无注入事件"}):e.jsxs(e.Fragment,{children:[e.jsxs(o.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(p,{size:"small",color:u.injection_type==="systemMessage"?"arcoblue":"orange",children:u.injection_type}),e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:u.source_handler})]}),e.jsx("pre",{style:ae,children:u.content})]},u.id))]})})]})}async function hn(t){const s=await fetch(`/api/tasks/${encodeURIComponent(t)}/timeline`);if(!s.ok)throw new Error(`timeline HTTP ${s.status}`);return s.json()}function yn(t){try{return se(L(t),"HH:mm:ss")}catch{return t.slice(11,19)}}function jn(t,s){if(t===null||t<0)return s==="task_end"?"进行中":"未知";if(t===0&&s!=="paired")return"未知";const r=(()=>{if(t<1e3)return`${t}ms`;const n=Math.round(t/1e3);return n<60?`${n}s`:`${Math.floor(n/60)}m${n%60}s`})();return s==="task_end"?`进行中 (≈${r})`:r}const Ye='"Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", sans-serif',bn={user_prompt:{icon:"👤",color:"gray",label:"用户"},daemon_hint:{icon:"⚡",color:"orange",label:"daemon 推荐"},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 vn({ev:t}){const s=bn[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(o.Text,{code:!0,type:"secondary",style:{fontSize:11,minWidth:70,fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace"},children:yn(t.at)}),e.jsx("span",{style:{fontSize:14,minWidth:24,fontFamily:Ye,fontVariantEmoji:"emoji"},children:s.icon}),e.jsx("div",{style:{flex:1,minWidth:0},children:e.jsx(wn,{ev:t})})]})}function wn({ev:t}){switch(t.kind){case"user_prompt":return e.jsxs("div",{children:[e.jsx(o.Text,{style:{fontSize:12,fontWeight:500},children:"用户"}),e.jsxs(o.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_hint":return e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap"},children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:500},children:["daemon 推 ",t.recommended_agent_type]}),e.jsx(p,{size:"small",color:"orange",children:_e(t.rule_id)})]}),t.reason&&e.jsx(o.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:2},children:t.reason})]});case"daemon_enforce":return e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap"},children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:500},children:[t.decision==="deny"?"daemon 拒绝":"daemon 警告"," ",t.tool]}),e.jsx(p,{size:"small",color:t.decision==="deny"?"red":"orange",children:_e(t.rule_id)})]}),t.hint&&e.jsx(o.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:2},children:t.hint.slice(0,200)})]});case"agent_spawn":{const s=ke(t.recommended_agent_type_before,t.subagent_type),{ids:r,cleanedPrompt:n}=nn(t.prompt_preview);return e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap"},children:[e.jsxs(o.Text,{style:{fontSize:12,fontWeight:500},children:["主线程 spawn ",t.subagent_type??"?"]}),e.jsxs(o.Text,{type:"secondary",style:{fontSize:11},children:["(",jn(t.duration_ms,t.duration_source),")"]}),e.jsx(p,{size:"small",color:t.was_recommended_by_daemon?"green":"gray",children:s}),r.map(i=>e.jsx(De,{to:`/decisions/${i}`,style:{textDecoration:"none"},title:`查看决策 ${i}`,children:e.jsxs(p,{size:"small",color:"purple",style:{cursor:"pointer"},children:[e.jsx("span",{style:{fontFamily:Ye},children:"📋"})," ","决策 ",i.slice(0,8)]})},i))]}),e.jsxs("div",{style:{marginTop:4,marginLeft:12,fontSize:11,color:"var(--color-text-3)"},children:[e.jsx("span",{children:"└─ "}),e.jsxs(o.Text,{type:"secondary",style:{fontSize:11},children:["prompt ",t.prompt_length," chars · output ",t.output_length," chars"]})]}),n&&e.jsx(o.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:n})]})}case"commit":return e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap"},children:[e.jsx(o.Text,{style:{fontSize:12,fontWeight:500},children:"提交"}),e.jsx(o.Text,{code:!0,style:{fontSize:11,color:"var(--cf-tag-green)"},children:t.hash})]}),t.message_preview&&e.jsx(o.Text,{style:{fontSize:11,display:"block",marginTop:2},children:t.message_preview})]});case"decision_resolved":return e.jsx("div",{children:e.jsxs(o.Text,{style:{fontSize:12,fontWeight:500},children:["决策闭环"," ",e.jsx(o.Text,{code:!0,style:{fontSize:11},children:t.decision_id})]})});default:return null}}function Sn({artifacts:t}){const s=Object.keys(t).map(r=>({key:r,label:r==="spec"?"📄 spec":r==="archive"?"📦 归档":r==="changelog"?"📝 changelog":r==="template"?"🧱 模板":"⚙ 代码",count:t[r].length,example:t[r][0]??"-"})).filter(r=>r.count>0);return e.jsxs("div",{"data-testid":"artifacts-table",style:{marginTop:16},children:[e.jsx(o.Text,{style:{fontSize:12,fontWeight:600,display:"block",marginBottom:6},children:"产物总览"}),s.length===0?e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"(本任务无产物)"}):e.jsx(wt,{size:"small",pagination:!1,data:s,columns:[{title:"类型",dataIndex:"label",width:120},{title:"数量",dataIndex:"count",width:80},{title:"示例路径",dataIndex:"example",render:r=>e.jsx(o.Text,{code:!0,style:{fontSize:11,wordBreak:"break-all"},children:r})}]})]})}function _n({data:t}){const[s,r]=I.useState(!1),{data:n,isLoading:i,isError:l}=ne({queryKey:["task-timeline",t.id],queryFn:()=>hn(t.id),staleTime:3e4,retry:1});if(l)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(o.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx(Ie,{style:{color:"var(--cf-tag-blue)"}}),"任务详情 · 时间线"]}),e.jsx(D,{size:"mini",type:"text",icon:e.jsx(vt,{}),onClick:()=>r(!0),"data-testid":"debug-drawer-toggle",title:"高级调试信息(仅故障排查时使用)",children:"调试"})]}),i&&e.jsx("div",{"data-testid":"task-timeline-loading",children:e.jsx(me,{animation:!0,text:{rows:6}})}),n&&e.jsxs(e.Fragment,{children:[e.jsx("div",{"data-testid":"task-timeline-events",children:n.events.length===0?e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"(时间线无事件)"}):n.events.map((x,m)=>e.jsx(vn,{ev:x},`${x.at}-${x.kind}-${m}`))}),e.jsx(Sn,{artifacts:n.artifacts})]}),e.jsx(gn,{data:t,timeline:n??null,visible:s,onClose:()=>r(!1)})]})}function kn(t){return!t||t==="success"?new Set:t==="failed"||t==="partial"?new Set(["execution"]):t==="abandoned"?new Set(["outcome"]):new Set}function zn(t){const s=t.get("expand");if(!s)return new Set;const r=new Set;for(const n of s.split(",")){const i=n.trim();(i==="intent"||i==="decision"||i==="execution"||i==="outcome")&&r.add(i)}return r}function Tn(t){return["intent","decision","execution","outcome"].filter(r=>t.has(r)).join(",")}class Cn extends I.Component{constructor(){super(...arguments);Fe(this,"state",{errored:!1})}static getDerivedStateFromError(){return{errored:!0}}componentDidCatch(r,n){console.warn("[TaskTimelineView] fallback to 4-card; error:",r.message,n)}render(){return this.state.errored?this.props.fallback:this.props.children}}function In({data:t}){const[s,r]=ze(),n=I.useMemo(()=>{const a=zn(s);return a.size>0?a:kn(t.outcome)},[s,t.outcome]),i=I.useCallback(a=>{const v=new Set(n);v.has(a)?v.delete(a):v.add(a);const y=Tn(v),w=new URLSearchParams(s);y?w.set("expand",y):w.delete("expand"),r(w,{replace:!0})},[n,s,r]),l=I.useMemo(()=>Ge(t),[t]),x=I.useMemo(()=>Yt(l,t),[l,t]),m=I.useMemo(()=>Zt(l,t),[l,t]);if(I.useMemo(()=>Ve(l),[l]))return e.jsx(fn,{data:t,summary:l});const b=e.jsxs(z,{bordered:!0,style:{marginBottom:16,background:"var(--cf-kpi-wash-blue, #F2F9FF)"},"data-testid":"tier-container",children:[e.jsxs(o.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6,marginBottom:8},children:[e.jsx(Ie,{style:{color:"var(--cf-tag-blue)"}}),"任务详情"]}),e.jsx(Qt,{banner:x,taskId:t.id,startedAt:t.start_time}),e.jsx(ge,{cardId:"intent",idx:1,title:"用户意图",oneLine:m.intent,expanded:n.has("intent"),onToggle:()=>i("intent"),detail:e.jsx(sn,{s:l})}),e.jsx(ge,{cardId:"decision",idx:2,title:"系统决策",oneLine:m.decision,expanded:n.has("decision"),onToggle:()=>i("decision"),detail:e.jsx(on,{s:l,data:t})}),e.jsx(ge,{cardId:"execution",idx:3,title:"执行",oneLine:m.execution,expanded:n.has("execution"),onToggle:()=>i("execution"),detail:e.jsx(ln,{s:l,data:t})}),e.jsx(ge,{cardId:"outcome",idx:4,title:"结果",oneLine:m.outcome,expanded:n.has("outcome"),onToggle:()=>i("outcome"),detail:e.jsx(cn,{s:l,data:t})}),e.jsx(mn,{taskId:t.id,outcome:t.outcome??null,pendingSpecs:t.pendingSpecs})]});return e.jsx(Cn,{fallback:b,children:e.jsx(_n,{data:t})})}async function $n(){const t=await fetch("/api/insights/badge?days=7");if(!t.ok)throw new Error(`badge HTTP ${t.status}`);return t.json()}function Mn({slot:t}={}){const{data:s,isLoading:r,isError:n}=ne({queryKey:["daemon-observer-badge"],queryFn:$n,refetchInterval:6e4,retry:1});if(r)return e.jsx("div",{"data-testid":"daemon-observer-badge-loading",style:{marginBottom:12},children:e.jsx(me,{animation:!0,text:{rows:1,width:360}})});if(n||!s)return null;const i=s.denied_7d??0,l=s.hinted_7d??0,x=s.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(o.Text,{type:"secondary",style:{fontSize:12},children:"本周 daemon:"}),e.jsxs(p,{size:"small",color:"red","data-testid":"daemon-observer-denied",children:["🚫 拒 ",i," 次"]}),e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsxs(p,{size:"small",color:"orange","data-testid":"daemon-observer-hinted",children:["⚡ hint ",l," 次"]}),e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"·"}),e.jsxs(p,{size:"small",color:"green","data-testid":"daemon-observer-trivial",children:["✓ 通过 ",x," 个 trivial"]})]})}async function Bn(t){const s=await fetch(`/api/tasks/${t}`);if(!s.ok)throw new Error("Failed to fetch task detail");const r=await s.json();return{...r.task,userPrompts:r.userPrompts??[],injections:(r.injections??[]).map(n=>({id:n.id,timestamp:n.timestamp,source_handler:n.source_handler,injection_type:n.injection_type,content:n.content,metadata_json:n.metadata_json??null})),timeline:(r.timeline??[]).map((n,i)=>({id:`${n.timestamp}-${n.tool_name??n.kind}-${i}`,timestamp:n.timestamp,kind:n.kind??"tool",tool_name:n.tool_name??null,hook_type:n.hook_type,input:n.input,output:n.output,is_agent_call:n.is_agent_call,agent_detail:n.agent_detail,notification:n.notification})),skillInvocations:r.skillInvocations??[],artifacts:r.artifacts??[],workflowRecommendations:r.workflowRecommendations??[],pendingSpecs:r.pendingSpecs??[],agentSpawns:r.agentSpawns??[]}}function Fn(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(pe,{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(Ie,{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(Tt,{style:{color:"var(--color-text-3)"}})}}function Ne(t,s){const r=L(t).getTime()-L(s).getTime();return r<1e3?"+0s":r<6e4?`+${Math.floor(r/1e3)}s`:r<36e5?`+${Math.floor(r/6e4)}m${Math.floor(r%6e4/1e3)}s`:`+${Math.floor(r/36e5)}h${Math.floor(r%36e5/6e4)}m`}function Ln(t){return t==="completed"?e.jsx(p,{color:"green",icon:e.jsx(xe,{}),children:"已完成"}):t==="active"?e.jsx(p,{color:"arcoblue",icon:e.jsx(Te,{spin:!0}),children:"进行中"}):t==="abandoned"?e.jsx(p,{color:"gray",children:"已放弃"}):e.jsx(p,{color:"gray",children:t})}function Pe(t){return t==="success"?e.jsx(p,{color:"green",size:"small",children:"成功"}):t==="partial"?e.jsx(p,{color:"orange",size:"small",children:"部分"}):t==="failed"?e.jsx(p,{color:"red",size:"small",children:"失败"}):t==="abandoned"?e.jsx(p,{color:"gray",size:"small",children:"放弃"}):e.jsx(p,{size:"small",children:t})}function En({taskId:t}){var b;const[s,r]=I.useState(new Set),{data:n,isLoading:i,error:l}=ne({queryKey:["task-detail",t],queryFn:()=>Bn(t),enabled:!!t,refetchInterval:1e4});if(i)return e.jsx(z,{bordered:!0,children:e.jsx(me,{animation:!0,text:{rows:6}})});if(l||!n)return e.jsx(z,{bordered:!0,children:e.jsxs(o.Text,{type:"error",children:["加载失败: ",(l==null?void 0:l.message)||"未知错误"]})});const x=a=>{r(v=>{const y=new Set(v);return y.has(a)?y.delete(a):y.add(a),y})},m=n.end_time?`${Math.round((L(n.end_time).getTime()-L(n.start_time).getTime())/1e3)}s`:"进行中",u=n.userPrompts.length===0&&n.injections.length===0&&n.timeline.length===0&&n.skillInvocations.length===0&&n.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(o.Title,{heading:6,style:{margin:0},children:Jt(n.title,(b=n.userPrompts[0])==null?void 0:b.content)}),e.jsxs("span",{style:{display:"inline-flex",gap:6},children:[Ln(n.status),n.outcome&&Pe(n.outcome)]})]}),e.jsx(St,{colon:" :",size:"small",column:2,data:[{label:"开始时间",value:se(L(n.start_time),"MM-dd HH:mm:ss")},{label:"结束时间",value:n.end_time?se(L(n.end_time),"MM-dd HH:mm:ss"):"-"},{label:"持续时间",value:m},{label:"事件数",value:n.event_count},...n.outcome?[{label:"结果",value:e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[Pe(n.outcome),n.outcome_reason&&e.jsx(o.Text,{type:"secondary",style:{fontSize:11},children:n.outcome_reason})]})}]:[],...typeof n.commit_count=="number"?[{label:"提交数",value:e.jsxs("span",{children:[n.commit_count,typeof n.reverted_commits=="number"&&n.reverted_commits>0&&e.jsxs(o.Text,{type:"secondary",style:{fontSize:11,marginLeft:4},children:["(",n.reverted_commits," reverted)"]})]})}]:[]]})]}),e.jsx(Mn,{slot:"task-detail"}),e.jsx(In,{data:n}),u&&e.jsx(z,{bordered:!0,children:e.jsx(de,{icon:e.jsx(Ee,{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:"事件可能仍在记录中,稍后刷新查看"})]})})}),n.timeline.length>0&&e.jsxs(z,{bordered:!0,style:{marginBottom:16},children:[e.jsxs(o.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6,marginBottom:16},children:[e.jsx(Ee,{style:{color:"var(--color-text-3)"}}),"执行时间线",e.jsx(p,{size:"small",color:"gray",children:n.timeline.length})]}),e.jsx(we,{children:n.timeline.map((a,v)=>{var U,$,k,h,S,_,R,f,Q;if(a.kind==="notification"){const N=((U=a.notification)==null?void 0:U.message)??"通知",G=(($=a.notification)==null?void 0:$.notification_type)??null;return e.jsx(we.Item,{dot:e.jsx(_t,{style:{color:"var(--cf-tag-orange)"}}),label:Ne(a.timestamp,n.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(o.Text,{style:{fontSize:13,fontWeight:500,color:"var(--cf-tag-orange)"},children:"通知"}),G&&e.jsx(p,{size:"small",color:"orange",children:G})]}),e.jsx(o.Text,{type:"secondary",style:{fontSize:12,display:"block",marginTop:2},children:N})]})},a.id||v)}const y=a.is_agent_call,w=a.tool_name==="Edit"||a.tool_name==="Write",g=s.has(v),T=a.input,C=T==null?void 0:T.file_path,E=(T==null?void 0:T.description)||(T==null?void 0:T.command),H=(k=a.agent_detail)==null?void 0:k.status,W=((h=a.agent_detail)==null?void 0:h.changed_files)??[],F=y?n.agentSpawns.find(N=>{var G;return N.timestamp===a.timestamp&&(N.subagent_type??void 0)===((G=a.agent_detail)==null?void 0:G.subagent_type)})??n.agentSpawns.find(N=>N.timestamp===a.timestamp):void 0,O=y?H==="running"?e.jsx(Te,{spin:!0,style:{color:"var(--cf-tag-orange)"}}):e.jsx(xe,{style:{color:"var(--cf-tag-green)"}}):Fn(a.tool_name);return e.jsx(we.Item,{dot:O,label:Ne(a.timestamp,n.start_time),labelPosition:"relative",dotType:"hollow",children:e.jsxs("div",{onClick:()=>x(v),style:{cursor:"pointer",padding:4,borderRadius:4},"data-testid":y?"timeline-agent-call":void 0,children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[y?e.jsx(o.Text,{style:{fontSize:13,fontWeight:600,color:H==="running"?"var(--cf-tag-orange)":"var(--cf-tag-green)"},children:H==="running"?`⏳ ${((S=a.agent_detail)==null?void 0:S.subagent_type)??"子 agent"} 进行中`:`✅ ${((_=a.agent_detail)==null?void 0:_.subagent_type)??"子 agent"} 完成`}):e.jsx(o.Text,{style:{fontSize:13,fontWeight:500,color:"var(--color-text-1)"},children:a.tool_name}),y&&W.length>0&&e.jsxs(p,{size:"small",color:"green",children:[W.length," 文件"]}),!y&&((R=a.agent_detail)==null?void 0:R.subagent_type)&&e.jsx(p,{size:"small",color:"arcoblue",children:a.agent_detail.subagent_type}),((f=a.agent_detail)==null?void 0:f.name)&&e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:a.agent_detail.name})]}),y&&!g&&((Q=a.agent_detail)==null?void 0:Q.description)&&e.jsx(o.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:a.agent_detail.description}),!g&&w&&C&&e.jsx(o.Text,{style:{fontSize:11,fontFamily:"monospace",color:"var(--cf-tag-green)",display:"block",marginTop:2},title:C,children:C}),!g&&!w&&E&&e.jsx(o.Text,{type:"secondary",style:{fontSize:11,display:"block",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:E}),g&&e.jsxs("div",{onClick:N=>N.stopPropagation(),style:{marginTop:8,display:"flex",flexDirection:"column",gap:8},children:[y&&a.agent_detail&&e.jsxs(z,{size:"small",bordered:!0,style:{background:"var(--cf-kpi-wash-blue, #E8F3FF)"},children:[a.agent_detail.subagent_type&&e.jsxs("div",{style:{fontSize:12,marginBottom:4},children:[e.jsx(o.Text,{type:"secondary",children:"subagent_type:"})," ",e.jsx(o.Text,{code:!0,children:a.agent_detail.subagent_type})]}),a.agent_detail.name&&e.jsxs("div",{style:{fontSize:12,marginBottom:4},children:[e.jsx(o.Text,{type:"secondary",children:"name:"})," ",e.jsx(o.Text,{code:!0,children:a.agent_detail.name})]}),a.agent_detail.prompt&&e.jsxs("div",{children:[e.jsx(o.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:a.agent_detail.prompt})]}),W.length>0&&e.jsxs("div",{style:{marginTop:8},"data-testid":"agent-changed-files",children:[e.jsxs(o.Text,{type:"secondary",style:{fontSize:12},children:["改动文件 (",W.length,"):"]}),e.jsx("div",{style:{marginTop:4,display:"flex",flexDirection:"column",gap:2},children:W.map(N=>e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx(pe,{style:{color:"var(--cf-tag-green)"}}),e.jsx(o.Text,{code:!0,style:{fontSize:11},title:N,children:N})]},N))})]}),(F==null?void 0:F.output)&&e.jsxs("div",{style:{marginTop:8},children:[e.jsx(o.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:F.output})]}),H==="running"&&e.jsx(o.Text,{type:"secondary",style:{fontSize:12,display:"block",marginTop:8},children:"⏳ 子 agent 仍在执行,报告尚未返回"})]}),w&&C&&e.jsxs(z,{size:"small",bordered:!0,children:[e.jsx(o.Text,{type:"secondary",style:{fontSize:12},children:"file:"})," ",e.jsx(o.Text,{code:!0,style:{color:"var(--cf-tag-green)"},children:C})]}),!y&&E&&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:E})})]})]})},a.id||v)})})]}),n.skillInvocations.length>0&&e.jsxs(z,{bordered:!0,style:{marginBottom:16},children:[e.jsxs(o.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6,marginBottom:12},children:[e.jsx(kt,{style:{color:"var(--cf-tag-purple)"}}),"Skill 调用",e.jsx(p,{size:"small",color:"gray",children:n.skillInvocations.length})]}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:8},children:n.skillInvocations.map(a=>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(o.Text,{style:{fontFamily:"monospace",fontSize:13,fontWeight:500,color:"var(--cf-tag-purple)"},children:a.skill_id}),a.workflow&&e.jsx(p,{size:"small",color:"purple",children:a.workflow}),a.phase&&e.jsxs(p,{size:"small",color:"purple",children:["phase: ",a.phase]})]}),e.jsx(o.Text,{style:{fontSize:12,color:"var(--color-text-2)"},children:a.reason})]},a.id))})]}),n.artifacts.length>0&&e.jsxs(z,{bordered:!0,children:[e.jsxs(o.Text,{style:{fontSize:13,fontWeight:600,display:"inline-flex",alignItems:"center",gap:6,marginBottom:12},children:[e.jsx(zt,{style:{color:"var(--cf-tag-green)"}}),"产物",e.jsxs(p,{size:"small",color:"gray",children:[n.artifacts.length," 个文件"]})]}),e.jsx(We,{size:"small",dataSource:n.artifacts,render:a=>e.jsx(We.Item,{style:{padding:"6px 12px"},children:e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:8},children:[e.jsx(pe,{style:{color:"var(--cf-tag-green)"}}),e.jsx(o.Text,{code:!0,style:{fontSize:12},title:a,children:a})]})},a)})]})]})}async function Wn(t){const s=await fetch(`/api/sessions/${t}/detail`);if(!s.ok)throw new Error("Failed to fetch session detail");return s.json()}function Rn({sessionId:t}){const{data:s,isLoading:r,error:n}=ne({queryKey:["session-detail",t],queryFn:()=>Wn(t),enabled:!!t});return r?e.jsx("div",{className:"p-6 text-gray-500",children:"加载中..."}):n||!s?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:s.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:s.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:s.tasks.length})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500",children:"开始时间"}),e.jsx("div",{className:"text-sm",children:s.session.start_time?se(L(s.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:s.tasks.map(i=>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:i.title}),e.jsx("span",{className:Dt("px-2 py-0.5 text-xs font-medium rounded-full whitespace-nowrap",i.status==="completed"&&"bg-green-100 text-green-700",i.status==="active"&&"bg-blue-100 text-blue-700",i.status==="abandoned"&&"bg-gray-100 text-gray-600"),children:i.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(At,{className:"h-3 w-3"}),"工具使用"]}),e.jsx("div",{className:"space-y-0.5",children:Object.entries(i.summary.toolUsage).slice(0,4).map(([l,x])=>e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:l}),e.jsx("span",{className:"font-mono text-gray-900",children:x})]},l))})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"text-gray-500 mb-1 flex items-center gap-1",children:[e.jsx(Ht,{className:"h-3 w-3"}),"文件变更"]}),e.jsxs("div",{className:"text-gray-700",children:[i.summary.filesChanged.length," 个"]}),i.summary.filesChanged.slice(0,3).map(l=>e.jsx("div",{className:"text-gray-500 truncate text-[10px]",title:l,children:l.split("/").pop()},l))]}),e.jsxs("div",{children:[e.jsxs("div",{className:"text-gray-500 mb-1 flex items-center gap-1",children:[e.jsx(Ot,{className:"h-3 w-3"}),"提交"]}),e.jsxs("div",{className:"text-gray-700",children:[i.summary.commits.length," 次"]})]})]}),i.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(Ut,{className:"h-3 w-3"}),"用户提示 (",i.prompts.length,")"]}),e.jsxs("div",{className:"space-y-1.5",children:[i.prompts.slice(0,3).map((l,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:l.content})},x)),i.prompts.length>3&&e.jsxs("div",{className:"text-xs text-gray-400",children:["还有 ",i.prompts.length-3," 条..."]})]})]})]},i.id))})]})]})}const Nn=720;function Pn(t){const s=t.get("task");if(s)return{kind:"task",id:s,paramKey:"task"};const r=t.get("session");return r?{kind:"session",id:r,paramKey:"session"}:null}function Dn(t){switch(t.kind){case"session":return`会话: ${t.id.slice(0,8)}...`;case"task":return`任务: ${t.id.slice(0,8)}...`}}function An(){const[t,s]=ze(),r=I.useMemo(()=>Pn(t),[t]),n=()=>{if(!r)return;const l=new URLSearchParams(t);l.delete(r.paramKey),s(l,{replace:!1})},i=!!r;return e.jsx(Ke,{title:r?Dn(r):"",width:Nn,placement:"right",visible:i,onCancel:n,footer:null,maskClosable:!0,unmountOnExit:!0,children:r?e.jsx(Hn,{target:r}):null})}function Hn({target:t}){return t.kind==="session"?e.jsx(Rn,{sessionId:t.id}):e.jsx(En,{taskId:t.id})}const On=[{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"}];function Un({active:t,counts:s,onChange:r}){return e.jsx("div",{style:{display:"inline-flex",gap:6,flexWrap:"wrap",alignItems:"center"},children:On.map(n=>{const i=n.key===t,l=s[n.key]??0;return e.jsxs(p,{checkable:!0,checked:i,onCheck:()=>r(n.key),color:i?n.color:void 0,style:{cursor:"pointer",fontSize:12,fontWeight:i?600:400,borderColor:i?void 0:"var(--color-border-2)"},children:[n.label," ",e.jsxs("span",{style:{opacity:.7,marginLeft:2},children:["(",l,")"]})]},n.key)})})}async function qn(t,s={}){const r=new URLSearchParams;r.set("window",String(s.windowDays??30)),t&&r.set("project",t),s.limit!=null&&r.set("limit",String(s.limit)),s.offset!=null&&r.set("offset",String(s.offset)),s.includeSystem&&r.set("include_kinds","user,agent-callback,image,system");const n=await fetch(`/api/insights/agent-board?${r.toString()}`);if(!n.ok)throw new Error(`API ${n.status}`);return n.json()}async function Kn(t,s={}){const r=new URLSearchParams;r.set("window",String(s.windowDays??30)),r.set("rows","prompt"),t&&r.set("project",t),s.limit!=null&&r.set("limit",String(s.limit)),s.offset!=null&&r.set("offset",String(s.offset)),s.includeSystem&&r.set("include_kinds","user,agent-callback,image,system");const n=await fetch(`/api/insights/agent-board?${r.toString()}`);if(!n.ok)throw new Error(`API ${n.status}`);return n.json()}function Jn(t){try{return se(L(t),"MM-dd HH:mm")}catch{return t}}function Ze(t){if(t==null)return"—";if(t<60)return`${t}s`;if(t<3600)return`${Math.round(t/60)}m`;const s=Math.floor(t/3600),r=Math.round(t%3600/60);return r>0?`${s}h ${r}m`:`${s}h`}function Xe(t){const s=Date.now()-L(t).getTime();return s<6e4?"刚刚":s<36e5?`${Math.round(s/6e4)}m 前`:s<864e5?`${Math.round(s/36e5)}h 前`:`${Math.round(s/864e5)}d 前`}function Gn(t){switch(t){case"agent-callback":return"回调";case"image":return"图片";case"system":return"系统";case"user":default:return""}}function Vn(t){return t!=="user"}const et={pending:{text:"待处理",color:"gray"},active:{text:"进行中",color:"arcoblue"},abandoned:{text:"中断",color:"orange"},completed:{text:"完成",color:"green"}};function Qn({row:t,group:s,onOpen:r}){const n=t.prompt_text||"(空 prompt)",i=n.length>160?`${n.slice(0,160)}…`:n,l=(s==null?void 0:s.lane)??"active",x=et[l];return e.jsx(z,{bordered:!0,hoverable:!0,onClick:()=>r(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(ee,{content:n,children:e.jsxs(o.Text,{style:{fontSize:13,color:"var(--color-text-1)"},children:["💬 ",i]})}),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:Xe(t.prompt_ts)}),e.jsx("span",{children:"·"}),e.jsx("span",{children:Jn(t.prompt_ts)})]})]}),e.jsx("div",{style:{flexShrink:0},children:s!=null&&s.outcome?e.jsx(qt,{value:s.outcome}):e.jsx(p,{color:x.color,size:"small",children:x.text})})]})})}const Yn=[{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 Zn({def:t,cards:s,onOpen:r,limit:n,onLoadMore:i}){const l=s.slice(0,n),x=Math.max(0,s.length-l.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(o.Text,{style:{fontSize:13,fontWeight:600},children:t.title}),e.jsx(p,{size:"small",style:{marginLeft:"auto"},children:s.length})]}),e.jsxs("div",{style:{flex:1,maxHeight:"calc(100vh - 300px)",overflowY:"auto",paddingRight:4},children:[s.length===0?e.jsx("div",{style:{padding:"16px 0",display:"flex",justifyContent:"center",opacity:.6},children:e.jsx(de,{description:"无任务"})}):l.map(m=>{const u=Vn(m.task_kind),b=u?"var(--color-fill-4)":m.status==="completed"?Kt(m.outcome):"var(--color-border-2)";return e.jsxs(z,{bordered:!0,size:"small",hoverable:!0,onClick:()=>r(m.task_id),"data-task-kind":m.task_kind,style:{marginBottom:8,background:u?"var(--color-fill-1)":"var(--color-bg-1)",borderLeft:`4px solid ${b}`,cursor:"pointer",opacity:u?.78:1},bodyStyle:{padding:"8px 10px"},children:[u&&e.jsx("div",{style:{marginBottom:4},children:e.jsx(p,{color:"gray",size:"small",style:{fontSize:10},children:Gn(m.task_kind)})}),e.jsx(o.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:m.title?m.title.length>80?m.title.slice(0,80)+"…":m.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:Xe(m.start_time)}),m.duration_sec!==null&&e.jsxs("span",{children:["· ",Ze(m.duration_sec)]}),m.files_changed>0&&e.jsxs("span",{children:["· ",m.files_changed," files"]}),m.kb_pages.length>0&&e.jsxs("span",{children:["· ",m.kb_pages.length," KB"]})]})]},m.task_id)}),x>0&&e.jsx("div",{style:{paddingTop:4},children:e.jsxs(D,{size:"mini",long:!0,type:"text",onClick:i,style:{fontSize:11,color:"var(--color-text-3)"},children:["再看 30 条(剩 ",x,")"]})})]})]})}function ps(){const[t,s]=ze(),r=t.get("project")??"",n=t.get("outcome")??"all",i=t.get("view")==="kanban"?"kanban":"list",l=t.get("q")??"",x=[7,30,90],m=parseInt(t.get("window")??"30",10),u=x.includes(m)?m:30,b=t.get("sys")==="1",a=[20,40,80],v=40,y=300,w=parseInt(t.get("page")??"1",10),g=parseInt(t.get("pageSize")??String(v),10),T=Number.isFinite(w)&&w>0?w:1,C=a.includes(g)?g:v,E=30,[H,W]=I.useState(E);I.useEffect(()=>{W(E)},[n,l]);const F=i==="list"?C:y,O=i==="list"?(T-1)*C:0,U=Ae(),$=i==="list",{data:k,isLoading:h,isError:S,refetch:_,isFetching:R}=ne({queryKey:["tasks-hub",r,"kanban",F,O,b,u],queryFn:()=>qn(r,{limit:F,offset:O,includeSystem:b,windowDays:u}),enabled:!$,refetchInterval:3e4,refetchIntervalInBackground:!1,placeholderData:Le}),{data:f,isLoading:Q,isError:N,refetch:G,isFetching:tt}=ne({queryKey:["tasks-hub",r,"prompt",F,O,b,u],queryFn:()=>Kn(r,{limit:F,offset:O,includeSystem:b,windowDays:u}),enabled:$,refetchInterval:3e4,refetchIntervalInBackground:!1,placeholderData:Le}),[ye,je]=I.useState(!1);I.useEffect(()=>{if(typeof EventSource>"u")return;const d=r?`/api/events/stream?project=${encodeURIComponent(r)}`:"/api/events/stream",c=new EventSource(d);let j=null;const P=()=>{j&&clearTimeout(j),j=setTimeout(()=>{U.invalidateQueries({queryKey:["tasks-hub"]})},700)};return c.onopen=()=>je(!0),c.onmessage=M=>{try{const A=JSON.parse(M.data||"{}");if((A==null?void 0:A.type)==="connected"){je(!0);return}}catch{}P()},c.onerror=()=>{je(!1)},()=>{j&&clearTimeout(j),c.close()}},[r,U]);const ue=I.useMemo(()=>k?[...k.lanes.pending,...k.lanes.active,...k.lanes.abandoned,...k.lanes.completed]:[],[k]),nt=I.useMemo(()=>{if($){const j=f?Object.values(f.groups).filter(M=>M.task_kind==="user"):[],P={all:j.length,success:0,partial:0,failed:0,abandoned:0};for(const M of j)M.outcome&&P[M.outcome]!==void 0?P[M.outcome]++:M.status==="abandoned"&&P.abandoned++;return P}const d=ue.filter(j=>j.task_kind==="user"),c={all:d.length,success:0,partial:0,failed:0,abandoned:0};for(const j of d)j.outcome&&c[j.outcome]!==void 0?c[j.outcome]++:j.status==="abandoned"&&c.abandoned++;return c},[$,f,ue]),st=I.useMemo(()=>{if(!k)return{pending:[],active:[],abandoned:[],failed:[],done:[]};const d=l.trim().toLowerCase(),c=A=>d?A.filter(B=>[B.title,...B.top_tools.map(Z=>Z.tool),...B.kb_pages.map(Z=>Z.name)].join(" ").toLowerCase().includes(d)):A,j=c(k.lanes.completed),P=j.filter(A=>A.outcome==="failed"),M=j.filter(A=>A.outcome!=="failed");return{pending:c(k.lanes.pending),active:c(k.lanes.active),abandoned:c(k.lanes.abandoned),failed:P,done:M}},[k,l]),V=I.useMemo(()=>{if($){const Y=(f?Object.values(f.groups):[]).filter(q=>q.task_kind==="user"),Z=Y.length,dt=Y.filter(q=>q.outcome==="failed").length,ve=Y.map(q=>q.duration_sec).filter(q=>typeof q=="number"&&q>0),pt=ve.length>0?Math.round(ve.reduce((q,xt)=>q+xt,0)/ve.length):0,mt=(f==null?void 0:f.total_in_window)??0;return{total:Z,failed:dt,intercepted:0,avgSec:pt,promptTotal:mt,groupCount:Z}}const d=ue.filter(B=>B.task_kind==="user"),c=(k==null?void 0:k.total_in_window)??d.length,j=d.filter(B=>B.outcome==="failed").length,P=d.filter(B=>B.intercepts.deny+B.intercepts.warn>0).length,M=d.map(B=>B.duration_sec).filter(B=>typeof B=="number"&&B>0),A=M.length>0?Math.round(M.reduce((B,Y)=>B+Y,0)/M.length):0;return{total:c,failed:j,intercepted:P,avgSec:A,promptTotal:0,groupCount:c}},[$,f,ue,k]),re=I.useMemo(()=>{if(!f)return[];const d=l.trim().toLowerCase();return f.rows.filter(c=>{const j=f.groups[c.group_id];if(n!=="all"){if(n==="abandoned"){if((j==null?void 0:j.outcome)!=="abandoned"&&(j==null?void 0:j.status)!=="abandoned")return!1}else if((j==null?void 0:j.outcome)!==n)return!1}return!(d&&![c.prompt_text,(j==null?void 0:j.title)??""].join(" ").toLowerCase().includes(d))})},[f,n,l]),rt=I.useMemo(()=>{const d=[],c=new Set;for(const j of re)c.has(j.group_id)||(c.add(j.group_id),d.push(j.group_id));return d},[re]),J=d=>s(d,{replace:!1}),oe=d=>{d.delete("page"),d.delete("pageSize")},Me=d=>{const c=new URLSearchParams(t);d==="all"?c.delete("outcome"):c.set("outcome",d),oe(c),J(c)},ot=d=>{const c=new URLSearchParams(t);d==="list"?c.delete("view"):c.set("view",d),oe(c),J(c)},it=d=>{const c=new URLSearchParams(t);d?c.set("q",d):c.delete("q"),oe(c),J(c)},lt=d=>{const c=new URLSearchParams(t);d?c.set("sys","1"):c.delete("sys"),oe(c),J(c)},be=d=>{const c=new URLSearchParams(t);c.set("task",d),J(c)},at=d=>{const c=new URLSearchParams(t);d===30?c.delete("window"):c.set("window",String(d)),oe(c),J(c)},ct=d=>{const c=new URLSearchParams(t);d<=1?c.delete("page"):c.set("page",String(d)),J(c)},Be=d=>{const c=new URLSearchParams(t);d===v?c.delete("pageSize"):c.set("pageSize",String(d)),c.delete("page"),J(c)};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(o.Title,{heading:5,style:{margin:0},children:"我的任务"}),e.jsxs(o.Text,{type:"secondary",style:{fontSize:12},children:["近 ",u,"d · ",$?"每行 = 1 条 user prompt(按任务分组)· 点行看执行链路":"看板按任务卡 · 点卡片看详情"]}),e.jsxs("div",{style:{marginLeft:"auto",display:"flex",gap:8,alignItems:"center"},children:[e.jsx(ee,{content:ye?"实时已连接(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:ye?"var(--cf-tag-green, #00B42A)":"var(--color-text-4, #C9CDD4)",display:"inline-block"}}),ye?"实时":"离线"]})}),e.jsx(Nt,{}),e.jsx(ie.Group,{type:"button",size:"small",value:u,onChange:d=>at(d),children:x.map(d=>e.jsxs(ie,{value:d,children:[d,"d"]},d))}),e.jsxs(ie.Group,{type:"button",size:"small",value:i,onChange:d=>ot(d),children:[e.jsxs(ie,{value:"list",children:[e.jsx(Ft,{})," 列表"]}),e.jsxs(ie,{value:"kanban",children:[e.jsx(Lt,{})," 看板"]})]}),e.jsx(D,{size:"small",icon:e.jsx(Ce,{}),loading:$?tt:R,onClick:()=>$?G():_(),children:"刷新"})]})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,flexWrap:"wrap"},children:[e.jsx(Un,{active:n,counts:nt,onChange:Me}),e.jsx(p,{checkable:!0,checked:b,onCheck:d=>lt(d),size:"small",color:b?"arcoblue":void 0,"data-testid":"sys-toggle",children:"含系统任务"}),e.jsx(Et.Search,{size:"small",placeholder:"搜索 title / tool / KB / file...",style:{width:280,marginLeft:"auto"},value:l,onChange:d=>it(d),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(le,{title:e.jsxs("span",{style:{fontSize:12,color:"var(--color-text-3)"},children:["总任务数 (",u,"d)"]}),value:V.total,groupSeparator:!0}),$&&e.jsx(le,{title:e.jsxs("span",{style:{fontSize:12,color:"var(--color-text-3)"},children:["prompt 数 (",u,"d)"]}),value:V.promptTotal,groupSeparator:!0}),e.jsx("div",{style:{cursor:"pointer"},onClick:()=>Me("failed"),title:"点击筛选失败任务",children:e.jsx(le,{title:e.jsx("span",{style:{fontSize:12,color:"#f44336"},children:"失败 (可点击 →)"}),value:V.failed,styleValue:{color:V.failed>0?"#f44336":void 0}})}),!$&&e.jsx(le,{title:e.jsx("span",{style:{fontSize:12,color:"var(--color-text-3)"},children:"被拦截"}),value:V.intercepted,styleValue:{color:V.intercepted>0?"#ff9800":void 0}}),e.jsx(le,{title:e.jsx("span",{style:{fontSize:12,color:"var(--color-text-3)"},children:"平均时长"}),value:Ze(V.avgSec)})]})}),$?N?e.jsx(z,{bordered:!0,children:e.jsx(de,{description:"加载失败"})}):Q||!f?e.jsx(z,{bordered:!0,children:e.jsx(me,{animation:!0,text:{rows:6}})}):e.jsxs("div",{style:{flex:1,minHeight:0,overflowY:"auto",display:"flex",flexDirection:"column"},children:[re.length===0?e.jsxs(z,{bordered:!0,children:[e.jsx(de,{description:n!=="all"?`近 ${u}d 无 ${n} prompt(当前页)`:`近 ${u}d 无 prompt(或被过滤掉)`}),(n!=="all"||l.length>0)&&((f==null?void 0:f.total_in_window)??0)>C&&e.jsxs(o.Text,{type:"secondary",style:{fontSize:11,display:"block",textAlign:"center",padding:12},children:["当前页无匹配;翻到其它页或清空筛选 (",e.jsx(De,{to:"?",children:"重置"}),")"]})]}):e.jsx("div",{style:{flex:1},children:rt.map(d=>{const c=f.groups[d],j=re.filter(M=>M.group_id===d),P=et[(c==null?void 0:c.lane)??"active"];return e.jsxs("div",{style:{marginBottom:14},"data-group-section":d,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(o.Text,{style:{fontSize:12,fontWeight:600,cursor:"pointer"},onClick:()=>be(d),children:["🎯 ",(c==null?void 0:c.title)||"(空 title)"]}),e.jsx(p,{size:"small",color:P.color,children:P.text}),e.jsx(p,{size:"small",style:{fontFamily:"monospace"},children:d.slice(0,8)}),e.jsxs(o.Text,{type:"secondary",style:{fontSize:11},children:[(c==null?void 0:c.prompt_count)??j.length," 条 prompt"]})]}),j.map(M=>e.jsx(Qn,{row:M,group:c,onOpen:be},M.event_id))]},d)})}),((f==null?void 0:f.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(o.Text,{type:"secondary",style:{fontSize:11},children:["近 ",u,"d 共 ",(f==null?void 0:f.total_in_window)??0," 条 prompt(",(f==null?void 0:f.summary.total_groups)??0," 个分组)· 第 ",T," / ",Math.max(1,Math.ceil(((f==null?void 0:f.total_in_window)??0)/C))," 页",(n!=="all"||l.length>0)&&e.jsxs("span",{style:{marginLeft:8},children:["(当前页 ",re.length," / ",(f==null?void 0:f.rows.length)??0," 条过滤后)"]})]}),e.jsx(Wt,{current:T,total:(f==null?void 0:f.total_in_window)??0,pageSize:C,sizeOptions:[...a],sizeCanChange:!0,showJumper:!0,size:"small",onChange:(d,c)=>{c!==C?Be(c):ct(d)},onPageSizeChange:d=>Be(d)})]})]}):S?e.jsx(z,{bordered:!0,children:e.jsx(de,{description:"加载失败"})}):h||!k?e.jsx(z,{bordered:!0,children:e.jsx(me,{animation:!0,text:{rows:6}})}):e.jsx("div",{style:{display:"flex",gap:12,flex:1,minHeight:0,overflowX:"auto"},children:Yn.map(d=>e.jsx(Zn,{def:d,cards:st[d.key]??[],onOpen:be,limit:H,onLoadMore:()=>W(c=>c+E)},d.key))}),e.jsx(An,{})]})}export{ps as default};
|
|
6
|
+
//# sourceMappingURL=TasksHubPage-03wsRRsJ.js.map
|