@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
package/dist/web/routes/ai.js
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { ConfigManager } from '../../core/config.js';
|
|
2
|
-
import { logger } from '../../core/utils/logger.js';
|
|
3
|
-
import { validateBaseUrl, extractHostFromBaseUrl, UPSTREAM_TIMEOUT_MS, } from '../ssrf-guard.js';
|
|
4
|
-
/**
|
|
5
|
-
* /api/ai/* and /api/config/ai — AI provider config + upstream connectivity.
|
|
6
|
-
*
|
|
7
|
-
* All outbound calls route through validateBaseUrl + redirect:'manual' so the
|
|
8
|
-
* daemon cannot be tricked into reaching internal hosts (SSRF guard).
|
|
9
|
-
*/
|
|
10
|
-
export function registerAIRoutes(app, _ctx) {
|
|
11
|
-
// GET /api/config/ai — read current AI config
|
|
12
|
-
app.get('/api/config/ai', (_req, res) => {
|
|
13
|
-
const configManager = new ConfigManager();
|
|
14
|
-
const config = configManager.get();
|
|
15
|
-
res.json({
|
|
16
|
-
api_key: config.ai.api_key || '',
|
|
17
|
-
base_url: config.ai.base_url || '',
|
|
18
|
-
model: config.ai.model,
|
|
19
|
-
provider: config.ai.provider,
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
// PUT /api/config/ai — update AI config
|
|
23
|
-
app.put('/api/config/ai', (req, res) => {
|
|
24
|
-
const { api_key, base_url, model, provider } = req.body ?? {};
|
|
25
|
-
try {
|
|
26
|
-
const configManager = new ConfigManager();
|
|
27
|
-
const config = configManager.get();
|
|
28
|
-
if (typeof api_key === 'string')
|
|
29
|
-
config.ai.api_key = api_key;
|
|
30
|
-
if (typeof base_url === 'string') {
|
|
31
|
-
// Normalize http → https for upstream gateways that force HTTPS redirect
|
|
32
|
-
// (e.g. iflytek one.iflytek.com returns 302 and drops Authorization header)
|
|
33
|
-
let url = base_url.trim();
|
|
34
|
-
if (url.startsWith('http://'))
|
|
35
|
-
url = 'https://' + url.slice('http://'.length);
|
|
36
|
-
config.ai.base_url = url;
|
|
37
|
-
}
|
|
38
|
-
if (typeof model === 'string')
|
|
39
|
-
config.ai.model = model;
|
|
40
|
-
if (typeof provider === 'string')
|
|
41
|
-
config.ai.provider = provider;
|
|
42
|
-
configManager.save();
|
|
43
|
-
logger.info('[Web] AI config updated');
|
|
44
|
-
res.json({ success: true });
|
|
45
|
-
}
|
|
46
|
-
catch (err) {
|
|
47
|
-
logger.warn(`[Web] Failed to update AI config: ${err}`);
|
|
48
|
-
res.status(500).json({ error: String(err) });
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
// GET /api/ai/models — proxy to upstream /v1/models
|
|
52
|
-
app.get('/api/ai/models', async (req, res) => {
|
|
53
|
-
try {
|
|
54
|
-
const configManager = new ConfigManager();
|
|
55
|
-
const config = configManager.get();
|
|
56
|
-
const queryKey = typeof req.query.api_key === 'string' ? req.query.api_key : '';
|
|
57
|
-
const queryUrl = typeof req.query.base_url === 'string' ? req.query.base_url : '';
|
|
58
|
-
const apiKey = queryKey || config.ai.api_key;
|
|
59
|
-
let baseUrl = queryUrl || config.ai.base_url || 'https://api.anthropic.com';
|
|
60
|
-
if (baseUrl.startsWith('http://'))
|
|
61
|
-
baseUrl = 'https://' + baseUrl.slice('http://'.length);
|
|
62
|
-
if (!apiKey) {
|
|
63
|
-
res.status(400).json({ error: 'API key not configured' });
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const configuredHost = extractHostFromBaseUrl(config.ai.base_url);
|
|
67
|
-
const validation = validateBaseUrl(baseUrl, configuredHost ? [configuredHost] : []);
|
|
68
|
-
if (!validation.ok) {
|
|
69
|
-
res.status(400).json({ error: validation.error });
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
const modelsUrl = baseUrl.endsWith('/v1')
|
|
73
|
-
? `${baseUrl}/models`
|
|
74
|
-
: `${baseUrl}/v1/models`;
|
|
75
|
-
const controller = new AbortController();
|
|
76
|
-
const timer = setTimeout(() => controller.abort(), UPSTREAM_TIMEOUT_MS);
|
|
77
|
-
let response;
|
|
78
|
-
try {
|
|
79
|
-
response = await fetch(modelsUrl, {
|
|
80
|
-
redirect: 'manual',
|
|
81
|
-
signal: controller.signal,
|
|
82
|
-
headers: {
|
|
83
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
84
|
-
'x-api-key': apiKey,
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
finally {
|
|
89
|
-
clearTimeout(timer);
|
|
90
|
-
}
|
|
91
|
-
if (response.status >= 300 && response.status < 400) {
|
|
92
|
-
res.status(400).json({
|
|
93
|
-
error: `Upstream tried to redirect (status ${response.status}); refusing to follow`,
|
|
94
|
-
});
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (!response.ok) {
|
|
98
|
-
const text = await response.text();
|
|
99
|
-
logger.warn(`[Web] Upstream /v1/models failed: ${response.status} ${text}`);
|
|
100
|
-
res.status(response.status).json({ error: text });
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const data = await response.json();
|
|
104
|
-
res.json(data);
|
|
105
|
-
}
|
|
106
|
-
catch (err) {
|
|
107
|
-
if (err instanceof Error && err.name === 'AbortError') {
|
|
108
|
-
res.status(504).json({ error: `Upstream timeout (${UPSTREAM_TIMEOUT_MS}ms)` });
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
logger.warn(`[Web] Failed to fetch models: ${err}`);
|
|
112
|
-
res.status(500).json({ error: String(err) });
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
// POST /api/ai/test — test AI connection using provided or saved config
|
|
116
|
-
app.post('/api/ai/test', async (req, res) => {
|
|
117
|
-
try {
|
|
118
|
-
const configManager = new ConfigManager();
|
|
119
|
-
const config = configManager.get();
|
|
120
|
-
const { api_key, base_url, model } = req.body ?? {};
|
|
121
|
-
const apiKey = (typeof api_key === 'string' && api_key) || config.ai.api_key;
|
|
122
|
-
let baseUrl = (typeof base_url === 'string' && base_url) || config.ai.base_url || 'https://api.anthropic.com';
|
|
123
|
-
const useModel = (typeof model === 'string' && model) || config.ai.model;
|
|
124
|
-
if (baseUrl.startsWith('http://'))
|
|
125
|
-
baseUrl = 'https://' + baseUrl.slice('http://'.length);
|
|
126
|
-
if (!apiKey) {
|
|
127
|
-
res.status(400).json({ error: 'API key not configured' });
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
const configuredHost = extractHostFromBaseUrl(config.ai.base_url);
|
|
131
|
-
const validation = validateBaseUrl(baseUrl, configuredHost ? [configuredHost] : []);
|
|
132
|
-
if (!validation.ok) {
|
|
133
|
-
res.status(400).json({ error: validation.error });
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const messagesUrl = baseUrl.endsWith('/v1')
|
|
137
|
-
? `${baseUrl}/messages`
|
|
138
|
-
: `${baseUrl}/v1/messages`;
|
|
139
|
-
const controller = new AbortController();
|
|
140
|
-
const timer = setTimeout(() => controller.abort(), UPSTREAM_TIMEOUT_MS);
|
|
141
|
-
let response;
|
|
142
|
-
try {
|
|
143
|
-
response = await fetch(messagesUrl, {
|
|
144
|
-
method: 'POST',
|
|
145
|
-
redirect: 'manual',
|
|
146
|
-
signal: controller.signal,
|
|
147
|
-
headers: {
|
|
148
|
-
'Content-Type': 'application/json',
|
|
149
|
-
'x-api-key': apiKey,
|
|
150
|
-
'anthropic-version': '2023-06-01',
|
|
151
|
-
},
|
|
152
|
-
body: JSON.stringify({
|
|
153
|
-
model: useModel,
|
|
154
|
-
max_tokens: 10,
|
|
155
|
-
messages: [{ role: 'user', content: 'ping' }],
|
|
156
|
-
}),
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
finally {
|
|
160
|
-
clearTimeout(timer);
|
|
161
|
-
}
|
|
162
|
-
if (response.status >= 300 && response.status < 400) {
|
|
163
|
-
res.status(400).json({
|
|
164
|
-
error: `Upstream tried to redirect (status ${response.status}); refusing to follow`,
|
|
165
|
-
});
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
if (!response.ok) {
|
|
169
|
-
const text = await response.text();
|
|
170
|
-
res.status(response.status).json({ error: text });
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
const data = await response.json();
|
|
174
|
-
res.json({ success: true, model: data.model || useModel });
|
|
175
|
-
}
|
|
176
|
-
catch (err) {
|
|
177
|
-
if (err instanceof Error && err.name === 'AbortError') {
|
|
178
|
-
res.status(504).json({ error: `Upstream timeout (${UPSTREAM_TIMEOUT_MS}ms)` });
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
logger.warn(`[Web] AI connection test failed: ${err}`);
|
|
182
|
-
res.status(500).json({ error: String(err) });
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
//# sourceMappingURL=ai.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../../src/web/routes/ai.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Application } from 'express';
|
|
2
|
-
import type { RouteContext } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* /api/token-usage/* — token usage queries by session.
|
|
5
|
-
*/
|
|
6
|
-
export declare function registerTokenUsageRoutes(app: Application, ctx: RouteContext): void;
|
|
7
|
-
//# sourceMappingURL=token-usage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-usage.d.ts","sourceRoot":"","sources":["../../../src/web/routes/token-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,GAAG,IAAI,CAalF"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /api/token-usage/* — token usage queries by session.
|
|
3
|
-
*/
|
|
4
|
-
export function registerTokenUsageRoutes(app, ctx) {
|
|
5
|
-
const { storage } = ctx;
|
|
6
|
-
app.get('/api/token-usage/session/:sessionId', (req, res) => {
|
|
7
|
-
const sessionId = req.params.sessionId;
|
|
8
|
-
try {
|
|
9
|
-
const usage = storage.getTokenUsageBySession(sessionId);
|
|
10
|
-
const details = storage.listTokenUsage({ session_id: sessionId, limit: 100 });
|
|
11
|
-
res.json({ ...usage, details });
|
|
12
|
-
}
|
|
13
|
-
catch (err) {
|
|
14
|
-
res.status(500).json({ error: String(err) });
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=token-usage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-usage.js","sourceRoot":"","sources":["../../../src/web/routes/token-usage.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAgB,EAAE,GAAiB;IAC1E,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC;IAExB,GAAG,CAAC,GAAG,CAAC,qCAAqC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC1D,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,OAAO,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YAC9E,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/web/ssrf-guard.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SSRF 防护 — Web API 对外 fetch 前的 URL 白名单校验
|
|
3
|
-
*
|
|
4
|
-
* 背景:`/api/ai/test` 与 `/api/ai/models` 允许请求方指定上游 `baseUrl`,
|
|
5
|
-
* 若不加约束可被滥用为 SSRF 通道(访问 169.254.169.254 / 127.0.0.1 / 内网 API
|
|
6
|
-
* 等),并通过 res.json 回显响应体。此模块统一做协议、主机、白名单校验。
|
|
7
|
-
*/
|
|
8
|
-
/** 校验结果 */
|
|
9
|
-
export interface SsrfValidationResult {
|
|
10
|
-
ok: boolean;
|
|
11
|
-
error?: string;
|
|
12
|
-
}
|
|
13
|
-
/** 默认允许访问的上游主机(已知 AI 服务商的官方域名) */
|
|
14
|
-
export declare const DEFAULT_ALLOWED_HOSTS: ReadonlySet<string>;
|
|
15
|
-
/** 统一的跨端点 fetch 超时(毫秒) */
|
|
16
|
-
export declare const UPSTREAM_TIMEOUT_MS = 10000;
|
|
17
|
-
/**
|
|
18
|
-
* 校验用户提供的 baseUrl 是否允许被 daemon 代为访问。
|
|
19
|
-
*
|
|
20
|
-
* 规则:
|
|
21
|
-
* 1. 必须能解析为 URL;
|
|
22
|
-
* 2. 协议必须是 http 或 https;
|
|
23
|
-
* 3. 禁止 IPv4 / IPv6 字面量、localhost 等本机/内网地址;
|
|
24
|
-
* 4. 主机必须在默认白名单或 extraHosts 中。
|
|
25
|
-
*
|
|
26
|
-
* @param baseUrl 待校验的 URL
|
|
27
|
-
* @param extraHosts 额外允许的主机(通常来自 config.yaml 里已配置的 base_url)
|
|
28
|
-
*/
|
|
29
|
-
export declare function validateBaseUrl(baseUrl: unknown, extraHosts?: Iterable<string>): SsrfValidationResult;
|
|
30
|
-
/**
|
|
31
|
-
* 从已配置的 base_url 中提取主机名,作为额外允许项。
|
|
32
|
-
* 无效/为空返回 null,调用方可忽略。
|
|
33
|
-
*/
|
|
34
|
-
export declare function extractHostFromBaseUrl(baseUrl: string | undefined | null): string | null;
|
|
35
|
-
//# sourceMappingURL=ssrf-guard.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ssrf-guard.d.ts","sourceRoot":"","sources":["../../src/web/ssrf-guard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,WAAW;AACX,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,kCAAkC;AAClC,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAIpD,CAAC;AAEH,0BAA0B;AAC1B,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAmB1C;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,UAAU,GAAE,QAAQ,CAAC,MAAM,CAAM,GAChC,oBAAoB,CA0CtB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAOxF"}
|
package/dist/web/ssrf-guard.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SSRF 防护 — Web API 对外 fetch 前的 URL 白名单校验
|
|
3
|
-
*
|
|
4
|
-
* 背景:`/api/ai/test` 与 `/api/ai/models` 允许请求方指定上游 `baseUrl`,
|
|
5
|
-
* 若不加约束可被滥用为 SSRF 通道(访问 169.254.169.254 / 127.0.0.1 / 内网 API
|
|
6
|
-
* 等),并通过 res.json 回显响应体。此模块统一做协议、主机、白名单校验。
|
|
7
|
-
*/
|
|
8
|
-
/** 默认允许访问的上游主机(已知 AI 服务商的官方域名) */
|
|
9
|
-
export const DEFAULT_ALLOWED_HOSTS = new Set([
|
|
10
|
-
'api.anthropic.com',
|
|
11
|
-
'api.openai.com',
|
|
12
|
-
'generativelanguage.googleapis.com',
|
|
13
|
-
]);
|
|
14
|
-
/** 统一的跨端点 fetch 超时(毫秒) */
|
|
15
|
-
export const UPSTREAM_TIMEOUT_MS = 10_000;
|
|
16
|
-
/** 判断字符串是否为 IPv4 字面量 */
|
|
17
|
-
function isIPv4Literal(host) {
|
|
18
|
-
return /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
19
|
-
}
|
|
20
|
-
/** 判断主机是否为 loopback / 保留名 */
|
|
21
|
-
function isLocalhostLike(host) {
|
|
22
|
-
const h = host.toLowerCase();
|
|
23
|
-
return (h === 'localhost' ||
|
|
24
|
-
h.endsWith('.localhost') ||
|
|
25
|
-
h === '0.0.0.0' ||
|
|
26
|
-
h === '::' ||
|
|
27
|
-
h === '::1');
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* 校验用户提供的 baseUrl 是否允许被 daemon 代为访问。
|
|
31
|
-
*
|
|
32
|
-
* 规则:
|
|
33
|
-
* 1. 必须能解析为 URL;
|
|
34
|
-
* 2. 协议必须是 http 或 https;
|
|
35
|
-
* 3. 禁止 IPv4 / IPv6 字面量、localhost 等本机/内网地址;
|
|
36
|
-
* 4. 主机必须在默认白名单或 extraHosts 中。
|
|
37
|
-
*
|
|
38
|
-
* @param baseUrl 待校验的 URL
|
|
39
|
-
* @param extraHosts 额外允许的主机(通常来自 config.yaml 里已配置的 base_url)
|
|
40
|
-
*/
|
|
41
|
-
export function validateBaseUrl(baseUrl, extraHosts = []) {
|
|
42
|
-
if (typeof baseUrl !== 'string' || baseUrl.length === 0) {
|
|
43
|
-
return { ok: false, error: 'baseUrl is required' };
|
|
44
|
-
}
|
|
45
|
-
let parsed;
|
|
46
|
-
try {
|
|
47
|
-
parsed = new URL(baseUrl);
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
return { ok: false, error: 'Invalid URL' };
|
|
51
|
-
}
|
|
52
|
-
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
|
53
|
-
return { ok: false, error: 'Only http/https protocols allowed' };
|
|
54
|
-
}
|
|
55
|
-
const host = parsed.hostname.toLowerCase();
|
|
56
|
-
if (isIPv4Literal(host)) {
|
|
57
|
-
return { ok: false, error: 'Direct IP access blocked (SSRF protection)' };
|
|
58
|
-
}
|
|
59
|
-
// URL parser strips brackets from IPv6 hostname; detect by ':' or '::'
|
|
60
|
-
if (host.includes(':')) {
|
|
61
|
-
return { ok: false, error: 'Direct IPv6 access blocked (SSRF protection)' };
|
|
62
|
-
}
|
|
63
|
-
if (isLocalhostLike(host)) {
|
|
64
|
-
return { ok: false, error: 'localhost access blocked (SSRF protection)' };
|
|
65
|
-
}
|
|
66
|
-
const allowed = new Set(DEFAULT_ALLOWED_HOSTS);
|
|
67
|
-
for (const extra of extraHosts) {
|
|
68
|
-
if (extra)
|
|
69
|
-
allowed.add(extra.toLowerCase());
|
|
70
|
-
}
|
|
71
|
-
if (!allowed.has(host)) {
|
|
72
|
-
return {
|
|
73
|
-
ok: false,
|
|
74
|
-
error: `Host ${host} not in allowlist. Allowed: ${[...allowed].sort().join(', ')}`,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
return { ok: true };
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* 从已配置的 base_url 中提取主机名,作为额外允许项。
|
|
81
|
-
* 无效/为空返回 null,调用方可忽略。
|
|
82
|
-
*/
|
|
83
|
-
export function extractHostFromBaseUrl(baseUrl) {
|
|
84
|
-
if (!baseUrl)
|
|
85
|
-
return null;
|
|
86
|
-
try {
|
|
87
|
-
return new URL(baseUrl).hostname.toLowerCase();
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
//# sourceMappingURL=ssrf-guard.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ssrf-guard.js","sourceRoot":"","sources":["../../src/web/ssrf-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Dashboard-CoEmmIDt.js","sources":["../../src/pages/Dashboard.tsx"],"sourcesContent":["import { useQuery } from '@tanstack/react-query'\nimport { useNavigate } from 'react-router-dom'\nimport { Activity, MessageSquare, Clock, BookOpen, Bot, ShieldAlert, AlertTriangle, AlertCircle, Info } from 'lucide-react'\nimport {\n AreaChart, Area, BarChart, Bar,\n PieChart, Pie, Cell,\n XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend,\n} from 'recharts'\n\ninterface Stats {\n pid: number\n uptime: number\n memory: any\n eventCount: number\n}\n\ninterface SystemStats {\n totalSessions: number\n totalEvents: number\n toolUsage: Record<string, number>\n dailyActivity: Array<{ date: string; eventCount: number; sessionCount: number }>\n skillInvocations: number\n}\n\ninterface SkillInvocationStats {\n days: number\n total: number\n invocations: Array<{ skill_id: string; total: number; success: number; failed: number }>\n}\n\ninterface RoutingStats {\n days: number\n total: number\n agentCalls: number\n noAgent: number\n agentRate: number\n byAgent: Array<{ agent: string; count: number }>\n}\n\ninterface RuleHitRate {\n period: { days: number; since: string }\n summary: {\n totalPrompts: number\n agentDelegations: number\n agentRate: string\n skillInvocations: number\n skillRate: string\n }\n skills: Array<{ skill_id: string; total: number; success: number; failed: number; rate: string }>\n agents: Array<{ agent: string; count: number; rate: string }>\n neverTriggered: string[]\n}\n\nasync function fetchStatus(): Promise<Stats> {\n const res = await fetch('/api/status')\n if (!res.ok) throw new Error('Failed')\n return res.json()\n}\n\nasync function fetchSystemStats(): Promise<SystemStats> {\n const res = await fetch('/api/stats')\n if (!res.ok) throw new Error('Failed')\n return res.json()\n}\n\nasync function fetchSessionsCount(): Promise<number> {\n const res = await fetch('/api/sessions?limit=1000')\n if (!res.ok) return 0\n const sessions = await res.json()\n return sessions.length\n}\n\nasync function fetchSkillInvocations(): Promise<SkillInvocationStats> {\n const res = await fetch('/api/skill-stats/invocations?days=7')\n if (!res.ok) throw new Error('Failed')\n return res.json()\n}\n\nasync function fetchRoutingStats(): Promise<RoutingStats> {\n const res = await fetch('/api/routing/stats?days=7')\n if (!res.ok) throw new Error('Failed')\n return res.json()\n}\n\nasync function fetchRuleHitRate(): Promise<RuleHitRate> {\n const res = await fetch('/api/rules/hit-rate?days=7')\n if (!res.ok) throw new Error('Failed')\n return res.json()\n}\n\ninterface AntiPattern {\n id: string\n type: 'edit_loop' | 'tool_failure_spike' | 'no_commit' | 'event_overflow'\n severity: 'info' | 'warn' | 'critical'\n title: string\n description: string\n detail: Record<string, unknown>\n detectedAt: string\n sessionId?: string\n filePath?: string\n}\n\ninterface InsightsResponse {\n generatedAt: string\n windowDays: number\n summary: { total: number; critical: number; warn: number; info: number }\n patterns: AntiPattern[]\n}\n\nasync function fetchInsights(): Promise<InsightsResponse> {\n const res = await fetch('/api/insights?days=7')\n if (!res.ok) throw new Error('Failed')\n return res.json()\n}\n\nfunction formatUptime(seconds: number): string {\n const days = Math.floor(seconds / 86400)\n const hours = Math.floor((seconds % 86400) / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n if (days > 0) return `${days}天 ${hours}小时`\n if (hours > 0) return `${hours}小时 ${minutes}分钟`\n return `${minutes}分钟`\n}\n\nconst COLORS = {\n primary: '#6366f1',\n green: '#10b981',\n}\n\nconst PIE_COLORS = ['#6366f1', '#e5e7eb']\n\nexport default function Dashboard() {\n const navigate = useNavigate()\n const { data: status } = useQuery({ queryKey: ['status'], queryFn: fetchStatus, refetchInterval: 5000 })\n const { data: systemStats } = useQuery({ queryKey: ['system-stats'], queryFn: fetchSystemStats, refetchInterval: 30000 })\n const { data: sessionsCount } = useQuery({ queryKey: ['sessions-count'], queryFn: fetchSessionsCount })\n const { data: skillStats } = useQuery({ queryKey: ['skill-invocations'], queryFn: fetchSkillInvocations, refetchInterval: 30000 })\n const { data: routingStats } = useQuery({ queryKey: ['routing-stats'], queryFn: fetchRoutingStats, refetchInterval: 30000 })\n const { data: ruleHitRate } = useQuery({ queryKey: ['rule-hit-rate'], queryFn: fetchRuleHitRate, refetchInterval: 30000 })\n const { data: insights } = useQuery({ queryKey: ['insights'], queryFn: fetchInsights, refetchInterval: 60000 })\n\n const toolUsageData = systemStats?.toolUsage\n ? Object.entries(systemStats.toolUsage)\n .sort(([, a], [, b]) => b - a)\n .slice(0, 8)\n .map(([name, count]) => ({ name, count }))\n : []\n\n const dailyData = systemStats?.dailyActivity || []\n const skillData = skillStats?.invocations.slice(0, 8) || []\n const agentPieData = routingStats\n ? [\n { name: 'Agent 调用', value: routingStats.agentCalls },\n { name: '直接执行', value: routingStats.noAgent },\n ]\n : []\n const agentByTypeData = routingStats?.byAgent.slice(0, 6) || []\n\n return (\n <div>\n <h1 className=\"text-2xl font-bold text-gray-900 mb-6\">仪表盘</h1>\n\n {/* Stats grid */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6\">\n <StatCard icon={Activity} label=\"总事件\" value={status?.eventCount?.toString() || '-'} color=\"blue\" onClick={() => navigate('/events')} />\n <StatCard icon={MessageSquare} label=\"会话数\" value={sessionsCount?.toString() || '-'} color=\"purple\" onClick={() => navigate('/sessions')} />\n <StatCard icon={BookOpen} label=\"Skill 调用\" value={skillStats?.total?.toString() || '0'} color=\"green\" />\n <StatCard\n icon={Bot}\n label={`Agent 调用率 (${routingStats?.days ?? 7}天)`}\n value={routingStats ? `${routingStats.agentRate}%` : '-'}\n color=\"indigo\"\n />\n </div>\n\n {/* Charts */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6\">\n {/* Daily activity */}\n <div className=\"bg-white rounded-lg shadow p-6\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-base font-semibold text-gray-900\">最近 7 天活动</h3>\n <button\n onClick={() => navigate('/events')}\n className=\"text-xs text-indigo-600 hover:text-indigo-700\"\n >\n 查看全部事件\n </button>\n </div>\n <ResponsiveContainer width=\"100%\" height={240}>\n <AreaChart data={dailyData}>\n <defs>\n <linearGradient id=\"colorEvents\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"5%\" stopColor={COLORS.primary} stopOpacity={0.3} />\n <stop offset=\"95%\" stopColor={COLORS.primary} stopOpacity={0} />\n </linearGradient>\n </defs>\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis dataKey=\"date\" tick={{ fontSize: 11 }} tickFormatter={(d) => d?.slice(5)} />\n <YAxis tick={{ fontSize: 11 }} />\n <Tooltip />\n <Area\n type=\"monotone\"\n dataKey=\"eventCount\"\n stroke={COLORS.primary}\n strokeWidth={2}\n fill=\"url(#colorEvents)\"\n name=\"事件\"\n />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n\n {/* Tool usage */}\n <div className=\"bg-white rounded-lg shadow p-6\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-base font-semibold text-gray-900\">工具使用分布</h3>\n </div>\n <ResponsiveContainer width=\"100%\" height={240}>\n <BarChart data={toolUsageData} layout=\"vertical\">\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis type=\"number\" tick={{ fontSize: 11 }} />\n <YAxis dataKey=\"name\" type=\"category\" tick={{ fontSize: 11 }} width={80} />\n <Tooltip />\n <Bar dataKey=\"count\" fill={COLORS.primary} radius={[0, 4, 4, 0]} />\n </BarChart>\n </ResponsiveContainer>\n </div>\n\n {/* Skill 调用统计 */}\n <div className=\"bg-white rounded-lg shadow p-6\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"flex items-center gap-2 text-base font-semibold text-gray-900\">\n <BookOpen className=\"h-4 w-4 text-green-600\" />\n Skill 调用统计 ({skillStats?.days ?? 7} 天)\n </h3>\n <span className=\"text-xs text-gray-500\">共 {skillStats?.total ?? 0} 次</span>\n </div>\n {skillData.length > 0 ? (\n <ResponsiveContainer width=\"100%\" height={240}>\n <BarChart data={skillData} layout=\"vertical\">\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis type=\"number\" tick={{ fontSize: 11 }} />\n <YAxis dataKey=\"skill_id\" type=\"category\" tick={{ fontSize: 10 }} width={140} />\n <Tooltip />\n <Legend wrapperStyle={{ fontSize: 11 }} />\n <Bar dataKey=\"success\" stackId=\"a\" fill={COLORS.green} name=\"成功\" radius={[0, 0, 0, 0]} />\n <Bar dataKey=\"failed\" stackId=\"a\" fill=\"#ef4444\" name=\"失败\" radius={[0, 4, 4, 0]} />\n </BarChart>\n </ResponsiveContainer>\n ) : (\n <div className=\"flex items-center justify-center h-[240px] text-sm text-gray-400\">\n 暂无 Skill 调用记录\n </div>\n )}\n </div>\n\n {/* Agent 调用率 */}\n <div className=\"bg-white rounded-lg shadow p-6\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"flex items-center gap-2 text-base font-semibold text-gray-900\">\n <Bot className=\"h-4 w-4 text-indigo-600\" />\n Agent 调用率 ({routingStats?.days ?? 7} 天)\n </h3>\n <span className=\"text-xs text-gray-500\">\n {routingStats ? `${routingStats.agentCalls} / ${routingStats.total}` : '-'}\n </span>\n </div>\n {routingStats && routingStats.total > 0 ? (\n <ResponsiveContainer width=\"100%\" height={240}>\n <PieChart>\n <Pie\n data={agentPieData}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={50}\n outerRadius={80}\n label={({ name, percent }) => `${name}: ${((percent ?? 0) * 100).toFixed(0)}%`}\n labelLine={false}\n >\n {agentPieData.map((_, idx) => (\n <Cell key={idx} fill={PIE_COLORS[idx]} />\n ))}\n </Pie>\n <Tooltip />\n </PieChart>\n </ResponsiveContainer>\n ) : (\n <div className=\"flex items-center justify-center h-[240px] text-sm text-gray-400\">\n 暂无路由记录\n </div>\n )}\n </div>\n\n {/* Agent 类型分布 */}\n <div className=\"bg-white rounded-lg shadow p-6\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-base font-semibold text-gray-900\">Agent 类型分布</h3>\n </div>\n {agentByTypeData.length > 0 ? (\n <ResponsiveContainer width=\"100%\" height={240}>\n <BarChart data={agentByTypeData} layout=\"vertical\">\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis type=\"number\" tick={{ fontSize: 11 }} />\n <YAxis dataKey=\"agent\" type=\"category\" tick={{ fontSize: 11 }} width={120} />\n <Tooltip />\n <Bar dataKey=\"count\" fill={COLORS.primary} radius={[0, 4, 4, 0]} />\n </BarChart>\n </ResponsiveContainer>\n ) : (\n <div className=\"flex items-center justify-center h-[240px] text-sm text-gray-400\">\n 暂无 Agent 调用记录\n </div>\n )}\n </div>\n\n {/* Rule Hit Rate */}\n <RuleHitRateCard data={ruleHitRate} />\n\n {/* Workflow Insights */}\n <InsightsCard data={insights} onSelectSession={(id) => navigate(`/sessions/${id}`)} />\n\n {/* System info */}\n <div className=\"bg-white rounded-lg shadow p-6\">\n <h3 className=\"flex items-center gap-2 text-base font-semibold text-gray-900 mb-4\">\n <Clock className=\"h-4 w-4 text-indigo-600\" />\n 系统状态\n </h3>\n <dl className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-gray-500\">PID</dt>\n <dd className=\"font-mono text-gray-900\">{status?.pid || '-'}</dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-gray-500\">运行时间</dt>\n <dd className=\"text-gray-900\">{status?.uptime ? formatUptime(status.uptime) : '-'}</dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-gray-500\">内存使用</dt>\n <dd className=\"text-gray-900\">\n {status?.memory ? `${Math.round(status.memory.heapUsed / 1024 / 1024)} MB` : '-'}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n </div>\n )\n}\n\nfunction StatCard({ icon: Icon, label, value, color, onClick }: {\n icon: any, label: string, value: string, color: string, onClick?: () => void\n}) {\n const colorClass: Record<string, string> = {\n blue: 'bg-blue-100 text-blue-600',\n purple: 'bg-purple-100 text-purple-600',\n indigo: 'bg-indigo-100 text-indigo-600',\n green: 'bg-green-100 text-green-600',\n }\n return (\n <div\n className={`bg-white rounded-lg shadow p-5 ${onClick ? 'cursor-pointer hover:shadow-md transition-shadow' : ''}`}\n onClick={onClick}\n >\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-sm text-gray-500\">{label}</span>\n <div className={`w-8 h-8 rounded-lg flex items-center justify-center ${colorClass[color]}`}>\n <Icon className=\"h-4 w-4\" />\n </div>\n </div>\n <div className=\"text-2xl font-bold text-gray-900\">{value}</div>\n </div>\n )\n}\n\nfunction RuleHitRateCard({ data }: { data?: RuleHitRate }) {\n const topSkills = data?.skills.slice(0, 5) || []\n\n return (\n <div className=\"bg-white rounded-lg shadow p-6 lg:col-span-2\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"flex items-center gap-2 text-base font-semibold text-gray-900\">\n <ShieldAlert className=\"h-4 w-4 text-amber-600\" />\n 规则命中率 ({data?.period.days ?? 7} 天)\n </h3>\n <span className=\"text-xs text-gray-500\">\n 共 {data?.summary.totalPrompts ?? 0} 次路由\n </span>\n </div>\n\n {/* Top metrics */}\n <div className=\"grid grid-cols-2 gap-4 mb-5\">\n <div className=\"bg-indigo-50 rounded-lg p-4 text-center\">\n <div className=\"text-2xl font-bold text-indigo-700\">\n {data?.summary.agentRate ?? '0%'}\n </div>\n <div className=\"text-xs text-indigo-600 mt-1\">Agent 委托率</div>\n </div>\n <div className=\"bg-green-50 rounded-lg p-4 text-center\">\n <div className=\"text-2xl font-bold text-green-700\">\n {data?.summary.skillRate ?? '0%'}\n </div>\n <div className=\"text-xs text-green-600 mt-1\">Skill 触发率</div>\n </div>\n </div>\n\n {/* Top 5 Skill bar chart */}\n {topSkills.length > 0 ? (\n <div className=\"mb-5\">\n <h4 className=\"text-sm font-medium text-gray-700 mb-2\">Top Skill 调用排行</h4>\n <ResponsiveContainer width=\"100%\" height={160}>\n <BarChart data={topSkills} layout=\"vertical\">\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis type=\"number\" tick={{ fontSize: 11 }} />\n <YAxis dataKey=\"skill_id\" type=\"category\" tick={{ fontSize: 10 }} width={140} />\n <Tooltip />\n <Bar dataKey=\"total\" fill=\"#10b981\" radius={[0, 4, 4, 0]} name=\"调用次数\" />\n </BarChart>\n </ResponsiveContainer>\n </div>\n ) : (\n <div className=\"flex items-center justify-center h-[100px] text-sm text-gray-400 mb-5\">\n 暂无 Skill 调用记录\n </div>\n )}\n\n {/* Never triggered */}\n {data && data.neverTriggered.length > 0 && (\n <div>\n <h4 className=\"text-sm font-medium text-gray-700 mb-2\">\n 从未触发的规则 ({data.neverTriggered.length})\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n {data.neverTriggered.map(id => (\n <span key={id} className=\"text-xs bg-gray-100 text-gray-500 px-2 py-1 rounded\">\n {id}\n </span>\n ))}\n </div>\n <p className=\"text-xs text-gray-400 mt-2\">\n 这些 Skill 在过去 {data.period.days} 天内从未被触发,可考虑清理或优化关键词\n </p>\n </div>\n )}\n </div>\n )\n}\n\nconst PATTERN_LABEL: Record<AntiPattern['type'], string> = {\n edit_loop: '编辑循环',\n tool_failure_spike: '工具失败',\n no_commit: '无 commit',\n event_overflow: '事件爆量',\n}\n\nfunction InsightsCard({\n data,\n onSelectSession,\n}: {\n data?: InsightsResponse\n onSelectSession: (sessionId: string) => void\n}) {\n const summary = data?.summary ?? { total: 0, critical: 0, warn: 0, info: 0 }\n const top = (data?.patterns ?? []).slice(0, 5)\n\n return (\n <div className=\"bg-white rounded-lg shadow p-6 lg:col-span-2\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"flex items-center gap-2 text-base font-semibold text-gray-900\">\n <AlertTriangle className=\"h-4 w-4 text-amber-600\" />\n 工作流洞察 ({data?.windowDays ?? 7} 天)\n </h3>\n <span className=\"text-xs text-gray-500\">共 {summary.total} 条</span>\n </div>\n\n {/* Severity counters */}\n <div className=\"grid grid-cols-3 gap-4 mb-5\">\n <div className=\"bg-red-50 rounded-lg p-4 text-center\">\n <div className=\"flex items-center justify-center gap-2 text-2xl font-bold text-red-700\">\n <AlertCircle className=\"h-5 w-5\" />\n {summary.critical}\n </div>\n <div className=\"text-xs text-red-600 mt-1\">Critical</div>\n </div>\n <div className=\"bg-amber-50 rounded-lg p-4 text-center\">\n <div className=\"flex items-center justify-center gap-2 text-2xl font-bold text-amber-700\">\n <AlertTriangle className=\"h-5 w-5\" />\n {summary.warn}\n </div>\n <div className=\"text-xs text-amber-600 mt-1\">Warn</div>\n </div>\n <div className=\"bg-blue-50 rounded-lg p-4 text-center\">\n <div className=\"flex items-center justify-center gap-2 text-2xl font-bold text-blue-700\">\n <Info className=\"h-5 w-5\" />\n {summary.info}\n </div>\n <div className=\"text-xs text-blue-600 mt-1\">Info</div>\n </div>\n </div>\n\n {/* Top patterns */}\n {top.length > 0 ? (\n <div>\n <h4 className=\"text-sm font-medium text-gray-700 mb-2\">最严重的 5 条</h4>\n <ul className=\"space-y-2\">\n {top.map(p => (\n <li\n key={p.id}\n className={`border-l-4 px-3 py-2 rounded ${severityBorder(p.severity)} ${\n p.sessionId ? 'cursor-pointer hover:bg-gray-50' : ''\n }`}\n onClick={() => p.sessionId && onSelectSession(p.sessionId)}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex items-center gap-2 min-w-0 flex-1\">\n <SeverityIcon severity={p.severity} />\n <span className=\"text-sm font-medium text-gray-900 truncate\">{p.title}</span>\n </div>\n <span className=\"text-xs text-gray-500 shrink-0\">{PATTERN_LABEL[p.type]}</span>\n </div>\n <p className=\"text-xs text-gray-500 mt-1\">{p.description}</p>\n <PatternKeyData pattern={p} />\n </li>\n ))}\n </ul>\n </div>\n ) : (\n <div className=\"flex items-center justify-center h-[120px] text-sm text-gray-400\">\n 没有检测到反模式,工作流健康\n </div>\n )}\n </div>\n )\n}\n\nfunction severityBorder(s: AntiPattern['severity']): string {\n if (s === 'critical') return 'border-red-500 bg-red-50/30'\n if (s === 'warn') return 'border-amber-500 bg-amber-50/30'\n return 'border-blue-400 bg-blue-50/30'\n}\n\nfunction SeverityIcon({ severity }: { severity: AntiPattern['severity'] }) {\n if (severity === 'critical') return <AlertCircle className=\"h-4 w-4 text-red-600 shrink-0\" />\n if (severity === 'warn') return <AlertTriangle className=\"h-4 w-4 text-amber-600 shrink-0\" />\n return <Info className=\"h-4 w-4 text-blue-600 shrink-0\" />\n}\n\nfunction PatternKeyData({ pattern }: { pattern: AntiPattern }) {\n const d = pattern.detail\n let text = ''\n if (pattern.type === 'edit_loop') {\n const fp = String(d.filePath ?? '')\n const count = Number(d.count ?? 0)\n text = `${fp} edited ${count} 次`\n } else if (pattern.type === 'tool_failure_spike') {\n const recent = Number(d.recentFailureRate ?? 0) * 100\n const baseline = Number(d.baselineFailureRate ?? 0) * 100\n const total = Number(d.totalToolUses ?? 0)\n text = `最近 24h ${recent.toFixed(1)}% / 基线 ${baseline.toFixed(1)}% (${total} 次工具调用)`\n } else if (pattern.type === 'no_commit') {\n const min = Number(d.durationMin ?? 0)\n const ec = Number(d.eventCount ?? 0)\n text = `${min} 分钟 · ${ec} 个事件 · 无 git commit`\n } else if (pattern.type === 'event_overflow') {\n const ec = Number(d.eventCount ?? 0)\n const min = Number(d.durationMin ?? 0)\n text = `${ec} 个事件 / ${min} 分钟`\n }\n if (!text) return null\n return <p className=\"text-xs text-gray-400 mt-1 font-mono truncate\">{text}</p>\n}\n"],"names":["fetchStatus","res","fetchSystemStats","fetchSessionsCount","fetchSkillInvocations","fetchRoutingStats","fetchRuleHitRate","fetchInsights","formatUptime","seconds","days","hours","minutes","COLORS","PIE_COLORS","Dashboard","navigate","useNavigate","status","useQuery","systemStats","sessionsCount","skillStats","routingStats","ruleHitRate","insights","toolUsageData","a","b","name","count","dailyData","skillData","agentPieData","agentByTypeData","jsx","jsxs","StatCard","Activity","_a","MessageSquare","BookOpen","_b","Bot","ResponsiveContainer","AreaChart","CartesianGrid","XAxis","d","YAxis","Tooltip","Area","BarChart","Bar","Legend","PieChart","Pie","percent","_","idx","Cell","RuleHitRateCard","InsightsCard","id","Clock","Icon","label","value","color","onClick","colorClass","data","topSkills","ShieldAlert","PATTERN_LABEL","onSelectSession","summary","top","AlertTriangle","AlertCircle","Info","p","severityBorder","SeverityIcon","PatternKeyData","severity","pattern","text","fp","recent","baseline","total","min","ec"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as c,j as e}from"./react-vendor-CSp-GLFF.js";import{d as i}from"./vendor-CMMjVdZs.js";import{X as x}from"./lucide-Bs_edTLa.js";function y({open:t,onClose:s,title:a,children:n,width:o="w-[600px]"}){return c.useEffect(()=>{const r=l=>{l.key==="Escape"&&s()};return t&&(document.addEventListener("keydown",r),document.body.style.overflow="hidden"),()=>{document.removeEventListener("keydown",r),document.body.style.overflow=""}},[t,s]),e.jsxs(e.Fragment,{children:[e.jsx("div",{className:i("fixed inset-0 bg-gray-600 transition-opacity z-40",t?"bg-opacity-50 visible":"bg-opacity-0 invisible pointer-events-none"),onClick:s}),e.jsxs("div",{className:i("fixed inset-y-0 right-0 bg-white shadow-xl z-50 transform transition-transform flex flex-col",o,"max-w-full",t?"translate-x-0":"translate-x-full"),children:[e.jsxs("div",{className:"flex items-center justify-between px-6 py-4 border-b border-gray-200 flex-shrink-0",children:[e.jsx("h2",{className:"text-lg font-semibold text-gray-900",children:a}),e.jsx("button",{onClick:s,className:"text-gray-400 hover:text-gray-600 transition-colors",children:e.jsx(x,{className:"h-5 w-5"})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-6",children:n})]})]})}export{y as D};
|
|
2
|
-
//# sourceMappingURL=Drawer-DdRTzlLB.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer-DdRTzlLB.js","sources":["../../src/components/Drawer.tsx"],"sourcesContent":["import { ReactNode, useEffect } from 'react'\nimport { X } from 'lucide-react'\nimport clsx from 'clsx'\n\ninterface DrawerProps {\n open: boolean\n onClose: () => void\n title: string\n children: ReactNode\n width?: string\n}\n\nexport default function Drawer({ open, onClose, title, children, width = 'w-[600px]' }: DrawerProps) {\n useEffect(() => {\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose()\n }\n if (open) {\n document.addEventListener('keydown', handleEsc)\n document.body.style.overflow = 'hidden'\n }\n return () => {\n document.removeEventListener('keydown', handleEsc)\n document.body.style.overflow = ''\n }\n }, [open, onClose])\n\n return (\n <>\n <div\n className={clsx(\n 'fixed inset-0 bg-gray-600 transition-opacity z-40',\n open ? 'bg-opacity-50 visible' : 'bg-opacity-0 invisible pointer-events-none'\n )}\n onClick={onClose}\n />\n <div\n className={clsx(\n 'fixed inset-y-0 right-0 bg-white shadow-xl z-50 transform transition-transform flex flex-col',\n width,\n 'max-w-full',\n open ? 'translate-x-0' : 'translate-x-full'\n )}\n >\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-gray-200 flex-shrink-0\">\n <h2 className=\"text-lg font-semibold text-gray-900\">{title}</h2>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 transition-colors\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n <div className=\"flex-1 overflow-y-auto p-6\">\n {children}\n </div>\n </div>\n </>\n )\n}\n"],"names":["Drawer","open","onClose","title","children","width","useEffect","handleEsc","e","jsxs","Fragment","jsx","clsx","X"],"mappings":"wIAYA,SAAwBA,EAAO,CAAE,KAAAC,EAAM,QAAAC,EAAS,MAAAC,EAAO,SAAAC,EAAU,MAAAC,EAAQ,aAA4B,CACnGC,OAAAA,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAaC,GAAqB,CAClCA,EAAE,MAAQ,UAAUN,EAAA,CAC1B,EACA,OAAID,IACF,SAAS,iBAAiB,UAAWM,CAAS,EAC9C,SAAS,KAAK,MAAM,SAAW,UAE1B,IAAM,CACX,SAAS,oBAAoB,UAAWA,CAAS,EACjD,SAAS,KAAK,MAAM,SAAW,EACjC,CACF,EAAG,CAACN,EAAMC,CAAO,CAAC,EAGhBO,EAAAA,KAAAC,WAAA,CACE,SAAA,CAAAC,EAAAA,IAAC,MAAA,CACC,UAAWC,EACT,oDACAX,EAAO,wBAA0B,4CAAA,EAEnC,QAASC,CAAA,CAAA,EAEXO,EAAAA,KAAC,MAAA,CACC,UAAWG,EACT,+FACAP,EACA,aACAJ,EAAO,gBAAkB,kBAAA,EAG3B,SAAA,CAAAQ,EAAAA,KAAC,MAAA,CAAI,UAAU,qFACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,sCAAuC,SAAAR,EAAM,EAC3DQ,EAAAA,IAAC,SAAA,CACC,QAAST,EACT,UAAU,sDAEV,SAAAS,EAAAA,IAACE,EAAA,CAAE,UAAU,SAAA,CAAU,CAAA,CAAA,CACzB,EACF,EACAF,EAAAA,IAAC,MAAA,CAAI,UAAU,6BACZ,SAAAP,CAAA,CACH,CAAA,CAAA,CAAA,CACF,EACF,CAEJ"}
|