@winspan/claude-forge 8.41.0 → 8.50.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +17 -0
- package/.eslintrc.js +23 -0
- package/.prettierrc +8 -0
- package/ARCHITECTURE_ISSUES.md +249 -0
- package/CLAUDE.md +265 -0
- package/CLAUDE.md.backup +488 -0
- package/DEVELOPMENT.md +310 -0
- package/dist/claudemd/claudemd-generator.d.ts +38 -3
- package/dist/claudemd/claudemd-generator.d.ts.map +1 -1
- package/dist/claudemd/claudemd-generator.js +629 -11
- package/dist/claudemd/claudemd-generator.js.map +1 -1
- package/dist/claudemd/index.d.ts +2 -2
- package/dist/claudemd/index.d.ts.map +1 -1
- package/dist/claudemd/index.js.map +1 -1
- package/dist/claudemd/resume-manager.d.ts.map +1 -1
- package/dist/claudemd/resume-manager.js +5 -2
- package/dist/claudemd/resume-manager.js.map +1 -1
- package/dist/claudemd/tech-detector.d.ts +1 -0
- package/dist/claudemd/tech-detector.d.ts.map +1 -1
- package/dist/claudemd/tech-detector.js +53 -0
- package/dist/claudemd/tech-detector.js.map +1 -1
- package/dist/cli/commands/claudemd.js +2 -2
- package/dist/cli/commands/claudemd.js.map +1 -1
- package/dist/cli/commands/daemon.d.ts +28 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/daemon.js +200 -8
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +3 -35
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/menu.js +10 -10
- package/dist/cli/commands/menu.js.map +1 -1
- package/dist/cli/commands/skills.d.ts.map +1 -1
- package/dist/cli/commands/skills.js +8 -2
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +0 -17
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/trace.d.ts +9 -0
- package/dist/cli/commands/trace.d.ts.map +1 -0
- package/dist/cli/commands/trace.js +137 -0
- package/dist/cli/commands/trace.js.map +1 -0
- package/dist/cli/index.js +2 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/core/ai/provider.d.ts +10 -2
- package/dist/core/ai/provider.d.ts.map +1 -1
- package/dist/core/ai/provider.js.map +1 -1
- package/dist/core/ai/types.d.ts +1 -19
- package/dist/core/ai/types.d.ts.map +1 -1
- package/dist/core/ai/types.js +1 -1
- package/dist/core/config.d.ts +2 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +23 -6
- package/dist/core/config.js.map +1 -1
- package/dist/core/constants.d.ts +2 -2
- package/dist/core/constants.js +2 -2
- package/dist/core/constants.js.map +1 -1
- package/dist/core/queue/index.d.ts +52 -0
- package/dist/core/queue/index.d.ts.map +1 -0
- package/dist/core/queue/index.js +176 -0
- package/dist/core/queue/index.js.map +1 -0
- package/dist/core/storage/base.d.ts +33 -0
- package/dist/core/storage/base.d.ts.map +1 -0
- package/dist/core/storage/base.js +211 -0
- package/dist/core/storage/base.js.map +1 -0
- package/dist/core/storage/events.d.ts +52 -0
- package/dist/core/storage/events.d.ts.map +1 -0
- package/dist/core/storage/events.js +201 -0
- package/dist/core/storage/events.js.map +1 -0
- package/dist/core/storage/injections.d.ts +27 -0
- package/dist/core/storage/injections.d.ts.map +1 -0
- package/dist/core/storage/injections.js +51 -0
- package/dist/core/storage/injections.js.map +1 -0
- package/dist/core/storage/maintenance.d.ts +21 -0
- package/dist/core/storage/maintenance.d.ts.map +1 -0
- package/dist/core/storage/maintenance.js +52 -0
- package/dist/core/storage/maintenance.js.map +1 -0
- package/dist/core/storage/routing.d.ts +71 -0
- package/dist/core/storage/routing.d.ts.map +1 -0
- package/dist/core/storage/routing.js +141 -0
- package/dist/core/storage/routing.js.map +1 -0
- package/dist/core/storage/rows.d.ts +0 -47
- package/dist/core/storage/rows.d.ts.map +1 -1
- package/dist/core/storage/schema.sql +74 -136
- package/dist/core/storage/sessions.d.ts +34 -0
- package/dist/core/storage/sessions.d.ts.map +1 -0
- package/dist/core/storage/sessions.js +78 -0
- package/dist/core/storage/sessions.js.map +1 -0
- package/dist/core/storage/skills.d.ts +40 -0
- package/dist/core/storage/skills.d.ts.map +1 -0
- package/dist/core/storage/skills.js +107 -0
- package/dist/core/storage/skills.js.map +1 -0
- package/dist/core/storage/sqlite.d.ts +63 -265
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +102 -759
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts +64 -0
- package/dist/core/storage/tasks.d.ts.map +1 -0
- package/dist/core/storage/tasks.js +134 -0
- package/dist/core/storage/tasks.js.map +1 -0
- package/dist/core/storage/token-usage.d.ts +36 -0
- package/dist/core/storage/token-usage.d.ts.map +1 -0
- package/dist/core/storage/token-usage.js +59 -0
- package/dist/core/storage/token-usage.js.map +1 -0
- package/dist/core/types.d.ts +60 -4
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +24 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/format.d.ts +28 -0
- package/dist/core/utils/format.d.ts.map +1 -0
- package/dist/core/utils/format.js +68 -0
- package/dist/core/utils/format.js.map +1 -0
- package/dist/core/utils/logger.d.ts +6 -1
- package/dist/core/utils/logger.d.ts.map +1 -1
- package/dist/core/utils/logger.js +72 -2
- package/dist/core/utils/logger.js.map +1 -1
- package/dist/core/utils/session.d.ts +16 -0
- package/dist/core/utils/session.d.ts.map +1 -0
- package/dist/core/utils/session.js +25 -0
- package/dist/core/utils/session.js.map +1 -0
- package/dist/core/utils/time.d.ts +22 -0
- package/dist/core/utils/time.d.ts.map +1 -0
- package/dist/core/utils/time.js +38 -0
- package/dist/core/utils/time.js.map +1 -0
- package/dist/daemon/handlers/history-exporter.d.ts.map +1 -1
- package/dist/daemon/handlers/history-exporter.js +6 -4
- package/dist/daemon/handlers/history-exporter.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts +5 -12
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +21 -79
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/stop.d.ts +24 -12
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +141 -42
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts +18 -19
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +103 -227
- package/dist/daemon/handlers/user-prompt.js.map +1 -1
- package/dist/daemon/index.d.ts +6 -2
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +76 -120
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/launchd/com.claude-forge.daemon.plist.template +47 -0
- package/dist/daemon/launchd-installer.d.ts +61 -0
- package/dist/daemon/launchd-installer.d.ts.map +1 -0
- package/dist/daemon/launchd-installer.js +182 -0
- package/dist/daemon/launchd-installer.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +11 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +44 -0
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/router.d.ts +9 -2
- package/dist/daemon/router.d.ts.map +1 -1
- package/dist/daemon/router.js +27 -3
- package/dist/daemon/router.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +6 -5
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/services/anti-pattern-detector.d.ts +50 -0
- package/dist/daemon/services/anti-pattern-detector.d.ts.map +1 -0
- package/dist/daemon/services/anti-pattern-detector.js +357 -0
- package/dist/daemon/services/anti-pattern-detector.js.map +1 -0
- package/dist/daemon/services/drift-detector.d.ts +64 -0
- package/dist/daemon/services/drift-detector.d.ts.map +1 -0
- package/dist/daemon/services/drift-detector.js +201 -0
- package/dist/daemon/services/drift-detector.js.map +1 -0
- package/dist/{intelligence → daemon/services}/task-segmenter.d.ts +7 -1
- package/dist/daemon/services/task-segmenter.d.ts.map +1 -0
- package/dist/{intelligence → daemon/services}/task-segmenter.js +29 -6
- package/dist/daemon/services/task-segmenter.js.map +1 -0
- package/dist/daemon/services/weekly-report.d.ts +91 -0
- package/dist/daemon/services/weekly-report.d.ts.map +1 -0
- package/dist/daemon/services/weekly-report.js +327 -0
- package/dist/daemon/services/weekly-report.js.map +1 -0
- package/dist/hooks/hook-lib.sh +81 -0
- package/dist/hooks/notification.sh +7 -3
- package/dist/hooks/post-tool-use.sh +8 -4
- package/dist/hooks/pre-tool-use.sh +7 -4
- package/dist/hooks/stop.sh +1 -1
- package/dist/hooks/user-prompt-submit.sh +8 -9
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +71 -11
- package/dist/mcp/server.js.map +1 -1
- package/dist/skills/invocation-guard.d.ts +20 -0
- package/dist/skills/invocation-guard.d.ts.map +1 -1
- package/dist/skills/invocation-guard.js +63 -0
- package/dist/skills/invocation-guard.js.map +1 -1
- package/dist/skills/matcher.d.ts.map +1 -1
- package/dist/skills/matcher.js +12 -3
- package/dist/skills/matcher.js.map +1 -1
- package/dist/skills/official/code-simplifier.md +16 -0
- package/dist/skills/official/find-skills.md +23 -0
- package/dist/skills/official/official-api-design.md +17 -0
- package/dist/skills/official/official-architecture-decision.md +20 -0
- package/dist/skills/official/official-bmad.md +118 -0
- package/dist/skills/official/official-db-schema-design.md +16 -0
- package/dist/skills/official/official-debug.md +17 -0
- package/dist/skills/official/official-doc-driven.md +31 -0
- package/dist/skills/official/official-harness-engineering.md +108 -0
- package/dist/skills/official/official-performance-optimization.md +30 -0
- package/dist/skills/official/official-pr-review.md +35 -0
- package/dist/skills/official/official-release-checklist.md +30 -0
- package/dist/skills/official/official-security-hardening.md +26 -0
- package/dist/skills/official/official-spec-driven-design.md +31 -0
- package/dist/skills/official/planning-with-files.md +37 -0
- package/dist/skills/official/ui-ux-pro-max.md +18 -0
- package/dist/skills/official/webapp-testing.md +12 -0
- package/dist/skills/official-skills.d.ts +8 -4
- package/dist/skills/official-skills.d.ts.map +1 -1
- package/dist/skills/official-skills.js +48 -704
- package/dist/skills/official-skills.js.map +1 -1
- package/dist/skills/registry.d.ts +5 -0
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +48 -15
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/tools/pipeline-suggest.d.ts +30 -0
- package/dist/skills/tools/pipeline-suggest.d.ts.map +1 -0
- package/dist/skills/tools/pipeline-suggest.js +178 -0
- package/dist/skills/tools/pipeline-suggest.js.map +1 -0
- package/dist/web/routes/ai.d.ts.map +1 -1
- package/dist/web/routes/ai.js +16 -22
- package/dist/web/routes/ai.js.map +1 -1
- package/dist/web/routes/drift.d.ts +10 -0
- package/dist/web/routes/drift.d.ts.map +1 -0
- package/dist/web/routes/drift.js +21 -0
- package/dist/web/routes/drift.js.map +1 -0
- package/dist/web/routes/error-handler.d.ts +43 -0
- package/dist/web/routes/error-handler.d.ts.map +1 -0
- package/dist/web/routes/error-handler.js +99 -0
- package/dist/web/routes/error-handler.js.map +1 -0
- package/dist/web/routes/insights.d.ts +9 -0
- package/dist/web/routes/insights.d.ts.map +1 -0
- package/dist/web/routes/insights.js +34 -0
- package/dist/web/routes/insights.js.map +1 -0
- package/dist/web/routes/patch.js +2 -2
- package/dist/web/routes/patch.js.map +1 -1
- package/dist/web/routes/reports.d.ts +10 -0
- package/dist/web/routes/reports.d.ts.map +1 -0
- package/dist/web/routes/reports.js +27 -0
- package/dist/web/routes/reports.js.map +1 -0
- package/dist/web/routes/rules.d.ts +10 -3
- package/dist/web/routes/rules.d.ts.map +1 -1
- package/dist/web/routes/rules.js +80 -95
- package/dist/web/routes/rules.js.map +1 -1
- package/dist/web/routes/sessions.d.ts +1 -2
- package/dist/web/routes/sessions.d.ts.map +1 -1
- package/dist/web/routes/sessions.js +27 -39
- package/dist/web/routes/sessions.js.map +1 -1
- package/dist/web/routes/skill-stats.d.ts.map +1 -1
- package/dist/web/routes/skill-stats.js +38 -0
- package/dist/web/routes/skill-stats.js.map +1 -1
- package/dist/web/routes/skills.d.ts.map +1 -1
- package/dist/web/routes/skills.js +34 -0
- package/dist/web/routes/skills.js.map +1 -1
- package/dist/web/routes/stats.d.ts +7 -0
- package/dist/web/routes/stats.d.ts.map +1 -0
- package/dist/web/routes/stats.js +44 -0
- package/dist/web/routes/stats.js.map +1 -0
- package/dist/web/routes/status.js +1 -1
- package/dist/web/routes/status.js.map +1 -1
- package/dist/web/routes/tasks.d.ts +4 -0
- package/dist/web/routes/tasks.d.ts.map +1 -0
- package/dist/web/routes/tasks.js +181 -0
- package/dist/web/routes/tasks.js.map +1 -0
- package/dist/web/routes/trace.d.ts +10 -0
- package/dist/web/routes/trace.d.ts.map +1 -0
- package/dist/web/routes/trace.js +123 -0
- package/dist/web/routes/trace.js.map +1 -0
- package/dist/web/routes/types.d.ts +1 -14
- package/dist/web/routes/types.d.ts.map +1 -1
- package/dist/web/routes/types.js +8 -17
- package/dist/web/routes/types.js.map +1 -1
- package/dist/web/server.d.ts +1 -9
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +28 -28
- package/dist/web/server.js.map +1 -1
- package/dist/web/static/assets/AIConfig-BQCAQE9D.js +2 -0
- package/dist/web/static/assets/AIConfig-BQCAQE9D.js.map +1 -0
- package/dist/web/static/assets/Dashboard-D7Bo6Kan.js +2 -0
- package/dist/web/static/assets/Dashboard-D7Bo6Kan.js.map +1 -0
- package/dist/web/static/assets/{Drawer-DcU3ln98.js → Drawer-BeHRQxUS.js} +2 -2
- package/dist/web/static/assets/{Drawer-DcU3ln98.js.map → Drawer-BeHRQxUS.js.map} +1 -1
- package/dist/web/static/assets/Events-K_tCY2ti.js +2 -0
- package/dist/web/static/assets/Events-K_tCY2ti.js.map +1 -0
- package/dist/web/static/assets/Reports-BJCmBnc_.js +2 -0
- package/dist/web/static/assets/Reports-BJCmBnc_.js.map +1 -0
- package/dist/web/static/assets/SearchInput-BX2KhMkw.js +2 -0
- package/dist/web/static/assets/SearchInput-BX2KhMkw.js.map +1 -0
- package/dist/web/static/assets/SessionDetail-Bkr-kC7V.js +2 -0
- package/dist/web/static/assets/SessionDetail-Bkr-kC7V.js.map +1 -0
- package/dist/web/static/assets/Sessions-Chx9OCLH.js +2 -0
- package/dist/web/static/assets/Sessions-Chx9OCLH.js.map +1 -0
- package/dist/web/static/assets/Skills-O0GT1i7m.js +2 -0
- package/dist/web/static/assets/Skills-O0GT1i7m.js.map +1 -0
- package/dist/web/static/assets/TaskDetail-5SR8zGzv.js +2 -0
- package/dist/web/static/assets/TaskDetail-5SR8zGzv.js.map +1 -0
- package/dist/web/static/assets/Tasks-DCgDqvOZ.js +2 -0
- package/dist/web/static/assets/Tasks-DCgDqvOZ.js.map +1 -0
- package/dist/web/static/assets/export-L_VBD2p1.js +4 -0
- package/dist/web/static/assets/export-L_VBD2p1.js.map +1 -0
- package/dist/web/static/assets/index-D8AKj26b.css +1 -0
- package/dist/web/static/assets/index-DxIbmNmr.js +3 -0
- package/dist/web/static/assets/index-DxIbmNmr.js.map +1 -0
- package/dist/web/static/assets/{lucide-53bR2rki.js → lucide-fJlPI3H7.js} +68 -38
- package/dist/web/static/assets/lucide-fJlPI3H7.js.map +1 -0
- package/dist/web/static/assets/time-Bxuk0M-C.js +2 -0
- package/dist/web/static/assets/time-Bxuk0M-C.js.map +1 -0
- package/dist/web/static/index.html +3 -3
- package/docs/concurrent-agents.md +129 -0
- package/docs/design/architecture-review-20260516.md +232 -0
- package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +219 -0
- package/docs/design/hook-failure-queue-spec-20260516-1530.md +204 -0
- package/docs/design/refactor-phase1-spec-20260515-1600.md +543 -0
- package/docs/design/refactor-phase2-spec-20260515-1700.md +424 -0
- package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +208 -0
- package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +104 -0
- package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +196 -0
- package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +56 -0
- package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +354 -0
- package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +421 -0
- package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +72 -0
- package/docs/reviews/claudemd-template-sync.md +54 -0
- package/docs/reviews/tasks-filter-pagination.md +80 -0
- package/docs/ruflo-learning-strategy.md +322 -0
- package/docs/skills-deduplication-analysis.md +83 -0
- package/docs/skills-multiformat-support.md +177 -0
- package/docs/skills-third-party.md +183 -0
- package/docs/testing/tasks-filter-pagination-test-report.md +86 -0
- package/forge +321 -0
- package/package.json +28 -62
- package/playwright.config.ts +40 -0
- package/scripts/demo-v2.ts +91 -0
- package/scripts/dev-daemon.sh +232 -0
- package/scripts/dev-web.ts +109 -0
- package/scripts/e2e-mcp-link.ts +423 -0
- package/scripts/e2e-methodology-quality.ts +253 -0
- package/scripts/e2e-routing.ts +456 -0
- package/scripts/e2e-user-methodology.ts +326 -0
- package/scripts/e2e-web-workflows.ts +299 -0
- package/scripts/migrate-legacy-to-dynamic.sql +108 -0
- package/scripts/regenerate-execution-docs.ts +116 -0
- package/scripts/sync-agent-skills.ts +193 -0
- package/scripts/test-hook.sh +71 -0
- package/scripts/verify-skill-loading.ts +62 -0
- package/src/claudemd/claudemd-generator.ts +777 -0
- package/src/claudemd/convention-extractor.ts +69 -0
- package/src/claudemd/index.ts +35 -0
- package/src/claudemd/persona-manager.ts +88 -0
- package/src/claudemd/resume-manager.ts +236 -0
- package/src/claudemd/tech-detector.ts +220 -0
- package/src/cli/commands/claudemd.ts +84 -0
- package/src/cli/commands/config.ts +46 -0
- package/src/cli/commands/daemon.ts +310 -0
- package/src/cli/commands/executions.ts +114 -0
- package/src/cli/commands/init.ts +204 -0
- package/src/cli/commands/logs.ts +181 -0
- package/src/cli/commands/mcp.ts +244 -0
- package/src/cli/commands/menu.ts +356 -0
- package/src/cli/commands/skills.ts +185 -0
- package/src/cli/commands/stats.ts +74 -0
- package/src/cli/commands/status.ts +69 -0
- package/src/cli/commands/template.ts +77 -0
- package/src/cli/commands/trace.ts +164 -0
- package/src/cli/index.ts +42 -0
- package/src/cli/init/hook-manager.ts +132 -0
- package/src/core/ai/provider.ts +308 -0
- package/src/core/ai/types.ts +51 -0
- package/src/core/config.ts +124 -0
- package/src/core/constants.ts +45 -0
- package/src/core/queue/index.ts +193 -0
- package/src/core/storage/base.ts +226 -0
- package/src/core/storage/events.ts +255 -0
- package/src/core/storage/injections.ts +78 -0
- package/src/core/storage/maintenance.ts +59 -0
- package/src/core/storage/migrations/002_add_skill_tracking.sql +6 -0
- package/src/core/storage/migrations/003_add_skill_invocations.sql +23 -0
- package/src/core/storage/performance-indexes.sql +23 -0
- package/src/core/storage/routing.ts +194 -0
- package/src/core/storage/rows.ts +112 -0
- package/src/core/storage/schema.sql +214 -0
- package/src/core/storage/sessions.ts +104 -0
- package/src/core/storage/skills.ts +164 -0
- package/src/core/storage/sqlite.ts +194 -0
- package/src/core/storage/tasks.ts +170 -0
- package/src/core/storage/token-usage.ts +93 -0
- package/src/core/types.ts +154 -0
- package/src/core/utils/error-handler.ts +256 -0
- package/src/core/utils/forge-resume-block.ts +74 -0
- package/src/core/utils/format.ts +69 -0
- package/src/core/utils/logger.ts +119 -0
- package/src/core/utils/lru-cache.ts +50 -0
- package/src/core/utils/path.ts +19 -0
- package/src/core/utils/session.ts +26 -0
- package/src/core/utils/time.ts +37 -0
- package/src/core/utils/token-tracker.ts +97 -0
- package/src/daemon/event-parser.ts +35 -0
- package/src/daemon/handlers/history-exporter.ts +117 -0
- package/src/daemon/handlers/post-tool-use.ts +50 -0
- package/src/daemon/handlers/stop.ts +215 -0
- package/src/daemon/handlers/user-prompt.ts +188 -0
- package/src/daemon/index.ts +278 -0
- package/src/daemon/launchd/com.claude-forge.daemon.plist.template +47 -0
- package/src/daemon/launchd-installer.ts +260 -0
- package/src/daemon/lifecycle.ts +128 -0
- package/src/daemon/router.ts +40 -0
- package/src/daemon/server.ts +209 -0
- package/src/daemon/services/anti-pattern-detector.ts +412 -0
- package/src/daemon/services/drift-detector.ts +232 -0
- package/src/daemon/services/task-segmenter.ts +112 -0
- package/src/daemon/services/weekly-report.ts +454 -0
- package/src/hooks/hook-lib.sh +81 -0
- package/src/hooks/notification.sh +35 -0
- package/src/hooks/post-tool-use.sh +61 -0
- package/src/hooks/pre-tool-use.sh +63 -0
- package/src/hooks/stop.sh +40 -0
- package/src/hooks/user-prompt-submit.sh +69 -0
- package/src/mcp/server.ts +322 -0
- package/src/skills/index.ts +2 -0
- package/src/skills/invocation-guard.ts +177 -0
- package/src/skills/matcher.ts +148 -0
- package/src/skills/official/code-simplifier.md +16 -0
- package/src/skills/official/find-skills.md +23 -0
- package/src/skills/official/official-api-design.md +17 -0
- package/src/skills/official/official-architecture-decision.md +20 -0
- package/src/skills/official/official-bmad.md +118 -0
- package/src/skills/official/official-db-schema-design.md +16 -0
- package/src/skills/official/official-debug.md +17 -0
- package/src/skills/official/official-doc-driven.md +31 -0
- package/src/skills/official/official-harness-engineering.md +108 -0
- package/src/skills/official/official-performance-optimization.md +30 -0
- package/src/skills/official/official-pr-review.md +35 -0
- package/src/skills/official/official-release-checklist.md +30 -0
- package/src/skills/official/official-security-hardening.md +26 -0
- package/src/skills/official/official-spec-driven-design.md +31 -0
- package/src/skills/official/planning-with-files.md +37 -0
- package/src/skills/official/ui-ux-pro-max.md +18 -0
- package/src/skills/official/webapp-testing.md +12 -0
- package/src/skills/official-skills.ts +89 -0
- package/src/skills/registry.ts +355 -0
- package/src/skills/semantic-matcher.ts +231 -0
- package/src/skills/tools/pipeline-suggest.ts +226 -0
- package/src/skills/tools/skill-invoke.ts +168 -0
- package/src/skills/tools/skill-list.ts +59 -0
- package/src/templates/go.yaml +53 -0
- package/src/templates/python.yaml +59 -0
- package/src/templates/react.yaml +55 -0
- package/src/templates/template-manager.ts +170 -0
- package/src/web/auth-middleware.ts +55 -0
- package/src/web/routes/ai.ts +204 -0
- package/src/web/routes/auth.ts +22 -0
- package/src/web/routes/drift.ts +25 -0
- package/src/web/routes/error-handler.ts +120 -0
- package/src/web/routes/events.ts +47 -0
- package/src/web/routes/insights.ts +43 -0
- package/src/web/routes/patch.ts +117 -0
- package/src/web/routes/reports.ts +34 -0
- package/src/web/routes/rules.ts +101 -0
- package/src/web/routes/sessions.ts +262 -0
- package/src/web/routes/skill-stats.ts +132 -0
- package/src/web/routes/skills.ts +349 -0
- package/src/web/routes/static.ts +67 -0
- package/src/web/routes/stats.ts +60 -0
- package/src/web/routes/status.ts +30 -0
- package/src/web/routes/tasks.ts +218 -0
- package/src/web/routes/token-usage.ts +20 -0
- package/src/web/routes/trace.ts +138 -0
- package/src/web/routes/types.ts +56 -0
- package/src/web/server.ts +134 -0
- package/src/web/ssrf-guard.ts +112 -0
- package/src/web/static/index.html +3251 -0
- package/src/web/static/vendor/chart.umd.min.js +20 -0
- package/tests/e2e/dashboard.spec.ts +205 -0
- package/tests/e2e/routing-skill-e2e.test.ts +39 -0
- package/tests/helpers/mock-ai.ts +92 -0
- package/tests/helpers/mock-storage.ts +159 -0
- package/tests/integration/queue-replay.integration.test.ts +193 -0
- package/tests/integration/tasks-filter.integration.test.ts +154 -0
- package/tests/performance/database.benchmark.ts +161 -0
- package/tests/semantic-matcher.test.ts +99 -0
- package/tests/skill-matcher.test.ts +110 -0
- package/tests/unit/ai-provider-retry.test.ts +194 -0
- package/tests/unit/ai-provider-vision.test.ts +224 -0
- package/tests/unit/claudemd-generator.test.ts +68 -0
- package/tests/unit/cli-mcp.test.ts +141 -0
- package/tests/unit/handlers.test.ts +171 -0
- package/tests/unit/invocation-guard.test.ts +125 -0
- package/tests/unit/queue.test.ts +272 -0
- package/tests/unit/router.test.ts +138 -0
- package/tests/unit/security.test.ts +128 -0
- package/tests/unit/skill-invocations-workflow.test.ts +495 -0
- package/tests/unit/skill-registry.test.ts +94 -0
- package/tests/unit/skills/invocation-guard-ttl.test.ts +211 -0
- package/tests/unit/skills/official-skills-loader.test.ts +126 -0
- package/tests/unit/skills/registry-multiformat.test.ts +92 -0
- package/tests/unit/storage/sessions-aggregate.test.ts +435 -0
- package/tests/unit/storage/sqlite-refactor-harness.test.ts +314 -0
- package/tests/unit/storage.test.ts +172 -0
- package/tests/unit/token-usage.test.ts +144 -0
- package/tests/unit/type-guards.test.ts +201 -0
- package/tests/unit/utils/format.test.ts +189 -0
- package/tests/unit/utils/session.test.ts +89 -0
- package/tests/unit/utils/time.test.ts +112 -0
- package/tests/unit/web/routes-auth.test.ts +93 -0
- package/tests/unit/web/routes-events.test.ts +101 -0
- package/tests/unit/web/routes-sessions.test.ts +181 -0
- package/tests/unit/web/routes-skill-stats.test.ts +179 -0
- package/tests/unit/web/routes-stats.test.ts +92 -0
- package/tests/unit/web/routes-tasks.test.ts +351 -0
- package/tsconfig.json +22 -0
- package/vitest.config.ts +21 -0
- package/vitest.integration.config.ts +16 -0
- package/web/CLAUDE.md +20 -0
- package/web/index.html +13 -0
- package/web/package-lock.json +4854 -0
- package/web/package.json +35 -0
- package/web/postcss.config.js +6 -0
- package/web/src/App.tsx +110 -0
- package/web/src/components/CodeBlock.tsx +31 -0
- package/web/src/components/Confirm.tsx +96 -0
- package/web/src/components/Drawer.tsx +60 -0
- package/web/src/components/Layout.tsx +145 -0
- package/web/src/components/MarkdownRenderer.tsx +77 -0
- package/web/src/components/SearchInput.tsx +31 -0
- package/web/src/components/SessionDetailContent.tsx +157 -0
- package/web/src/components/Toast.tsx +92 -0
- package/web/src/index.css +19 -0
- package/web/src/main.tsx +31 -0
- package/web/src/pages/AIConfig.tsx +233 -0
- package/web/src/pages/Dashboard.tsx +572 -0
- package/web/src/pages/Events.tsx +271 -0
- package/web/src/pages/Reports.tsx +428 -0
- package/web/src/pages/SessionDetail.tsx +162 -0
- package/web/src/pages/Sessions.tsx +205 -0
- package/web/src/pages/Skills.tsx +180 -0
- package/web/src/pages/TaskDetail.tsx +511 -0
- package/web/src/pages/Tasks.tsx +150 -0
- package/web/src/utils/auth.ts +59 -0
- package/web/src/utils/export.ts +54 -0
- package/web/src/utils/time.ts +13 -0
- package/web/tailwind.config.js +11 -0
- package/web/tsconfig.json +21 -0
- package/web/tsconfig.node.json +10 -0
- package/web/vite.config.ts +76 -0
- package/winspan-claude-forge-8.43.0.tgz +0 -0
- package/dist/agents/definition.d.ts +0 -62
- package/dist/agents/definition.d.ts.map +0 -1
- package/dist/agents/definition.js +0 -27
- package/dist/agents/definition.js.map +0 -1
- package/dist/agents/distributor.d.ts +0 -23
- package/dist/agents/distributor.d.ts.map +0 -1
- package/dist/agents/distributor.js +0 -85
- package/dist/agents/distributor.js.map +0 -1
- package/dist/agents/index.d.ts +0 -5
- package/dist/agents/index.d.ts.map +0 -1
- package/dist/agents/index.js +0 -5
- package/dist/agents/index.js.map +0 -1
- package/dist/agents/methodologies/agent-builder.d.ts +0 -21
- package/dist/agents/methodologies/agent-builder.d.ts.map +0 -1
- package/dist/agents/methodologies/agent-builder.js +0 -149
- package/dist/agents/methodologies/agent-builder.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/analyze.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/analyze.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/analyze.js +0 -19
- package/dist/agents/methodologies/phases/bmad/analyze.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/design.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/design.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/design.js +0 -18
- package/dist/agents/methodologies/phases/bmad/design.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/implement.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/implement.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/implement.js +0 -17
- package/dist/agents/methodologies/phases/bmad/implement.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/index.d.ts +0 -6
- package/dist/agents/methodologies/phases/bmad/index.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/index.js +0 -6
- package/dist/agents/methodologies/phases/bmad/index.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/review.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/review.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/review.js +0 -17
- package/dist/agents/methodologies/phases/bmad/review.js.map +0 -1
- package/dist/agents/methodologies/phases/bmad/test.d.ts +0 -3
- package/dist/agents/methodologies/phases/bmad/test.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/bmad/test.js +0 -21
- package/dist/agents/methodologies/phases/bmad/test.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/fix.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/fix.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/fix.js +0 -17
- package/dist/agents/methodologies/phases/harness/fix.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/index.d.ts +0 -6
- package/dist/agents/methodologies/phases/harness/index.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/index.js +0 -6
- package/dist/agents/methodologies/phases/harness/index.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/reproduce.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/reproduce.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/reproduce.js +0 -20
- package/dist/agents/methodologies/phases/harness/reproduce.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/root-cause.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/root-cause.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/root-cause.js +0 -21
- package/dist/agents/methodologies/phases/harness/root-cause.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/safety-net.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/safety-net.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/safety-net.js +0 -17
- package/dist/agents/methodologies/phases/harness/safety-net.js.map +0 -1
- package/dist/agents/methodologies/phases/harness/verify.d.ts +0 -3
- package/dist/agents/methodologies/phases/harness/verify.d.ts.map +0 -1
- package/dist/agents/methodologies/phases/harness/verify.js +0 -22
- package/dist/agents/methodologies/phases/harness/verify.js.map +0 -1
- package/dist/agents/methodologies/presets.d.ts +0 -10
- package/dist/agents/methodologies/presets.d.ts.map +0 -1
- package/dist/agents/methodologies/presets.js +0 -79
- package/dist/agents/methodologies/presets.js.map +0 -1
- package/dist/agents/methodologies/types.d.ts +0 -45
- package/dist/agents/methodologies/types.d.ts.map +0 -1
- package/dist/agents/methodologies/types.js +0 -10
- package/dist/agents/methodologies/types.js.map +0 -1
- package/dist/agents/methodologies/user-config-loader.d.ts +0 -30
- package/dist/agents/methodologies/user-config-loader.d.ts.map +0 -1
- package/dist/agents/methodologies/user-config-loader.js +0 -159
- package/dist/agents/methodologies/user-config-loader.js.map +0 -1
- package/dist/agents/official-agents.d.ts +0 -4
- package/dist/agents/official-agents.d.ts.map +0 -1
- package/dist/agents/official-agents.js +0 -559
- package/dist/agents/official-agents.js.map +0 -1
- package/dist/agents/registry.d.ts +0 -57
- package/dist/agents/registry.d.ts.map +0 -1
- package/dist/agents/registry.js +0 -271
- package/dist/agents/registry.js.map +0 -1
- package/dist/capability/index.d.ts +0 -10
- package/dist/capability/index.d.ts.map +0 -1
- package/dist/capability/index.js +0 -10
- package/dist/capability/index.js.map +0 -1
- package/dist/capability/types.d.ts +0 -10
- package/dist/capability/types.d.ts.map +0 -1
- package/dist/capability/types.js +0 -10
- package/dist/capability/types.js.map +0 -1
- package/dist/cli/commands/agents.d.ts +0 -3
- package/dist/cli/commands/agents.d.ts.map +0 -1
- package/dist/cli/commands/agents.js +0 -62
- package/dist/cli/commands/agents.js.map +0 -1
- package/dist/cli/commands/rules.d.ts +0 -8
- package/dist/cli/commands/rules.d.ts.map +0 -1
- package/dist/cli/commands/rules.js +0 -89
- package/dist/cli/commands/rules.js.map +0 -1
- package/dist/daemon/auto-disable-scheduler.d.ts +0 -53
- package/dist/daemon/auto-disable-scheduler.d.ts.map +0 -1
- package/dist/daemon/auto-disable-scheduler.js +0 -114
- package/dist/daemon/auto-disable-scheduler.js.map +0 -1
- package/dist/daemon/handlers/pre-tool-use.d.ts +0 -39
- package/dist/daemon/handlers/pre-tool-use.d.ts.map +0 -1
- package/dist/daemon/handlers/pre-tool-use.js +0 -166
- package/dist/daemon/handlers/pre-tool-use.js.map +0 -1
- package/dist/daemon/routing-observer.d.ts +0 -42
- package/dist/daemon/routing-observer.d.ts.map +0 -1
- package/dist/daemon/routing-observer.js +0 -264
- package/dist/daemon/routing-observer.js.map +0 -1
- package/dist/daemon/routing-state.d.ts +0 -64
- package/dist/daemon/routing-state.d.ts.map +0 -1
- package/dist/daemon/routing-state.js +0 -240
- package/dist/daemon/routing-state.js.map +0 -1
- package/dist/engine/agent-router.d.ts +0 -142
- package/dist/engine/agent-router.d.ts.map +0 -1
- package/dist/engine/agent-router.js +0 -276
- package/dist/engine/agent-router.js.map +0 -1
- package/dist/engine/context-builder.d.ts +0 -23
- package/dist/engine/context-builder.d.ts.map +0 -1
- package/dist/engine/context-builder.js +0 -63
- package/dist/engine/context-builder.js.map +0 -1
- package/dist/engine/conventions/basic-security.yaml +0 -109
- package/dist/engine/conventions/code-quality.yaml +0 -123
- package/dist/engine/conventions/database-safety.yaml +0 -74
- package/dist/engine/conventions/dependency-safety.yaml +0 -132
- package/dist/engine/conventions/docker-safety.yaml +0 -69
- package/dist/engine/conventions/git-safety.yaml +0 -118
- package/dist/engine/conventions/go-best-practices.yaml +0 -84
- package/dist/engine/conventions/python-best-practices.yaml +0 -96
- package/dist/engine/conventions/react-best-practices.yaml +0 -96
- package/dist/engine/conventions/routing.yaml +0 -378
- package/dist/engine/conventions/strict-security.yaml +0 -30
- package/dist/engine/conventions/ts-quality.yaml +0 -49
- package/dist/engine/dsl/compiler.d.ts +0 -34
- package/dist/engine/dsl/compiler.d.ts.map +0 -1
- package/dist/engine/dsl/compiler.js +0 -702
- package/dist/engine/dsl/compiler.js.map +0 -1
- package/dist/engine/dsl/parser.d.ts +0 -25
- package/dist/engine/dsl/parser.d.ts.map +0 -1
- package/dist/engine/dsl/parser.js +0 -208
- package/dist/engine/dsl/parser.js.map +0 -1
- package/dist/engine/dsl/runtime.d.ts +0 -46
- package/dist/engine/dsl/runtime.d.ts.map +0 -1
- package/dist/engine/dsl/runtime.js +0 -173
- package/dist/engine/dsl/runtime.js.map +0 -1
- package/dist/engine/dsl/types.d.ts +0 -139
- package/dist/engine/dsl/types.d.ts.map +0 -1
- package/dist/engine/dsl/types.js +0 -11
- package/dist/engine/dsl/types.js.map +0 -1
- package/dist/engine/evidence-store.d.ts +0 -44
- package/dist/engine/evidence-store.d.ts.map +0 -1
- package/dist/engine/evidence-store.js +0 -109
- package/dist/engine/evidence-store.js.map +0 -1
- package/dist/engine/experiment-router.d.ts +0 -102
- package/dist/engine/experiment-router.d.ts.map +0 -1
- package/dist/engine/experiment-router.js +0 -289
- package/dist/engine/experiment-router.js.map +0 -1
- package/dist/engine/recommender.d.ts +0 -52
- package/dist/engine/recommender.d.ts.map +0 -1
- package/dist/engine/recommender.js +0 -162
- package/dist/engine/recommender.js.map +0 -1
- package/dist/engine/rule-engine.d.ts +0 -33
- package/dist/engine/rule-engine.d.ts.map +0 -1
- package/dist/engine/rule-engine.js +0 -250
- package/dist/engine/rule-engine.js.map +0 -1
- package/dist/engine/security-gates.d.ts +0 -42
- package/dist/engine/security-gates.d.ts.map +0 -1
- package/dist/engine/security-gates.js +0 -210
- package/dist/engine/security-gates.js.map +0 -1
- package/dist/intelligence/classifier.d.ts +0 -75
- package/dist/intelligence/classifier.d.ts.map +0 -1
- package/dist/intelligence/classifier.js +0 -352
- package/dist/intelligence/classifier.js.map +0 -1
- package/dist/intelligence/context-gatherer.d.ts +0 -101
- package/dist/intelligence/context-gatherer.d.ts.map +0 -1
- package/dist/intelligence/context-gatherer.js +0 -417
- package/dist/intelligence/context-gatherer.js.map +0 -1
- package/dist/intelligence/cot-classifier.d.ts +0 -95
- package/dist/intelligence/cot-classifier.d.ts.map +0 -1
- package/dist/intelligence/cot-classifier.js +0 -391
- package/dist/intelligence/cot-classifier.js.map +0 -1
- package/dist/intelligence/distiller.d.ts +0 -22
- package/dist/intelligence/distiller.d.ts.map +0 -1
- package/dist/intelligence/distiller.js +0 -108
- package/dist/intelligence/distiller.js.map +0 -1
- package/dist/intelligence/execution-doc-builder.d.ts +0 -151
- package/dist/intelligence/execution-doc-builder.d.ts.map +0 -1
- package/dist/intelligence/execution-doc-builder.js +0 -1018
- package/dist/intelligence/execution-doc-builder.js.map +0 -1
- package/dist/intelligence/intent-types.d.ts +0 -13
- package/dist/intelligence/intent-types.d.ts.map +0 -1
- package/dist/intelligence/intent-types.js +0 -19
- package/dist/intelligence/intent-types.js.map +0 -1
- package/dist/intelligence/multimodal-parser.d.ts +0 -105
- package/dist/intelligence/multimodal-parser.d.ts.map +0 -1
- package/dist/intelligence/multimodal-parser.js +0 -425
- package/dist/intelligence/multimodal-parser.js.map +0 -1
- package/dist/intelligence/quality-gate.d.ts +0 -45
- package/dist/intelligence/quality-gate.d.ts.map +0 -1
- package/dist/intelligence/quality-gate.js +0 -193
- package/dist/intelligence/quality-gate.js.map +0 -1
- package/dist/intelligence/task-segmenter.d.ts.map +0 -1
- package/dist/intelligence/task-segmenter.js.map +0 -1
- package/dist/web/routes/agents.d.ts +0 -7
- package/dist/web/routes/agents.d.ts.map +0 -1
- package/dist/web/routes/agents.js +0 -209
- package/dist/web/routes/agents.js.map +0 -1
- package/dist/web/routes/execution-trace.d.ts +0 -21
- package/dist/web/routes/execution-trace.d.ts.map +0 -1
- package/dist/web/routes/execution-trace.js +0 -353
- package/dist/web/routes/execution-trace.js.map +0 -1
- package/dist/web/routes/experiments.d.ts +0 -15
- package/dist/web/routes/experiments.d.ts.map +0 -1
- package/dist/web/routes/experiments.js +0 -187
- package/dist/web/routes/experiments.js.map +0 -1
- package/dist/web/routes/routing.d.ts +0 -17
- package/dist/web/routes/routing.d.ts.map +0 -1
- package/dist/web/routes/routing.js +0 -592
- package/dist/web/routes/routing.js.map +0 -1
- package/dist/web/routes/workflows.d.ts +0 -19
- package/dist/web/routes/workflows.d.ts.map +0 -1
- package/dist/web/routes/workflows.js +0 -86
- package/dist/web/routes/workflows.js.map +0 -1
- package/dist/web/static/assets/AIConfig-R5wZ3ZKT.js +0 -2
- package/dist/web/static/assets/AIConfig-R5wZ3ZKT.js.map +0 -1
- package/dist/web/static/assets/Agents-Beg34V1g.js +0 -2
- package/dist/web/static/assets/Agents-Beg34V1g.js.map +0 -1
- package/dist/web/static/assets/CodeBlock--H53gk46.js +0 -2
- package/dist/web/static/assets/CodeBlock--H53gk46.js.map +0 -1
- package/dist/web/static/assets/Dashboard-Cy1xsj1J.js +0 -2
- package/dist/web/static/assets/Dashboard-Cy1xsj1J.js.map +0 -1
- package/dist/web/static/assets/Events-mFhXl4zI.js +0 -2
- package/dist/web/static/assets/Events-mFhXl4zI.js.map +0 -1
- package/dist/web/static/assets/ExecutionTrace-DG901hLR.js +0 -3
- package/dist/web/static/assets/ExecutionTrace-DG901hLR.js.map +0 -1
- package/dist/web/static/assets/MarkdownRenderer-CCIz1MOz.js +0 -2
- package/dist/web/static/assets/MarkdownRenderer-CCIz1MOz.js.map +0 -1
- package/dist/web/static/assets/Routing-B7BFLfjh.js +0 -2
- package/dist/web/static/assets/Routing-B7BFLfjh.js.map +0 -1
- package/dist/web/static/assets/SessionDetail-BT0l4RrK.js +0 -2
- package/dist/web/static/assets/SessionDetail-BT0l4RrK.js.map +0 -1
- package/dist/web/static/assets/Sessions-C6J_HQ_u.js +0 -2
- package/dist/web/static/assets/Sessions-C6J_HQ_u.js.map +0 -1
- package/dist/web/static/assets/Skills-4DQWLaTv.js +0 -2
- package/dist/web/static/assets/Skills-4DQWLaTv.js.map +0 -1
- package/dist/web/static/assets/WorkflowDetail-zhNqUkBE.js +0 -2
- package/dist/web/static/assets/WorkflowDetail-zhNqUkBE.js.map +0 -1
- package/dist/web/static/assets/Workflows-Btvi-lGw.js +0 -2
- package/dist/web/static/assets/Workflows-Btvi-lGw.js.map +0 -1
- package/dist/web/static/assets/export-BQQZLaHV.js +0 -4
- package/dist/web/static/assets/export-BQQZLaHV.js.map +0 -1
- package/dist/web/static/assets/index-Cgr9qMtq.js +0 -3
- package/dist/web/static/assets/index-Cgr9qMtq.js.map +0 -1
- package/dist/web/static/assets/index-CngWb5gC.css +0 -1
- package/dist/web/static/assets/lucide-53bR2rki.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as e,r as m}from"./react-vendor-CSp-GLFF.js";import{b as y,u,c as p}from"./query-C99w429o.js";import{D as j}from"./Drawer-BeHRQxUS.js";import{N as b,O as N}from"./vendor-CMMjVdZs.js";import{h as w,o as v}from"./syntax-highlighter-44FakypI.js";import{u as k}from"./index-DxIbmNmr.js";import{a as S}from"./auth-Bnf8ZcqN.js";import{B as f,P as C,X as E,l as q}from"./lucide-fJlPI3H7.js";import"./react-router-I-HqunH7.js";function F({content:a,className:t=""}){return e.jsx("div",{className:`prose prose-sm max-w-none ${t}`,children:e.jsx(b,{remarkPlugins:[N],components:{code({inline:s,className:c,children:i,...d}){const o=/language-(\w+)/.exec(c||""),l=o==null?void 0:o[1];return!s&&l?e.jsx(w,{style:v,language:l,PreTag:"div",customStyle:{margin:0,borderRadius:"6px",fontSize:"12px",padding:"12px"},...d,children:String(i).replace(/\n$/,"")}):e.jsx("code",{className:"bg-gray-100 text-gray-800 px-1 py-0.5 rounded text-xs font-mono",...d,children:i})},h1:({children:s})=>e.jsx("h1",{className:"text-lg font-bold text-gray-900 mt-4 mb-2",children:s}),h2:({children:s})=>e.jsx("h2",{className:"text-base font-bold text-gray-900 mt-3 mb-2",children:s}),h3:({children:s})=>e.jsx("h3",{className:"text-sm font-semibold text-gray-900 mt-2 mb-1",children:s}),p:({children:s})=>e.jsx("p",{className:"text-sm text-gray-700 my-2",children:s}),ul:({children:s})=>e.jsx("ul",{className:"list-disc list-inside text-sm text-gray-700 my-2 space-y-0.5",children:s}),ol:({children:s})=>e.jsx("ol",{className:"list-decimal list-inside text-sm text-gray-700 my-2 space-y-0.5",children:s}),li:({children:s})=>e.jsx("li",{className:"text-sm",children:s}),a:({children:s,href:c})=>e.jsx("a",{href:c,target:"_blank",rel:"noopener noreferrer",className:"text-indigo-600 hover:text-indigo-700 underline",children:s}),blockquote:({children:s})=>e.jsx("blockquote",{className:"border-l-4 border-gray-300 pl-3 italic text-gray-600 my-2",children:s}),table:({children:s})=>e.jsx("div",{className:"overflow-x-auto my-2",children:e.jsx("table",{className:"min-w-full border border-gray-200 text-sm",children:s})}),th:({children:s})=>e.jsx("th",{className:"border border-gray-200 px-2 py-1 bg-gray-50 font-semibold text-left",children:s}),td:({children:s})=>e.jsx("td",{className:"border border-gray-200 px-2 py-1",children:s})},children:a})})}async function P(){const a=await fetch("/api/skills");if(!a.ok)throw new Error("Failed to fetch skills");const t=await a.json();return Array.isArray(t)?t:t.skills||[]}async function $(a){const t=await fetch(`/api/skills/${a}`);if(!t.ok)throw new Error("Failed to fetch");return t.json()}async function K(a,t){if(!(await S(`/api/skills/${a}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t})})).ok)throw new Error("Failed to save")}function z(){const a=y(),t=k(),{data:s,isLoading:c}=u({queryKey:["skills"],queryFn:P}),[i,d]=m.useState(null),[o,l]=m.useState(!1),[h,g]=m.useState(""),{data:r}=u({queryKey:["skill-detail",i],queryFn:()=>$(i),enabled:!!i});m.useEffect(()=>{r!=null&&r.content&&g(r.content),l(!1)},[r]);const x=p({mutationFn:n=>K(n.name,n.content),onSuccess:()=>{t.success("Skill 已保存"),l(!1),a.invalidateQueries({queryKey:["skill-detail",i]}),a.invalidateQueries({queryKey:["skills"]})},onError:n=>t.error(`保存失败: ${n.message}`)});return c?e.jsx("div",{className:"bg-white rounded-lg shadow p-6",children:"加载中..."}):e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-6",children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"Skill 管理"}),e.jsxs("div",{className:"text-sm text-gray-500",children:["共 ",(s==null?void 0:s.length)||0," 个 Skill"]})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:s==null?void 0:s.map(n=>e.jsx("div",{className:"bg-white rounded-lg shadow p-5 hover:shadow-md transition-shadow cursor-pointer",onClick:()=>d(n.name),children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"w-10 h-10 rounded-lg bg-purple-100 flex items-center justify-center flex-shrink-0",children:e.jsx(f,{className:"h-5 w-5 text-purple-600"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("h3",{className:"font-semibold text-gray-900 truncate",children:n.name}),e.jsx("p",{className:"text-xs text-gray-500 mt-1 line-clamp-3",children:n.description||"(无描述)"})]})]})},n.name))}),e.jsx(j,{open:i!==null,onClose:()=>{d(null),l(!1)},title:`Skill: ${i}`,width:"w-[800px]",children:r&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(f,{className:"h-5 w-5 text-purple-600"}),e.jsx("h3",{className:"text-lg font-semibold text-gray-900",children:r.name})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500 mb-1",children:"描述"}),e.jsx("div",{className:"text-sm text-gray-800",children:r.description})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("div",{className:"text-xs text-gray-500",children:"完整内容 (Markdown)"}),e.jsx("div",{className:"flex items-center gap-2",children:o?e.jsxs(e.Fragment,{children:[e.jsxs("button",{onClick:()=>{l(!1),g(r.content||"")},className:"inline-flex items-center gap-1 text-xs text-gray-600 hover:text-gray-700",children:[e.jsx(E,{className:"h-3 w-3"}),"取消"]}),e.jsxs("button",{onClick:()=>x.mutate({name:r.name,content:h}),disabled:x.isPending,className:"inline-flex items-center gap-1 text-xs bg-indigo-600 text-white px-2 py-1 rounded hover:bg-indigo-700 disabled:bg-gray-400",children:[e.jsx(q,{className:"h-3 w-3"}),x.isPending?"保存中...":"保存"]})]}):e.jsxs("button",{onClick:()=>l(!0),className:"inline-flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-700",children:[e.jsx(C,{className:"h-3 w-3"}),"编辑"]})})]}),o?e.jsx("textarea",{value:h,onChange:n=>g(n.target.value),className:"w-full font-mono text-xs bg-gray-50 rounded p-3 border border-gray-300 focus:border-indigo-500 focus:outline-none",rows:20}):e.jsx("div",{className:"bg-white rounded p-3 border border-gray-200 max-h-[500px] overflow-y-auto",children:e.jsx(F,{content:r.content||""})}),x.isError&&e.jsxs("div",{className:"text-xs text-red-600 mt-1",children:["保存失败:",x.error.message]})]})]})})]})}export{z as default};
|
|
2
|
+
//# sourceMappingURL=Skills-O0GT1i7m.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skills-O0GT1i7m.js","sources":["../../src/components/MarkdownRenderer.tsx","../../src/pages/Skills.tsx"],"sourcesContent":["import ReactMarkdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'\nimport { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism'\n\ninterface Props {\n content: string\n className?: string\n}\n\nexport default function MarkdownRenderer({ content, className = '' }: Props) {\n return (\n <div className={`prose prose-sm max-w-none ${className}`}>\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={{\n code({ inline, className, children, ...props }: any) {\n const match = /language-(\\w+)/.exec(className || '')\n const lang = match?.[1]\n if (!inline && lang) {\n return (\n <SyntaxHighlighter\n style={oneLight}\n language={lang}\n PreTag=\"div\"\n customStyle={{\n margin: 0,\n borderRadius: '6px',\n fontSize: '12px',\n padding: '12px',\n }}\n {...props}\n >\n {String(children).replace(/\\n$/, '')}\n </SyntaxHighlighter>\n )\n }\n return (\n <code\n className=\"bg-gray-100 text-gray-800 px-1 py-0.5 rounded text-xs font-mono\"\n {...props}\n >\n {children}\n </code>\n )\n },\n h1: ({ children }) => <h1 className=\"text-lg font-bold text-gray-900 mt-4 mb-2\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"text-base font-bold text-gray-900 mt-3 mb-2\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"text-sm font-semibold text-gray-900 mt-2 mb-1\">{children}</h3>,\n p: ({ children }) => <p className=\"text-sm text-gray-700 my-2\">{children}</p>,\n ul: ({ children }) => <ul className=\"list-disc list-inside text-sm text-gray-700 my-2 space-y-0.5\">{children}</ul>,\n ol: ({ children }) => <ol className=\"list-decimal list-inside text-sm text-gray-700 my-2 space-y-0.5\">{children}</ol>,\n li: ({ children }) => <li className=\"text-sm\">{children}</li>,\n a: ({ children, href }) => (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-indigo-600 hover:text-indigo-700 underline\">\n {children}\n </a>\n ),\n blockquote: ({ children }) => (\n <blockquote className=\"border-l-4 border-gray-300 pl-3 italic text-gray-600 my-2\">\n {children}\n </blockquote>\n ),\n table: ({ children }) => (\n <div className=\"overflow-x-auto my-2\">\n <table className=\"min-w-full border border-gray-200 text-sm\">{children}</table>\n </div>\n ),\n th: ({ children }) => <th className=\"border border-gray-200 px-2 py-1 bg-gray-50 font-semibold text-left\">{children}</th>,\n td: ({ children }) => <td className=\"border border-gray-200 px-2 py-1\">{children}</td>,\n }}\n >\n {content}\n </ReactMarkdown>\n </div>\n )\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useState, useEffect } from 'react'\nimport { BookOpen, Edit2, Save, X } from 'lucide-react'\nimport Drawer from '../components/Drawer'\nimport MarkdownRenderer from '../components/MarkdownRenderer'\nimport { useToast } from '../components/Toast'\nimport { authFetch } from '../utils/auth'\n\ninterface Skill {\n name: string\n description: string\n content?: string\n}\n\ninterface SkillsResponse {\n skills?: Skill[]\n}\n\nasync function fetchSkills(): Promise<Skill[]> {\n const res = await fetch('/api/skills')\n if (!res.ok) throw new Error('Failed to fetch skills')\n const data: SkillsResponse | Skill[] = await res.json()\n if (Array.isArray(data)) return data\n return data.skills || []\n}\n\nasync function fetchSkillDetail(name: string): Promise<Skill> {\n const res = await fetch(`/api/skills/${name}`)\n if (!res.ok) throw new Error('Failed to fetch')\n return res.json()\n}\n\nasync function saveSkill(name: string, content: string): Promise<void> {\n const res = await authFetch(`/api/skills/${name}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ content }),\n })\n if (!res.ok) throw new Error('Failed to save')\n}\n\nexport default function Skills() {\n const queryClient = useQueryClient()\n const toast = useToast()\n const { data: skills, isLoading } = useQuery({\n queryKey: ['skills'],\n queryFn: fetchSkills,\n })\n\n const [selectedSkill, setSelectedSkill] = useState<string | null>(null)\n const [editing, setEditing] = useState(false)\n const [editContent, setEditContent] = useState('')\n\n const { data: detail } = useQuery({\n queryKey: ['skill-detail', selectedSkill],\n queryFn: () => fetchSkillDetail(selectedSkill!),\n enabled: !!selectedSkill,\n })\n\n useEffect(() => {\n if (detail?.content) setEditContent(detail.content)\n setEditing(false)\n }, [detail])\n\n const mutation = useMutation({\n mutationFn: (vars: { name: string; content: string }) => saveSkill(vars.name, vars.content),\n onSuccess: () => {\n toast.success('Skill 已保存')\n setEditing(false)\n queryClient.invalidateQueries({ queryKey: ['skill-detail', selectedSkill] })\n queryClient.invalidateQueries({ queryKey: ['skills'] })\n },\n onError: (e: Error) => toast.error(`保存失败: ${e.message}`),\n })\n\n if (isLoading) {\n return <div className=\"bg-white rounded-lg shadow p-6\">加载中...</div>\n }\n\n return (\n <div>\n <div className=\"flex items-center justify-between mb-6\">\n <h1 className=\"text-2xl font-bold text-gray-900\">Skill 管理</h1>\n <div className=\"text-sm text-gray-500\">共 {skills?.length || 0} 个 Skill</div>\n </div>\n\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {skills?.map((skill) => (\n <div\n key={skill.name}\n className=\"bg-white rounded-lg shadow p-5 hover:shadow-md transition-shadow cursor-pointer\"\n onClick={() => setSelectedSkill(skill.name)}\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"w-10 h-10 rounded-lg bg-purple-100 flex items-center justify-center flex-shrink-0\">\n <BookOpen className=\"h-5 w-5 text-purple-600\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"font-semibold text-gray-900 truncate\">{skill.name}</h3>\n <p className=\"text-xs text-gray-500 mt-1 line-clamp-3\">\n {skill.description || '(无描述)'}\n </p>\n </div>\n </div>\n </div>\n ))}\n </div>\n\n {/* Skill Detail Drawer */}\n <Drawer\n open={selectedSkill !== null}\n onClose={() => { setSelectedSkill(null); setEditing(false) }}\n title={`Skill: ${selectedSkill}`}\n width=\"w-[800px]\"\n >\n {detail && (\n <div className=\"space-y-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <BookOpen className=\"h-5 w-5 text-purple-600\" />\n <h3 className=\"text-lg font-semibold text-gray-900\">{detail.name}</h3>\n </div>\n\n <div>\n <div className=\"text-xs text-gray-500 mb-1\">描述</div>\n <div className=\"text-sm text-gray-800\">{detail.description}</div>\n </div>\n\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"text-xs text-gray-500\">完整内容 (Markdown)</div>\n <div className=\"flex items-center gap-2\">\n {!editing ? (\n <button\n onClick={() => setEditing(true)}\n className=\"inline-flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-700\"\n >\n <Edit2 className=\"h-3 w-3\" />编辑\n </button>\n ) : (\n <>\n <button\n onClick={() => { setEditing(false); setEditContent(detail.content || '') }}\n className=\"inline-flex items-center gap-1 text-xs text-gray-600 hover:text-gray-700\"\n >\n <X className=\"h-3 w-3\" />取消\n </button>\n <button\n onClick={() => mutation.mutate({ name: detail.name, content: editContent })}\n disabled={mutation.isPending}\n className=\"inline-flex items-center gap-1 text-xs bg-indigo-600 text-white px-2 py-1 rounded hover:bg-indigo-700 disabled:bg-gray-400\"\n >\n <Save className=\"h-3 w-3\" />\n {mutation.isPending ? '保存中...' : '保存'}\n </button>\n </>\n )}\n </div>\n </div>\n {editing ? (\n <textarea\n value={editContent}\n onChange={(e) => setEditContent(e.target.value)}\n className=\"w-full font-mono text-xs bg-gray-50 rounded p-3 border border-gray-300 focus:border-indigo-500 focus:outline-none\"\n rows={20}\n />\n ) : (\n <div className=\"bg-white rounded p-3 border border-gray-200 max-h-[500px] overflow-y-auto\">\n <MarkdownRenderer content={detail.content || ''} />\n </div>\n )}\n {mutation.isError && (\n <div className=\"text-xs text-red-600 mt-1\">保存失败:{(mutation.error as Error).message}</div>\n )}\n </div>\n </div>\n )}\n </Drawer>\n </div>\n )\n}\n"],"names":["MarkdownRenderer","content","className","jsx","ReactMarkdown","remarkGfm","inline","children","props","match","lang","SyntaxHighlighter","oneLight","href","fetchSkills","res","data","fetchSkillDetail","name","saveSkill","authFetch","Skills","queryClient","useQueryClient","toast","useToast","skills","isLoading","useQuery","selectedSkill","setSelectedSkill","useState","editing","setEditing","editContent","setEditContent","detail","useEffect","mutation","useMutation","vars","e","jsxs","skill","BookOpen","Drawer","Fragment","X","Save","Edit2"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as N,j as e}from"./react-vendor-CSp-GLFF.js";import{c as H,L as k}from"./react-router-I-HqunH7.js";import{u as L}from"./query-C99w429o.js";import{p as m}from"./time-Bxuk0M-C.js";import{d as o}from"./vendor-CMMjVdZs.js";import{j as I,o as q,n as B,a as R,g as S,q as W,r as f,s as y,B as A,t as D,F as G,h as E,u as O,p as z,f as K,i as Q,v as U,m as J}from"./lucide-fJlPI3H7.js";import{f as w}from"./date-fns-CZ_bHujz.js";async function V(n){const d=await fetch(`/api/tasks/${n}`);if(!d.ok)throw new Error("Failed to fetch task detail");const a=await d.json();return{...a.task,userPrompts:a.userPrompts??[],injections:a.injections??[],timeline:(a.timeline??[]).map((l,j)=>({id:`${l.timestamp}-${l.tool_name}-${j}`,timestamp:l.timestamp,tool_name:l.tool_name,hook_type:l.hook_type,input:l.input,output:l.output,is_agent_call:l.is_agent_call,agent_detail:l.agent_detail})),skillInvocations:a.skillInvocations??[],artifacts:a.artifacts??[]}}function X(n){switch(n){case"Read":return e.jsx(J,{className:"h-4 w-4 text-gray-500"});case"Edit":return e.jsx(U,{className:"h-4 w-4 text-amber-600"});case"Write":return e.jsx(Q,{className:"h-4 w-4 text-green-600"});case"Bash":return e.jsx(E,{className:"h-4 w-4 text-orange-600"});case"Agent":case"Task":return e.jsx(K,{className:"h-4 w-4 text-blue-600"});case"Grep":case"Glob":return e.jsx(z,{className:"h-4 w-4 text-purple-500"});case"WebSearch":case"WebFetch":return e.jsx(O,{className:"h-4 w-4 text-cyan-600"});default:return e.jsx(E,{className:"h-4 w-4 text-gray-400"})}}function Y(n,d){const a=m(n).getTime()-m(d).getTime();return a<1e3?"+0s":a<6e4?`+${Math.floor(a/1e3)}s`:a<36e5?`+${Math.floor(a/6e4)}m${Math.floor(a%6e4/1e3)}s`:`+${Math.floor(a/36e5)}h${Math.floor(a%36e5/6e4)}m`}function ne(){const{taskId:n}=H(),[d,a]=N.useState(new Set),[l,j]=N.useState(new Set),[b,M]=N.useState(!0),{data:t,isLoading:T,error:h}=L({queryKey:["task-detail",n],queryFn:()=>V(n),enabled:!!n,refetchInterval:1e4});if(T)return e.jsx("div",{className:"bg-white rounded-lg shadow p-6",children:e.jsx("p",{className:"text-gray-600",children:"加载中..."})});if(h||!t)return e.jsxs("div",{children:[e.jsxs(k,{to:"/tasks",className:"inline-flex items-center text-sm text-gray-500 hover:text-gray-700 mb-4",children:[e.jsx(I,{className:"h-4 w-4 mr-1"}),"返回"]}),e.jsx("div",{className:"bg-white rounded-lg shadow p-6",children:e.jsxs("p",{className:"text-red-600",children:["加载失败: ",(h==null?void 0:h.message)||"未知错误"]})})]});const C=s=>{a(i=>{const r=new Set(i);return r.has(s)?r.delete(s):r.add(s),r})},$=s=>{j(i=>{const r=new Set(i);return r.has(s)?r.delete(s):r.add(s),r})},P=t.end_time?`${Math.round((m(t.end_time).getTime()-m(t.start_time).getTime())/1e3)}s`:"进行中";return e.jsxs("div",{children:[e.jsxs(k,{to:"/tasks",className:"inline-flex items-center text-sm text-gray-500 hover:text-gray-700 mb-4",children:[e.jsx(I,{className:"h-4 w-4 mr-1"}),"返回任务列表"]}),e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 mb-6",children:[e.jsxs("div",{className:"flex items-start justify-between mb-4",children:[e.jsx("h1",{className:"text-xl font-bold text-gray-900",children:t.title}),e.jsxs("span",{className:o("px-2 py-1 text-xs font-medium rounded-full",t.status==="completed"&&"bg-green-100 text-green-700",t.status==="active"&&"bg-blue-100 text-blue-700",t.status==="abandoned"&&"bg-gray-100 text-gray-600"),children:[t.status==="completed"&&e.jsx(q,{className:"h-3 w-3 inline mr-1"}),t.status==="active"&&e.jsx(B,{className:"h-3 w-3 inline mr-1 animate-spin"}),t.status]})]}),e.jsxs("div",{className:"grid grid-cols-4 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500 mb-1",children:"开始时间"}),e.jsx("div",{className:"text-gray-900",children:w(m(t.start_time),"MM-dd HH:mm:ss")})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500 mb-1",children:"结束时间"}),e.jsx("div",{className:"text-gray-900",children:t.end_time?w(m(t.end_time),"MM-dd HH:mm:ss"):"-"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500 mb-1",children:"持续时间"}),e.jsx("div",{className:"text-gray-900",children:P})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-gray-500 mb-1",children:"事件数"}),e.jsx("div",{className:"text-gray-900",children:t.event_count})]})]})]}),t.userPrompts.length>0&&e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 mb-6",children:[e.jsxs("h2",{className:"text-base font-semibold text-gray-900 mb-4 flex items-center gap-2",children:[e.jsx(R,{className:"h-4 w-4 text-purple-500"}),"用户消息",e.jsx("span",{className:"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full",children:t.userPrompts.length})]}),e.jsx("div",{className:"space-y-3",children:t.userPrompts.map((s,i)=>e.jsxs("div",{className:"bg-purple-50 border border-purple-100 rounded-lg p-3",children:[e.jsx("div",{className:"text-xs text-gray-500 mb-1 font-mono",children:w(m(s.timestamp),"HH:mm:ss")}),e.jsx("div",{className:"text-sm text-gray-800 whitespace-pre-wrap",children:s.content})]},i))})]}),t.userPrompts.length===0&&t.injections.length===0&&t.timeline.length===0&&t.skillInvocations.length===0&&t.artifacts.length===0&&e.jsxs("div",{className:"bg-white rounded-lg shadow p-12 text-center",children:[e.jsx(S,{className:"h-12 w-12 text-gray-300 mx-auto mb-3"}),e.jsx("p",{className:"text-sm text-gray-500",children:"该任务暂无可展示的执行内容"}),e.jsx("p",{className:"text-xs text-gray-400 mt-1",children:"事件可能仍在记录中,稍后刷新查看"})]}),t.injections.length>0&&e.jsxs("div",{className:"bg-white rounded-lg shadow mb-6",children:[e.jsxs("button",{onClick:()=>M(!b),className:"w-full flex items-center justify-between p-4 text-left hover:bg-gray-50 rounded-t-lg",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{className:"h-4 w-4 text-gray-500"}),e.jsx("h2",{className:"text-base font-semibold text-gray-900",children:"注入内容"}),e.jsx("span",{className:"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full",children:t.injections.length})]}),b?e.jsx(f,{className:"h-4 w-4 text-gray-400"}):e.jsx(y,{className:"h-4 w-4 text-gray-400"})]}),b&&e.jsx("div",{className:"px-4 pb-4 space-y-2",children:t.injections.map(s=>e.jsxs("div",{className:"bg-gray-50 rounded-lg border border-gray-100",children:[e.jsxs("button",{onClick:()=>C(s.id),className:"w-full flex items-center justify-between p-3 text-left",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:o("px-1.5 py-0.5 text-xs rounded font-mono",s.injection_type==="systemMessage"?"bg-blue-50 text-blue-700":"bg-amber-50 text-amber-700"),children:s.injection_type}),e.jsx("span",{className:"text-gray-600",children:s.source_handler})]}),d.has(s.id)?e.jsx(f,{className:"h-3 w-3 text-gray-400"}):e.jsx(y,{className:"h-3 w-3 text-gray-400"})]}),d.has(s.id)&&e.jsx("div",{className:"px-3 pb-3",children:e.jsx("pre",{className:"text-xs text-gray-700 bg-white border border-gray-200 rounded p-3 overflow-x-auto max-h-64 overflow-y-auto whitespace-pre-wrap",children:s.content})})]},s.id))})]}),t.timeline.length>0&&e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 mb-6",children:[e.jsxs("h2",{className:"text-base font-semibold text-gray-900 mb-4 flex items-center gap-2",children:[e.jsx(S,{className:"h-4 w-4 text-gray-500"}),"执行时间线",e.jsx("span",{className:"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full",children:t.timeline.length})]}),e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute left-[19px] top-2 bottom-2 w-px bg-gray-200"}),e.jsx("div",{className:"space-y-0",children:t.timeline.map((s,i)=>{var v,_;const r=s.is_agent_call,p=s.tool_name==="Edit"||s.tool_name==="Write",g=l.has(i),c=s.input,x=c==null?void 0:c.file_path,u=(c==null?void 0:c.description)||(c==null?void 0:c.command);return e.jsxs("div",{className:o("relative flex items-start gap-3 py-2 px-2 rounded-md cursor-pointer hover:bg-gray-50 transition-colors",r&&"bg-blue-50 hover:bg-blue-100"),onClick:()=>$(i),children:[e.jsx("div",{className:"relative z-10 flex-shrink-0 w-10 flex justify-center",children:e.jsx("div",{className:o("w-8 h-8 rounded-full flex items-center justify-center",r?"bg-blue-100":"bg-white border border-gray-200"),children:X(s.tool_name)})}),e.jsxs("div",{className:"flex-1 min-w-0 pt-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:o("text-sm font-medium",r?"text-blue-700":"text-gray-900"),children:s.tool_name}),((v=s.agent_detail)==null?void 0:v.subagent_type)&&e.jsx("span",{className:"text-xs bg-blue-100 text-blue-700 px-1.5 py-0.5 rounded font-mono",children:s.agent_detail.subagent_type}),((_=s.agent_detail)==null?void 0:_.name)&&e.jsx("span",{className:"text-xs text-blue-600",children:s.agent_detail.name}),e.jsxs("span",{className:"text-xs text-gray-400 font-mono ml-auto flex items-center gap-1",children:[Y(s.timestamp,t.start_time),g?e.jsx(f,{className:"h-3 w-3"}):e.jsx(y,{className:"h-3 w-3"})]})]}),!g&&p&&x&&e.jsx("p",{className:"text-xs text-green-700 font-mono mt-0.5 truncate",title:x,children:x}),!g&&!p&&u&&e.jsx("p",{className:"text-xs text-gray-500 mt-0.5 truncate",children:u}),g&&e.jsxs("div",{className:"mt-2 space-y-2 text-xs",onClick:F=>F.stopPropagation(),children:[r&&s.agent_detail&&e.jsxs("div",{className:"bg-blue-50 border border-blue-200 rounded-lg p-3 space-y-2",children:[s.agent_detail.subagent_type&&e.jsxs("div",{children:[e.jsx("span",{className:"text-blue-600 font-medium",children:"subagent_type: "}),e.jsx("span",{className:"font-mono text-blue-800",children:s.agent_detail.subagent_type})]}),s.agent_detail.name&&e.jsxs("div",{children:[e.jsx("span",{className:"text-blue-600 font-medium",children:"name: "}),e.jsx("span",{className:"font-mono text-blue-800",children:s.agent_detail.name})]}),s.agent_detail.prompt&&e.jsxs("div",{children:[e.jsx("span",{className:"text-blue-600 font-medium",children:"prompt:"}),e.jsx("pre",{className:"mt-1 p-2 bg-white rounded border border-blue-100 text-gray-800 whitespace-pre-wrap break-words max-h-60 overflow-y-auto",children:s.agent_detail.prompt})]})]}),p&&x&&e.jsxs("div",{className:"bg-green-50 border border-green-200 rounded-lg p-3",children:[e.jsx("span",{className:"text-green-700 font-medium",children:"file: "}),e.jsx("span",{className:"font-mono text-green-800",children:x})]}),!r&&u&&e.jsx("div",{className:"bg-gray-50 border border-gray-200 rounded-lg p-3",children:e.jsx("pre",{className:"text-gray-700 whitespace-pre-wrap break-words max-h-40 overflow-y-auto",children:u})}),!r&&!p&&x&&e.jsxs("div",{className:"text-gray-500",children:[e.jsx("span",{className:"font-medium",children:"path: "}),e.jsx("span",{className:"font-mono",children:x})]})]})]})]},s.id||i)})})]})]}),t.skillInvocations.length>0&&e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 mb-6",children:[e.jsxs("h2",{className:"text-base font-semibold text-gray-900 mb-4 flex items-center gap-2",children:[e.jsx(A,{className:"h-4 w-4 text-purple-500"}),"Skill 调用",e.jsx("span",{className:"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full",children:t.skillInvocations.length})]}),e.jsx("div",{className:"space-y-3",children:t.skillInvocations.map(s=>e.jsxs("div",{className:"border border-purple-100 bg-purple-50 rounded-lg p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx("span",{className:"text-sm font-medium text-purple-800 font-mono",children:s.skill_id}),s.workflow&&e.jsx("span",{className:"text-xs bg-purple-100 text-purple-700 px-1.5 py-0.5 rounded",children:s.workflow}),s.phase&&e.jsxs("span",{className:"text-xs bg-purple-100 text-purple-700 px-1.5 py-0.5 rounded",children:["phase: ",s.phase]})]}),e.jsx("p",{className:"text-xs text-purple-700",children:s.reason})]},s.id))})]}),t.artifacts.length>0&&e.jsxs("div",{className:"bg-white rounded-lg shadow p-6 mb-6",children:[e.jsxs("h2",{className:"text-base font-semibold text-gray-900 mb-4 flex items-center gap-2",children:[e.jsx(D,{className:"h-4 w-4 text-green-600"}),"产物",e.jsxs("span",{className:"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full",children:[t.artifacts.length," 个文件"]})]}),e.jsx("div",{className:"space-y-1",children:t.artifacts.map(s=>e.jsxs("div",{className:"flex items-center gap-2 py-1.5 px-3 rounded hover:bg-green-50",children:[e.jsx(G,{className:"h-4 w-4 text-green-600 flex-shrink-0"}),e.jsx("span",{className:"text-sm text-gray-800 font-mono truncate",title:s,children:s})]},s))})]})]})}export{ne as default};
|
|
2
|
+
//# sourceMappingURL=TaskDetail-5SR8zGzv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskDetail-5SR8zGzv.js","sources":["../../src/pages/TaskDetail.tsx"],"sourcesContent":["import { useParams, Link } from 'react-router-dom'\nimport { useQuery } from '@tanstack/react-query'\nimport { useState } from 'react'\nimport { format } from 'date-fns'\nimport { parseUTC } from '../utils/time'\nimport {\n ArrowLeft,\n Clock,\n CheckCircle2,\n Loader2,\n ChevronDown,\n ChevronRight,\n FileText,\n Terminal,\n FileEdit,\n Bot,\n BookOpen,\n Syringe,\n FolderOpen,\n Eye,\n Pencil,\n Search,\n Globe,\n MessageSquare,\n} from 'lucide-react'\nimport clsx from 'clsx'\n\ninterface Injection {\n id: string\n injection_type: 'systemMessage' | 'additionalContext'\n source_handler: string\n content: string\n timestamp: string\n}\n\ninterface TimelineEvent {\n id: string\n timestamp: string\n tool_name: string\n hook_type: string\n input: unknown\n output: unknown\n is_agent_call: boolean\n agent_detail?: {\n subagent_type?: string\n name?: string\n prompt?: string\n }\n}\n\ninterface SkillInvocation {\n id: string\n skill_id: string\n reason: string\n workflow?: string\n phase?: string\n timestamp: string\n}\n\ninterface UserPrompt {\n timestamp: string\n content: string\n}\n\ninterface TaskDetailData {\n id: string\n title: string\n status: 'active' | 'completed' | 'abandoned'\n start_time: string\n end_time?: string\n event_count: number\n session_id: string\n userPrompts: UserPrompt[]\n injections: Injection[]\n timeline: TimelineEvent[]\n skillInvocations: SkillInvocation[]\n artifacts: string[]\n}\n\nasync function fetchTaskDetail(taskId: string): Promise<TaskDetailData> {\n const res = await fetch(`/api/tasks/${taskId}`)\n if (!res.ok) throw new Error('Failed to fetch task detail')\n const raw = await res.json()\n // API returns { task: {...}, injections, timeline, skillInvocations, artifacts }\n // Flatten task fields into top level for component consumption\n return {\n ...raw.task,\n userPrompts: raw.userPrompts ?? [],\n injections: raw.injections ?? [],\n timeline: (raw.timeline ?? []).map((e: any, idx: number) => ({\n id: `${e.timestamp}-${e.tool_name}-${idx}`,\n timestamp: e.timestamp,\n tool_name: e.tool_name,\n hook_type: e.hook_type,\n input: e.input,\n output: e.output,\n is_agent_call: e.is_agent_call,\n agent_detail: e.agent_detail,\n })),\n skillInvocations: raw.skillInvocations ?? [],\n artifacts: raw.artifacts ?? [],\n }\n}\n\nfunction getToolIcon(toolName: string) {\n switch (toolName) {\n case 'Read':\n return <Eye className=\"h-4 w-4 text-gray-500\" />\n case 'Edit':\n return <Pencil className=\"h-4 w-4 text-amber-600\" />\n case 'Write':\n return <FileEdit className=\"h-4 w-4 text-green-600\" />\n case 'Bash':\n return <Terminal className=\"h-4 w-4 text-orange-600\" />\n case 'Agent':\n case 'Task':\n return <Bot className=\"h-4 w-4 text-blue-600\" />\n case 'Grep':\n case 'Glob':\n return <Search className=\"h-4 w-4 text-purple-500\" />\n case 'WebSearch':\n case 'WebFetch':\n return <Globe className=\"h-4 w-4 text-cyan-600\" />\n default:\n return <Terminal className=\"h-4 w-4 text-gray-400\" />\n }\n}\n\nfunction getRelativeTime(eventTime: string, startTime: string): string {\n const diff = parseUTC(eventTime).getTime() - parseUTC(startTime).getTime()\n if (diff < 1000) return '+0s'\n if (diff < 60000) return `+${Math.floor(diff / 1000)}s`\n if (diff < 3600000) return `+${Math.floor(diff / 60000)}m${Math.floor((diff % 60000) / 1000)}s`\n return `+${Math.floor(diff / 3600000)}h${Math.floor((diff % 3600000) / 60000)}m`\n}\n\nexport default function TaskDetail() {\n const { taskId } = useParams<{ taskId: string }>()\n const [expandedInjections, setExpandedInjections] = useState<Set<string>>(new Set())\n const [expandedEvents, setExpandedEvents] = useState<Set<number>>(new Set())\n const [showInjections, setShowInjections] = useState(true)\n\n const { data, isLoading, error } = useQuery({\n queryKey: ['task-detail', taskId],\n queryFn: () => fetchTaskDetail(taskId!),\n enabled: !!taskId,\n refetchInterval: 10000,\n })\n\n if (isLoading) {\n return (\n <div className=\"bg-white rounded-lg shadow p-6\">\n <p className=\"text-gray-600\">加载中...</p>\n </div>\n )\n }\n\n if (error || !data) {\n return (\n <div>\n <Link to=\"/tasks\" className=\"inline-flex items-center text-sm text-gray-500 hover:text-gray-700 mb-4\">\n <ArrowLeft className=\"h-4 w-4 mr-1\" />返回\n </Link>\n <div className=\"bg-white rounded-lg shadow p-6\">\n <p className=\"text-red-600\">加载失败: {(error as Error)?.message || '未知错误'}</p>\n </div>\n </div>\n )\n }\n\n const toggleInjection = (id: string) => {\n setExpandedInjections(prev => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }\n\n const toggleEvent = (idx: number) => {\n setExpandedEvents(prev => {\n const next = new Set(prev)\n if (next.has(idx)) next.delete(idx)\n else next.add(idx)\n return next\n })\n }\n\n const duration = data.end_time\n ? `${Math.round((parseUTC(data.end_time).getTime() - parseUTC(data.start_time).getTime()) / 1000)}s`\n : '进行中'\n\n return (\n <div>\n <Link to=\"/tasks\" className=\"inline-flex items-center text-sm text-gray-500 hover:text-gray-700 mb-4\">\n <ArrowLeft className=\"h-4 w-4 mr-1\" />返回任务列表\n </Link>\n\n {/* 区域 1:任务概览 */}\n <div className=\"bg-white rounded-lg shadow p-6 mb-6\">\n <div className=\"flex items-start justify-between mb-4\">\n <h1 className=\"text-xl font-bold text-gray-900\">{data.title}</h1>\n <span className={clsx(\n 'px-2 py-1 text-xs font-medium rounded-full',\n data.status === 'completed' && 'bg-green-100 text-green-700',\n data.status === 'active' && 'bg-blue-100 text-blue-700',\n data.status === 'abandoned' && 'bg-gray-100 text-gray-600'\n )}>\n {data.status === 'completed' && <CheckCircle2 className=\"h-3 w-3 inline mr-1\" />}\n {data.status === 'active' && <Loader2 className=\"h-3 w-3 inline mr-1 animate-spin\" />}\n {data.status}\n </span>\n </div>\n <div className=\"grid grid-cols-4 gap-4 text-sm\">\n <div>\n <div className=\"text-xs text-gray-500 mb-1\">开始时间</div>\n <div className=\"text-gray-900\">\n {format(parseUTC(data.start_time), 'MM-dd HH:mm:ss')}\n </div>\n </div>\n <div>\n <div className=\"text-xs text-gray-500 mb-1\">结束时间</div>\n <div className=\"text-gray-900\">\n {data.end_time ? format(parseUTC(data.end_time), 'MM-dd HH:mm:ss') : '-'}\n </div>\n </div>\n <div>\n <div className=\"text-xs text-gray-500 mb-1\">持续时间</div>\n <div className=\"text-gray-900\">{duration}</div>\n </div>\n <div>\n <div className=\"text-xs text-gray-500 mb-1\">事件数</div>\n <div className=\"text-gray-900\">{data.event_count}</div>\n </div>\n </div>\n </div>\n\n {/* 区域 1.5:用户消息 */}\n {data.userPrompts.length > 0 && (\n <div className=\"bg-white rounded-lg shadow p-6 mb-6\">\n <h2 className=\"text-base font-semibold text-gray-900 mb-4 flex items-center gap-2\">\n <MessageSquare className=\"h-4 w-4 text-purple-500\" />\n 用户消息\n <span className=\"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full\">\n {data.userPrompts.length}\n </span>\n </h2>\n <div className=\"space-y-3\">\n {data.userPrompts.map((up, idx) => (\n <div key={idx} className=\"bg-purple-50 border border-purple-100 rounded-lg p-3\">\n <div className=\"text-xs text-gray-500 mb-1 font-mono\">\n {format(parseUTC(up.timestamp), 'HH:mm:ss')}\n </div>\n <div className=\"text-sm text-gray-800 whitespace-pre-wrap\">{up.content}</div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* 空状态:所有详情区块都为空时的兜底提示 */}\n {data.userPrompts.length === 0 &&\n data.injections.length === 0 &&\n data.timeline.length === 0 &&\n data.skillInvocations.length === 0 &&\n data.artifacts.length === 0 && (\n <div className=\"bg-white rounded-lg shadow p-12 text-center\">\n <Clock className=\"h-12 w-12 text-gray-300 mx-auto mb-3\" />\n <p className=\"text-sm text-gray-500\">该任务暂无可展示的执行内容</p>\n <p className=\"text-xs text-gray-400 mt-1\">事件可能仍在记录中,稍后刷新查看</p>\n </div>\n )}\n\n {/* 区域 2:注入内容 */}\n {data.injections.length > 0 && (\n <div className=\"bg-white rounded-lg shadow mb-6\">\n <button\n onClick={() => setShowInjections(!showInjections)}\n className=\"w-full flex items-center justify-between p-4 text-left hover:bg-gray-50 rounded-t-lg\"\n >\n <div className=\"flex items-center gap-2\">\n <Syringe className=\"h-4 w-4 text-gray-500\" />\n <h2 className=\"text-base font-semibold text-gray-900\">注入内容</h2>\n <span className=\"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full\">\n {data.injections.length}\n </span>\n </div>\n {showInjections ? <ChevronDown className=\"h-4 w-4 text-gray-400\" /> : <ChevronRight className=\"h-4 w-4 text-gray-400\" />}\n </button>\n {showInjections && (\n <div className=\"px-4 pb-4 space-y-2\">\n {data.injections.map((inj) => (\n <div key={inj.id} className=\"bg-gray-50 rounded-lg border border-gray-100\">\n <button\n onClick={() => toggleInjection(inj.id)}\n className=\"w-full flex items-center justify-between p-3 text-left\"\n >\n <div className=\"flex items-center gap-2 text-sm\">\n <span className={clsx(\n 'px-1.5 py-0.5 text-xs rounded font-mono',\n inj.injection_type === 'systemMessage' ? 'bg-blue-50 text-blue-700' : 'bg-amber-50 text-amber-700'\n )}>\n {inj.injection_type}\n </span>\n <span className=\"text-gray-600\">{inj.source_handler}</span>\n </div>\n {expandedInjections.has(inj.id) ? <ChevronDown className=\"h-3 w-3 text-gray-400\" /> : <ChevronRight className=\"h-3 w-3 text-gray-400\" />}\n </button>\n {expandedInjections.has(inj.id) && (\n <div className=\"px-3 pb-3\">\n <pre className=\"text-xs text-gray-700 bg-white border border-gray-200 rounded p-3 overflow-x-auto max-h-64 overflow-y-auto whitespace-pre-wrap\">\n {inj.content}\n </pre>\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* 区域 3:执行时间线 */}\n {data.timeline.length > 0 && (\n <div className=\"bg-white rounded-lg shadow p-6 mb-6\">\n <h2 className=\"text-base font-semibold text-gray-900 mb-4 flex items-center gap-2\">\n <Clock className=\"h-4 w-4 text-gray-500\" />\n 执行时间线\n <span className=\"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full\">\n {data.timeline.length}\n </span>\n </h2>\n <div className=\"relative\">\n {/* 竖线 */}\n <div className=\"absolute left-[19px] top-2 bottom-2 w-px bg-gray-200\" />\n <div className=\"space-y-0\">\n {data.timeline.map((event, idx) => {\n const isAgent = event.is_agent_call\n const isFileOp = event.tool_name === 'Edit' || event.tool_name === 'Write'\n const isExpanded = expandedEvents.has(idx)\n const input = event.input as Record<string, unknown> | null\n const filePath = input?.file_path as string | undefined\n const description = (input?.description || input?.command) as string | undefined\n\n return (\n <div key={event.id || idx} className={clsx(\n 'relative flex items-start gap-3 py-2 px-2 rounded-md cursor-pointer hover:bg-gray-50 transition-colors',\n isAgent && 'bg-blue-50 hover:bg-blue-100',\n )}\n onClick={() => toggleEvent(idx)}\n >\n <div className=\"relative z-10 flex-shrink-0 w-10 flex justify-center\">\n <div className={clsx(\n 'w-8 h-8 rounded-full flex items-center justify-center',\n isAgent ? 'bg-blue-100' : 'bg-white border border-gray-200'\n )}>\n {getToolIcon(event.tool_name)}\n </div>\n </div>\n <div className=\"flex-1 min-w-0 pt-1\">\n <div className=\"flex items-center gap-2\">\n <span className={clsx(\n 'text-sm font-medium',\n isAgent ? 'text-blue-700' : 'text-gray-900'\n )}>\n {event.tool_name}\n </span>\n {event.agent_detail?.subagent_type && (\n <span className=\"text-xs bg-blue-100 text-blue-700 px-1.5 py-0.5 rounded font-mono\">\n {event.agent_detail.subagent_type}\n </span>\n )}\n {event.agent_detail?.name && (\n <span className=\"text-xs text-blue-600\">\n {event.agent_detail.name}\n </span>\n )}\n <span className=\"text-xs text-gray-400 font-mono ml-auto flex items-center gap-1\">\n {getRelativeTime(event.timestamp, data.start_time)}\n {isExpanded ? <ChevronDown className=\"h-3 w-3\" /> : <ChevronRight className=\"h-3 w-3\" />}\n </span>\n </div>\n {!isExpanded && isFileOp && filePath && (\n <p className=\"text-xs text-green-700 font-mono mt-0.5 truncate\" title={filePath}>\n {filePath}\n </p>\n )}\n {!isExpanded && !isFileOp && description && (\n <p className=\"text-xs text-gray-500 mt-0.5 truncate\">{description}</p>\n )}\n {/* 展开的详细内容 */}\n {isExpanded && (\n <div className=\"mt-2 space-y-2 text-xs\" onClick={e => e.stopPropagation()}>\n {/* Agent 调用详情 */}\n {isAgent && event.agent_detail && (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-3 space-y-2\">\n {event.agent_detail.subagent_type && (\n <div>\n <span className=\"text-blue-600 font-medium\">subagent_type: </span>\n <span className=\"font-mono text-blue-800\">{event.agent_detail.subagent_type}</span>\n </div>\n )}\n {event.agent_detail.name && (\n <div>\n <span className=\"text-blue-600 font-medium\">name: </span>\n <span className=\"font-mono text-blue-800\">{event.agent_detail.name}</span>\n </div>\n )}\n {event.agent_detail.prompt && (\n <div>\n <span className=\"text-blue-600 font-medium\">prompt:</span>\n <pre className=\"mt-1 p-2 bg-white rounded border border-blue-100 text-gray-800 whitespace-pre-wrap break-words max-h-60 overflow-y-auto\">\n {event.agent_detail.prompt}\n </pre>\n </div>\n )}\n </div>\n )}\n {/* 文件操作详情 */}\n {isFileOp && filePath && (\n <div className=\"bg-green-50 border border-green-200 rounded-lg p-3\">\n <span className=\"text-green-700 font-medium\">file: </span>\n <span className=\"font-mono text-green-800\">{filePath}</span>\n </div>\n )}\n {/* 通用工具详情 */}\n {!isAgent && description && (\n <div className=\"bg-gray-50 border border-gray-200 rounded-lg p-3\">\n <pre className=\"text-gray-700 whitespace-pre-wrap break-words max-h-40 overflow-y-auto\">\n {description}\n </pre>\n </div>\n )}\n {/* 文件路径(非文件操作工具,如 Read) */}\n {!isAgent && !isFileOp && filePath && (\n <div className=\"text-gray-500\">\n <span className=\"font-medium\">path: </span>\n <span className=\"font-mono\">{filePath}</span>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )\n })}\n </div>\n </div>\n </div>\n )}\n\n {/* 区域 4:Skill 调用 */}\n {data.skillInvocations.length > 0 && (\n <div className=\"bg-white rounded-lg shadow p-6 mb-6\">\n <h2 className=\"text-base font-semibold text-gray-900 mb-4 flex items-center gap-2\">\n <BookOpen className=\"h-4 w-4 text-purple-500\" />\n Skill 调用\n <span className=\"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full\">\n {data.skillInvocations.length}\n </span>\n </h2>\n <div className=\"space-y-3\">\n {data.skillInvocations.map((skill) => (\n <div key={skill.id} className=\"border border-purple-100 bg-purple-50 rounded-lg p-4\">\n <div className=\"flex items-center gap-2 mb-2\">\n <span className=\"text-sm font-medium text-purple-800 font-mono\">\n {skill.skill_id}\n </span>\n {skill.workflow && (\n <span className=\"text-xs bg-purple-100 text-purple-700 px-1.5 py-0.5 rounded\">\n {skill.workflow}\n </span>\n )}\n {skill.phase && (\n <span className=\"text-xs bg-purple-100 text-purple-700 px-1.5 py-0.5 rounded\">\n phase: {skill.phase}\n </span>\n )}\n </div>\n <p className=\"text-xs text-purple-700\">{skill.reason}</p>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* 区域 5:产物 */}\n {data.artifacts.length > 0 && (\n <div className=\"bg-white rounded-lg shadow p-6 mb-6\">\n <h2 className=\"text-base font-semibold text-gray-900 mb-4 flex items-center gap-2\">\n <FolderOpen className=\"h-4 w-4 text-green-600\" />\n 产物\n <span className=\"text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full\">\n {data.artifacts.length} 个文件\n </span>\n </h2>\n <div className=\"space-y-1\">\n {data.artifacts.map((filePath) => (\n <div key={filePath} className=\"flex items-center gap-2 py-1.5 px-3 rounded hover:bg-green-50\">\n <FileText className=\"h-4 w-4 text-green-600 flex-shrink-0\" />\n <span className=\"text-sm text-gray-800 font-mono truncate\" title={filePath}>\n {filePath}\n </span>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}\n"],"names":["fetchTaskDetail","taskId","res","raw","e","idx","getToolIcon","toolName","jsx","Eye","Pencil","FileEdit","Terminal","Bot","Search","Globe","getRelativeTime","eventTime","startTime","diff","parseUTC","TaskDetail","useParams","expandedInjections","setExpandedInjections","useState","expandedEvents","setExpandedEvents","showInjections","setShowInjections","data","isLoading","error","useQuery","jsxs","Link","ArrowLeft","toggleInjection","id","prev","next","toggleEvent","duration","clsx","CheckCircle2","Loader2","format","MessageSquare","up","Clock","Syringe","ChevronDown","ChevronRight","inj","event","isAgent","isFileOp","isExpanded","input","filePath","description","_a","_b","BookOpen","skill","FolderOpen","FileText"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as d,j as e}from"./react-vendor-CSp-GLFF.js";import{u}from"./query-C99w429o.js";import{p as f}from"./time-Bxuk0M-C.js";import{S as g}from"./SearchInput-BX2KhMkw.js";import{d as p}from"./vendor-CMMjVdZs.js";import{b as j}from"./react-router-I-HqunH7.js";import{A as o,g as N,n as w,o as b}from"./lucide-fJlPI3H7.js";import{a as v,z as y}from"./date-fns-CZ_bHujz.js";async function C(){const a=await fetch("/api/tasks");if(!a.ok)throw new Error("Failed to fetch tasks");return a.json()}function A(){const a=j(),[t,m]=d.useState(""),{data:r,isLoading:x,error:l}=u({queryKey:["tasks"],queryFn:C,refetchInterval:1e4}),i=d.useMemo(()=>{if(!r)return[];if(!t.trim())return r;const s=t.toLowerCase();return r.filter(n=>{var c;return((c=n.title)==null?void 0:c.toLowerCase().includes(s))||n.id.toLowerCase().includes(s)})},[r,t]);if(x)return e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-6",children:"任务"}),e.jsx("div",{className:"bg-white rounded-lg shadow p-6",children:e.jsx("p",{className:"text-gray-600",children:"加载中..."})})]});if(l)return e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-6",children:"任务"}),e.jsx("div",{className:"bg-white rounded-lg shadow p-6",children:e.jsxs("p",{className:"text-red-600",children:["加载失败: ",l.message]})})]});const h=s=>{switch(s){case"completed":return e.jsx(b,{className:"h-4 w-4 text-green-600"});case"active":return e.jsx(w,{className:"h-4 w-4 text-blue-600 animate-spin"});default:return e.jsx(o,{className:"h-4 w-4 text-gray-400"})}};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4 flex-wrap gap-3",children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"任务"}),e.jsx(g,{value:t,onChange:m,placeholder:"搜索任务标题...",className:"w-64"})]}),e.jsxs("div",{className:"text-sm text-gray-500 mb-3",children:["显示 ",i.length," 个任务 ",t&&"(已过滤)"]}),e.jsxs("div",{className:"grid gap-4",children:[i.map(s=>e.jsxs("div",{onClick:()=>a(`/tasks/${s.id}`),className:"bg-white rounded-lg shadow hover:shadow-md transition-shadow cursor-pointer p-5",children:[e.jsxs("div",{className:"flex items-start justify-between mb-3",children:[e.jsxs("div",{className:"flex items-start gap-3 flex-1",children:[e.jsx("div",{className:"mt-0.5",children:h(s.status)}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("h3",{className:"text-base font-semibold text-gray-900 mb-1",children:s.title}),e.jsxs("p",{className:"text-xs text-gray-500 font-mono",children:[s.id.slice(0,16),"..."]})]})]}),e.jsx("span",{className:p("px-2 py-1 text-xs font-medium rounded-full whitespace-nowrap ml-3",s.status==="completed"&&"bg-green-100 text-green-700",s.status==="active"&&"bg-blue-100 text-blue-700",s.status==="abandoned"&&"bg-gray-100 text-gray-600"),children:s.status})]}),e.jsxs("div",{className:"flex items-center gap-6 text-sm text-gray-600",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(o,{className:"h-4 w-4"}),s.event_count," 个事件"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(N,{className:"h-4 w-4"}),s.start_time?v(f(s.start_time),{addSuffix:!0,locale:y}):"-"]})]})]},s.id)),i.length===0&&e.jsx("div",{className:"bg-white rounded-lg shadow p-12 text-center text-gray-500",children:t?"无匹配结果":"暂无任务记录"})]})]})}export{A as default};
|
|
2
|
+
//# sourceMappingURL=Tasks-DCgDqvOZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tasks-DCgDqvOZ.js","sources":["../../src/pages/Tasks.tsx"],"sourcesContent":["import { useQuery } from '@tanstack/react-query'\nimport { useState, useMemo } from 'react'\nimport { useNavigate } from 'react-router-dom'\nimport { formatDistanceToNow } from 'date-fns'\nimport { parseUTC } from '../utils/time'\nimport { zhCN } from 'date-fns/locale'\nimport { Clock, Activity, CheckCircle2, Loader2 } from 'lucide-react'\nimport SearchInput from '../components/SearchInput'\nimport clsx from 'clsx'\n\ninterface Task {\n id: string\n title: string\n status: 'active' | 'completed' | 'abandoned'\n start_time: string\n end_time?: string\n event_count: number\n session_id: string\n}\n\nasync function fetchTasks(): Promise<Task[]> {\n const res = await fetch('/api/tasks')\n if (!res.ok) throw new Error('Failed to fetch tasks')\n return res.json()\n}\n\nexport default function Tasks() {\n const navigate = useNavigate()\n const [search, setSearch] = useState('')\n\n const { data: tasks, isLoading, error } = useQuery({\n queryKey: ['tasks'],\n queryFn: fetchTasks,\n refetchInterval: 10000,\n })\n\n const filteredTasks = useMemo(() => {\n if (!tasks) return []\n if (!search.trim()) return tasks\n const q = search.toLowerCase()\n return tasks.filter(t =>\n t.title?.toLowerCase().includes(q) ||\n t.id.toLowerCase().includes(q)\n )\n }, [tasks, search])\n\n if (isLoading) {\n return (\n <div>\n <h1 className=\"text-2xl font-bold text-gray-900 mb-6\">任务</h1>\n <div className=\"bg-white rounded-lg shadow p-6\">\n <p className=\"text-gray-600\">加载中...</p>\n </div>\n </div>\n )\n }\n\n if (error) {\n return (\n <div>\n <h1 className=\"text-2xl font-bold text-gray-900 mb-6\">任务</h1>\n <div className=\"bg-white rounded-lg shadow p-6\">\n <p className=\"text-red-600\">加载失败: {(error as Error).message}</p>\n </div>\n </div>\n )\n }\n\n const getStatusIcon = (status: string) => {\n switch (status) {\n case 'completed':\n return <CheckCircle2 className=\"h-4 w-4 text-green-600\" />\n case 'active':\n return <Loader2 className=\"h-4 w-4 text-blue-600 animate-spin\" />\n default:\n return <Activity className=\"h-4 w-4 text-gray-400\" />\n }\n }\n\n return (\n <div>\n <div className=\"flex items-center justify-between mb-4 flex-wrap gap-3\">\n <h1 className=\"text-2xl font-bold text-gray-900\">任务</h1>\n <SearchInput\n value={search}\n onChange={setSearch}\n placeholder=\"搜索任务标题...\"\n className=\"w-64\"\n />\n </div>\n\n <div className=\"text-sm text-gray-500 mb-3\">\n 显示 {filteredTasks.length} 个任务 {search && `(已过滤)`}\n </div>\n\n <div className=\"grid gap-4\">\n {filteredTasks.map((task) => (\n <div\n key={task.id}\n onClick={() => navigate(`/tasks/${task.id}`)}\n className=\"bg-white rounded-lg shadow hover:shadow-md transition-shadow cursor-pointer p-5\"\n >\n <div className=\"flex items-start justify-between mb-3\">\n <div className=\"flex items-start gap-3 flex-1\">\n <div className=\"mt-0.5\">{getStatusIcon(task.status)}</div>\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-base font-semibold text-gray-900 mb-1\">\n {task.title}\n </h3>\n <p className=\"text-xs text-gray-500 font-mono\">\n {task.id.slice(0, 16)}...\n </p>\n </div>\n </div>\n <span className={clsx(\n 'px-2 py-1 text-xs font-medium rounded-full whitespace-nowrap ml-3',\n task.status === 'completed' && 'bg-green-100 text-green-700',\n task.status === 'active' && 'bg-blue-100 text-blue-700',\n task.status === 'abandoned' && 'bg-gray-100 text-gray-600'\n )}>\n {task.status}\n </span>\n </div>\n\n <div className=\"flex items-center gap-6 text-sm text-gray-600\">\n <span className=\"inline-flex items-center gap-1\">\n <Activity className=\"h-4 w-4\" />\n {task.event_count} 个事件\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"h-4 w-4\" />\n {task.start_time\n ? formatDistanceToNow(parseUTC(task.start_time), {\n addSuffix: true,\n locale: zhCN,\n })\n : '-'}\n </span>\n </div>\n </div>\n ))}\n {filteredTasks.length === 0 && (\n <div className=\"bg-white rounded-lg shadow p-12 text-center text-gray-500\">\n {search ? '无匹配结果' : '暂无任务记录'}\n </div>\n )}\n </div>\n </div>\n )\n}\n"],"names":["fetchTasks","res","Tasks","navigate","useNavigate","search","setSearch","useState","tasks","isLoading","error","useQuery","filteredTasks","useMemo","q","t","_a","jsx","jsxs","getStatusIcon","status","CheckCircle2","Loader2","Activity","SearchInput","task","clsx","Clock","formatDistanceToNow","parseUTC","zhCN"],"mappings":"sXAoBA,eAAeA,GAA8B,CAC3C,MAAMC,EAAM,MAAM,MAAM,YAAY,EACpC,GAAI,CAACA,EAAI,GAAI,MAAM,IAAI,MAAM,uBAAuB,EACpD,OAAOA,EAAI,KAAA,CACb,CAEA,SAAwBC,GAAQ,CAC9B,MAAMC,EAAWC,EAAA,EACX,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAS,EAAE,EAEjC,CAAE,KAAMC,EAAO,UAAAC,EAAW,MAAAC,CAAA,EAAUC,EAAS,CACjD,SAAU,CAAC,OAAO,EAClB,QAASX,EACT,gBAAiB,GAAA,CAClB,EAEKY,EAAgBC,EAAAA,QAAQ,IAAM,CAClC,GAAI,CAACL,EAAO,MAAO,CAAA,EACnB,GAAI,CAACH,EAAO,KAAA,EAAQ,OAAOG,EAC3B,MAAMM,EAAIT,EAAO,YAAA,EACjB,OAAOG,EAAM,OAAOO,GAAA,OAClB,QAAAC,EAAAD,EAAE,QAAF,YAAAC,EAAS,cAAc,SAASF,KAChCC,EAAE,GAAG,YAAA,EAAc,SAASD,CAAC,EAAA,CAEjC,EAAG,CAACN,EAAOH,CAAM,CAAC,EAElB,GAAII,EACF,cACG,MAAA,CACC,SAAA,CAAAQ,EAAAA,IAAC,KAAA,CAAG,UAAU,wCAAwC,SAAA,KAAE,EACxDA,EAAAA,IAAC,OAAI,UAAU,iCACb,eAAC,IAAA,CAAE,UAAU,gBAAgB,SAAA,QAAA,CAAM,CAAA,CACrC,CAAA,EACF,EAIJ,GAAIP,EACF,cACG,MAAA,CACC,SAAA,CAAAO,EAAAA,IAAC,KAAA,CAAG,UAAU,wCAAwC,SAAA,KAAE,QACvD,MAAA,CAAI,UAAU,iCACb,SAAAC,EAAAA,KAAC,IAAA,CAAE,UAAU,eAAe,SAAA,CAAA,SAAQR,EAAgB,OAAA,CAAA,CAAQ,CAAA,CAC9D,CAAA,EACF,EAIJ,MAAMS,EAAiBC,GAAmB,CACxC,OAAQA,EAAA,CACN,IAAK,YACH,OAAOH,EAAAA,IAACI,EAAA,CAAa,UAAU,wBAAA,CAAyB,EAC1D,IAAK,SACH,OAAOJ,EAAAA,IAACK,EAAA,CAAQ,UAAU,oCAAA,CAAqC,EACjE,QACE,OAAOL,EAAAA,IAACM,EAAA,CAAS,UAAU,uBAAA,CAAwB,CAAA,CAEzD,EAEA,cACG,MAAA,CACC,SAAA,CAAAL,EAAAA,KAAC,MAAA,CAAI,UAAU,yDACb,SAAA,CAAAD,EAAAA,IAAC,KAAA,CAAG,UAAU,mCAAmC,SAAA,KAAE,EACnDA,EAAAA,IAACO,EAAA,CACC,MAAOnB,EACP,SAAUC,EACV,YAAY,YACZ,UAAU,MAAA,CAAA,CACZ,EACF,EAEAY,EAAAA,KAAC,MAAA,CAAI,UAAU,6BAA6B,SAAA,CAAA,MACtCN,EAAc,OAAO,QAAMP,GAAU,OAAA,EAC3C,EAEAa,EAAAA,KAAC,MAAA,CAAI,UAAU,aACZ,SAAA,CAAAN,EAAc,IAAKa,GAClBP,EAAAA,KAAC,MAAA,CAEC,QAAS,IAAMf,EAAS,UAAUsB,EAAK,EAAE,EAAE,EAC3C,UAAU,kFAEV,SAAA,CAAAP,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,gCACb,SAAA,CAAAD,MAAC,OAAI,UAAU,SAAU,SAAAE,EAAcM,EAAK,MAAM,EAAE,EACpDP,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAD,EAAAA,IAAC,KAAA,CAAG,UAAU,6CACX,SAAAQ,EAAK,MACR,EACAP,EAAAA,KAAC,IAAA,CAAE,UAAU,kCACV,SAAA,CAAAO,EAAK,GAAG,MAAM,EAAG,EAAE,EAAE,KAAA,CAAA,CACxB,CAAA,CAAA,CACF,CAAA,EACF,EACAR,MAAC,QAAK,UAAWS,EACf,oEACAD,EAAK,SAAW,aAAe,8BAC/BA,EAAK,SAAW,UAAY,4BAC5BA,EAAK,SAAW,aAAe,2BAAA,EAE9B,WAAK,MAAA,CACR,CAAA,EACF,EAEAP,EAAAA,KAAC,MAAA,CAAI,UAAU,gDACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,iCACd,SAAA,CAAAD,EAAAA,IAACM,EAAA,CAAS,UAAU,SAAA,CAAU,EAC7BE,EAAK,YAAY,MAAA,EACpB,EACAP,EAAAA,KAAC,OAAA,CAAK,UAAU,iCACd,SAAA,CAAAD,EAAAA,IAACU,EAAA,CAAM,UAAU,SAAA,CAAU,EAC1BF,EAAK,WACFG,EAAoBC,EAASJ,EAAK,UAAU,EAAG,CAC7C,UAAW,GACX,OAAQK,CAAA,CACT,EACD,GAAA,CAAA,CACN,CAAA,CAAA,CACF,CAAA,CAAA,EAxCKL,EAAK,EAAA,CA0Cb,EACAb,EAAc,SAAW,GACxBK,EAAAA,IAAC,OAAI,UAAU,4DACZ,SAAAZ,EAAS,QAAU,QAAA,CACtB,CAAA,CAAA,CAEJ,CAAA,EACF,CAEJ"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
function a(n,t){const e=JSON.stringify(t,null,2),o=new Blob([e],{type:"application/json"});c(n,o)}function l(n,t){if(!t||t.length===0){a(n.replace(/\.csv$/,".json"),t);return}const e=Object.keys(t[0]),o=[e.join(","),...t.map(s=>e.map(r=>d(s[r])).join(","))].join(`
|
|
2
|
+
`),i=new Blob(["\uFEFF"+o],{type:"text/csv;charset=utf-8"});c(n,i)}function d(n){if(n==null)return"";const t=typeof n=="object"?JSON.stringify(n):String(n);return t.includes(",")||t.includes('"')||t.includes(`
|
|
3
|
+
`)?`"${t.replace(/"/g,'""')}"`:t}function c(n,t){const e=URL.createObjectURL(t),o=document.createElement("a");o.href=e,o.download=n,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(e)}function u(){const n=new Date,t=e=>String(e).padStart(2,"0");return`${n.getFullYear()}${t(n.getMonth()+1)}${t(n.getDate())}-${t(n.getHours())}${t(n.getMinutes())}${t(n.getSeconds())}`}export{l as a,a as d,u as g};
|
|
4
|
+
//# sourceMappingURL=export-L_VBD2p1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-L_VBD2p1.js","sources":["../../src/utils/export.ts"],"sourcesContent":["/**\n * 导出工具函数:JSON / CSV\n */\n\nexport function downloadJSON(filename: string, data: unknown): void {\n const content = JSON.stringify(data, null, 2)\n const blob = new Blob([content], { type: 'application/json' })\n triggerDownload(filename, blob)\n}\n\nexport function downloadCSV<T extends object>(filename: string, rows: T[]): void {\n if (!rows || rows.length === 0) {\n downloadJSON(filename.replace(/\\.csv$/, '.json'), rows)\n return\n }\n\n const headers = Object.keys(rows[0]) as (keyof T & string)[]\n const csv = [\n headers.join(','),\n ...rows.map(row =>\n headers.map(h => escapeCSV(row[h])).join(',')\n ),\n ].join('\\n')\n\n // 添加 BOM 让 Excel 识别 UTF-8\n const blob = new Blob(['' + csv], { type: 'text/csv;charset=utf-8' })\n triggerDownload(filename, blob)\n}\n\nfunction escapeCSV(value: unknown): string {\n if (value === null || value === undefined) return ''\n const str = typeof value === 'object' ? JSON.stringify(value) : String(value)\n if (str.includes(',') || str.includes('\"') || str.includes('\\n')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`\n }\n return str\n}\n\nfunction triggerDownload(filename: string, blob: Blob): void {\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = filename\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(url)\n}\n\nexport function getTimestamp(): string {\n const now = new Date()\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`\n}\n"],"names":["downloadJSON","filename","data","content","blob","triggerDownload","downloadCSV","rows","headers","csv","row","h","escapeCSV","value","str","url","a","getTimestamp","now","pad","n"],"mappings":"AAIO,SAASA,EAAaC,EAAkBC,EAAqB,CAClE,MAAMC,EAAU,KAAK,UAAUD,EAAM,KAAM,CAAC,EACtCE,EAAO,IAAI,KAAK,CAACD,CAAO,EAAG,CAAE,KAAM,mBAAoB,EAC7DE,EAAgBJ,EAAUG,CAAI,CAChC,CAEO,SAASE,EAA8BL,EAAkBM,EAAiB,CAC/E,GAAI,CAACA,GAAQA,EAAK,SAAW,EAAG,CAC9BP,EAAaC,EAAS,QAAQ,SAAU,OAAO,EAAGM,CAAI,EACtD,MACF,CAEA,MAAMC,EAAU,OAAO,KAAKD,EAAK,CAAC,CAAC,EAC7BE,EAAM,CACVD,EAAQ,KAAK,GAAG,EAChB,GAAGD,EAAK,IAAIG,GACVF,EAAQ,IAAIG,GAAKC,EAAUF,EAAIC,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAA,CAC9C,EACA,KAAK;AAAA,CAAI,EAGLP,EAAO,IAAI,KAAK,CAAC,SAAMK,CAAG,EAAG,CAAE,KAAM,yBAA0B,EACrEJ,EAAgBJ,EAAUG,CAAI,CAChC,CAEA,SAASQ,EAAUC,EAAwB,CACzC,GAAIA,GAAU,KAA6B,MAAO,GAClD,MAAMC,EAAM,OAAOD,GAAU,SAAW,KAAK,UAAUA,CAAK,EAAI,OAAOA,CAAK,EAC5E,OAAIC,EAAI,SAAS,GAAG,GAAKA,EAAI,SAAS,GAAG,GAAKA,EAAI,SAAS;AAAA,CAAI,EACtD,IAAIA,EAAI,QAAQ,KAAM,IAAI,CAAC,IAE7BA,CACT,CAEA,SAAST,EAAgBJ,EAAkBG,EAAkB,CAC3D,MAAMW,EAAM,IAAI,gBAAgBX,CAAI,EAC9BY,EAAI,SAAS,cAAc,GAAG,EACpCA,EAAE,KAAOD,EACTC,EAAE,SAAWf,EACb,SAAS,KAAK,YAAYe,CAAC,EAC3BA,EAAE,MAAA,EACF,SAAS,KAAK,YAAYA,CAAC,EAC3B,IAAI,gBAAgBD,CAAG,CACzB,CAEO,SAASE,GAAuB,CACrC,MAAMC,MAAU,KACVC,EAAOC,GAAc,OAAOA,CAAC,EAAE,SAAS,EAAG,GAAG,EACpD,MAAO,GAAGF,EAAI,YAAA,CAAa,GAAGC,EAAID,EAAI,SAAA,EAAa,CAAC,CAAC,GAAGC,EAAID,EAAI,SAAS,CAAC,IAAIC,EAAID,EAAI,SAAA,CAAU,CAAC,GAAGC,EAAID,EAAI,WAAA,CAAY,CAAC,GAAGC,EAAID,EAAI,WAAA,CAAY,CAAC,EACnJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.invisible{visibility:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.bottom-2{bottom:.5rem}.left-0{left:0}.left-2\.5{left:.625rem}.left-\[19px\]{left:19px}.right-0{right:0}.right-2{right:.5rem}.right-4{right:1rem}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:.5rem}.top-4{top:1rem}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[9999\]{z-index:9999}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.-ml-px{margin-left:-1px}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.ml-3{margin-left:.75rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-3{margin-right:.75rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.block{display:block}.\!inline{display:inline!important}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-\[100px\]{height:100px}.h-\[120px\]{height:120px}.h-\[240px\]{height:240px}.h-full{height:100%}.max-h-40{max-height:10rem}.max-h-60{max-height:15rem}.max-h-64{max-height:16rem}.max-h-\[500px\]{max-height:500px}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-\[600px\]{width:600px}.w-\[800px\]{width:800px}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-7xl{max-width:80rem}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-full{--tw-translate-x: 100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity, 1))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-500{--tw-border-opacity: 1;border-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.border-blue-100{--tw-border-opacity: 1;border-color:rgb(219 234 254 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-400{--tw-border-opacity: 1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.border-emerald-200{--tw-border-opacity: 1;border-color:rgb(167 243 208 / var(--tw-border-opacity, 1))}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-indigo-600{--tw-border-opacity: 1;border-color:rgb(79 70 229 / var(--tw-border-opacity, 1))}.border-purple-100{--tw-border-opacity: 1;border-color:rgb(243 232 255 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-yellow-200{--tw-border-opacity: 1;border-color:rgb(254 240 138 / var(--tw-border-opacity, 1))}.border-t-blue-500{--tw-border-opacity: 1;border-top-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-50\/30{background-color:#fffbeb4d}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-50\/30{background-color:#eff6ff4d}.bg-emerald-50{--tw-bg-opacity: 1;background-color:rgb(236 253 245 / var(--tw-bg-opacity, 1))}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-indigo-100{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.bg-indigo-50{--tw-bg-opacity: 1;background-color:rgb(238 242 255 / var(--tw-bg-opacity, 1))}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-purple-50{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-50\/30{background-color:#fef2f24d}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-100{--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1))}.bg-yellow-600{--tw-bg-opacity: 1;background-color:rgb(202 138 4 / var(--tw-bg-opacity, 1))}.bg-opacity-0{--tw-bg-opacity: 0}.bg-opacity-50{--tw-bg-opacity: .5}.bg-opacity-75{--tw-bg-opacity: .75}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-indigo-500{--tw-gradient-from: #6366f1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(99 102 241 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-purple-600{--tw-gradient-to: #9333ea var(--tw-gradient-to-position)}.p-12{padding:3rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-3{padding-left:.75rem}.pl-8{padding-left:2rem}.pr-10{padding-right:2.5rem}.pr-8{padding-right:2rem}.pt-1{padding-top:.25rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tracking-wider{letter-spacing:.05em}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-cyan-600{--tw-text-opacity: 1;color:rgb(8 145 178 / var(--tw-text-opacity, 1))}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-indigo-600{--tw-text-opacity: 1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-orange-600{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-purple-800{--tw-text-opacity: 1;color:rgb(107 33 168 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.text-rose-600{--tw-text-opacity: 1;color:rgb(225 29 72 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.text-yellow-700{--tw-text-opacity: 1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:root{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,sans-serif;line-height:1.5;font-weight:400;color-scheme:light;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{margin:0;min-height:100vh}.hover\:bg-blue-100:hover{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.hover\:bg-emerald-700:hover{--tw-bg-opacity: 1;background-color:rgb(4 120 87 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-green-50:hover{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.hover\:bg-indigo-700:hover{--tw-bg-opacity: 1;background-color:rgb(67 56 202 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-yellow-700:hover{--tw-bg-opacity: 1;background-color:rgb(161 98 7 / var(--tw-bg-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-indigo-700:hover{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:border-indigo-500:focus{--tw-border-opacity: 1;border-color:rgb(99 102 241 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-indigo-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity, 1))}.disabled\:bg-gray-400:disabled{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.disabled\:bg-gray-50:disabled{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.disabled\:text-gray-400:disabled{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width: 640px){.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width: 1024px){.lg\:fixed{position:fixed}.lg\:inset-y-0{top:0;bottom:0}.lg\:col-span-2{grid-column:span 2 / span 2}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:w-64{width:16rem}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-col{flex-direction:column}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:pl-64{padding-left:16rem}}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Dashboard-D7Bo6Kan.js","assets/react-vendor-CSp-GLFF.js","assets/query-C99w429o.js","assets/react-router-I-HqunH7.js","assets/vendor-CMMjVdZs.js","assets/lucide-fJlPI3H7.js","assets/charts-CLrM0_uM.js","assets/Sessions-Chx9OCLH.js","assets/time-Bxuk0M-C.js","assets/Drawer-BeHRQxUS.js","assets/date-fns-CZ_bHujz.js","assets/SearchInput-BX2KhMkw.js","assets/export-L_VBD2p1.js","assets/syntax-highlighter-44FakypI.js","assets/SessionDetail-Bkr-kC7V.js","assets/Events-K_tCY2ti.js","assets/Skills-O0GT1i7m.js","assets/auth-Bnf8ZcqN.js","assets/AIConfig-BQCAQE9D.js","assets/Tasks-DCgDqvOZ.js","assets/TaskDetail-5SR8zGzv.js","assets/Reports-BJCmBnc_.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{r,j as e,e as b,d as y}from"./react-vendor-CSp-GLFF.js";import{u as v,O as N,L as w,R as _,a as c,N as C,B as k}from"./react-router-I-HqunH7.js";import{Q as T,a as E}from"./query-C99w429o.js";import{_ as m}from"./syntax-highlighter-44FakypI.js";import{d as f}from"./vendor-CMMjVdZs.js";import{X as p,M as O,L as P,a as L,b as S,F as I,A,B as R,C as z,I as D,c as F,d as V,e as B,T as M}from"./lucide-fJlPI3H7.js";(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const t of document.querySelectorAll('link[rel="modulepreload"]'))o(t);new MutationObserver(t=>{for(const n of t)if(n.type==="childList")for(const s of n.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&o(s)}).observe(document,{childList:!0,subtree:!0});function l(t){const n={};return t.integrity&&(n.integrity=t.integrity),t.referrerPolicy&&(n.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?n.credentials="include":t.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function o(t){if(t.ep)return;t.ep=!0;const n=l(t);fetch(t.href,n)}})();const q=[{title:"总览",items:[{name:"仪表盘",href:"/dashboard",icon:P}]},{title:"活动",items:[{name:"会话",href:"/sessions",icon:L},{name:"任务",href:"/tasks",icon:S},{name:"周报",href:"/reports",icon:I},{name:"事件",href:"/events",icon:A}]},{title:"配置",items:[{name:"Skill 管理",href:"/skills",icon:R},{name:"AI 配置",href:"/ai-config",icon:z}]}];function Q(){const i=v(),[a,l]=r.useState(!1),o=t=>e.jsx(e.Fragment,{children:q.map(n=>e.jsxs("div",{className:"mb-4",children:[e.jsx("div",{className:"px-3 py-2 text-xs font-semibold text-gray-400 uppercase tracking-wider",children:n.title}),n.items.map(s=>{const u=s.icon,d=i.pathname===s.href||i.pathname.startsWith(s.href+"/");return e.jsxs(w,{to:s.href,onClick:t,className:f("group flex items-center px-3 py-2 text-sm font-medium rounded-md mb-0.5",d?"bg-indigo-50 text-indigo-600":"text-gray-700 hover:bg-gray-50"),children:[e.jsx(u,{className:f("mr-3 h-4 w-4",d?"text-indigo-600":"text-gray-400")}),s.name]},s.name)})]},n.title))});return e.jsxs("div",{className:"min-h-screen bg-gray-50",children:[e.jsxs("div",{className:f("fixed inset-0 z-40 lg:hidden",a?"block":"hidden"),children:[e.jsx("div",{className:"fixed inset-0 bg-gray-600 bg-opacity-75",onClick:()=>l(!1)}),e.jsxs("div",{className:"fixed inset-y-0 left-0 flex w-64 flex-col bg-white",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-4 border-b",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm",children:"CF"}),e.jsx("h1",{className:"text-base font-bold text-gray-900",children:"Claude Forge"})]}),e.jsx("button",{onClick:()=>l(!1),className:"text-gray-500",children:e.jsx(p,{className:"h-5 w-5"})})]}),e.jsx("nav",{className:"flex-1 overflow-y-auto px-2 py-4",children:o(()=>l(!1))})]})]}),e.jsx("div",{className:"hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col",children:e.jsxs("div",{className:"flex flex-col flex-grow border-r border-gray-200 bg-white",children:[e.jsxs("div",{className:"flex items-center gap-2 px-4 py-4 border-b",children:[e.jsx("div",{className:"w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm",children:"CF"}),e.jsx("h1",{className:"text-base font-bold text-gray-900",children:"Claude Forge"})]}),e.jsx("nav",{className:"flex-1 overflow-y-auto px-2 py-4",children:o()})]})}),e.jsxs("div",{className:"lg:pl-64",children:[e.jsxs("div",{className:"sticky top-0 z-10 flex h-14 flex-shrink-0 bg-white border-b border-gray-200 lg:hidden",children:[e.jsx("button",{onClick:()=>l(!0),className:"px-4 text-gray-500 focus:outline-none",children:e.jsx(O,{className:"h-5 w-5"})}),e.jsx("div",{className:"flex flex-1 items-center px-4",children:e.jsx("h1",{className:"text-base font-semibold text-gray-900",children:"Claude Forge"})})]}),e.jsx("main",{className:"py-6",children:e.jsx("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8",children:e.jsx(N,{})})})]})]})}const W=r.lazy(()=>m(()=>import("./Dashboard-D7Bo6Kan.js"),__vite__mapDeps([0,1,2,3,4,5,6]))),X=r.lazy(()=>m(()=>import("./Sessions-Chx9OCLH.js"),__vite__mapDeps([7,1,2,8,9,4,5,10,11,12,3,13]))),$=r.lazy(()=>m(()=>import("./SessionDetail-Bkr-kC7V.js"),__vite__mapDeps([14,1,3,4,2,8,5,10]))),K=r.lazy(()=>m(()=>import("./Events-K_tCY2ti.js"),__vite__mapDeps([15,1,2,8,4,9,5,13,11,12,10,3]))),G=r.lazy(()=>m(()=>import("./Skills-O0GT1i7m.js"),__vite__mapDeps([16,1,2,9,4,5,13,17,3]))),H=r.lazy(()=>m(()=>import("./AIConfig-BQCAQE9D.js"),__vite__mapDeps([18,1,2,17,5,3,4,13]))),J=r.lazy(()=>m(()=>import("./Tasks-DCgDqvOZ.js"),__vite__mapDeps([19,1,2,8,11,5,4,3,10]))),U=r.lazy(()=>m(()=>import("./TaskDetail-5SR8zGzv.js"),__vite__mapDeps([20,1,3,4,2,8,5,10]))),Y=r.lazy(()=>m(()=>import("./Reports-BJCmBnc_.js"),__vite__mapDeps([21,1,2,5,6,4])));function x(){return e.jsx("div",{className:"flex items-center justify-center h-full py-16",children:e.jsxs("div",{className:"flex items-center gap-3 text-sm text-gray-500",children:[e.jsx("div",{className:"w-4 h-4 border-2 border-gray-300 border-t-blue-500 rounded-full animate-spin"}),"加载中..."]})})}function Z(){return e.jsx(_,{children:e.jsxs(c,{path:"/",element:e.jsx(Q,{}),children:[e.jsx(c,{index:!0,element:e.jsx(C,{to:"/dashboard",replace:!0})}),e.jsx(c,{path:"dashboard",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx(W,{})})}),e.jsx(c,{path:"sessions",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx(X,{})})}),e.jsx(c,{path:"sessions/:id",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx($,{})})}),e.jsx(c,{path:"events",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx(K,{})})}),e.jsx(c,{path:"skills",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx(G,{})})}),e.jsx(c,{path:"ai-config",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx(H,{})})}),e.jsx(c,{path:"tasks",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx(J,{})})}),e.jsx(c,{path:"tasks/:taskId",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx(U,{})})}),e.jsx(c,{path:"reports",element:e.jsx(r.Suspense,{fallback:e.jsx(x,{}),children:e.jsx(Y,{})})})]})})}const g=r.createContext(null);function me(){const i=r.useContext(g);if(!i)throw new Error("useToast must be used within ToastProvider");return i}let ee=1;function se({children:i}){const[a,l]=r.useState([]),o=r.useCallback(s=>{l(u=>u.filter(d=>d.id!==s))},[]),t=r.useCallback((s,u)=>{const d=ee++;l(h=>[...h,{id:d,type:s,message:u}]),setTimeout(()=>o(d),4e3)},[o]),n={show:t,success:s=>t("success",s),error:s=>t("error",s),warning:s=>t("warning",s),info:s=>t("info",s)};return e.jsxs(g.Provider,{value:n,children:[i,e.jsx("div",{className:"fixed top-4 right-4 z-[9999] space-y-2 max-w-md",children:a.map(s=>e.jsx(te,{toast:s,onClose:()=>o(s.id)},s.id))})]})}function te({toast:i,onClose:a}){const l={success:e.jsx(B,{className:"h-5 w-5 text-green-500"}),error:e.jsx(V,{className:"h-5 w-5 text-red-500"}),warning:e.jsx(F,{className:"h-5 w-5 text-yellow-500"}),info:e.jsx(D,{className:"h-5 w-5 text-blue-500"})},o={success:"border-green-200",error:"border-red-200",warning:"border-yellow-200",info:"border-blue-200"};return e.jsxs("div",{className:f("bg-white shadow-lg rounded-lg border px-4 py-3 flex items-start gap-3 animate-in slide-in-from-right",o[i.type]),children:[l[i.type],e.jsx("div",{className:"flex-1 text-sm text-gray-800",children:i.message}),e.jsx("button",{onClick:a,className:"text-gray-400 hover:text-gray-600",children:e.jsx(p,{className:"h-4 w-4"})})]})}const re=r.createContext(null);function ne({children:i}){var d;const[a,l]=r.useState({open:!1,options:null,resolve:null}),o=r.useCallback(h=>new Promise(j=>{l({open:!0,options:h,resolve:j})}),[]),t=h=>{a.resolve&&a.resolve(h),l({open:!1,options:null,resolve:null})},n=((d=a.options)==null?void 0:d.variant)||"danger",s={danger:"text-red-600",warning:"text-yellow-600",info:"text-blue-600"}[n],u={danger:"bg-red-600 hover:bg-red-700",warning:"bg-yellow-600 hover:bg-yellow-700",info:"bg-indigo-600 hover:bg-indigo-700"}[n];return e.jsxs(re.Provider,{value:{confirm:o},children:[i,a.open&&a.options&&e.jsxs("div",{className:"fixed inset-0 z-[9999] flex items-center justify-center",children:[e.jsx("div",{className:"absolute inset-0 bg-black bg-opacity-50",onClick:()=>t(!1)}),e.jsxs("div",{className:"relative bg-white rounded-lg shadow-xl max-w-md w-full mx-4 p-6",children:[e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:`flex-shrink-0 ${s}`,children:e.jsx(M,{className:"h-6 w-6"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 mb-2",children:a.options.title}),e.jsx("p",{className:"text-sm text-gray-600 whitespace-pre-wrap",children:a.options.message})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[e.jsx("button",{onClick:()=>t(!1),className:"px-4 py-2 text-sm text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50",children:a.options.cancelText||"取消"}),e.jsx("button",{onClick:()=>t(!0),className:`px-4 py-2 text-sm text-white rounded ${u}`,children:a.options.confirmText||"确定"})]})]})]})]})}const ae=new T({defaultOptions:{queries:{refetchOnWindowFocus:!1,retry:1}}});b.createRoot(document.getElementById("root")).render(e.jsx(y.StrictMode,{children:e.jsx(E,{client:ae,children:e.jsx(se,{children:e.jsx(ne,{children:e.jsx(k,{children:e.jsx(Z,{})})})})})}));export{me as u};
|
|
3
|
+
//# sourceMappingURL=index-DxIbmNmr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"mappings":"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","names":["sections","LayoutDashboard","MessageSquare","ListTodo","FileText","Activity","BookOpen","Cpu","Layout","location","useLocation","sidebarOpen","setSidebarOpen","useState","renderNav","onClick","jsx","Fragment","section","jsxs","item","Icon","isActive","Link","clsx","X","Menu","Outlet","Dashboard","lazy","Sessions","SessionDetail","Events","Skills","AIConfig","Tasks","TaskDetail","Reports","PageFallback","App","Routes","Route","Navigate","Suspense","ToastContext","createContext","useToast","ctx","useContext","nextId","ToastProvider","children","toasts","setToasts","remove","useCallback","id","prev","t","show","type","message","value","msg","ToastItem","toast","onClose","icons","CheckCircle","XCircle","AlertCircle","Info","borderColors","ConfirmContext","ConfirmProvider","state","setState","confirm","options","resolve","handleClose","result","variant","_a","iconColor","btnColor","AlertTriangle","queryClient","QueryClient","ReactDOM","React","QueryClientProvider","BrowserRouter"],"ignoreList":[],"sources":["../../src/components/Layout.tsx","../../src/App.tsx","../../src/components/Toast.tsx","../../src/components/Confirm.tsx","../../src/main.tsx"],"sourcesContent":["import { Outlet, Link, useLocation } from 'react-router-dom'\nimport {\n LayoutDashboard,\n MessageSquare,\n Activity,\n Menu,\n X,\n BookOpen,\n Cpu,\n ListTodo,\n FileText,\n} from 'lucide-react'\nimport { useState } from 'react'\nimport clsx from 'clsx'\n\ninterface NavItem {\n name: string\n href: string\n icon: any\n}\n\ninterface NavSection {\n title: string\n items: NavItem[]\n}\n\nconst sections: NavSection[] = [\n {\n title: '总览',\n items: [\n { name: '仪表盘', href: '/dashboard', icon: LayoutDashboard },\n ],\n },\n {\n title: '活动',\n items: [\n { name: '会话', href: '/sessions', icon: MessageSquare },\n { name: '任务', href: '/tasks', icon: ListTodo },\n { name: '周报', href: '/reports', icon: FileText },\n { name: '事件', href: '/events', icon: Activity },\n ],\n },\n {\n title: '配置',\n items: [\n { name: 'Skill 管理', href: '/skills', icon: BookOpen },\n { name: 'AI 配置', href: '/ai-config', icon: Cpu },\n ],\n },\n]\n\nexport default function Layout() {\n const location = useLocation()\n const [sidebarOpen, setSidebarOpen] = useState(false)\n\n const renderNav = (onClick?: () => void) => (\n <>\n {sections.map((section) => (\n <div key={section.title} className=\"mb-4\">\n <div className=\"px-3 py-2 text-xs font-semibold text-gray-400 uppercase tracking-wider\">\n {section.title}\n </div>\n {section.items.map((item) => {\n const Icon = item.icon\n const isActive = location.pathname === item.href || location.pathname.startsWith(item.href + '/')\n return (\n <Link\n key={item.name}\n to={item.href}\n onClick={onClick}\n className={clsx(\n 'group flex items-center px-3 py-2 text-sm font-medium rounded-md mb-0.5',\n isActive\n ? 'bg-indigo-50 text-indigo-600'\n : 'text-gray-700 hover:bg-gray-50'\n )}\n >\n <Icon className={clsx('mr-3 h-4 w-4', isActive ? 'text-indigo-600' : 'text-gray-400')} />\n {item.name}\n </Link>\n )\n })}\n </div>\n ))}\n </>\n )\n\n return (\n <div className=\"min-h-screen bg-gray-50\">\n {/* Mobile sidebar */}\n <div className={clsx('fixed inset-0 z-40 lg:hidden', sidebarOpen ? 'block' : 'hidden')}>\n <div className=\"fixed inset-0 bg-gray-600 bg-opacity-75\" onClick={() => setSidebarOpen(false)} />\n <div className=\"fixed inset-y-0 left-0 flex w-64 flex-col bg-white\">\n <div className=\"flex items-center justify-between px-4 py-4 border-b\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm\">\n CF\n </div>\n <h1 className=\"text-base font-bold text-gray-900\">Claude Forge</h1>\n </div>\n <button onClick={() => setSidebarOpen(false)} className=\"text-gray-500\">\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n <nav className=\"flex-1 overflow-y-auto px-2 py-4\">\n {renderNav(() => setSidebarOpen(false))}\n </nav>\n </div>\n </div>\n\n {/* Desktop sidebar */}\n <div className=\"hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col\">\n <div className=\"flex flex-col flex-grow border-r border-gray-200 bg-white\">\n <div className=\"flex items-center gap-2 px-4 py-4 border-b\">\n <div className=\"w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm\">\n CF\n </div>\n <h1 className=\"text-base font-bold text-gray-900\">Claude Forge</h1>\n </div>\n <nav className=\"flex-1 overflow-y-auto px-2 py-4\">{renderNav()}</nav>\n </div>\n </div>\n\n {/* Main content */}\n <div className=\"lg:pl-64\">\n <div className=\"sticky top-0 z-10 flex h-14 flex-shrink-0 bg-white border-b border-gray-200 lg:hidden\">\n <button\n onClick={() => setSidebarOpen(true)}\n className=\"px-4 text-gray-500 focus:outline-none\"\n >\n <Menu className=\"h-5 w-5\" />\n </button>\n <div className=\"flex flex-1 items-center px-4\">\n <h1 className=\"text-base font-semibold text-gray-900\">Claude Forge</h1>\n </div>\n </div>\n <main className=\"py-6\">\n <div className=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n <Outlet />\n </div>\n </main>\n </div>\n </div>\n )\n}\n","import { lazy, Suspense } from 'react'\nimport { Routes, Route, Navigate } from 'react-router-dom'\nimport Layout from './components/Layout'\n\n// 路由级代码分割:按需加载 page 组件,缩小主 bundle\nconst Dashboard = lazy(() => import('./pages/Dashboard'))\nconst Sessions = lazy(() => import('./pages/Sessions'))\nconst SessionDetail = lazy(() => import('./pages/SessionDetail'))\nconst Events = lazy(() => import('./pages/Events'))\nconst Skills = lazy(() => import('./pages/Skills'))\nconst AIConfig = lazy(() => import('./pages/AIConfig'))\nconst Tasks = lazy(() => import('./pages/Tasks'))\nconst TaskDetail = lazy(() => import('./pages/TaskDetail'))\nconst Reports = lazy(() => import('./pages/Reports'))\n\nfunction PageFallback() {\n return (\n <div className=\"flex items-center justify-center h-full py-16\">\n <div className=\"flex items-center gap-3 text-sm text-gray-500\">\n <div className=\"w-4 h-4 border-2 border-gray-300 border-t-blue-500 rounded-full animate-spin\" />\n 加载中...\n </div>\n </div>\n )\n}\n\nexport default function App() {\n return (\n <Routes>\n <Route path=\"/\" element={<Layout />}>\n <Route\n index\n element={<Navigate to=\"/dashboard\" replace />}\n />\n <Route\n path=\"dashboard\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Dashboard />\n </Suspense>\n }\n />\n <Route\n path=\"sessions\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Sessions />\n </Suspense>\n }\n />\n <Route\n path=\"sessions/:id\"\n element={\n <Suspense fallback={<PageFallback />}>\n <SessionDetail />\n </Suspense>\n }\n />\n <Route\n path=\"events\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Events />\n </Suspense>\n }\n />\n <Route\n path=\"skills\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Skills />\n </Suspense>\n }\n />\n <Route\n path=\"ai-config\"\n element={\n <Suspense fallback={<PageFallback />}>\n <AIConfig />\n </Suspense>\n }\n />\n <Route\n path=\"tasks\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Tasks />\n </Suspense>\n }\n />\n <Route\n path=\"tasks/:taskId\"\n element={\n <Suspense fallback={<PageFallback />}>\n <TaskDetail />\n </Suspense>\n }\n />\n <Route\n path=\"reports\"\n element={\n <Suspense fallback={<PageFallback />}>\n <Reports />\n </Suspense>\n }\n />\n </Route>\n </Routes>\n )\n}\n","import { createContext, useContext, useState, useCallback, ReactNode } from 'react'\nimport { CheckCircle, XCircle, AlertCircle, Info, X } from 'lucide-react'\nimport clsx from 'clsx'\n\ntype ToastType = 'success' | 'error' | 'warning' | 'info'\n\ninterface Toast {\n id: number\n type: ToastType\n message: string\n}\n\ninterface ToastContextValue {\n show: (type: ToastType, message: string) => void\n success: (message: string) => void\n error: (message: string) => void\n warning: (message: string) => void\n info: (message: string) => void\n}\n\nconst ToastContext = createContext<ToastContextValue | null>(null)\n\nexport function useToast() {\n const ctx = useContext(ToastContext)\n if (!ctx) throw new Error('useToast must be used within ToastProvider')\n return ctx\n}\n\nlet nextId = 1\n\nexport function ToastProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<Toast[]>([])\n\n const remove = useCallback((id: number) => {\n setToasts(prev => prev.filter(t => t.id !== id))\n }, [])\n\n const show = useCallback((type: ToastType, message: string) => {\n const id = nextId++\n setToasts(prev => [...prev, { id, type, message }])\n setTimeout(() => remove(id), 4000)\n }, [remove])\n\n const value: ToastContextValue = {\n show,\n success: (msg) => show('success', msg),\n error: (msg) => show('error', msg),\n warning: (msg) => show('warning', msg),\n info: (msg) => show('info', msg),\n }\n\n return (\n <ToastContext.Provider value={value}>\n {children}\n <div className=\"fixed top-4 right-4 z-[9999] space-y-2 max-w-md\">\n {toasts.map(t => (\n <ToastItem key={t.id} toast={t} onClose={() => remove(t.id)} />\n ))}\n </div>\n </ToastContext.Provider>\n )\n}\n\nfunction ToastItem({ toast, onClose }: { toast: Toast; onClose: () => void }) {\n const icons = {\n success: <CheckCircle className=\"h-5 w-5 text-green-500\" />,\n error: <XCircle className=\"h-5 w-5 text-red-500\" />,\n warning: <AlertCircle className=\"h-5 w-5 text-yellow-500\" />,\n info: <Info className=\"h-5 w-5 text-blue-500\" />,\n }\n const borderColors = {\n success: 'border-green-200',\n error: 'border-red-200',\n warning: 'border-yellow-200',\n info: 'border-blue-200',\n }\n\n return (\n <div\n className={clsx(\n 'bg-white shadow-lg rounded-lg border px-4 py-3 flex items-start gap-3 animate-in slide-in-from-right',\n borderColors[toast.type]\n )}\n >\n {icons[toast.type]}\n <div className=\"flex-1 text-sm text-gray-800\">{toast.message}</div>\n <button onClick={onClose} className=\"text-gray-400 hover:text-gray-600\">\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n )\n}\n","import { createContext, useContext, useState, useCallback, ReactNode } from 'react'\nimport { AlertTriangle } from 'lucide-react'\n\ninterface ConfirmOptions {\n title: string\n message: string\n confirmText?: string\n cancelText?: string\n variant?: 'danger' | 'warning' | 'info'\n}\n\ninterface ConfirmContextValue {\n confirm: (options: ConfirmOptions) => Promise<boolean>\n}\n\nconst ConfirmContext = createContext<ConfirmContextValue | null>(null)\n\nexport function useConfirm() {\n const ctx = useContext(ConfirmContext)\n if (!ctx) throw new Error('useConfirm must be used within ConfirmProvider')\n return ctx.confirm\n}\n\nexport function ConfirmProvider({ children }: { children: ReactNode }) {\n const [state, setState] = useState<{\n open: boolean\n options: ConfirmOptions | null\n resolve: ((value: boolean) => void) | null\n }>({ open: false, options: null, resolve: null })\n\n const confirm = useCallback((options: ConfirmOptions): Promise<boolean> => {\n return new Promise((resolve) => {\n setState({ open: true, options, resolve })\n })\n }, [])\n\n const handleClose = (result: boolean) => {\n if (state.resolve) state.resolve(result)\n setState({ open: false, options: null, resolve: null })\n }\n\n const variant = state.options?.variant || 'danger'\n const iconColor = {\n danger: 'text-red-600',\n warning: 'text-yellow-600',\n info: 'text-blue-600',\n }[variant]\n const btnColor = {\n danger: 'bg-red-600 hover:bg-red-700',\n warning: 'bg-yellow-600 hover:bg-yellow-700',\n info: 'bg-indigo-600 hover:bg-indigo-700',\n }[variant]\n\n return (\n <ConfirmContext.Provider value={{ confirm }}>\n {children}\n {state.open && state.options && (\n <div className=\"fixed inset-0 z-[9999] flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black bg-opacity-50\"\n onClick={() => handleClose(false)}\n />\n <div className=\"relative bg-white rounded-lg shadow-xl max-w-md w-full mx-4 p-6\">\n <div className=\"flex items-start gap-4\">\n <div className={`flex-shrink-0 ${iconColor}`}>\n <AlertTriangle className=\"h-6 w-6\" />\n </div>\n <div className=\"flex-1\">\n <h3 className=\"text-lg font-semibold text-gray-900 mb-2\">\n {state.options.title}\n </h3>\n <p className=\"text-sm text-gray-600 whitespace-pre-wrap\">\n {state.options.message}\n </p>\n </div>\n </div>\n <div className=\"flex justify-end gap-2 mt-6\">\n <button\n onClick={() => handleClose(false)}\n className=\"px-4 py-2 text-sm text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50\"\n >\n {state.options.cancelText || '取消'}\n </button>\n <button\n onClick={() => handleClose(true)}\n className={`px-4 py-2 text-sm text-white rounded ${btnColor}`}\n >\n {state.options.confirmText || '确定'}\n </button>\n </div>\n </div>\n </div>\n )}\n </ConfirmContext.Provider>\n )\n}\n","import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport { BrowserRouter } from 'react-router-dom'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport App from './App'\nimport { ToastProvider } from './components/Toast'\nimport { ConfirmProvider } from './components/Confirm'\nimport './index.css'\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n retry: 1,\n },\n },\n})\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n <React.StrictMode>\n <QueryClientProvider client={queryClient}>\n <ToastProvider>\n <ConfirmProvider>\n <BrowserRouter>\n <App />\n </BrowserRouter>\n </ConfirmProvider>\n </ToastProvider>\n </QueryClientProvider>\n </React.StrictMode>,\n)\n"],"file":"assets/index-DxIbmNmr.js"}
|