@winspan/claude-forge 8.50.6 → 8.51.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/CLAUDE.md +7 -7
- package/dist/claudemd/claudemd-generator.d.ts.map +1 -1
- package/dist/claudemd/claudemd-generator.js +27 -237
- package/dist/claudemd/claudemd-generator.js.map +1 -1
- package/dist/claudemd/resume-manager.js +1 -1
- package/dist/claudemd/resume-manager.js.map +1 -1
- package/dist/claudemd/templates/swarm-protocol.md +222 -0
- package/dist/cli/commands/daemon.js +6 -6
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/cli/commands/executions.d.ts.map +1 -1
- package/dist/cli/commands/executions.js +4 -3
- package/dist/cli/commands/executions.js.map +1 -1
- package/dist/cli/commands/init.js +2 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +3 -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 +4 -3
- package/dist/cli/commands/menu.js.map +1 -1
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +2 -3
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/status.js +2 -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 +11 -23
- package/dist/cli/commands/trace.js.map +1 -1
- package/dist/cli/init/hook-manager.d.ts.map +1 -1
- package/dist/cli/init/hook-manager.js +2 -2
- package/dist/cli/init/hook-manager.js.map +1 -1
- package/dist/core/ai/provider.js +2 -2
- package/dist/core/ai/provider.js.map +1 -1
- package/dist/core/constants.d.ts +12 -1
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +15 -1
- package/dist/core/constants.js.map +1 -1
- package/dist/core/event-fields.d.ts +16 -0
- package/dist/core/event-fields.d.ts.map +1 -0
- package/dist/core/event-fields.js +19 -0
- package/dist/core/event-fields.js.map +1 -0
- package/dist/core/queue/index.d.ts.map +1 -1
- package/dist/core/queue/index.js +3 -4
- package/dist/core/queue/index.js.map +1 -1
- package/dist/core/storage/base.d.ts +36 -3
- package/dist/core/storage/base.d.ts.map +1 -1
- package/dist/core/storage/base.js +101 -58
- package/dist/core/storage/base.js.map +1 -1
- package/dist/core/storage/events.d.ts +92 -3
- package/dist/core/storage/events.d.ts.map +1 -1
- package/dist/core/storage/events.js +147 -0
- package/dist/core/storage/events.js.map +1 -1
- package/dist/core/storage/routing.d.ts +54 -1
- package/dist/core/storage/routing.d.ts.map +1 -1
- package/dist/core/storage/routing.js +99 -1
- package/dist/core/storage/routing.js.map +1 -1
- package/dist/core/storage/schema.sql +12 -2
- package/dist/core/storage/sessions.d.ts +20 -0
- package/dist/core/storage/sessions.d.ts.map +1 -1
- package/dist/core/storage/sessions.js +59 -0
- package/dist/core/storage/sessions.js.map +1 -1
- package/dist/core/storage/skills.d.ts +23 -0
- package/dist/core/storage/skills.d.ts.map +1 -1
- package/dist/core/storage/skills.js +47 -0
- package/dist/core/storage/skills.js.map +1 -1
- package/dist/core/storage/sqlite.d.ts +35 -2
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +93 -4
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts +49 -0
- package/dist/core/storage/tasks.d.ts.map +1 -1
- package/dist/core/storage/tasks.js +143 -1
- package/dist/core/storage/tasks.js.map +1 -1
- package/dist/core/storage/token-usage.d.ts +1 -1
- package/dist/core/storage/token-usage.d.ts.map +1 -1
- package/dist/core/storage/token-usage.js +1 -1
- package/dist/core/storage/token-usage.js.map +1 -1
- package/dist/core/types.d.ts +24 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/error-handler.d.ts.map +1 -1
- package/dist/core/utils/error-handler.js +3 -2
- package/dist/core/utils/error-handler.js.map +1 -1
- package/dist/core/utils/git.d.ts +10 -0
- package/dist/core/utils/git.d.ts.map +1 -0
- package/dist/core/utils/git.js +24 -0
- package/dist/core/utils/git.js.map +1 -0
- package/dist/core/utils/logger.d.ts.map +1 -1
- package/dist/core/utils/logger.js +15 -1
- package/dist/core/utils/logger.js.map +1 -1
- package/dist/core/utils/lru-cache.d.ts +1 -0
- package/dist/core/utils/lru-cache.d.ts.map +1 -1
- package/dist/core/utils/lru-cache.js +3 -0
- package/dist/core/utils/lru-cache.js.map +1 -1
- package/dist/core/utils/token-tracker.js +1 -1
- package/dist/core/utils/token-tracker.js.map +1 -1
- package/dist/daemon/event-parser.d.ts.map +1 -1
- package/dist/daemon/event-parser.js +2 -1
- package/dist/daemon/event-parser.js.map +1 -1
- package/dist/daemon/handlers/history-exporter.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +7 -3
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/stop.d.ts +4 -0
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +23 -35
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts +3 -3
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +12 -22
- package/dist/daemon/handlers/user-prompt.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +23 -9
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/lifecycle.js +3 -4
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/server.d.ts +6 -4
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +76 -85
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/services/task-segmenter.js +1 -1
- package/dist/daemon/services/task-segmenter.js.map +1 -1
- package/dist/hooks/hook-lib.sh +37 -0
- package/dist/hooks/notification.sh +2 -2
- package/dist/hooks/post-tool-use.sh +2 -2
- package/dist/hooks/pre-tool-use.sh +2 -2
- package/dist/hooks/stop.sh +9 -6
- package/dist/hooks/user-prompt-submit.sh +2 -2
- package/dist/{daemon/services → web/analytics}/anti-pattern-detector.d.ts +3 -4
- package/dist/web/analytics/anti-pattern-detector.d.ts.map +1 -0
- package/dist/{daemon/services → web/analytics}/anti-pattern-detector.js +7 -46
- package/dist/{daemon/services → web/analytics}/anti-pattern-detector.js.map +1 -1
- package/dist/web/analytics/drift-detector.d.ts.map +1 -0
- package/dist/{daemon/services → web/analytics}/drift-detector.js +10 -13
- package/dist/web/analytics/drift-detector.js.map +1 -0
- package/dist/web/analytics/weekly-report.d.ts.map +1 -0
- package/dist/{daemon/services → web/analytics}/weekly-report.js +51 -50
- package/dist/web/analytics/weekly-report.js.map +1 -0
- package/dist/web/auth-middleware.d.ts.map +1 -1
- package/dist/web/auth-middleware.js +1 -2
- package/dist/web/auth-middleware.js.map +1 -1
- package/dist/web/routes/_helpers.d.ts +16 -0
- package/dist/web/routes/_helpers.d.ts.map +1 -0
- package/dist/web/routes/_helpers.js +32 -0
- package/dist/web/routes/_helpers.js.map +1 -0
- package/dist/web/routes/drift.js +1 -1
- package/dist/web/routes/drift.js.map +1 -1
- package/dist/web/routes/insights.js +1 -1
- package/dist/web/routes/insights.js.map +1 -1
- package/dist/web/routes/reports.js +1 -1
- package/dist/web/routes/reports.js.map +1 -1
- package/dist/web/routes/rules.d.ts +3 -0
- package/dist/web/routes/rules.d.ts.map +1 -1
- package/dist/web/routes/rules.js +28 -52
- 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 +16 -30
- package/dist/web/routes/sessions.js.map +1 -1
- package/dist/web/routes/skill-stats.d.ts +2 -0
- package/dist/web/routes/skill-stats.d.ts.map +1 -1
- package/dist/web/routes/skill-stats.js +28 -64
- package/dist/web/routes/skill-stats.js.map +1 -1
- package/dist/web/routes/skills.d.ts.map +1 -1
- package/dist/web/routes/skills.js +5 -4
- package/dist/web/routes/skills.js.map +1 -1
- package/dist/web/routes/stats.d.ts +4 -0
- package/dist/web/routes/stats.d.ts.map +1 -1
- package/dist/web/routes/stats.js +19 -21
- package/dist/web/routes/stats.js.map +1 -1
- package/dist/web/routes/tasks.d.ts.map +1 -1
- package/dist/web/routes/tasks.js +17 -42
- 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 +7 -17
- package/dist/web/routes/trace.js.map +1 -1
- package/dist/web/routes/types.d.ts.map +1 -1
- package/dist/web/routes/types.js +4 -3
- package/dist/web/routes/types.js.map +1 -1
- package/dist/web/static/assets/{AIConfig-BQCAQE9D.js → AIConfig-CdDWzJyO.js} +2 -2
- package/dist/web/static/assets/{AIConfig-BQCAQE9D.js.map → AIConfig-CdDWzJyO.js.map} +1 -1
- package/dist/web/static/assets/{Dashboard-D7Bo6Kan.js → Dashboard-CoEmmIDt.js} +2 -2
- package/dist/web/static/assets/{Dashboard-D7Bo6Kan.js.map → Dashboard-CoEmmIDt.js.map} +1 -1
- package/dist/web/static/assets/{Drawer-BeHRQxUS.js → Drawer-DdRTzlLB.js} +2 -2
- package/dist/web/static/assets/{Drawer-BeHRQxUS.js.map → Drawer-DdRTzlLB.js.map} +1 -1
- package/dist/web/static/assets/{Events-K_tCY2ti.js → Events-DrIq1SUS.js} +2 -2
- package/dist/web/static/assets/{Events-K_tCY2ti.js.map → Events-DrIq1SUS.js.map} +1 -1
- package/dist/web/static/assets/{Reports-BJCmBnc_.js → Reports-DFBM3MDK.js} +2 -2
- package/dist/web/static/assets/{Reports-BJCmBnc_.js.map → Reports-DFBM3MDK.js.map} +1 -1
- package/dist/web/static/assets/{SearchInput-BX2KhMkw.js → SearchInput-qCj_jAcf.js} +2 -2
- package/dist/web/static/assets/{SearchInput-BX2KhMkw.js.map → SearchInput-qCj_jAcf.js.map} +1 -1
- package/dist/web/static/assets/{SessionDetail-Bkr-kC7V.js → SessionDetail-CCzwdoT7.js} +2 -2
- package/dist/web/static/assets/{SessionDetail-Bkr-kC7V.js.map → SessionDetail-CCzwdoT7.js.map} +1 -1
- package/dist/web/static/assets/{Sessions-Chx9OCLH.js → Sessions-FfLYkAw9.js} +2 -2
- package/dist/web/static/assets/{Sessions-Chx9OCLH.js.map → Sessions-FfLYkAw9.js.map} +1 -1
- package/dist/web/static/assets/{Skills-O0GT1i7m.js → Skills-C8Gvs3Qa.js} +2 -2
- package/dist/web/static/assets/{Skills-O0GT1i7m.js.map → Skills-C8Gvs3Qa.js.map} +1 -1
- package/dist/web/static/assets/TaskDetail-BS8pYhaR.js +2 -0
- package/dist/web/static/assets/TaskDetail-BS8pYhaR.js.map +1 -0
- package/dist/web/static/assets/Tasks-CyuhizG8.js +2 -0
- package/dist/web/static/assets/Tasks-CyuhizG8.js.map +1 -0
- package/dist/web/static/assets/index-CBX47X8l.js +3 -0
- package/dist/web/static/assets/{index-DxIbmNmr.js.map → index-CBX47X8l.js.map} +1 -1
- package/dist/web/static/assets/index-DjIoMdoR.css +1 -0
- package/dist/web/static/assets/{lucide-fJlPI3H7.js → lucide-Bs_edTLa.js} +44 -39
- package/dist/web/static/assets/lucide-Bs_edTLa.js.map +1 -0
- package/dist/web/static/assets/react-router-r79dBVy4.js +20 -0
- package/dist/web/static/assets/{react-router-I-HqunH7.js.map → react-router-r79dBVy4.js.map} +1 -1
- package/dist/web/static/assets/task-title-BhOcemuR.js +2 -0
- package/dist/web/static/assets/task-title-BhOcemuR.js.map +1 -0
- package/dist/web/static/index.html +4 -4
- package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +299 -0
- package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +191 -0
- package/docs/design/h3-fallback-removal-spec-20260518-1245.md +76 -0
- package/docs/design/h4-index-dedup-spec-20260518-1230.md +109 -0
- package/docs/design/h6-services-migration-spec-20260518-1355.md +82 -0
- package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +106 -0
- package/docs/design/m10-forge-paths-spec-20260518-1320.md +121 -0
- package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +131 -0
- package/docs/design/m7-routing-event-association-spec-20260518-1545.md +103 -0
- package/docs/design/project-path-gitroot-spec-20260518-1715.md +134 -0
- package/docs/design/task-active-gc-spec-20260518-1745.md +146 -0
- package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +82 -0
- package/docs/implementation/h2-final-changelog-20260518-1530.md +61 -0
- package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +70 -0
- package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +120 -0
- package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +71 -0
- package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +71 -0
- package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +60 -0
- package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +46 -0
- package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +46 -0
- package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +45 -0
- package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +63 -0
- package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +38 -0
- package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +58 -0
- package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +60 -0
- package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +43 -0
- package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +56 -0
- package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +69 -0
- package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +63 -0
- package/docs/implementation/task-active-gc-changelog-20260518-1745.md +35 -0
- package/docs/implementation/task-title-summary-changelog-20260518-1130.md +39 -0
- package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +22 -0
- package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +56 -0
- package/docs/reviews/task-title-summary.md +92 -0
- package/docs/reviews/tasks-detail-back-loses-filters.md +58 -0
- package/docs/reviews/tasks-page-white-screen-hotfix.md +126 -0
- package/package.json +2 -2
- package/src/claudemd/claudemd-generator.ts +29 -238
- package/src/claudemd/resume-manager.ts +1 -1
- package/src/claudemd/templates/swarm-protocol.md +222 -0
- package/src/cli/commands/daemon.ts +6 -6
- package/src/cli/commands/executions.ts +4 -3
- package/src/cli/commands/init.ts +2 -2
- package/src/cli/commands/logs.ts +1 -1
- package/src/cli/commands/mcp.ts +3 -5
- package/src/cli/commands/menu.ts +4 -3
- package/src/cli/commands/stats.ts +2 -3
- package/src/cli/commands/status.ts +2 -2
- package/src/cli/commands/trace.ts +10 -26
- package/src/cli/init/hook-manager.ts +2 -2
- package/src/core/ai/provider.ts +2 -2
- package/src/core/constants.ts +18 -1
- package/src/core/event-fields.ts +32 -0
- package/src/core/queue/index.ts +3 -4
- package/src/core/storage/base.ts +132 -56
- package/src/core/storage/events.ts +183 -4
- package/src/core/storage/routing.ts +129 -1
- package/src/core/storage/schema.sql +12 -2
- package/src/core/storage/sessions.ts +64 -0
- package/src/core/storage/skills.ts +69 -0
- package/src/core/storage/sqlite.ts +103 -4
- package/src/core/storage/tasks.ts +149 -1
- package/src/core/storage/token-usage.ts +1 -1
- package/src/core/types.ts +30 -3
- package/src/core/utils/error-handler.ts +3 -2
- package/src/core/utils/git.ts +23 -0
- package/src/core/utils/logger.ts +16 -1
- package/src/core/utils/lru-cache.ts +4 -0
- package/src/core/utils/token-tracker.ts +1 -1
- package/src/daemon/event-parser.ts +4 -3
- package/src/daemon/handlers/history-exporter.ts +1 -1
- package/src/daemon/handlers/post-tool-use.ts +7 -3
- package/src/daemon/handlers/stop.ts +32 -39
- package/src/daemon/handlers/user-prompt.ts +12 -22
- package/src/daemon/index.ts +24 -10
- package/src/daemon/lifecycle.ts +3 -3
- package/src/daemon/server.ts +76 -89
- package/src/daemon/services/task-segmenter.ts +1 -1
- package/src/hooks/hook-lib.sh +37 -0
- package/src/hooks/notification.sh +2 -2
- package/src/hooks/post-tool-use.sh +2 -2
- package/src/hooks/pre-tool-use.sh +2 -2
- package/src/hooks/stop.sh +9 -6
- package/src/hooks/user-prompt-submit.sh +2 -2
- package/src/{daemon/services → web/analytics}/anti-pattern-detector.ts +9 -54
- package/src/{daemon/services → web/analytics}/drift-detector.ts +10 -23
- package/src/{daemon/services → web/analytics}/weekly-report.ts +52 -75
- package/src/web/auth-middleware.ts +1 -2
- package/src/web/routes/_helpers.ts +34 -0
- package/src/web/routes/drift.ts +1 -1
- package/src/web/routes/insights.ts +1 -1
- package/src/web/routes/reports.ts +1 -1
- package/src/web/routes/rules.ts +31 -56
- package/src/web/routes/sessions.ts +18 -30
- package/src/web/routes/skill-stats.ts +29 -69
- package/src/web/routes/skills.ts +5 -4
- package/src/web/routes/stats.ts +19 -29
- package/src/web/routes/tasks.ts +17 -42
- package/src/web/routes/trace.ts +7 -19
- package/src/web/routes/types.ts +4 -3
- package/tests/integration/claudemd-generator.test.ts +90 -0
- package/tests/integration/web-analytics.integration.test.ts +133 -0
- package/tests/integration/web-stats.integration.test.ts +135 -0
- package/tests/integration/web-trace.integration.test.ts +175 -0
- package/tests/unit/core/forge-paths.test.ts +99 -0
- package/tests/unit/daemon/post-tool-use.test.ts +121 -0
- package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +202 -0
- package/tests/unit/daemon/task-segmenter-recover.test.ts +84 -0
- package/tests/unit/event-fields.test.ts +88 -0
- package/tests/unit/event-parser.test.ts +55 -0
- package/tests/unit/hooks/resolve-project-path.test.ts +122 -0
- package/tests/unit/socket-server.test.ts +183 -0
- package/tests/unit/storage/event-operations-aggregates.test.ts +342 -0
- package/tests/unit/storage/migration-idempotent.test.ts +304 -0
- package/tests/unit/storage/routing-aggregates.test.ts +276 -0
- package/tests/unit/storage/routing.test.ts +117 -0
- package/tests/unit/storage/schema-missing.test.ts +81 -0
- package/tests/unit/storage/session-operations-aggregates.test.ts +120 -0
- package/tests/unit/storage/skill-operations-counts.test.ts +106 -0
- package/tests/unit/storage/skills-aggregates.test.ts +104 -0
- package/tests/unit/storage/sqlite-refactor-harness.test.ts +3 -3
- package/tests/unit/storage/task-operations-counts.test.ts +46 -0
- package/tests/unit/storage/tasks-getById.test.ts +343 -0
- package/tests/unit/storage/tasks-stale-gc.test.ts +86 -0
- package/tests/unit/token-usage.test.ts +6 -6
- package/tests/unit/web/navigation-back-contract.test.ts +134 -0
- package/tests/unit/web/routes-rules.test.ts +182 -0
- package/tests/unit/web/routes-tasks.test.ts +34 -0
- package/tests/unit/web/task-title-contract.test.ts +210 -0
- package/tests/unit/web/tasks-component-contract.test.ts +179 -0
- package/vitest.config.ts +1 -1
- package/web/src/pages/TaskDetail.tsx +9 -5
- package/web/src/pages/Tasks.tsx +315 -50
- package/web/src/utils/navigation.ts +25 -0
- package/web/src/utils/task-title.ts +49 -0
- package/dist/daemon/services/anti-pattern-detector.d.ts.map +0 -1
- package/dist/daemon/services/drift-detector.d.ts.map +0 -1
- package/dist/daemon/services/drift-detector.js.map +0 -1
- package/dist/daemon/services/weekly-report.d.ts.map +0 -1
- package/dist/daemon/services/weekly-report.js.map +0 -1
- package/dist/web/static/assets/TaskDetail-5SR8zGzv.js +0 -2
- package/dist/web/static/assets/TaskDetail-5SR8zGzv.js.map +0 -1
- package/dist/web/static/assets/Tasks-DCgDqvOZ.js +0 -2
- package/dist/web/static/assets/Tasks-DCgDqvOZ.js.map +0 -1
- package/dist/web/static/assets/index-D8AKj26b.css +0 -1
- package/dist/web/static/assets/index-DxIbmNmr.js +0 -3
- package/dist/web/static/assets/lucide-fJlPI3H7.js.map +0 -1
- package/dist/web/static/assets/react-router-I-HqunH7.js +0 -20
- /package/dist/{daemon/services → web/analytics}/drift-detector.d.ts +0 -0
- /package/dist/{daemon/services → web/analytics}/weekly-report.d.ts +0 -0
package/dist/web/routes/tasks.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { truncateField } from './_helpers.js';
|
|
3
|
+
import { getFilePath, getUserPrompt } from '../../core/event-fields.js';
|
|
2
4
|
/**
|
|
3
5
|
* /api/tasks — Task execution view.
|
|
4
6
|
*
|
|
@@ -47,24 +49,18 @@ export function registerTasksRoutes(app, ctx) {
|
|
|
47
49
|
// ── GET /api/tasks/:taskId — full execution detail ─────────────────────────
|
|
48
50
|
app.get('/api/tasks/:taskId', (req, res) => {
|
|
49
51
|
const taskId = req.params.taskId;
|
|
50
|
-
//
|
|
51
|
-
const
|
|
52
|
-
const task = allTasks.find(t => t.id === taskId);
|
|
52
|
+
// H1: PK direct fetch (was: queryTasks({limit:5000}).find)
|
|
53
|
+
const task = storage.getTask(taskId);
|
|
53
54
|
if (!task) {
|
|
54
55
|
res.status(404).json({ error: 'Task not found' });
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
57
|
-
//
|
|
58
|
-
const
|
|
59
|
-
// Fetch all events for the session, then filter to task events
|
|
60
|
-
const allEvents = storage.queryEvents({ session_id: task.session_id, limit: 5000 });
|
|
61
|
-
const taskEvents = allEvents.filter(e => e.event_id && eventIds.has(e.event_id));
|
|
62
|
-
// Sort by timestamp ascending (chronological order)
|
|
63
|
-
taskEvents.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
58
|
+
// H1: JOIN task_events (was: queryEvents({limit:5000}) + Set.has filter)
|
|
59
|
+
const taskEvents = storage.queryEventsByTaskId(taskId, { limit: 5000 });
|
|
64
60
|
// ── Injections ──────────────────────────────────────────────────────
|
|
65
|
-
|
|
61
|
+
// H1: JOIN task_events (was: queryInjections({limit:500}) + Set.has filter)
|
|
62
|
+
const allInjections = storage.queryInjectionsByTaskId(taskId);
|
|
66
63
|
const injections = allInjections
|
|
67
|
-
.filter(inj => inj.event_id && eventIds.has(inj.event_id))
|
|
68
64
|
.map(inj => ({
|
|
69
65
|
id: inj.id,
|
|
70
66
|
timestamp: inj.timestamp,
|
|
@@ -75,22 +71,6 @@ export function registerTasksRoutes(app, ctx) {
|
|
|
75
71
|
truncated: inj.content.length > 1000,
|
|
76
72
|
}));
|
|
77
73
|
// ── Timeline ────────────────────────────────────────────────────────
|
|
78
|
-
const truncateField = (obj, maxLen = 300) => {
|
|
79
|
-
if (!obj)
|
|
80
|
-
return obj;
|
|
81
|
-
if (typeof obj === 'string')
|
|
82
|
-
return obj.length > maxLen ? obj.slice(0, maxLen) + '...' : obj;
|
|
83
|
-
if (Array.isArray(obj))
|
|
84
|
-
return obj.slice(0, 10);
|
|
85
|
-
if (typeof obj === 'object') {
|
|
86
|
-
const result = {};
|
|
87
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
88
|
-
result[k] = truncateField(v, maxLen);
|
|
89
|
-
}
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
return obj;
|
|
93
|
-
};
|
|
94
74
|
const timeline = taskEvents
|
|
95
75
|
.filter(e => e.tool_name && (e.hook_type === 'PreToolUse' || e.hook_type === 'PostToolUse'))
|
|
96
76
|
.reduce((acc, e) => {
|
|
@@ -103,7 +83,7 @@ export function registerTasksRoutes(app, ctx) {
|
|
|
103
83
|
}
|
|
104
84
|
return acc;
|
|
105
85
|
}
|
|
106
|
-
const toolInput = e.tool_input;
|
|
86
|
+
const toolInput = e.tool_input ?? null;
|
|
107
87
|
const isAgentCall = e.tool_name === 'Agent' || e.tool_name === 'Task';
|
|
108
88
|
const entry = {
|
|
109
89
|
timestamp: e.timestamp,
|
|
@@ -115,8 +95,8 @@ export function registerTasksRoutes(app, ctx) {
|
|
|
115
95
|
};
|
|
116
96
|
if (isAgentCall && toolInput) {
|
|
117
97
|
entry.agent_detail = {
|
|
118
|
-
subagent_type: toolInput.subagent_type,
|
|
119
|
-
name: toolInput.name,
|
|
98
|
+
subagent_type: typeof toolInput.subagent_type === 'string' ? toolInput.subagent_type : undefined,
|
|
99
|
+
name: typeof toolInput.name === 'string' ? toolInput.name : undefined,
|
|
120
100
|
prompt: typeof toolInput.prompt === 'string'
|
|
121
101
|
? toolInput.prompt
|
|
122
102
|
: undefined,
|
|
@@ -126,14 +106,9 @@ export function registerTasksRoutes(app, ctx) {
|
|
|
126
106
|
return acc;
|
|
127
107
|
}, []);
|
|
128
108
|
// ── Skill Invocations ───────────────────────────────────────────────
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const taskStart = task.start_time;
|
|
132
|
-
const taskEnd = task.end_time || new Date().toISOString();
|
|
133
|
-
const taskStartMs = new Date(taskStart).getTime();
|
|
134
|
-
const taskEndMs = new Date(taskEnd).getTime();
|
|
109
|
+
// H1: SQL window filter (was: querySkillInvocations({limit:200}) + JS time filter)
|
|
110
|
+
const allSkillInvocations = storage.querySkillInvocationsByTaskWindow(taskId);
|
|
135
111
|
const skillInvocations = allSkillInvocations
|
|
136
|
-
.filter(si => si.timestamp >= taskStartMs && si.timestamp <= taskEndMs)
|
|
137
112
|
.map(si => ({
|
|
138
113
|
id: si.id,
|
|
139
114
|
skill_id: si.skill_id,
|
|
@@ -150,14 +125,14 @@ export function registerTasksRoutes(app, ctx) {
|
|
|
150
125
|
// ── Artifacts ───────────────────────────────────────────────────────
|
|
151
126
|
const artifacts = [...new Set(taskEvents
|
|
152
127
|
.filter(e => (e.tool_name === 'Edit' || e.tool_name === 'Write') &&
|
|
153
|
-
e
|
|
154
|
-
.map(e => e
|
|
128
|
+
getFilePath(e))
|
|
129
|
+
.map(e => getFilePath(e)))];
|
|
155
130
|
// ── User Prompts ────────────────────────────────────────────────────
|
|
156
131
|
const userPrompts = taskEvents
|
|
157
|
-
.filter(e => e.hook_type === 'UserPromptSubmit' && (e
|
|
132
|
+
.filter(e => e.hook_type === 'UserPromptSubmit' && getUserPrompt(e))
|
|
158
133
|
.map(e => ({
|
|
159
134
|
timestamp: e.timestamp,
|
|
160
|
-
content: e
|
|
135
|
+
content: getUserPrompt(e),
|
|
161
136
|
}));
|
|
162
137
|
res.json({
|
|
163
138
|
task: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/web/routes/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/web/routes/tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../../src/web/routes/trace.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../../src/web/routes/trace.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,GAAG,IAAI,CAgH7E"}
|
package/dist/web/routes/trace.js
CHANGED
|
@@ -81,7 +81,7 @@ export function registerTraceRoutes(app, ctx) {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
// 4. Query session details
|
|
84
|
-
|
|
84
|
+
// H2 Phase 3: 改用 facade 聚合方法,消除 db.prepare 直写。
|
|
85
85
|
const allSessions = storage.querySessions({ limit: 5000 });
|
|
86
86
|
const sessionDetails = sessionIds.map(sid => {
|
|
87
87
|
const session = allSessions.find(s => s.session_id === sid || s.session_id.startsWith(sid));
|
|
@@ -91,19 +91,9 @@ export function registerTraceRoutes(app, ctx) {
|
|
|
91
91
|
const start = new Date(session.start_time);
|
|
92
92
|
const end = new Date(session.end_time);
|
|
93
93
|
const durationMin = Math.round((end.getTime() - start.getTime()) / 60000);
|
|
94
|
-
const eventBreakdown =
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
`).all(fullId);
|
|
98
|
-
const agentRows = db.prepare(`
|
|
99
|
-
SELECT json_extract(tool_input, '$.subagent_type') as agent_type, COUNT(*) as cnt
|
|
100
|
-
FROM events
|
|
101
|
-
WHERE session_id = ? AND tool_name IN ('Agent', 'Task') AND tool_input IS NOT NULL
|
|
102
|
-
GROUP BY agent_type
|
|
103
|
-
`).all(fullId);
|
|
104
|
-
const skillRows = db.prepare(`
|
|
105
|
-
SELECT DISTINCT skill_id FROM skill_invocations WHERE session_id = ?
|
|
106
|
-
`).all(fullId);
|
|
94
|
+
const eventBreakdown = storage.aggregateHookTypeBySession(fullId);
|
|
95
|
+
const agentRows = storage.aggregateAgentTypeBySession(fullId);
|
|
96
|
+
const skillIds = storage.queryDistinctSkillIdsBySession(fullId);
|
|
107
97
|
return {
|
|
108
98
|
session_id: fullId,
|
|
109
99
|
found: true,
|
|
@@ -112,9 +102,9 @@ export function registerTraceRoutes(app, ctx) {
|
|
|
112
102
|
end_time: session.end_time,
|
|
113
103
|
duration_min: durationMin,
|
|
114
104
|
event_count: session.event_count,
|
|
115
|
-
event_breakdown: Object.fromEntries(eventBreakdown.map(r => [r.hook_type, r.
|
|
116
|
-
agent_calls: agentRows.filter(r => r.agent_type).map(r => ({ type: r.agent_type, count: r.
|
|
117
|
-
skills:
|
|
105
|
+
event_breakdown: Object.fromEntries(eventBreakdown.map(r => [r.hook_type, r.count])),
|
|
106
|
+
agent_calls: agentRows.filter(r => r.agent_type).map(r => ({ type: r.agent_type, count: r.count })),
|
|
107
|
+
skills: skillIds,
|
|
118
108
|
};
|
|
119
109
|
});
|
|
120
110
|
res.json({ commit: commitHash, message: commitMessage, sessions: sessionDetails });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/web/routes/trace.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/web/routes/trace.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/web/routes/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/web/routes/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG9D,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,aAAa,CAAC;IACvB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAmBzC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjE"}
|
package/dist/web/routes/types.js
CHANGED
|
@@ -5,6 +5,7 @@ import path from 'path';
|
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import { homedir } from 'os';
|
|
8
|
+
import { FORGE_PATHS } from '../../core/constants.js';
|
|
8
9
|
/**
|
|
9
10
|
* Resolve the concrete on-disk path + backup dir for a patchable target.
|
|
10
11
|
*/
|
|
@@ -16,13 +17,13 @@ export function resolvePatchTarget(targetType, targetName) {
|
|
|
16
17
|
if (targetType === 'skill') {
|
|
17
18
|
return {
|
|
18
19
|
filePath: path.join(homedir(), '.claude', 'skills', `${targetName}.md`),
|
|
19
|
-
backupDir:
|
|
20
|
+
backupDir: FORGE_PATHS.backups('skills'),
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
if (targetType === 'routing_rule') {
|
|
23
24
|
return {
|
|
24
|
-
filePath:
|
|
25
|
-
backupDir:
|
|
25
|
+
filePath: FORGE_PATHS.routingYaml(),
|
|
26
|
+
backupDir: FORGE_PATHS.backups('routing'),
|
|
26
27
|
};
|
|
27
28
|
}
|
|
28
29
|
throw new Error(`Unsupported targetType: ${targetType}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/web/routes/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/web/routes/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAG7B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAOtD;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAkB,EAClB,UAAkB;IAElB,2CAA2C;IAC3C,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtG,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,UAAU,KAAK,CAAC;YACvE,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;SACzC,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,KAAK,cAAc,EAAE,CAAC;QAClC,OAAO;YACL,QAAQ,EAAE,WAAW,CAAC,WAAW,EAAE;YACnC,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC;SAC1C,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,yBAAyB,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC;KACvC,CAAC;IACF,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACxD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as m,j as e}from"./react-vendor-CSp-GLFF.js";import{b as N,u as p,c as y}from"./query-C99w429o.js";import{u as v}from"./index-
|
|
2
|
-
//# sourceMappingURL=AIConfig-
|
|
1
|
+
import{r as m,j as e}from"./react-vendor-CSp-GLFF.js";import{b as N,u as p,c as y}from"./query-C99w429o.js";import{u as v}from"./index-CBX47X8l.js";import{a as f}from"./auth-Bnf8ZcqN.js";import{C as k,E as C,m as _,e as P,d as S,n as E,Z as A,l as F}from"./lucide-Bs_edTLa.js";import"./react-router-r79dBVy4.js";import"./vendor-CMMjVdZs.js";import"./syntax-highlighter-44FakypI.js";async function I(){const a=await fetch("/api/config/ai");if(!a.ok)throw new Error("Failed to fetch config");return a.json()}async function K(a,i){const r=new URLSearchParams;a&&r.set("api_key",a),i&&r.set("base_url",i);const l=await fetch(`/api/ai/models?${r.toString()}`);return l.ok?(await l.json()).data||[]:[]}async function T(a){if(!(await f("/api/config/ai",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})).ok)throw new Error("Failed to save config")}async function q(a){const i=await f("/api/ai/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),r=await i.json().catch(()=>({}));if(!i.ok)throw new Error(r.error||"Test failed");return r}function J(){const a=N(),i=v(),{data:r,isLoading:l}=p({queryKey:["ai-config"],queryFn:I}),[s,o]=m.useState({api_key:"",base_url:"",model:""}),[x,b]=m.useState(!1),[d,h]=m.useState(null);m.useEffect(()=>{r&&o(r)},[r]);const{data:n,refetch:j,isFetching:g}=p({queryKey:["ai-models",s.api_key,s.base_url],queryFn:()=>K(s.api_key,s.base_url),enabled:!!s.api_key&&!!s.base_url}),u=y({mutationFn:T,onSuccess:()=>{i.success("AI 配置已保存"),a.invalidateQueries({queryKey:["ai-config"]})},onError:t=>i.error(`保存失败: ${t.message}`)}),c=y({mutationFn:q,onSuccess:t=>{const w=(t==null?void 0:t.model)||s.model;h({ok:!0,message:`连接成功!模型: ${w}`}),i.success("API 连接测试通过")},onError:t=>{h({ok:!1,message:t.message}),i.error("API 连接测试失败")}});return l?e.jsx("div",{className:"bg-white rounded-lg shadow p-6",children:"加载中..."}):e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-6",children:"AI 配置"}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 max-w-2xl",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(k,{className:"h-5 w-5 text-indigo-600"}),e.jsx("h3",{className:"text-lg font-semibold text-gray-900",children:"AI 服务配置"})]}),e.jsx("p",{className:"text-xs text-gray-500 mb-6",children:"用于 CLAUDE.md 生成、Skill 语义匹配、AI 辅助 Patch"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"API Key"}),e.jsxs("div",{className:"relative",children:[e.jsx("input",{type:x?"text":"password",value:s.api_key||"",onChange:t=>o({...s,api_key:t.target.value}),placeholder:"sk-...",className:"w-full px-3 py-2 pr-10 border border-gray-300 rounded-md text-sm font-mono"}),e.jsx("button",{type:"button",onClick:()=>b(!x),className:"absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600",children:x?e.jsx(C,{className:"h-4 w-4"}):e.jsx(_,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"Base URL"}),e.jsx("input",{type:"text",value:s.base_url||"",onChange:t=>o({...s,base_url:t.target.value}),placeholder:"https://api.anthropic.com",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700",children:"模型"}),e.jsx("button",{type:"button",onClick:()=>j(),disabled:!s.api_key||!s.base_url||g,className:"text-xs text-indigo-600 hover:text-indigo-700 disabled:text-gray-400",children:g?"加载中...":"刷新模型列表"})]}),n&&n.length>0?e.jsxs("select",{value:s.model||"",onChange:t=>o({...s,model:t.target.value}),className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm bg-white",children:[e.jsx("option",{value:"",children:"-- 选择模型 --"}),n.map(t=>e.jsxs("option",{value:t.id,children:[t.id," ",t.owned_by&&`(${t.owned_by})`]},t.id))]}):e.jsx("input",{type:"text",value:s.model||"",onChange:t=>o({...s,model:t.target.value}),placeholder:"claude-sonnet-4-6",className:"w-full px-3 py-2 border border-gray-300 rounded-md text-sm"}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:n&&n.length>0?`发现 ${n.length} 个可用模型`:"填入 API Key 和 Base URL 后可自动发现模型"})]}),d&&e.jsxs("div",{className:`flex items-start gap-2 p-3 rounded text-sm ${d.ok?"bg-green-50 text-green-800":"bg-red-50 text-red-800"}`,children:[d.ok?e.jsx(P,{className:"h-4 w-4 flex-shrink-0 mt-0.5"}):e.jsx(S,{className:"h-4 w-4 flex-shrink-0 mt-0.5"}),e.jsx("div",{className:"flex-1 break-all",children:d.message})]}),e.jsx("div",{className:"flex items-center justify-end pt-4 border-t",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:()=>c.mutate({api_key:s.api_key,base_url:s.base_url,model:s.model}),disabled:c.isPending||!s.api_key||!s.model,className:"inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 text-sm font-medium rounded-md hover:bg-gray-200 disabled:bg-gray-50 disabled:text-gray-400",children:[c.isPending?e.jsx(E,{className:"h-4 w-4 animate-spin"}):e.jsx(A,{className:"h-4 w-4"}),c.isPending?"测试中...":"测试连接"]}),e.jsxs("button",{onClick:()=>u.mutate(s),disabled:u.isPending,className:"inline-flex items-center gap-2 px-4 py-2 bg-indigo-600 text-white text-sm font-medium rounded-md hover:bg-indigo-700 disabled:bg-gray-400",children:[e.jsx(F,{className:"h-4 w-4"}),u.isPending?"保存中...":"保存配置"]})]})})]})]})]})}export{J as default};
|
|
2
|
+
//# sourceMappingURL=AIConfig-CdDWzJyO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AIConfig-BQCAQE9D.js","sources":["../../src/pages/AIConfig.tsx"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useState, useEffect } from 'react'\nimport { Save, Eye, EyeOff, Cpu, Zap, CheckCircle, XCircle, Loader2 } from 'lucide-react'\nimport { useToast } from '../components/Toast'\nimport { authFetch } from '../utils/auth'\n\ninterface AIConfig {\n api_key: string\n base_url: string\n model: string\n provider?: string\n}\n\ninterface ModelOption {\n id: string\n owned_by?: string\n}\n\nasync function fetchConfig(): Promise<AIConfig> {\n const res = await fetch('/api/config/ai')\n if (!res.ok) throw new Error('Failed to fetch config')\n return res.json()\n}\n\nasync function fetchModels(api_key?: string, base_url?: string): Promise<ModelOption[]> {\n const params = new URLSearchParams()\n if (api_key) params.set('api_key', api_key)\n if (base_url) params.set('base_url', base_url)\n const res = await fetch(`/api/ai/models?${params.toString()}`)\n if (!res.ok) return []\n const data = await res.json()\n return data.data || []\n}\n\nasync function saveConfig(config: AIConfig): Promise<void> {\n const res = await authFetch('/api/config/ai', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n })\n if (!res.ok) throw new Error('Failed to save config')\n}\n\nasync function testConnection(config: { api_key: string; base_url: string; model: string }): Promise<any> {\n const res = await authFetch('/api/ai/test', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) throw new Error(data.error || 'Test failed')\n return data\n}\n\nexport default function AIConfig() {\n const queryClient = useQueryClient()\n const toast = useToast()\n const { data: config, isLoading } = useQuery({\n queryKey: ['ai-config'],\n queryFn: fetchConfig,\n })\n\n const [form, setForm] = useState<AIConfig>({\n api_key: '',\n base_url: '',\n model: '',\n })\n const [showKey, setShowKey] = useState(false)\n const [testResult, setTestResult] = useState<{ ok: boolean; message: string } | null>(null)\n\n useEffect(() => {\n if (config) setForm(config)\n }, [config])\n\n const { data: models, refetch: refetchModels, isFetching: loadingModels } = useQuery({\n queryKey: ['ai-models', form.api_key, form.base_url],\n queryFn: () => fetchModels(form.api_key, form.base_url),\n enabled: !!form.api_key && !!form.base_url,\n })\n\n const saveMutation = useMutation({\n mutationFn: saveConfig,\n onSuccess: () => {\n toast.success('AI 配置已保存')\n queryClient.invalidateQueries({ queryKey: ['ai-config'] })\n },\n onError: (e: Error) => toast.error(`保存失败: ${e.message}`),\n })\n\n const testMutation = useMutation({\n mutationFn: testConnection,\n onSuccess: (data) => {\n const modelName = data?.model || form.model\n setTestResult({ ok: true, message: `连接成功!模型: ${modelName}` })\n toast.success('API 连接测试通过')\n },\n onError: (err: Error) => {\n setTestResult({ ok: false, message: err.message })\n toast.error('API 连接测试失败')\n },\n })\n\n if (isLoading) {\n return <div className=\"bg-white rounded-lg shadow p-6\">加载中...</div>\n }\n\n return (\n <div>\n <h1 className=\"text-2xl font-bold text-gray-900 mb-6\">AI 配置</h1>\n\n <div className=\"bg-white rounded-lg shadow p-6 max-w-2xl\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Cpu className=\"h-5 w-5 text-indigo-600\" />\n <h3 className=\"text-lg font-semibold text-gray-900\">AI 服务配置</h3>\n </div>\n <p className=\"text-xs text-gray-500 mb-6\">用于 CLAUDE.md 生成、Skill 语义匹配、AI 辅助 Patch</p>\n\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">API Key</label>\n <div className=\"relative\">\n <input\n type={showKey ? 'text' : 'password'}\n value={form.api_key || ''}\n onChange={(e) => setForm({ ...form, api_key: e.target.value })}\n placeholder=\"sk-...\"\n className=\"w-full px-3 py-2 pr-10 border border-gray-300 rounded-md text-sm font-mono\"\n />\n <button\n type=\"button\"\n onClick={() => setShowKey(!showKey)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\"\n >\n {showKey ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n </button>\n </div>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">Base URL</label>\n <input\n type=\"text\"\n value={form.base_url || ''}\n onChange={(e) => setForm({ ...form, base_url: e.target.value })}\n placeholder=\"https://api.anthropic.com\"\n className=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm\"\n />\n </div>\n\n <div>\n <div className=\"flex items-center justify-between mb-1\">\n <label className=\"block text-sm font-medium text-gray-700\">模型</label>\n <button\n type=\"button\"\n onClick={() => refetchModels()}\n disabled={!form.api_key || !form.base_url || loadingModels}\n className=\"text-xs text-indigo-600 hover:text-indigo-700 disabled:text-gray-400\"\n >\n {loadingModels ? '加载中...' : '刷新模型列表'}\n </button>\n </div>\n {models && models.length > 0 ? (\n <select\n value={form.model || ''}\n onChange={(e) => setForm({ ...form, model: e.target.value })}\n className=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm bg-white\"\n >\n <option value=\"\">-- 选择模型 --</option>\n {models.map((m) => (\n <option key={m.id} value={m.id}>\n {m.id} {m.owned_by && `(${m.owned_by})`}\n </option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={form.model || ''}\n onChange={(e) => setForm({ ...form, model: e.target.value })}\n placeholder=\"claude-sonnet-4-6\"\n className=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm\"\n />\n )}\n <p className=\"text-xs text-gray-500 mt-1\">\n {models && models.length > 0\n ? `发现 ${models.length} 个可用模型`\n : '填入 API Key 和 Base URL 后可自动发现模型'}\n </p>\n </div>\n\n {/* Test result */}\n {testResult && (\n <div className={`flex items-start gap-2 p-3 rounded text-sm ${\n testResult.ok ? 'bg-green-50 text-green-800' : 'bg-red-50 text-red-800'\n }`}>\n {testResult.ok ? (\n <CheckCircle className=\"h-4 w-4 flex-shrink-0 mt-0.5\" />\n ) : (\n <XCircle className=\"h-4 w-4 flex-shrink-0 mt-0.5\" />\n )}\n <div className=\"flex-1 break-all\">{testResult.message}</div>\n </div>\n )}\n\n <div className=\"flex items-center justify-end pt-4 border-t\">\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => testMutation.mutate({ api_key: form.api_key, base_url: form.base_url, model: form.model })}\n disabled={testMutation.isPending || !form.api_key || !form.model}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 text-sm font-medium rounded-md hover:bg-gray-200 disabled:bg-gray-50 disabled:text-gray-400\"\n >\n {testMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Zap className=\"h-4 w-4\" />\n )}\n {testMutation.isPending ? '测试中...' : '测试连接'}\n </button>\n <button\n onClick={() => saveMutation.mutate(form)}\n disabled={saveMutation.isPending}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-indigo-600 text-white text-sm font-medium rounded-md hover:bg-indigo-700 disabled:bg-gray-400\"\n >\n <Save className=\"h-4 w-4\" />\n {saveMutation.isPending ? '保存中...' : '保存配置'}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n )\n}\n"],"names":["fetchConfig","res","fetchModels","api_key","base_url","params","saveConfig","config","authFetch","testConnection","data","AIConfig","queryClient","useQueryClient","toast","useToast","isLoading","useQuery","form","setForm","useState","showKey","setShowKey","testResult","setTestResult","useEffect","models","refetchModels","loadingModels","saveMutation","useMutation","e","testMutation","modelName","err","jsx","jsxs","Cpu","EyeOff","Eye","m","CheckCircle","XCircle","Loader2","Zap","Save"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AIConfig-CdDWzJyO.js","sources":["../../src/pages/AIConfig.tsx"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useState, useEffect } from 'react'\nimport { Save, Eye, EyeOff, Cpu, Zap, CheckCircle, XCircle, Loader2 } from 'lucide-react'\nimport { useToast } from '../components/Toast'\nimport { authFetch } from '../utils/auth'\n\ninterface AIConfig {\n api_key: string\n base_url: string\n model: string\n provider?: string\n}\n\ninterface ModelOption {\n id: string\n owned_by?: string\n}\n\nasync function fetchConfig(): Promise<AIConfig> {\n const res = await fetch('/api/config/ai')\n if (!res.ok) throw new Error('Failed to fetch config')\n return res.json()\n}\n\nasync function fetchModels(api_key?: string, base_url?: string): Promise<ModelOption[]> {\n const params = new URLSearchParams()\n if (api_key) params.set('api_key', api_key)\n if (base_url) params.set('base_url', base_url)\n const res = await fetch(`/api/ai/models?${params.toString()}`)\n if (!res.ok) return []\n const data = await res.json()\n return data.data || []\n}\n\nasync function saveConfig(config: AIConfig): Promise<void> {\n const res = await authFetch('/api/config/ai', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n })\n if (!res.ok) throw new Error('Failed to save config')\n}\n\nasync function testConnection(config: { api_key: string; base_url: string; model: string }): Promise<any> {\n const res = await authFetch('/api/ai/test', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) throw new Error(data.error || 'Test failed')\n return data\n}\n\nexport default function AIConfig() {\n const queryClient = useQueryClient()\n const toast = useToast()\n const { data: config, isLoading } = useQuery({\n queryKey: ['ai-config'],\n queryFn: fetchConfig,\n })\n\n const [form, setForm] = useState<AIConfig>({\n api_key: '',\n base_url: '',\n model: '',\n })\n const [showKey, setShowKey] = useState(false)\n const [testResult, setTestResult] = useState<{ ok: boolean; message: string } | null>(null)\n\n useEffect(() => {\n if (config) setForm(config)\n }, [config])\n\n const { data: models, refetch: refetchModels, isFetching: loadingModels } = useQuery({\n queryKey: ['ai-models', form.api_key, form.base_url],\n queryFn: () => fetchModels(form.api_key, form.base_url),\n enabled: !!form.api_key && !!form.base_url,\n })\n\n const saveMutation = useMutation({\n mutationFn: saveConfig,\n onSuccess: () => {\n toast.success('AI 配置已保存')\n queryClient.invalidateQueries({ queryKey: ['ai-config'] })\n },\n onError: (e: Error) => toast.error(`保存失败: ${e.message}`),\n })\n\n const testMutation = useMutation({\n mutationFn: testConnection,\n onSuccess: (data) => {\n const modelName = data?.model || form.model\n setTestResult({ ok: true, message: `连接成功!模型: ${modelName}` })\n toast.success('API 连接测试通过')\n },\n onError: (err: Error) => {\n setTestResult({ ok: false, message: err.message })\n toast.error('API 连接测试失败')\n },\n })\n\n if (isLoading) {\n return <div className=\"bg-white rounded-lg shadow p-6\">加载中...</div>\n }\n\n return (\n <div>\n <h1 className=\"text-2xl font-bold text-gray-900 mb-6\">AI 配置</h1>\n\n <div className=\"bg-white rounded-lg shadow p-6 max-w-2xl\">\n <div className=\"flex items-center gap-2 mb-2\">\n <Cpu className=\"h-5 w-5 text-indigo-600\" />\n <h3 className=\"text-lg font-semibold text-gray-900\">AI 服务配置</h3>\n </div>\n <p className=\"text-xs text-gray-500 mb-6\">用于 CLAUDE.md 生成、Skill 语义匹配、AI 辅助 Patch</p>\n\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">API Key</label>\n <div className=\"relative\">\n <input\n type={showKey ? 'text' : 'password'}\n value={form.api_key || ''}\n onChange={(e) => setForm({ ...form, api_key: e.target.value })}\n placeholder=\"sk-...\"\n className=\"w-full px-3 py-2 pr-10 border border-gray-300 rounded-md text-sm font-mono\"\n />\n <button\n type=\"button\"\n onClick={() => setShowKey(!showKey)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600\"\n >\n {showKey ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n </button>\n </div>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">Base URL</label>\n <input\n type=\"text\"\n value={form.base_url || ''}\n onChange={(e) => setForm({ ...form, base_url: e.target.value })}\n placeholder=\"https://api.anthropic.com\"\n className=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm\"\n />\n </div>\n\n <div>\n <div className=\"flex items-center justify-between mb-1\">\n <label className=\"block text-sm font-medium text-gray-700\">模型</label>\n <button\n type=\"button\"\n onClick={() => refetchModels()}\n disabled={!form.api_key || !form.base_url || loadingModels}\n className=\"text-xs text-indigo-600 hover:text-indigo-700 disabled:text-gray-400\"\n >\n {loadingModels ? '加载中...' : '刷新模型列表'}\n </button>\n </div>\n {models && models.length > 0 ? (\n <select\n value={form.model || ''}\n onChange={(e) => setForm({ ...form, model: e.target.value })}\n className=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm bg-white\"\n >\n <option value=\"\">-- 选择模型 --</option>\n {models.map((m) => (\n <option key={m.id} value={m.id}>\n {m.id} {m.owned_by && `(${m.owned_by})`}\n </option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={form.model || ''}\n onChange={(e) => setForm({ ...form, model: e.target.value })}\n placeholder=\"claude-sonnet-4-6\"\n className=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm\"\n />\n )}\n <p className=\"text-xs text-gray-500 mt-1\">\n {models && models.length > 0\n ? `发现 ${models.length} 个可用模型`\n : '填入 API Key 和 Base URL 后可自动发现模型'}\n </p>\n </div>\n\n {/* Test result */}\n {testResult && (\n <div className={`flex items-start gap-2 p-3 rounded text-sm ${\n testResult.ok ? 'bg-green-50 text-green-800' : 'bg-red-50 text-red-800'\n }`}>\n {testResult.ok ? (\n <CheckCircle className=\"h-4 w-4 flex-shrink-0 mt-0.5\" />\n ) : (\n <XCircle className=\"h-4 w-4 flex-shrink-0 mt-0.5\" />\n )}\n <div className=\"flex-1 break-all\">{testResult.message}</div>\n </div>\n )}\n\n <div className=\"flex items-center justify-end pt-4 border-t\">\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => testMutation.mutate({ api_key: form.api_key, base_url: form.base_url, model: form.model })}\n disabled={testMutation.isPending || !form.api_key || !form.model}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 text-sm font-medium rounded-md hover:bg-gray-200 disabled:bg-gray-50 disabled:text-gray-400\"\n >\n {testMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Zap className=\"h-4 w-4\" />\n )}\n {testMutation.isPending ? '测试中...' : '测试连接'}\n </button>\n <button\n onClick={() => saveMutation.mutate(form)}\n disabled={saveMutation.isPending}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-indigo-600 text-white text-sm font-medium rounded-md hover:bg-indigo-700 disabled:bg-gray-400\"\n >\n <Save className=\"h-4 w-4\" />\n {saveMutation.isPending ? '保存中...' : '保存配置'}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n )\n}\n"],"names":["fetchConfig","res","fetchModels","api_key","base_url","params","saveConfig","config","authFetch","testConnection","data","AIConfig","queryClient","useQueryClient","toast","useToast","isLoading","useQuery","form","setForm","useState","showKey","setShowKey","testResult","setTestResult","useEffect","models","refetchModels","loadingModels","saveMutation","useMutation","e","testMutation","modelName","err","jsx","jsxs","Cpu","EyeOff","Eye","m","CheckCircle","XCircle","Loader2","Zap","Save"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e}from"./react-vendor-CSp-GLFF.js";import{u as o}from"./query-C99w429o.js";import{b as q}from"./react-router-I-HqunH7.js";import{A as _,a as D,B as C,f as $,g as E,S as T,T as b,c as S,I as A}from"./lucide-fJlPI3H7.js";import{R as d,A as z,C as h,X as f,Y as j,T as m,a as B,B as y,b as g,L as P,P as M,c as O,d as L}from"./charts-CLrM0_uM.js";import"./vendor-CMMjVdZs.js";async function U(){const s=await fetch("/api/status");if(!s.ok)throw new Error("Failed");return s.json()}async function H(){const s=await fetch("/api/stats");if(!s.ok)throw new Error("Failed");return s.json()}async function G(){const s=await fetch("/api/sessions?limit=1000");return s.ok?(await s.json()).length:0}async function W(){const s=await fetch("/api/skill-stats/invocations?days=7");if(!s.ok)throw new Error("Failed");return s.json()}async function X(){const s=await fetch("/api/routing/stats?days=7");if(!s.ok)throw new Error("Failed");return s.json()}async function Y(){const s=await fetch("/api/rules/hit-rate?days=7");if(!s.ok)throw new Error("Failed");return s.json()}async function Q(){const s=await fetch("/api/insights?days=7");if(!s.ok)throw new Error("Failed");return s.json()}function J(s){const t=Math.floor(s/86400),r=Math.floor(s%86400/3600),n=Math.floor(s%3600/60);return t>0?`${t}天 ${r}小时`:r>0?`${r}小时 ${n}分钟`:`${n}分钟`}const x={primary:"#6366f1",green:"#10b981"},V=["#6366f1","#e5e7eb"];function de(){var w,k;const s=q(),{data:t}=o({queryKey:["status"],queryFn:U,refetchInterval:5e3}),{data:r}=o({queryKey:["system-stats"],queryFn:H,refetchInterval:3e4}),{data:n}=o({queryKey:["sessions-count"],queryFn:G}),{data:i}=o({queryKey:["skill-invocations"],queryFn:W,refetchInterval:3e4}),{data:a}=o({queryKey:["routing-stats"],queryFn:X,refetchInterval:3e4}),{data:K}=o({queryKey:["rule-hit-rate"],queryFn:Y,refetchInterval:3e4}),{data:I}=o({queryKey:["insights"],queryFn:Q,refetchInterval:6e4}),F=r!=null&&r.toolUsage?Object.entries(r.toolUsage).sort(([,l],[,c])=>c-l).slice(0,8).map(([l,c])=>({name:l,count:c})):[],R=(r==null?void 0:r.dailyActivity)||[],p=(i==null?void 0:i.invocations.slice(0,8))||[],N=a?[{name:"Agent 调用",value:a.agentCalls},{name:"直接执行",value:a.noAgent}]:[],v=(a==null?void 0:a.byAgent.slice(0,6))||[];return e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-6",children:"仪表盘"}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6",children:[e.jsx(u,{icon:_,label:"总事件",value:((w=t==null?void 0:t.eventCount)==null?void 0:w.toString())||"-",color:"blue",onClick:()=>s("/events")}),e.jsx(u,{icon:D,label:"会话数",value:(n==null?void 0:n.toString())||"-",color:"purple",onClick:()=>s("/sessions")}),e.jsx(u,{icon:C,label:"Skill 调用",value:((k=i==null?void 0:i.total)==null?void 0:k.toString())||"0",color:"green"}),e.jsx(u,{icon:$,label:`Agent 调用率 (${(a==null?void 0:a.days)??7}天)`,value:a?`${a.agentRate}%`:"-",color:"indigo"})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6",children:[e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("h3",{className:"text-base font-semibold text-gray-900",children:"最近 7 天活动"}),e.jsx("button",{onClick:()=>s("/events"),className:"text-xs text-indigo-600 hover:text-indigo-700",children:"查看全部事件"})]}),e.jsx(d,{width:"100%",height:240,children:e.jsxs(z,{data:R,children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"colorEvents",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"5%",stopColor:x.primary,stopOpacity:.3}),e.jsx("stop",{offset:"95%",stopColor:x.primary,stopOpacity:0})]})}),e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{dataKey:"date",tick:{fontSize:11},tickFormatter:l=>l==null?void 0:l.slice(5)}),e.jsx(j,{tick:{fontSize:11}}),e.jsx(m,{}),e.jsx(B,{type:"monotone",dataKey:"eventCount",stroke:x.primary,strokeWidth:2,fill:"url(#colorEvents)",name:"事件"})]})})]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsx("div",{className:"flex items-center justify-between mb-4",children:e.jsx("h3",{className:"text-base font-semibold text-gray-900",children:"工具使用分布"})}),e.jsx(d,{width:"100%",height:240,children:e.jsxs(y,{data:F,layout:"vertical",children:[e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{type:"number",tick:{fontSize:11}}),e.jsx(j,{dataKey:"name",type:"category",tick:{fontSize:11},width:80}),e.jsx(m,{}),e.jsx(g,{dataKey:"count",fill:x.primary,radius:[0,4,4,0]})]})})]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900",children:[e.jsx(C,{className:"h-4 w-4 text-green-600"}),"Skill 调用统计 (",(i==null?void 0:i.days)??7," 天)"]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["共 ",(i==null?void 0:i.total)??0," 次"]})]}),p.length>0?e.jsx(d,{width:"100%",height:240,children:e.jsxs(y,{data:p,layout:"vertical",children:[e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{type:"number",tick:{fontSize:11}}),e.jsx(j,{dataKey:"skill_id",type:"category",tick:{fontSize:10},width:140}),e.jsx(m,{}),e.jsx(P,{wrapperStyle:{fontSize:11}}),e.jsx(g,{dataKey:"success",stackId:"a",fill:x.green,name:"成功",radius:[0,0,0,0]}),e.jsx(g,{dataKey:"failed",stackId:"a",fill:"#ef4444",name:"失败",radius:[0,4,4,0]})]})}):e.jsx("div",{className:"flex items-center justify-center h-[240px] text-sm text-gray-400",children:"暂无 Skill 调用记录"})]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900",children:[e.jsx($,{className:"h-4 w-4 text-indigo-600"}),"Agent 调用率 (",(a==null?void 0:a.days)??7," 天)"]}),e.jsx("span",{className:"text-xs text-gray-500",children:a?`${a.agentCalls} / ${a.total}`:"-"})]}),a&&a.total>0?e.jsx(d,{width:"100%",height:240,children:e.jsxs(M,{children:[e.jsx(O,{data:N,dataKey:"value",nameKey:"name",cx:"50%",cy:"50%",innerRadius:50,outerRadius:80,label:({name:l,percent:c})=>`${l}: ${((c??0)*100).toFixed(0)}%`,labelLine:!1,children:N.map((l,c)=>e.jsx(L,{fill:V[c]},c))}),e.jsx(m,{})]})}):e.jsx("div",{className:"flex items-center justify-center h-[240px] text-sm text-gray-400",children:"暂无路由记录"})]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsx("div",{className:"flex items-center justify-between mb-4",children:e.jsx("h3",{className:"text-base font-semibold text-gray-900",children:"Agent 类型分布"})}),v.length>0?e.jsx(d,{width:"100%",height:240,children:e.jsxs(y,{data:v,layout:"vertical",children:[e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{type:"number",tick:{fontSize:11}}),e.jsx(j,{dataKey:"agent",type:"category",tick:{fontSize:11},width:120}),e.jsx(m,{}),e.jsx(g,{dataKey:"count",fill:x.primary,radius:[0,4,4,0]})]})}):e.jsx("div",{className:"flex items-center justify-center h-[240px] text-sm text-gray-400",children:"暂无 Agent 调用记录"})]}),e.jsx(Z,{data:K}),e.jsx(se,{data:I,onSelectSession:l=>s(`/sessions/${l}`)}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900 mb-4",children:[e.jsx(E,{className:"h-4 w-4 text-indigo-600"}),"系统状态"]}),e.jsxs("dl",{className:"space-y-3 text-sm",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("dt",{className:"text-gray-500",children:"PID"}),e.jsx("dd",{className:"font-mono text-gray-900",children:(t==null?void 0:t.pid)||"-"})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("dt",{className:"text-gray-500",children:"运行时间"}),e.jsx("dd",{className:"text-gray-900",children:t!=null&&t.uptime?J(t.uptime):"-"})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("dt",{className:"text-gray-500",children:"内存使用"}),e.jsx("dd",{className:"text-gray-900",children:t!=null&&t.memory?`${Math.round(t.memory.heapUsed/1024/1024)} MB`:"-"})]})]})]})]})]})}function u({icon:s,label:t,value:r,color:n,onClick:i}){const a={blue:"bg-blue-100 text-blue-600",purple:"bg-purple-100 text-purple-600",indigo:"bg-indigo-100 text-indigo-600",green:"bg-green-100 text-green-600"};return e.jsxs("div",{className:`bg-white rounded-lg shadow p-5 ${i?"cursor-pointer hover:shadow-md transition-shadow":""}`,onClick:i,children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("span",{className:"text-sm text-gray-500",children:t}),e.jsx("div",{className:`w-8 h-8 rounded-lg flex items-center justify-center ${a[n]}`,children:e.jsx(s,{className:"h-4 w-4"})})]}),e.jsx("div",{className:"text-2xl font-bold text-gray-900",children:r})]})}function Z({data:s}){const t=(s==null?void 0:s.skills.slice(0,5))||[];return e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 lg:col-span-2",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900",children:[e.jsx(T,{className:"h-4 w-4 text-amber-600"}),"规则命中率 (",(s==null?void 0:s.period.days)??7," 天)"]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["共 ",(s==null?void 0:s.summary.totalPrompts)??0," 次路由"]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 mb-5",children:[e.jsxs("div",{className:"bg-indigo-50 rounded-lg p-4 text-center",children:[e.jsx("div",{className:"text-2xl font-bold text-indigo-700",children:(s==null?void 0:s.summary.agentRate)??"0%"}),e.jsx("div",{className:"text-xs text-indigo-600 mt-1",children:"Agent 委托率"})]}),e.jsxs("div",{className:"bg-green-50 rounded-lg p-4 text-center",children:[e.jsx("div",{className:"text-2xl font-bold text-green-700",children:(s==null?void 0:s.summary.skillRate)??"0%"}),e.jsx("div",{className:"text-xs text-green-600 mt-1",children:"Skill 触发率"})]})]}),t.length>0?e.jsxs("div",{className:"mb-5",children:[e.jsx("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:"Top Skill 调用排行"}),e.jsx(d,{width:"100%",height:160,children:e.jsxs(y,{data:t,layout:"vertical",children:[e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{type:"number",tick:{fontSize:11}}),e.jsx(j,{dataKey:"skill_id",type:"category",tick:{fontSize:10},width:140}),e.jsx(m,{}),e.jsx(g,{dataKey:"total",fill:"#10b981",radius:[0,4,4,0],name:"调用次数"})]})})]}):e.jsx("div",{className:"flex items-center justify-center h-[100px] text-sm text-gray-400 mb-5",children:"暂无 Skill 调用记录"}),s&&s.neverTriggered.length>0&&e.jsxs("div",{children:[e.jsxs("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:["从未触发的规则 (",s.neverTriggered.length,")"]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:s.neverTriggered.map(r=>e.jsx("span",{className:"text-xs bg-gray-100 text-gray-500 px-2 py-1 rounded",children:r},r))}),e.jsxs("p",{className:"text-xs text-gray-400 mt-2",children:["这些 Skill 在过去 ",s.period.days," 天内从未被触发,可考虑清理或优化关键词"]})]})]})}const ee={edit_loop:"编辑循环",tool_failure_spike:"工具失败",no_commit:"无 commit",event_overflow:"事件爆量"};function se({data:s,onSelectSession:t}){const r=(s==null?void 0:s.summary)??{total:0,critical:0,warn:0,info:0},n=((s==null?void 0:s.patterns)??[]).slice(0,5);return e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 lg:col-span-2",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900",children:[e.jsx(b,{className:"h-4 w-4 text-amber-600"}),"工作流洞察 (",(s==null?void 0:s.windowDays)??7," 天)"]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["共 ",r.total," 条"]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-4 mb-5",children:[e.jsxs("div",{className:"bg-red-50 rounded-lg p-4 text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-2 text-2xl font-bold text-red-700",children:[e.jsx(S,{className:"h-5 w-5"}),r.critical]}),e.jsx("div",{className:"text-xs text-red-600 mt-1",children:"Critical"})]}),e.jsxs("div",{className:"bg-amber-50 rounded-lg p-4 text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-2 text-2xl font-bold text-amber-700",children:[e.jsx(b,{className:"h-5 w-5"}),r.warn]}),e.jsx("div",{className:"text-xs text-amber-600 mt-1",children:"Warn"})]}),e.jsxs("div",{className:"bg-blue-50 rounded-lg p-4 text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-2 text-2xl font-bold text-blue-700",children:[e.jsx(A,{className:"h-5 w-5"}),r.info]}),e.jsx("div",{className:"text-xs text-blue-600 mt-1",children:"Info"})]})]}),n.length>0?e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:"最严重的 5 条"}),e.jsx("ul",{className:"space-y-2",children:n.map(i=>e.jsxs("li",{className:`border-l-4 px-3 py-2 rounded ${te(i.severity)} ${i.sessionId?"cursor-pointer hover:bg-gray-50":""}`,onClick:()=>i.sessionId&&t(i.sessionId),children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[e.jsx(ie,{severity:i.severity}),e.jsx("span",{className:"text-sm font-medium text-gray-900 truncate",children:i.title})]}),e.jsx("span",{className:"text-xs text-gray-500 shrink-0",children:ee[i.type]})]}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:i.description}),e.jsx(re,{pattern:i})]},i.id))})]}):e.jsx("div",{className:"flex items-center justify-center h-[120px] text-sm text-gray-400",children:"没有检测到反模式,工作流健康"})]})}function te(s){return s==="critical"?"border-red-500 bg-red-50/30":s==="warn"?"border-amber-500 bg-amber-50/30":"border-blue-400 bg-blue-50/30"}function ie({severity:s}){return s==="critical"?e.jsx(S,{className:"h-4 w-4 text-red-600 shrink-0"}):s==="warn"?e.jsx(b,{className:"h-4 w-4 text-amber-600 shrink-0"}):e.jsx(A,{className:"h-4 w-4 text-blue-600 shrink-0"})}function re({pattern:s}){const t=s.detail;let r="";if(s.type==="edit_loop"){const n=String(t.filePath??""),i=Number(t.count??0);r=`${n} edited ${i} 次`}else if(s.type==="tool_failure_spike"){const n=Number(t.recentFailureRate??0)*100,i=Number(t.baselineFailureRate??0)*100,a=Number(t.totalToolUses??0);r=`最近 24h ${n.toFixed(1)}% / 基线 ${i.toFixed(1)}% (${a} 次工具调用)`}else if(s.type==="no_commit"){const n=Number(t.durationMin??0),i=Number(t.eventCount??0);r=`${n} 分钟 · ${i} 个事件 · 无 git commit`}else if(s.type==="event_overflow"){const n=Number(t.eventCount??0),i=Number(t.durationMin??0);r=`${n} 个事件 / ${i} 分钟`}return r?e.jsx("p",{className:"text-xs text-gray-400 mt-1 font-mono truncate",children:r}):null}export{de as default};
|
|
2
|
-
//# sourceMappingURL=Dashboard-
|
|
1
|
+
import{j as e}from"./react-vendor-CSp-GLFF.js";import{u as o}from"./query-C99w429o.js";import{b as q}from"./react-router-r79dBVy4.js";import{A as _,a as D,B as C,f as $,g as E,S as T,T as b,c as S,I as A}from"./lucide-Bs_edTLa.js";import{R as d,A as z,C as h,X as f,Y as j,T as m,a as B,B as y,b as g,L as P,P as M,c as O,d as L}from"./charts-CLrM0_uM.js";import"./vendor-CMMjVdZs.js";async function U(){const s=await fetch("/api/status");if(!s.ok)throw new Error("Failed");return s.json()}async function H(){const s=await fetch("/api/stats");if(!s.ok)throw new Error("Failed");return s.json()}async function G(){const s=await fetch("/api/sessions?limit=1000");return s.ok?(await s.json()).length:0}async function W(){const s=await fetch("/api/skill-stats/invocations?days=7");if(!s.ok)throw new Error("Failed");return s.json()}async function X(){const s=await fetch("/api/routing/stats?days=7");if(!s.ok)throw new Error("Failed");return s.json()}async function Y(){const s=await fetch("/api/rules/hit-rate?days=7");if(!s.ok)throw new Error("Failed");return s.json()}async function Q(){const s=await fetch("/api/insights?days=7");if(!s.ok)throw new Error("Failed");return s.json()}function J(s){const t=Math.floor(s/86400),r=Math.floor(s%86400/3600),n=Math.floor(s%3600/60);return t>0?`${t}天 ${r}小时`:r>0?`${r}小时 ${n}分钟`:`${n}分钟`}const x={primary:"#6366f1",green:"#10b981"},V=["#6366f1","#e5e7eb"];function de(){var w,k;const s=q(),{data:t}=o({queryKey:["status"],queryFn:U,refetchInterval:5e3}),{data:r}=o({queryKey:["system-stats"],queryFn:H,refetchInterval:3e4}),{data:n}=o({queryKey:["sessions-count"],queryFn:G}),{data:i}=o({queryKey:["skill-invocations"],queryFn:W,refetchInterval:3e4}),{data:a}=o({queryKey:["routing-stats"],queryFn:X,refetchInterval:3e4}),{data:K}=o({queryKey:["rule-hit-rate"],queryFn:Y,refetchInterval:3e4}),{data:I}=o({queryKey:["insights"],queryFn:Q,refetchInterval:6e4}),F=r!=null&&r.toolUsage?Object.entries(r.toolUsage).sort(([,l],[,c])=>c-l).slice(0,8).map(([l,c])=>({name:l,count:c})):[],R=(r==null?void 0:r.dailyActivity)||[],p=(i==null?void 0:i.invocations.slice(0,8))||[],N=a?[{name:"Agent 调用",value:a.agentCalls},{name:"直接执行",value:a.noAgent}]:[],v=(a==null?void 0:a.byAgent.slice(0,6))||[];return e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-6",children:"仪表盘"}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6",children:[e.jsx(u,{icon:_,label:"总事件",value:((w=t==null?void 0:t.eventCount)==null?void 0:w.toString())||"-",color:"blue",onClick:()=>s("/events")}),e.jsx(u,{icon:D,label:"会话数",value:(n==null?void 0:n.toString())||"-",color:"purple",onClick:()=>s("/sessions")}),e.jsx(u,{icon:C,label:"Skill 调用",value:((k=i==null?void 0:i.total)==null?void 0:k.toString())||"0",color:"green"}),e.jsx(u,{icon:$,label:`Agent 调用率 (${(a==null?void 0:a.days)??7}天)`,value:a?`${a.agentRate}%`:"-",color:"indigo"})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6",children:[e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("h3",{className:"text-base font-semibold text-gray-900",children:"最近 7 天活动"}),e.jsx("button",{onClick:()=>s("/events"),className:"text-xs text-indigo-600 hover:text-indigo-700",children:"查看全部事件"})]}),e.jsx(d,{width:"100%",height:240,children:e.jsxs(z,{data:R,children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"colorEvents",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"5%",stopColor:x.primary,stopOpacity:.3}),e.jsx("stop",{offset:"95%",stopColor:x.primary,stopOpacity:0})]})}),e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{dataKey:"date",tick:{fontSize:11},tickFormatter:l=>l==null?void 0:l.slice(5)}),e.jsx(j,{tick:{fontSize:11}}),e.jsx(m,{}),e.jsx(B,{type:"monotone",dataKey:"eventCount",stroke:x.primary,strokeWidth:2,fill:"url(#colorEvents)",name:"事件"})]})})]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsx("div",{className:"flex items-center justify-between mb-4",children:e.jsx("h3",{className:"text-base font-semibold text-gray-900",children:"工具使用分布"})}),e.jsx(d,{width:"100%",height:240,children:e.jsxs(y,{data:F,layout:"vertical",children:[e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{type:"number",tick:{fontSize:11}}),e.jsx(j,{dataKey:"name",type:"category",tick:{fontSize:11},width:80}),e.jsx(m,{}),e.jsx(g,{dataKey:"count",fill:x.primary,radius:[0,4,4,0]})]})})]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900",children:[e.jsx(C,{className:"h-4 w-4 text-green-600"}),"Skill 调用统计 (",(i==null?void 0:i.days)??7," 天)"]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["共 ",(i==null?void 0:i.total)??0," 次"]})]}),p.length>0?e.jsx(d,{width:"100%",height:240,children:e.jsxs(y,{data:p,layout:"vertical",children:[e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{type:"number",tick:{fontSize:11}}),e.jsx(j,{dataKey:"skill_id",type:"category",tick:{fontSize:10},width:140}),e.jsx(m,{}),e.jsx(P,{wrapperStyle:{fontSize:11}}),e.jsx(g,{dataKey:"success",stackId:"a",fill:x.green,name:"成功",radius:[0,0,0,0]}),e.jsx(g,{dataKey:"failed",stackId:"a",fill:"#ef4444",name:"失败",radius:[0,4,4,0]})]})}):e.jsx("div",{className:"flex items-center justify-center h-[240px] text-sm text-gray-400",children:"暂无 Skill 调用记录"})]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900",children:[e.jsx($,{className:"h-4 w-4 text-indigo-600"}),"Agent 调用率 (",(a==null?void 0:a.days)??7," 天)"]}),e.jsx("span",{className:"text-xs text-gray-500",children:a?`${a.agentCalls} / ${a.total}`:"-"})]}),a&&a.total>0?e.jsx(d,{width:"100%",height:240,children:e.jsxs(M,{children:[e.jsx(O,{data:N,dataKey:"value",nameKey:"name",cx:"50%",cy:"50%",innerRadius:50,outerRadius:80,label:({name:l,percent:c})=>`${l}: ${((c??0)*100).toFixed(0)}%`,labelLine:!1,children:N.map((l,c)=>e.jsx(L,{fill:V[c]},c))}),e.jsx(m,{})]})}):e.jsx("div",{className:"flex items-center justify-center h-[240px] text-sm text-gray-400",children:"暂无路由记录"})]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsx("div",{className:"flex items-center justify-between mb-4",children:e.jsx("h3",{className:"text-base font-semibold text-gray-900",children:"Agent 类型分布"})}),v.length>0?e.jsx(d,{width:"100%",height:240,children:e.jsxs(y,{data:v,layout:"vertical",children:[e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{type:"number",tick:{fontSize:11}}),e.jsx(j,{dataKey:"agent",type:"category",tick:{fontSize:11},width:120}),e.jsx(m,{}),e.jsx(g,{dataKey:"count",fill:x.primary,radius:[0,4,4,0]})]})}):e.jsx("div",{className:"flex items-center justify-center h-[240px] text-sm text-gray-400",children:"暂无 Agent 调用记录"})]}),e.jsx(Z,{data:K}),e.jsx(se,{data:I,onSelectSession:l=>s(`/sessions/${l}`)}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900 mb-4",children:[e.jsx(E,{className:"h-4 w-4 text-indigo-600"}),"系统状态"]}),e.jsxs("dl",{className:"space-y-3 text-sm",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("dt",{className:"text-gray-500",children:"PID"}),e.jsx("dd",{className:"font-mono text-gray-900",children:(t==null?void 0:t.pid)||"-"})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("dt",{className:"text-gray-500",children:"运行时间"}),e.jsx("dd",{className:"text-gray-900",children:t!=null&&t.uptime?J(t.uptime):"-"})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("dt",{className:"text-gray-500",children:"内存使用"}),e.jsx("dd",{className:"text-gray-900",children:t!=null&&t.memory?`${Math.round(t.memory.heapUsed/1024/1024)} MB`:"-"})]})]})]})]})]})}function u({icon:s,label:t,value:r,color:n,onClick:i}){const a={blue:"bg-blue-100 text-blue-600",purple:"bg-purple-100 text-purple-600",indigo:"bg-indigo-100 text-indigo-600",green:"bg-green-100 text-green-600"};return e.jsxs("div",{className:`bg-white rounded-lg shadow p-5 ${i?"cursor-pointer hover:shadow-md transition-shadow":""}`,onClick:i,children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("span",{className:"text-sm text-gray-500",children:t}),e.jsx("div",{className:`w-8 h-8 rounded-lg flex items-center justify-center ${a[n]}`,children:e.jsx(s,{className:"h-4 w-4"})})]}),e.jsx("div",{className:"text-2xl font-bold text-gray-900",children:r})]})}function Z({data:s}){const t=(s==null?void 0:s.skills.slice(0,5))||[];return e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 lg:col-span-2",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900",children:[e.jsx(T,{className:"h-4 w-4 text-amber-600"}),"规则命中率 (",(s==null?void 0:s.period.days)??7," 天)"]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["共 ",(s==null?void 0:s.summary.totalPrompts)??0," 次路由"]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 mb-5",children:[e.jsxs("div",{className:"bg-indigo-50 rounded-lg p-4 text-center",children:[e.jsx("div",{className:"text-2xl font-bold text-indigo-700",children:(s==null?void 0:s.summary.agentRate)??"0%"}),e.jsx("div",{className:"text-xs text-indigo-600 mt-1",children:"Agent 委托率"})]}),e.jsxs("div",{className:"bg-green-50 rounded-lg p-4 text-center",children:[e.jsx("div",{className:"text-2xl font-bold text-green-700",children:(s==null?void 0:s.summary.skillRate)??"0%"}),e.jsx("div",{className:"text-xs text-green-600 mt-1",children:"Skill 触发率"})]})]}),t.length>0?e.jsxs("div",{className:"mb-5",children:[e.jsx("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:"Top Skill 调用排行"}),e.jsx(d,{width:"100%",height:160,children:e.jsxs(y,{data:t,layout:"vertical",children:[e.jsx(h,{strokeDasharray:"3 3",stroke:"#f3f4f6"}),e.jsx(f,{type:"number",tick:{fontSize:11}}),e.jsx(j,{dataKey:"skill_id",type:"category",tick:{fontSize:10},width:140}),e.jsx(m,{}),e.jsx(g,{dataKey:"total",fill:"#10b981",radius:[0,4,4,0],name:"调用次数"})]})})]}):e.jsx("div",{className:"flex items-center justify-center h-[100px] text-sm text-gray-400 mb-5",children:"暂无 Skill 调用记录"}),s&&s.neverTriggered.length>0&&e.jsxs("div",{children:[e.jsxs("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:["从未触发的规则 (",s.neverTriggered.length,")"]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:s.neverTriggered.map(r=>e.jsx("span",{className:"text-xs bg-gray-100 text-gray-500 px-2 py-1 rounded",children:r},r))}),e.jsxs("p",{className:"text-xs text-gray-400 mt-2",children:["这些 Skill 在过去 ",s.period.days," 天内从未被触发,可考虑清理或优化关键词"]})]})]})}const ee={edit_loop:"编辑循环",tool_failure_spike:"工具失败",no_commit:"无 commit",event_overflow:"事件爆量"};function se({data:s,onSelectSession:t}){const r=(s==null?void 0:s.summary)??{total:0,critical:0,warn:0,info:0},n=((s==null?void 0:s.patterns)??[]).slice(0,5);return e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 lg:col-span-2",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-base font-semibold text-gray-900",children:[e.jsx(b,{className:"h-4 w-4 text-amber-600"}),"工作流洞察 (",(s==null?void 0:s.windowDays)??7," 天)"]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["共 ",r.total," 条"]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-4 mb-5",children:[e.jsxs("div",{className:"bg-red-50 rounded-lg p-4 text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-2 text-2xl font-bold text-red-700",children:[e.jsx(S,{className:"h-5 w-5"}),r.critical]}),e.jsx("div",{className:"text-xs text-red-600 mt-1",children:"Critical"})]}),e.jsxs("div",{className:"bg-amber-50 rounded-lg p-4 text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-2 text-2xl font-bold text-amber-700",children:[e.jsx(b,{className:"h-5 w-5"}),r.warn]}),e.jsx("div",{className:"text-xs text-amber-600 mt-1",children:"Warn"})]}),e.jsxs("div",{className:"bg-blue-50 rounded-lg p-4 text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-2 text-2xl font-bold text-blue-700",children:[e.jsx(A,{className:"h-5 w-5"}),r.info]}),e.jsx("div",{className:"text-xs text-blue-600 mt-1",children:"Info"})]})]}),n.length>0?e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:"最严重的 5 条"}),e.jsx("ul",{className:"space-y-2",children:n.map(i=>e.jsxs("li",{className:`border-l-4 px-3 py-2 rounded ${te(i.severity)} ${i.sessionId?"cursor-pointer hover:bg-gray-50":""}`,onClick:()=>i.sessionId&&t(i.sessionId),children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[e.jsx(ie,{severity:i.severity}),e.jsx("span",{className:"text-sm font-medium text-gray-900 truncate",children:i.title})]}),e.jsx("span",{className:"text-xs text-gray-500 shrink-0",children:ee[i.type]})]}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:i.description}),e.jsx(re,{pattern:i})]},i.id))})]}):e.jsx("div",{className:"flex items-center justify-center h-[120px] text-sm text-gray-400",children:"没有检测到反模式,工作流健康"})]})}function te(s){return s==="critical"?"border-red-500 bg-red-50/30":s==="warn"?"border-amber-500 bg-amber-50/30":"border-blue-400 bg-blue-50/30"}function ie({severity:s}){return s==="critical"?e.jsx(S,{className:"h-4 w-4 text-red-600 shrink-0"}):s==="warn"?e.jsx(b,{className:"h-4 w-4 text-amber-600 shrink-0"}):e.jsx(A,{className:"h-4 w-4 text-blue-600 shrink-0"})}function re({pattern:s}){const t=s.detail;let r="";if(s.type==="edit_loop"){const n=String(t.filePath??""),i=Number(t.count??0);r=`${n} edited ${i} 次`}else if(s.type==="tool_failure_spike"){const n=Number(t.recentFailureRate??0)*100,i=Number(t.baselineFailureRate??0)*100,a=Number(t.totalToolUses??0);r=`最近 24h ${n.toFixed(1)}% / 基线 ${i.toFixed(1)}% (${a} 次工具调用)`}else if(s.type==="no_commit"){const n=Number(t.durationMin??0),i=Number(t.eventCount??0);r=`${n} 分钟 · ${i} 个事件 · 无 git commit`}else if(s.type==="event_overflow"){const n=Number(t.eventCount??0),i=Number(t.durationMin??0);r=`${n} 个事件 / ${i} 分钟`}return r?e.jsx("p",{className:"text-xs text-gray-400 mt-1 font-mono truncate",children:r}):null}export{de as default};
|
|
2
|
+
//# sourceMappingURL=Dashboard-CoEmmIDt.js.map
|