claude-code-workflow 7.2.10 → 7.2.11
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/agents/cli-planning-agent.md +3 -0
- package/.claude/agents/debug-explore-agent.md +1 -0
- package/.claude/agents/tdd-developer.md +1 -0
- package/.claude/agents/team-worker.md +1 -1
- package/.claude/agents/test-action-planning-agent.md +3 -0
- package/.claude/agents/test-context-search-agent.md +1 -0
- package/.claude/agents/test-fix-agent.md +3 -0
- package/.claude/skills/review-code/SKILL.md +2 -0
- package/.claude/skills/review-cycle/SKILL.md +4 -0
- package/.claude/skills/skill-simplify/phases/02-optimize.md +4 -0
- package/.claude/skills/spec-generator/phases/05-epics-stories.md +4 -0
- package/.claude/skills/team-arch-opt/specs/team-config.json +5 -5
- package/.claude/skills/team-frontend-debug/roles/analyzer/role.md +3 -2
- package/.claude/skills/team-perf-opt/roles/coordinator/commands/monitor.md +1 -1
- package/.claude/skills/team-perf-opt/specs/team-config.json +5 -5
- package/.claude/skills/team-quality-assurance/roles/executor/role.md +2 -1
- package/.claude/skills/team-review/roles/reviewer/role.md +2 -1
- package/.claude/skills/team-tech-debt/roles/scanner/role.md +2 -1
- package/.claude/skills/team-testing/roles/executor/role.md +2 -1
- package/.claude/skills/team-testing/roles/generator/role.md +2 -1
- package/.claude/skills/team-ultra-analyze/roles/explorer/role.md +2 -1
- package/.claude/skills/team-ux-improve/specs/team-config.json +6 -6
- package/.claude/skills/workflow-execute/phases/06-review.md +4 -4
- package/.claude/skills/workflow-lite-test-review/SKILL.md +2 -0
- package/.claude/skills/workflow-plan/phases/05-plan-verify.md +4 -0
- package/.claude/skills/workflow-tdd-plan/phases/02-context-gathering.md +1 -0
- package/.claude/skills/workflow-tdd-plan/phases/05-tdd-task-generation.md +2 -1
- package/.claude/skills/workflow-test-fix/phases/02-test-context-gather.md +1 -0
- package/.claude/skills/workflow-test-fix/phases/05-test-cycle-execute.md +2 -1
- package/.claude/skills/workflow-tune/SKILL.md +487 -0
- package/.claude/skills/workflow-tune/phases/01-setup.md +548 -0
- package/.claude/skills/workflow-tune/phases/02-step-execute.md +197 -0
- package/.claude/skills/workflow-tune/phases/03-step-analyze.md +386 -0
- package/.claude/skills/workflow-tune/phases/04-synthesize.md +257 -0
- package/.claude/skills/workflow-tune/phases/05-optimize-report.md +246 -0
- package/.claude/skills/workflow-tune/specs/workflow-eval-criteria.md +57 -0
- package/.claude/skills/workflow-tune/templates/step-analysis-prompt.md +88 -0
- package/.claude/skills/workflow-tune/templates/synthesis-prompt.md +90 -0
- package/.codex/skills/analyze-with-file/SKILL.md +2 -0
- package/.codex/skills/debug-with-file/SKILL.md +4 -0
- package/.codex/skills/issue-discover/SKILL.md +1 -0
- package/.codex/skills/review-cycle/phases/02-parallel-review.md +3 -0
- package/.codex/skills/team-designer/agents/validation-reporter.md +186 -0
- package/.codex/skills/team-iterdev/agents/gc-controller.md +193 -0
- package/.codex/skills/team-iterdev/agents/task-analyzer.md +206 -0
- package/.codex/skills/team-lifecycle-v4/agents/quality-gate.md +165 -0
- package/.codex/skills/team-lifecycle-v4/agents/requirement-clarifier.md +163 -0
- package/.codex/skills/team-lifecycle-v4/agents/supervisor.md +182 -0
- package/.codex/skills/team-uidesign/agents/completion-handler.md +177 -0
- package/.codex/skills/team-uidesign/agents/gc-loop-handler.md +162 -0
- package/.codex/skills/workflow-test-fix-cycle/phases/01-test-fix-gen.md +4 -0
- package/.codex/skills/workflow-test-fix-cycle/phases/02-test-cycle-execute.md +2 -0
- package/ccw/dist/commands/spec.d.ts.map +1 -1
- package/ccw/dist/commands/spec.js +9 -4
- package/ccw/dist/commands/spec.js.map +1 -1
- package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens-routes.js +3 -1
- package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
- package/ccw/dist/tools/spec-index-builder.d.ts +8 -4
- package/ccw/dist/tools/spec-index-builder.d.ts.map +1 -1
- package/ccw/dist/tools/spec-index-builder.js +8 -4
- package/ccw/dist/tools/spec-index-builder.js.map +1 -1
- package/ccw/dist/tools/spec-init.d.ts +1 -1
- package/ccw/dist/tools/spec-init.d.ts.map +1 -1
- package/ccw/dist/tools/spec-init.js +127 -0
- package/ccw/dist/tools/spec-init.js.map +1 -1
- package/ccw/dist/tools/spec-loader.d.ts.map +1 -1
- package/ccw/dist/tools/spec-loader.js +2 -1
- package/ccw/dist/tools/spec-loader.js.map +1 -1
- package/ccw/frontend/dist/assets/{AlertDialog-gTMl4gSG.js → AlertDialog-BW9jiZ-p.js} +2 -2
- package/ccw/frontend/dist/assets/{AlertDialog-gTMl4gSG.js.map → AlertDialog-BW9jiZ-p.js.map} +1 -1
- package/ccw/frontend/dist/assets/{AnalysisPage-Bc4p4SvJ.js → AnalysisPage-ds-w_nVO.js} +2 -2
- package/ccw/frontend/dist/assets/{AnalysisPage-Bc4p4SvJ.js.map → AnalysisPage-ds-w_nVO.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ApiSettingsPage-CVK108u2.js → ApiSettingsPage-DlCbXxTz.js} +2 -2
- package/ccw/frontend/dist/assets/{ApiSettingsPage-CVK108u2.js.map → ApiSettingsPage-DlCbXxTz.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliModeToggle-34Sjwl05.js → CliModeToggle-Dq3nL4fF.js} +2 -2
- package/ccw/frontend/dist/assets/{CliModeToggle-34Sjwl05.js.map → CliModeToggle-Dq3nL4fF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliSessionSharePage-bJZAYI38.js → CliSessionSharePage-BNDkEE4u.js} +2 -2
- package/ccw/frontend/dist/assets/{CliSessionSharePage-bJZAYI38.js.map → CliSessionSharePage-BNDkEE4u.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliViewerPage-VYnQGjxU.js → CliViewerPage-ChM-uNx_.js} +2 -2
- package/ccw/frontend/dist/assets/{CliViewerPage-VYnQGjxU.js.map → CliViewerPage-ChM-uNx_.js.map} +1 -1
- package/ccw/frontend/dist/assets/CodexLensPage-DOcsYNQk.js +2 -0
- package/ccw/frontend/dist/assets/CodexLensPage-DOcsYNQk.js.map +1 -0
- package/ccw/frontend/dist/assets/{Collapsible-B_xd1Qbg.js → Collapsible-CRNbykXN.js} +2 -2
- package/ccw/frontend/dist/assets/{Collapsible-B_xd1Qbg.js.map → Collapsible-CRNbykXN.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CommandsManagerPage-Bjx1bPbH.js → CommandsManagerPage-C2JWcemF.js} +2 -2
- package/ccw/frontend/dist/assets/{CommandsManagerPage-Bjx1bPbH.js.map → CommandsManagerPage-C2JWcemF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{DeepWikiPage-EgHsHvAH.js → DeepWikiPage-CvleOtJy.js} +2 -2
- package/ccw/frontend/dist/assets/{DeepWikiPage-EgHsHvAH.js.map → DeepWikiPage-CvleOtJy.js.map} +1 -1
- package/ccw/frontend/dist/assets/{EndpointsPage-CuwpbCzK.js → EndpointsPage-CMOWQG64.js} +2 -2
- package/ccw/frontend/dist/assets/{EndpointsPage-CuwpbCzK.js.map → EndpointsPage-CMOWQG64.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ExplorerPage-cvlx0Zw0.js → ExplorerPage-DaFPRlNo.js} +2 -2
- package/ccw/frontend/dist/assets/{ExplorerPage-cvlx0Zw0.js.map → ExplorerPage-DaFPRlNo.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FixSessionPage-C74-MPza.js → FixSessionPage-CC4p04Az.js} +2 -2
- package/ccw/frontend/dist/assets/{FixSessionPage-C74-MPza.js.map → FixSessionPage-CC4p04Az.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-x_-6y_n2.js → FloatingFileBrowser-DROn1xZ5.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-x_-6y_n2.js.map → FloatingFileBrowser-DROn1xZ5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingPanel-BGwmbJR1.js → FloatingPanel-CmL_yhDv.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingPanel-BGwmbJR1.js.map → FloatingPanel-CmL_yhDv.js.map} +1 -1
- package/ccw/frontend/dist/assets/{GraphExplorerPage-Bg5-aQxi.js → GraphExplorerPage-DCV5ybKE.js} +2 -2
- package/ccw/frontend/dist/assets/{GraphExplorerPage-Bg5-aQxi.js.map → GraphExplorerPage-DCV5ybKE.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HistoryPage-C00fh0HE.js → HistoryPage-D0fYQZgc.js} +2 -2
- package/ccw/frontend/dist/assets/{HistoryPage-C00fh0HE.js.map → HistoryPage-D0fYQZgc.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HookManagerPage-CtVTB_ae.js → HookManagerPage-D2FuJfsM.js} +2 -2
- package/ccw/frontend/dist/assets/{HookManagerPage-CtVTB_ae.js.map → HookManagerPage-D2FuJfsM.js.map} +1 -1
- package/ccw/frontend/dist/assets/{InstallationsPage-CYuMQDbC.js → InstallationsPage-tjklillZ.js} +2 -2
- package/ccw/frontend/dist/assets/{InstallationsPage-CYuMQDbC.js.map → InstallationsPage-tjklillZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{IssueHubPage-T_VSvUMh.js → IssueHubPage-E4JVrhO1.js} +2 -2
- package/ccw/frontend/dist/assets/{IssueHubPage-T_VSvUMh.js.map → IssueHubPage-E4JVrhO1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{LiteTasksPage-DmcgvIvi.js → LiteTasksPage-aJuRoyLt.js} +2 -2
- package/ccw/frontend/dist/assets/{LiteTasksPage-DmcgvIvi.js.map → LiteTasksPage-aJuRoyLt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{McpManagerPage-C_a7QSKz.js → McpManagerPage-BJeuWJv1.js} +2 -2
- package/ccw/frontend/dist/assets/{McpManagerPage-C_a7QSKz.js.map → McpManagerPage-BJeuWJv1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{MemoryPage-CWKmXY5k.js → MemoryPage-BI4FAXhs.js} +2 -2
- package/ccw/frontend/dist/assets/{MemoryPage-CWKmXY5k.js.map → MemoryPage-BI4FAXhs.js.map} +1 -1
- package/ccw/frontend/dist/assets/{NotFoundPage-B1duXK6r.js → NotFoundPage-DD2svchp.js} +2 -2
- package/ccw/frontend/dist/assets/{NotFoundPage-B1duXK6r.js.map → NotFoundPage-DD2svchp.js.map} +1 -1
- package/ccw/frontend/dist/assets/{OrchestratorPage-Ib9TM6HE.js → OrchestratorPage-FC__7yYa.js} +2 -2
- package/ccw/frontend/dist/assets/{OrchestratorPage-Ib9TM6HE.js.map → OrchestratorPage-FC__7yYa.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-sXSWMbF8.js → ProjectOverviewPage-DBB_-FzV.js} +2 -2
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-sXSWMbF8.js.map → ProjectOverviewPage-DBB_-FzV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{PromptHistoryPage-B6jaqG12.js → PromptHistoryPage-BwOAvCH8.js} +2 -2
- package/ccw/frontend/dist/assets/{PromptHistoryPage-B6jaqG12.js.map → PromptHistoryPage-BwOAvCH8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ReviewSessionPage-D5qJyr3s.js → ReviewSessionPage-Dd1-g_gp.js} +2 -2
- package/ccw/frontend/dist/assets/{ReviewSessionPage-D5qJyr3s.js.map → ReviewSessionPage-Dd1-g_gp.js.map} +1 -1
- package/ccw/frontend/dist/assets/{RulesManagerPage-DyawK8QE.js → RulesManagerPage-B3RGdsKD.js} +2 -2
- package/ccw/frontend/dist/assets/{RulesManagerPage-DyawK8QE.js.map → RulesManagerPage-B3RGdsKD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionDetailPage-Cym_RvC9.js → SessionDetailPage-DM-W5R8K.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionDetailPage-Cym_RvC9.js.map → SessionDetailPage-DM-W5R8K.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionsPage-Dkc1Hv8W.js → SessionsPage-BVz1KCc7.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionsPage-Dkc1Hv8W.js.map → SessionsPage-BVz1KCc7.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SettingsPage-Rik9cUIj.js → SettingsPage-ComW7EZS.js} +4 -4
- package/ccw/frontend/dist/assets/{SettingsPage-Rik9cUIj.js.map → SettingsPage-ComW7EZS.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SkillsManagerPage-BGDWYAyI.js → SkillsManagerPage-CKom9XwV.js} +2 -2
- package/ccw/frontend/dist/assets/{SkillsManagerPage-BGDWYAyI.js.map → SkillsManagerPage-CKom9XwV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-CTiA1DMP.js → SpecsSettingsPage-DQz7WP2s.js} +2 -2
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-CTiA1DMP.js.map → SpecsSettingsPage-DQz7WP2s.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Switch-BgAFC-Wk.js → Switch-BPMdND9H.js} +2 -2
- package/ccw/frontend/dist/assets/{Switch-BgAFC-Wk.js.map → Switch-BPMdND9H.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TabsNavigation-drSnu5jn.js → TabsNavigation-qqt70VYL.js} +2 -2
- package/ccw/frontend/dist/assets/{TabsNavigation-drSnu5jn.js.map → TabsNavigation-qqt70VYL.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TaskDrawer-ePC__6-P.js → TaskDrawer-BqK_qiHX.js} +2 -2
- package/ccw/frontend/dist/assets/{TaskDrawer-ePC__6-P.js.map → TaskDrawer-BqK_qiHX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TeamPage-C6bdFWn8.js → TeamPage-u5_i0Rgh.js} +2 -2
- package/ccw/frontend/dist/assets/{TeamPage-C6bdFWn8.js.map → TeamPage-u5_i0Rgh.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-Zofi_DZM.js → TerminalDashboardPage-rUtC9e40.js} +2 -2
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-Zofi_DZM.js.map → TerminalDashboardPage-rUtC9e40.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-Bza1KlB9.js → archive-C3u8YNQF.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-Bza1KlB9.js.map → archive-C3u8YNQF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-restore-CpsDm-cG.js → archive-restore-DfQ998g5.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-restore-CpsDm-cG.js.map → archive-restore-DfQ998g5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{arrow-right-CibG_LVO.js → arrow-right-BshJM9Po.js} +2 -2
- package/ccw/frontend/dist/assets/{arrow-right-CibG_LVO.js.map → arrow-right-BshJM9Po.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bookmark-plus-BheO8EgG.js → bookmark-plus-D03qJyOZ.js} +2 -2
- package/ccw/frontend/dist/assets/{bookmark-plus-BheO8EgG.js.map → bookmark-plus-D03qJyOZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bot-BlhM0Nl0.js → bot-CyzWuwq0.js} +2 -2
- package/ccw/frontend/dist/assets/{bot-BlhM0Nl0.js.map → bot-CyzWuwq0.js.map} +1 -1
- package/ccw/frontend/dist/assets/{braces-Dqjg_eCO.js → braces-BPgtyjsG.js} +2 -2
- package/ccw/frontend/dist/assets/{braces-Dqjg_eCO.js.map → braces-BPgtyjsG.js.map} +1 -1
- package/ccw/frontend/dist/assets/{circle-stop-DYZSLYU0.js → circle-stop-Dix1AOmw.js} +2 -2
- package/ccw/frontend/dist/assets/{circle-stop-DYZSLYU0.js.map → circle-stop-Dix1AOmw.js.map} +1 -1
- package/ccw/frontend/dist/assets/{cpu-DWCyAOAv.js → cpu-CCQ4Q0Zh.js} +2 -2
- package/ccw/frontend/dist/assets/{cpu-DWCyAOAv.js.map → cpu-CCQ4Q0Zh.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ellipsis-vertical-DIyoSEHx.js → ellipsis-vertical-BpTysg-Y.js} +2 -2
- package/ccw/frontend/dist/assets/{ellipsis-vertical-DIyoSEHx.js.map → ellipsis-vertical-BpTysg-Y.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-DUy7aLEx.js → eye-DGY1rAZs.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-DUy7aLEx.js.map → eye-DGY1rAZs.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-off-CGRUVRDR.js → eye-off-D8t3JfWG.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-off-CGRUVRDR.js.map → eye-off-D8t3JfWG.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-json-BxLBtU9d.js → file-json-BAdJb0n8.js} +2 -2
- package/ccw/frontend/dist/assets/{file-json-BxLBtU9d.js.map → file-json-BAdJb0n8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-text-BoHsW2es.js → file-text-DrJFiOUB.js} +2 -2
- package/ccw/frontend/dist/assets/{file-text-BoHsW2es.js.map → file-text-DrJFiOUB.js.map} +1 -1
- package/ccw/frontend/dist/assets/{filter-B4vOqP6B.js → filter-CKqzYbz7.js} +2 -2
- package/ccw/frontend/dist/assets/{filter-B4vOqP6B.js.map → filter-CKqzYbz7.js.map} +1 -1
- package/ccw/frontend/dist/assets/{folder-BKhwCNFG.js → folder-CV8511y9.js} +2 -2
- package/ccw/frontend/dist/assets/{folder-BKhwCNFG.js.map → folder-CV8511y9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{gauge-Dgf64gkT.js → gauge-XKvmu_uU.js} +2 -2
- package/ccw/frontend/dist/assets/{gauge-Dgf64gkT.js.map → gauge-XKvmu_uU.js.map} +1 -1
- package/ccw/frontend/dist/assets/{globe-Cus_S6Ux.js → globe-C56cDUzX.js} +2 -2
- package/ccw/frontend/dist/assets/{globe-Cus_S6Ux.js.map → globe-C56cDUzX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{grid-3x3-DM08hpAN.js → grid-3x3-Bya-suFW.js} +2 -2
- package/ccw/frontend/dist/assets/{grid-3x3-DM08hpAN.js.map → grid-3x3-Bya-suFW.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hard-drive-eCtll84F.js → hard-drive-CmuTZpsB.js} +2 -2
- package/ccw/frontend/dist/assets/{hard-drive-eCtll84F.js.map → hard-drive-CmuTZpsB.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hash-Bd1RD285.js → hash-CRPT_tJQ.js} +2 -2
- package/ccw/frontend/dist/assets/{hash-Bd1RD285.js.map → hash-CRPT_tJQ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{history-eyyCQA6b.js → history-C1pJZQCL.js} +2 -2
- package/ccw/frontend/dist/assets/{history-eyyCQA6b.js.map → history-C1pJZQCL.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-ZnmWxcZg.js → index-B6TpijCe.js} +2 -2
- package/ccw/frontend/dist/assets/{index-ZnmWxcZg.js.map → index-B6TpijCe.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-b2C0iFd1.js → index-Bcq-7r6F.js} +2 -2
- package/ccw/frontend/dist/assets/{index-b2C0iFd1.js.map → index-Bcq-7r6F.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-Cs2ShCCy.js → index-CI8-rBff.js} +2 -2
- package/ccw/frontend/dist/assets/{index-Cs2ShCCy.js.map → index-CI8-rBff.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-CY6Lueph.js → index-Dmt9OiEf.js} +2 -2
- package/ccw/frontend/dist/assets/{index-CY6Lueph.js.map → index-Dmt9OiEf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-DfeBbFXo.js → index-anSMmEF8.js} +2 -2
- package/ccw/frontend/dist/assets/{index-DfeBbFXo.js.map → index-anSMmEF8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-B6I7GQC5.js → index-dWT2M6Ef.js} +4 -4
- package/ccw/frontend/dist/assets/{index-B6I7GQC5.js.map → index-dWT2M6Ef.js.map} +1 -1
- package/ccw/frontend/dist/assets/{layout-grid-ChrTrCby.js → layout-grid-TSO0BFQE.js} +2 -2
- package/ccw/frontend/dist/assets/{layout-grid-ChrTrCby.js.map → layout-grid-TSO0BFQE.js.map} +1 -1
- package/ccw/frontend/dist/assets/{lightbulb-CvXiTlzN.js → lightbulb-Caj6fIQD.js} +2 -2
- package/ccw/frontend/dist/assets/{lightbulb-CvXiTlzN.js.map → lightbulb-Caj6fIQD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-2-W0Nl17ec.js → link-2-DE9lMxa-.js} +2 -2
- package/ccw/frontend/dist/assets/{link-2-W0Nl17ec.js.map → link-2-DE9lMxa-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-CL4JmoHb.js → link-BZtPgLW0.js} +2 -2
- package/ccw/frontend/dist/assets/{link-CL4JmoHb.js.map → link-BZtPgLW0.js.map} +1 -1
- package/ccw/frontend/dist/assets/{list-CDmYFcio.js → list-DubWyY-U.js} +2 -2
- package/ccw/frontend/dist/assets/{list-CDmYFcio.js.map → list-DubWyY-U.js.map} +1 -1
- package/ccw/frontend/dist/assets/{map-pin-0Mfsw_3d.js → map-pin-DwN_48AF.js} +2 -2
- package/ccw/frontend/dist/assets/{map-pin-0Mfsw_3d.js.map → map-pin-DwN_48AF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{messages-square-C6h08ple.js → messages-square-bjxvaiM9.js} +2 -2
- package/ccw/frontend/dist/assets/{messages-square-C6h08ple.js.map → messages-square-bjxvaiM9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{minimize-2-Cbu2yRzi.js → minimize-2-CGfBKD_V.js} +2 -2
- package/ccw/frontend/dist/assets/{minimize-2-Cbu2yRzi.js.map → minimize-2-CGfBKD_V.js.map} +1 -1
- package/ccw/frontend/dist/assets/{package-CoLVUZGJ.js → package-nzWY6ilt.js} +2 -2
- package/ccw/frontend/dist/assets/{package-CoLVUZGJ.js.map → package-nzWY6ilt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{plug-BYTYqsw1.js → plug-CiLce49C.js} +2 -2
- package/ccw/frontend/dist/assets/{plug-BYTYqsw1.js.map → plug-CiLce49C.js.map} +1 -1
- package/ccw/frontend/dist/assets/{power-DmIojFl-.js → power-CFLmB-U9.js} +2 -2
- package/ccw/frontend/dist/assets/{power-DmIojFl-.js.map → power-CFLmB-U9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{save-BFa03OnG.js → save-DuO6OF0C.js} +2 -2
- package/ccw/frontend/dist/assets/{save-BFa03OnG.js.map → save-DuO6OF0C.js.map} +1 -1
- package/ccw/frontend/dist/assets/{send-Vet3sN4J.js → send-CZk9p0mM.js} +2 -2
- package/ccw/frontend/dist/assets/{send-Vet3sN4J.js.map → send-CZk9p0mM.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-check-big-B9nzZRfE.js → square-check-big-BY_1YQQg.js} +2 -2
- package/ccw/frontend/dist/assets/{square-check-big-B9nzZRfE.js.map → square-check-big-BY_1YQQg.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-pen-C7K13x4Z.js → square-pen-CnZgm6g-.js} +2 -2
- package/ccw/frontend/dist/assets/{square-pen-C7K13x4Z.js.map → square-pen-CnZgm6g-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{star-BCQHcnSe.js → star-Cn1F0qy7.js} +2 -2
- package/ccw/frontend/dist/assets/{star-BCQHcnSe.js.map → star-Cn1F0qy7.js.map} +1 -1
- package/ccw/frontend/dist/assets/{style-CJsrp48L.js → style-Dxs1iXCV.js} +2 -2
- package/ccw/frontend/dist/assets/{style-CJsrp48L.js.map → style-Dxs1iXCV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{target-CBzCJCB1.js → target-Bz1fLRKH.js} +2 -2
- package/ccw/frontend/dist/assets/{target-CBzCJCB1.js.map → target-Bz1fLRKH.js.map} +1 -1
- package/ccw/frontend/dist/assets/{test-tube-BYTc5mvQ.js → test-tube-C6qCYlDr.js} +2 -2
- package/ccw/frontend/dist/assets/{test-tube-BYTc5mvQ.js.map → test-tube-C6qCYlDr.js.map} +1 -1
- package/ccw/frontend/dist/assets/{upload-DzyQj7ib.js → upload-C71kd4Qs.js} +2 -2
- package/ccw/frontend/dist/assets/{upload-DzyQj7ib.js.map → upload-C71kd4Qs.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useApiSettings-CFPww7gU.js → useApiSettings-CqP2BAJ7.js} +2 -2
- package/ccw/frontend/dist/assets/{useApiSettings-CFPww7gU.js.map → useApiSettings-CqP2BAJ7.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCli-ByL_a5CD.js → useCli-PCoPoVeM.js} +2 -2
- package/ccw/frontend/dist/assets/{useCli-ByL_a5CD.js.map → useCli-PCoPoVeM.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCommands-BvKIoOzB.js → useCommands-3OfPQPw4.js} +2 -2
- package/ccw/frontend/dist/assets/{useCommands-BvKIoOzB.js.map → useCommands-3OfPQPw4.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useDebounce-CmKmoP7n.js → useDebounce-bXiFhQx9.js} +2 -2
- package/ccw/frontend/dist/assets/{useDebounce-CmKmoP7n.js.map → useDebounce-bXiFhQx9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useFileExplorer-G5UoArCU.js → useFileExplorer-DEyUm46_.js} +2 -2
- package/ccw/frontend/dist/assets/{useFileExplorer-G5UoArCU.js.map → useFileExplorer-DEyUm46_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useLocale-D2iHK44M.js → useLocale-sXTrdxcJ.js} +2 -2
- package/ccw/frontend/dist/assets/{useLocale-D2iHK44M.js.map → useLocale-sXTrdxcJ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSkills-CYU4zqhm.js → useSkills-D0W0kXYm.js} +3 -3
- package/ccw/frontend/dist/assets/{useSkills-CYU4zqhm.js.map → useSkills-D0W0kXYm.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSystemSettings-JznNpij7.js → useSystemSettings-DZ-8lZsG.js} +2 -2
- package/ccw/frontend/dist/assets/{useSystemSettings-JznNpij7.js.map → useSystemSettings-DZ-8lZsG.js.map} +1 -1
- package/ccw/frontend/dist/assets/{wand-sparkles-DqS0VCeN.js → wand-sparkles-83GmAYuw.js} +2 -2
- package/ccw/frontend/dist/assets/{wand-sparkles-DqS0VCeN.js.map → wand-sparkles-83GmAYuw.js.map} +1 -1
- package/ccw/frontend/dist/index.html +1 -1
- package/package.json +1 -1
- package/.claude/skills/team-arch-opt/role-specs/analyzer.md +0 -80
- package/.claude/skills/team-arch-opt/role-specs/designer.md +0 -118
- package/.claude/skills/team-arch-opt/role-specs/refactorer.md +0 -106
- package/.claude/skills/team-arch-opt/role-specs/reviewer.md +0 -116
- package/.claude/skills/team-arch-opt/role-specs/validator.md +0 -117
- package/.claude/skills/team-brainstorm/role-specs/challenger.md +0 -63
- package/.claude/skills/team-brainstorm/role-specs/evaluator.md +0 -58
- package/.claude/skills/team-brainstorm/role-specs/ideator.md +0 -71
- package/.claude/skills/team-brainstorm/role-specs/synthesizer.md +0 -59
- package/.claude/skills/team-frontend/role-specs/analyst.md +0 -91
- package/.claude/skills/team-frontend/role-specs/architect.md +0 -85
- package/.claude/skills/team-frontend/role-specs/developer.md +0 -92
- package/.claude/skills/team-frontend/role-specs/qa.md +0 -78
- package/.claude/skills/team-issue/role-specs/explorer.md +0 -95
- package/.claude/skills/team-issue/role-specs/implementer.md +0 -89
- package/.claude/skills/team-issue/role-specs/integrator.md +0 -86
- package/.claude/skills/team-issue/role-specs/planner.md +0 -83
- package/.claude/skills/team-issue/role-specs/reviewer.md +0 -89
- package/.claude/skills/team-iterdev/role-specs/architect.md +0 -64
- package/.claude/skills/team-iterdev/role-specs/developer.md +0 -73
- package/.claude/skills/team-iterdev/role-specs/reviewer.md +0 -65
- package/.claude/skills/team-iterdev/role-specs/tester.md +0 -87
- package/.claude/skills/team-perf-opt/role-specs/benchmarker.md +0 -110
- package/.claude/skills/team-perf-opt/role-specs/optimizer.md +0 -102
- package/.claude/skills/team-perf-opt/role-specs/profiler.md +0 -73
- package/.claude/skills/team-perf-opt/role-specs/reviewer.md +0 -91
- package/.claude/skills/team-perf-opt/role-specs/strategist.md +0 -114
- package/.claude/skills/team-planex/role-specs/executor.md +0 -90
- package/.claude/skills/team-planex/role-specs/planner.md +0 -110
- package/.claude/skills/team-quality-assurance/role-specs/analyst.md +0 -79
- package/.claude/skills/team-quality-assurance/role-specs/executor.md +0 -64
- package/.claude/skills/team-quality-assurance/role-specs/generator.md +0 -67
- package/.claude/skills/team-quality-assurance/role-specs/scout.md +0 -66
- package/.claude/skills/team-quality-assurance/role-specs/strategist.md +0 -70
- package/.claude/skills/team-review/role-specs/fixer.md +0 -75
- package/.claude/skills/team-review/role-specs/reviewer.md +0 -66
- package/.claude/skills/team-review/role-specs/scanner.md +0 -70
- package/.claude/skills/team-roadmap-dev/role-specs/executor.md +0 -71
- package/.claude/skills/team-roadmap-dev/role-specs/planner.md +0 -77
- package/.claude/skills/team-roadmap-dev/role-specs/verifier.md +0 -73
- package/.claude/skills/team-tech-debt/role-specs/assessor.md +0 -70
- package/.claude/skills/team-tech-debt/role-specs/executor.md +0 -80
- package/.claude/skills/team-tech-debt/role-specs/planner.md +0 -71
- package/.claude/skills/team-tech-debt/role-specs/scanner.md +0 -85
- package/.claude/skills/team-tech-debt/role-specs/validator.md +0 -83
- package/.claude/skills/team-testing/role-specs/analyst.md +0 -94
- package/.claude/skills/team-testing/role-specs/executor.md +0 -97
- package/.claude/skills/team-testing/role-specs/generator.md +0 -96
- package/.claude/skills/team-testing/role-specs/strategist.md +0 -82
- package/.claude/skills/team-uidesign/role-specs/designer.md +0 -72
- package/.claude/skills/team-uidesign/role-specs/implementer.md +0 -74
- package/.claude/skills/team-uidesign/role-specs/researcher.md +0 -84
- package/.claude/skills/team-uidesign/role-specs/reviewer.md +0 -70
- package/.claude/skills/team-ux-improve/role-specs/designer.md +0 -191
- package/.claude/skills/team-ux-improve/role-specs/diagnoser.md +0 -110
- package/.claude/skills/team-ux-improve/role-specs/explorer.md +0 -109
- package/.claude/skills/team-ux-improve/role-specs/implementer.md +0 -164
- package/.claude/skills/team-ux-improve/role-specs/scanner.md +0 -117
- package/.claude/skills/team-ux-improve/role-specs/tester.md +0 -163
- package/ccw/frontend/dist/assets/CodexLensPage-My6DnfN6.js +0 -2
- package/ccw/frontend/dist/assets/CodexLensPage-My6DnfN6.js.map +0 -1
package/ccw/frontend/dist/assets/{AnalysisPage-Bc4p4SvJ.js.map → AnalysisPage-ds-w_nVO.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisPage-Bc4p4SvJ.js","sources":["../../src/components/shared/JsonCardView.tsx","../../src/pages/AnalysisPage.tsx"],"sourcesContent":["// ========================================\r\n// JsonCardView Component\r\n// ========================================\r\n// Renders JSON data as structured cards for better readability\r\n\r\nimport { useState } from 'react';\r\nimport { ChevronDown, ChevronRight, Database } from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface JsonCardViewProps {\r\n /** JSON data to render - accepts any object type */\r\n data: object | unknown[] | null;\r\n /** Additional CSS className */\r\n className?: string;\r\n /** Initial expanded state */\r\n defaultExpanded?: boolean;\r\n}\r\n\r\ninterface CardItemProps {\r\n label: string;\r\n value: unknown;\r\n depth?: number;\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\nfunction isObject(value: unknown): value is Record<string, unknown> {\r\n return typeof value === 'object' && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction isArray(value: unknown): value is unknown[] {\r\n return Array.isArray(value);\r\n}\r\n\r\nfunction formatLabel(key: string): string {\r\n return key\r\n .replace(/_/g, ' ')\r\n .replace(/([A-Z])/g, ' $1')\r\n .replace(/^./, (str) => str.toUpperCase())\r\n .trim();\r\n}\r\n\r\n// ========== Sub Components ==========\r\n\r\nfunction PrimitiveValue({ value }: { value: unknown }) {\r\n if (value === null || value === undefined) {\r\n return <span className=\"text-muted-foreground italic\">null</span>;\r\n }\r\n if (typeof value === 'boolean') {\r\n return (\r\n <Badge variant={value ? 'default' : 'secondary'}>\r\n {value ? 'true' : 'false'}\r\n </Badge>\r\n );\r\n }\r\n if (typeof value === 'number') {\r\n return <span className=\"text-blue-600 dark:text-blue-400 font-mono\">{value}</span>;\r\n }\r\n if (typeof value === 'string') {\r\n // Check if it's a URL\r\n if (value.startsWith('http://') || value.startsWith('https://')) {\r\n return (\r\n <a\r\n href={value}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"text-blue-600 dark:text-blue-400 hover:underline break-all\"\r\n >\r\n {value}\r\n </a>\r\n );\r\n }\r\n // Long text\r\n if (value.length > 100) {\r\n return (\r\n <div className=\"text-sm text-foreground bg-muted/50 p-2 rounded whitespace-pre-wrap break-words\">\r\n {value}\r\n </div>\r\n );\r\n }\r\n return <span className=\"text-foreground\">{value}</span>;\r\n }\r\n return <span>{String(value)}</span>;\r\n}\r\n\r\nfunction ArrayView({ items, displayName = 'items' }: { items: unknown[]; displayName?: string }) {\r\n const [expanded, setExpanded] = useState(true);\r\n\r\n if (items.length === 0) {\r\n return (\r\n <div className=\"text-muted-foreground text-sm flex items-center gap-2 p-3 bg-muted/30 rounded-md\">\r\n <Database className=\"w-4 h-4\" />\r\n <span>No {displayName} entries.</span>\r\n </div>\r\n );\r\n }\r\n\r\n // Simple array of primitives\r\n const allPrimitives = items.every(\r\n (item) => typeof item !== 'object' || item === null\r\n );\r\n\r\n if (allPrimitives) {\r\n return (\r\n <div className=\"flex flex-wrap gap-1.5\">\r\n {items.map((item, index) => (\r\n <Badge key={index} variant=\"outline\" className=\"font-normal\">\r\n {String(item)}\r\n </Badge>\r\n ))}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-2\">\r\n <button\r\n onClick={() => setExpanded(!expanded)}\r\n className=\"flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground\"\r\n >\r\n {expanded ? <ChevronDown className=\"w-4 h-4\" /> : <ChevronRight className=\"w-4 h-4\" />}\r\n {items.length} items\r\n </button>\r\n {expanded && (\r\n <div className=\"space-y-2 pl-4 border-l-2 border-border\">\r\n {items.map((item, index) => (\r\n <Card key={index} className=\"p-3\">\r\n <div className=\"text-xs text-muted-foreground mb-2\">#{index + 1}</div>\r\n {isObject(item) ? (\r\n <ObjectView data={item} />\r\n ) : (\r\n <PrimitiveValue value={item} />\r\n )}\r\n </Card>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction ObjectView({ data, depth = 0 }: { data: Record<string, unknown>; depth?: number }) {\r\n const entries = Object.entries(data);\r\n\r\n if (entries.length === 0) {\r\n return <div className=\"text-muted-foreground italic text-sm\">Empty object</div>;\r\n }\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {entries.map(([key, value]) => (\r\n <CardItem key={key} label={key} value={value} depth={depth} />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nfunction CardItem({ label, value, depth = 0 }: CardItemProps) {\r\n const formattedLabel = formatLabel(label);\r\n\r\n // Nested object\r\n if (isObject(value)) {\r\n return (\r\n <div className=\"space-y-2\">\r\n <div className=\"font-medium text-sm text-foreground\">{formattedLabel}</div>\r\n <div className={cn('pl-3 border-l-2 border-border', depth > 1 && 'ml-2')}>\r\n <ObjectView data={value} depth={depth + 1} />\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Array\r\n if (isArray(value)) {\r\n return (\r\n <div className=\"space-y-2\">\r\n <div className=\"font-medium text-sm text-foreground\">{formattedLabel}</div>\r\n <ArrayView items={value} displayName={formattedLabel.toLowerCase()} />\r\n </div>\r\n );\r\n }\r\n\r\n // Primitive value\r\n return (\r\n <div className=\"flex items-start gap-2\">\r\n <div className=\"font-medium text-sm text-muted-foreground min-w-[120px] shrink-0\">\r\n {formattedLabel}\r\n </div>\r\n <div className=\"flex-1 text-sm\">\r\n <PrimitiveValue value={value} />\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function JsonCardView({ data, className }: JsonCardViewProps) {\r\n if (!data) {\r\n return (\r\n <div className=\"text-muted-foreground italic text-sm\">No data available</div>\r\n );\r\n }\r\n\r\n // Handle array at root level\r\n if (isArray(data)) {\r\n return (\r\n <div className={cn('space-y-3', className)}>\r\n <ArrayView items={data} />\r\n </div>\r\n );\r\n }\r\n\r\n // Handle object\r\n return (\r\n <div className={cn('space-y-4', className)}>\r\n <ObjectView data={data as Record<string, unknown>} />\r\n </div>\r\n );\r\n}\r\n\r\nexport default JsonCardView;\r\n","// ========================================\r\n// Analysis Viewer Page\r\n// ========================================\r\n// View analysis sessions from /workflow:analyze-with-file command\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport {\r\n FileSearch,\r\n Search,\r\n CheckCircle,\r\n Clock,\r\n ChevronLeft,\r\n ChevronRight,\r\n Loader2,\r\n AlertCircle,\r\n X,\r\n FileText,\r\n Code,\r\n MessageSquare,\r\n Maximize2,\r\n Minimize2,\r\n} from 'lucide-react';\r\nimport { useWorkflowStore } from '@/stores/workflowStore';\r\nimport { useAppStore } from '@/stores/appStore';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\r\nimport {\r\n Drawer,\r\n DrawerContent,\r\n DrawerHeader,\r\n DrawerTitle,\r\n DrawerClose,\r\n} from '@/components/ui/Drawer';\r\nimport { fetchAnalysisSessions, fetchAnalysisDetail } from '@/lib/api';\r\nimport { MessageRenderer } from '@/components/shared/CliStreamMonitor/MessageRenderer';\r\nimport { JsonCardView } from '@/components/shared/JsonCardView';\r\nimport { cn } from '@/lib/utils';\r\nimport type { AnalysisSessionSummary } from '@/types/analysis';\r\n\r\nconst PAGE_SIZE = 16; // 4 rows × 4 columns\r\n\r\n// ========== Session Card Component (Compact) ==========\r\n\r\ninterface SessionCardProps {\r\n session: AnalysisSessionSummary;\r\n onClick: () => void;\r\n onStatusClick: (status: string) => void;\r\n isStatusFiltered: boolean;\r\n}\r\n\r\nfunction SessionCard({ session, onClick, onStatusClick, isStatusFiltered }: SessionCardProps) {\r\n const handleStatusClick = (e: React.MouseEvent) => {\r\n e.stopPropagation(); // Prevent card click\r\n onStatusClick(session.status);\r\n };\r\n\r\n return (\r\n <Card\r\n className=\"p-3 cursor-pointer transition-all hover:shadow-md hover:border-primary/50 h-full flex flex-col\"\r\n onClick={onClick}\r\n >\r\n {/* Topic - smaller font */}\r\n <h3 className=\"text-sm font-medium text-foreground line-clamp-2 mb-2 leading-snug\">\r\n {session.topic}\r\n </h3>\r\n\r\n {/* Session ID - truncate */}\r\n <p className=\"text-xs text-muted-foreground truncate mb-2\">\r\n {session.id}\r\n </p>\r\n\r\n {/* Status and Date */}\r\n <div className=\"flex items-center justify-between text-xs mt-auto pt-2 border-t\">\r\n <Badge\r\n variant={session.status === 'completed' ? 'success' : 'warning'}\r\n className={cn(\r\n \"text-[10px] px-1.5 py-0 cursor-pointer transition-all\",\r\n isStatusFiltered && \"ring-2 ring-primary ring-offset-1\"\r\n )}\r\n onClick={handleStatusClick}\r\n >\r\n {session.status === 'completed' ? (\r\n <><CheckCircle className=\"w-2.5 h-2.5 mr-0.5\" />完成</>\r\n ) : (\r\n <><Clock className=\"w-2.5 h-2.5 mr-0.5\" />进行中</>\r\n )}\r\n </Badge>\r\n <span className=\"text-muted-foreground\">{session.createdAt}</span>\r\n </div>\r\n\r\n {/* Conclusions indicator */}\r\n {session.hasConclusions && (\r\n <div className=\"flex items-center gap-1 text-[10px] text-muted-foreground mt-1\">\r\n <FileText className=\"w-2.5 h-2.5\" />\r\n <span>有结论</span>\r\n </div>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Detail Panel Component ==========\r\n\r\ninterface DetailPanelProps {\r\n sessionId: string;\r\n projectPath: string;\r\n}\r\n\r\nfunction DetailPanel({ sessionId, projectPath }: DetailPanelProps) {\r\n const [activeTab, setActiveTab] = useState('discussion');\r\n\r\n const { data: detail, isLoading, error } = useQuery({\r\n queryKey: ['analysis-detail', sessionId, projectPath],\r\n queryFn: () => fetchAnalysisDetail(sessionId, projectPath),\r\n });\r\n\r\n if (isLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-full\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-muted-foreground\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"flex items-center justify-center h-full p-4\">\r\n <div className=\"flex items-center gap-2 text-destructive\">\r\n <AlertCircle className=\"w-5 h-5\" />\r\n <span>加载失败: {(error as Error).message}</span>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!detail) return null;\r\n\r\n // Build available tabs based on content\r\n const tabs = [\r\n { value: 'discussion', label: '讨论记录', icon: <MessageSquare className=\"w-4 h-4\" /> },\r\n { value: 'conclusions', label: '结论', icon: <CheckCircle className=\"w-4 h-4\" /> },\r\n { value: 'explorations', label: '代码探索', icon: <Code className=\"w-4 h-4\" /> },\r\n { value: 'perspectives', label: '视角分析', icon: <FileText className=\"w-4 h-4\" /> },\r\n ].filter(tab => {\r\n const key = tab.value as keyof typeof detail;\r\n return detail[key];\r\n });\r\n\r\n // Ensure activeTab is valid\r\n const validTab = tabs.find(t => t.value === activeTab);\r\n if (!validTab && tabs.length > 0) {\r\n setActiveTab(tabs[0].value);\r\n }\r\n\r\n return (\r\n <div className=\"h-full flex flex-col\">\r\n {/* Session Info (in drawer, header is already shown) */}\r\n <div className=\"px-4 pb-3 border-b shrink-0\">\r\n <div className=\"min-w-0\">\r\n <h2 className=\"font-semibold truncate\">{detail.topic}</h2>\r\n <div className=\"flex items-center gap-2 mt-1\">\r\n <Badge variant={detail.status === 'completed' ? 'default' : 'secondary'} className=\"text-xs\">\r\n {detail.status === 'completed' ? '完成' : '进行中'}\r\n </Badge>\r\n <span className=\"text-xs text-muted-foreground\">{detail.createdAt}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Tabs Content */}\r\n {tabs.length > 0 ? (\r\n <>\r\n <TabsNavigation\r\n value={activeTab}\r\n onValueChange={setActiveTab}\r\n tabs={tabs}\r\n className=\"px-4\"\r\n />\r\n <div className=\"flex-1 overflow-auto min-h-0 p-4\">\r\n {/* Discussion Tab */}\r\n {activeTab === 'discussion' && detail.discussion && (\r\n <MessageRenderer content={detail.discussion} format=\"markdown\" />\r\n )}\r\n\r\n {/* Conclusions Tab */}\r\n {activeTab === 'conclusions' && detail.conclusions && (\r\n <JsonCardView data={detail.conclusions} />\r\n )}\r\n\r\n {/* Explorations Tab */}\r\n {activeTab === 'explorations' && detail.explorations && (\r\n <JsonCardView data={detail.explorations} />\r\n )}\r\n\r\n {/* Perspectives Tab */}\r\n {activeTab === 'perspectives' && detail.perspectives && (\r\n <JsonCardView data={detail.perspectives} />\r\n )}\r\n </div>\r\n </>\r\n ) : (\r\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground\">\r\n 暂无分析内容\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\ntype DateFilter = 'all' | 'today' | 'week' | 'month';\r\ntype StatusFilter = 'all' | 'in_progress' | 'completed';\r\n\r\nconst DATE_FILTERS: { value: DateFilter; label: string }[] = [\r\n { value: 'all', label: '全部' },\r\n { value: 'today', label: '今天' },\r\n { value: 'week', label: '本周' },\r\n { value: 'month', label: '本月' },\r\n];\r\n\r\nconst STATUS_FILTERS: { value: StatusFilter; label: string; icon: React.ReactNode }[] = [\r\n { value: 'all', label: '全部', icon: <FileSearch className=\"w-4 h-4\" /> },\r\n { value: 'in_progress', label: '进行中', icon: <Clock className=\"w-4 h-4\" /> },\r\n { value: 'completed', label: '已完成', icon: <CheckCircle className=\"w-4 h-4\" /> },\r\n];\r\n\r\nexport function AnalysisPage() {\r\n const projectPath = useWorkflowStore((state) => state.projectPath);\r\n const isImmersiveMode = useAppStore((s) => s.isImmersiveMode);\r\n const toggleImmersiveMode = useAppStore((s) => s.toggleImmersiveMode);\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [selectedSession, setSelectedSession] = useState<string | null>(null);\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [dateFilter, setDateFilter] = useState<DateFilter>('all');\r\n const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');\r\n const [selectedDate, setSelectedDate] = useState<string | null>(null);\r\n\r\n const { data: sessions = [], isLoading, error } = useQuery({\r\n queryKey: ['analysis-sessions', projectPath],\r\n queryFn: () => fetchAnalysisSessions(projectPath),\r\n });\r\n\r\n // Get unique dates with counts for quick filter bubbles\r\n const uniqueDates = useMemo(() => {\r\n const dateCounts = new Map<string, number>();\r\n sessions.forEach((session) => {\r\n const count = dateCounts.get(session.createdAt) || 0;\r\n dateCounts.set(session.createdAt, count + 1);\r\n });\r\n // Sort by date descending, show top 10\r\n return Array.from(dateCounts.entries())\r\n .sort((a, b) => b[0].localeCompare(a[0]))\r\n .slice(0, 10)\r\n .map(([date, count]) => ({\r\n date,\r\n label: date.slice(5), // MM-DD format\r\n count,\r\n }));\r\n }, [sessions]);\r\n\r\n // Filter by date, status and search query\r\n const filteredSessions = useMemo(() => {\r\n const now = new Date();\r\n const today = now.toISOString().split('T')[0];\r\n const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];\r\n const monthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];\r\n\r\n let filtered = sessions.filter((session) => {\r\n // Search filter\r\n const matchesSearch = session.topic.toLowerCase().includes(searchQuery.toLowerCase()) ||\r\n session.id.toLowerCase().includes(searchQuery.toLowerCase());\r\n\r\n // Status filter\r\n const matchesStatus = statusFilter === 'all' || session.status === statusFilter;\r\n\r\n // Date filter\r\n let matchesDate = true;\r\n if (selectedDate) {\r\n matchesDate = session.createdAt === selectedDate;\r\n } else if (dateFilter === 'today') {\r\n matchesDate = session.createdAt === today;\r\n } else if (dateFilter === 'week') {\r\n matchesDate = session.createdAt >= weekAgo;\r\n } else if (dateFilter === 'month') {\r\n matchesDate = session.createdAt >= monthAgo;\r\n }\r\n\r\n return matchesSearch && matchesStatus && matchesDate;\r\n });\r\n\r\n // Sort by createdAt descending (newest first)\r\n return filtered.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\r\n }, [sessions, searchQuery, dateFilter, statusFilter, selectedDate]);\r\n\r\n // Handle date select\r\n const handleDateSelect = (date: string) => {\r\n if (selectedDate === date) {\r\n setSelectedDate(null);\r\n } else {\r\n setSelectedDate(date);\r\n setDateFilter('all');\r\n }\r\n setCurrentPage(1);\r\n };\r\n\r\n // Handle status filter from card click\r\n const handleStatusClick = (status: string) => {\r\n if (statusFilter === status) {\r\n setStatusFilter('all');\r\n } else {\r\n setStatusFilter(status as StatusFilter);\r\n }\r\n setCurrentPage(1);\r\n };\r\n\r\n // Pagination\r\n const totalPages = Math.ceil(filteredSessions.length / PAGE_SIZE);\r\n const paginatedSessions = useMemo(() => {\r\n const start = (currentPage - 1) * PAGE_SIZE;\r\n return filteredSessions.slice(start, start + PAGE_SIZE);\r\n }, [filteredSessions, currentPage]);\r\n\r\n // Reset to page 1 when filters change\r\n const handleSearchChange = (value: string) => {\r\n setSearchQuery(value);\r\n setCurrentPage(1);\r\n };\r\n\r\n const handleDateFilterChange = (filter: DateFilter) => {\r\n setDateFilter(filter);\r\n setCurrentPage(1);\r\n };\r\n\r\n const handleStatusFilterChange = (filter: StatusFilter) => {\r\n setStatusFilter(filter);\r\n setSelectedDate(null);\r\n setCurrentPage(1);\r\n };\r\n\r\n return (\r\n <div className={cn(\r\n \"h-full flex overflow-hidden\",\r\n isImmersiveMode && \"fixed inset-0 z-50 bg-background\"\r\n )}>\r\n {/* Main Content - List */}\r\n <div className=\"flex-1 flex flex-col p-4 space-y-3 overflow-auto\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between shrink-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <FileSearch className=\"w-5 h-5 text-primary\" />\r\n <div>\r\n <h1 className=\"text-xl font-semibold text-foreground\">\r\n Analysis Viewer\r\n </h1>\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">\r\n 查看 /workflow:analyze-with-file 命令的分析结果\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n 共 {filteredSessions.length} 个会话\r\n </span>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-7 w-7 p-0\"\r\n onClick={toggleImmersiveMode}\r\n title={isImmersiveMode ? '退出全屏' : '全屏模式'}\r\n >\r\n {isImmersiveMode ? (\r\n <Minimize2 className=\"w-4 h-4\" />\r\n ) : (\r\n <Maximize2 className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Filters */}\r\n <div className=\"flex items-center gap-4 shrink-0\">\r\n {/* Search */}\r\n <div className=\"relative flex-1 max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n <Input\r\n placeholder=\"搜索分析会话...\"\r\n value={searchQuery}\r\n onChange={(e) => handleSearchChange(e.target.value)}\r\n className=\"pl-9\"\r\n />\r\n </div>\r\n\r\n {/* Status Filter Tabs */}\r\n <div className=\"flex items-center gap-1 bg-muted/50 rounded-lg p-1\">\r\n {STATUS_FILTERS.map((filter) => (\r\n <Button\r\n key={filter.value}\r\n variant={statusFilter === filter.value ? 'default' : 'ghost'}\r\n size=\"sm\"\r\n className=\"h-7 px-3 text-xs gap-1\"\r\n onClick={() => handleStatusFilterChange(filter.value)}\r\n >\r\n {filter.icon}\r\n {filter.label}\r\n </Button>\r\n ))}\r\n </div>\r\n\r\n {/* Date Filter Tabs */}\r\n <div className=\"flex items-center gap-1 bg-muted/50 rounded-lg p-1\">\r\n {DATE_FILTERS.map((filter) => (\r\n <Button\r\n key={filter.value}\r\n variant={dateFilter === filter.value ? 'default' : 'ghost'}\r\n size=\"sm\"\r\n className=\"h-7 px-3 text-xs\"\r\n onClick={() => handleDateFilterChange(filter.value)}\r\n >\r\n {filter.label}\r\n </Button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Date Quick Filter Bubbles */}\r\n <div className=\"flex items-center gap-2 flex-wrap shrink-0\">\r\n {uniqueDates.map((date) => (\r\n <Button\r\n key={date.date}\r\n variant={selectedDate === date.date ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-7 px-2 text-xs gap-1\"\r\n onClick={() => handleDateSelect(date.date)}\r\n >\r\n <span>{date.label}</span>\r\n <Badge variant=\"secondary\" className=\"ml-1 px-1.5 py-0 text-[10px]\">\r\n {date.count}\r\n </Badge>\r\n </Button>\r\n ))}\r\n </div>\r\n\r\n {/* Content */}\r\n {isLoading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-muted-foreground\" />\r\n </div>\r\n ) : error ? (\r\n <Card className=\"p-6\">\r\n <div className=\"flex items-center gap-2 text-destructive\">\r\n <AlertCircle className=\"w-5 h-5\" />\r\n <span>加载失败: {(error as Error).message}</span>\r\n </div>\r\n </Card>\r\n ) : filteredSessions.length === 0 ? (\r\n <Card className=\"p-12 text-center\">\r\n <FileSearch className=\"w-12 h-12 mx-auto text-muted-foreground mb-4\" />\r\n <p className=\"text-muted-foreground\">\r\n {searchQuery ? '没有匹配的分析会话' : '暂无分析会话'}\r\n </p>\r\n <p className=\"text-sm text-muted-foreground mt-2\">\r\n 使用 /workflow:analyze-with-file 命令创建分析\r\n </p>\r\n </Card>\r\n ) : (\r\n <>\r\n {/* Grid - flex-1 to fill remaining space */}\r\n <div className=\"flex-1 grid grid-cols-4 gap-3 content-start\">\r\n {paginatedSessions.map((session) => (\r\n <SessionCard\r\n key={session.id}\r\n session={session}\r\n onClick={() => setSelectedSession(session.id)}\r\n onStatusClick={handleStatusClick}\r\n isStatusFiltered={statusFilter !== 'all'}\r\n />\r\n ))}\r\n </div>\r\n\r\n {/* Pagination */}\r\n {totalPages > 1 && (\r\n <div className=\"flex items-center justify-center gap-2 pt-4\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n disabled={currentPage === 1}\r\n onClick={() => setCurrentPage(p => p - 1)}\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </Button>\r\n <span className=\"text-sm text-muted-foreground px-3\">\r\n {currentPage} / {totalPages}\r\n </span>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n disabled={currentPage === totalPages}\r\n onClick={() => setCurrentPage(p => p + 1)}\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n\r\n {/* Detail Drawer */}\r\n <Drawer open={!!selectedSession} onOpenChange={(open) => !open && setSelectedSession(null)}>\r\n <DrawerContent side=\"right\" className=\"w-1/2 h-full max-w-none\">\r\n <DrawerHeader className=\"shrink-0\">\r\n <DrawerTitle>分析详情</DrawerTitle>\r\n <DrawerClose asChild>\r\n <Button variant=\"ghost\" size=\"sm\" className=\"absolute right-4 top-4\">\r\n <X className=\"w-4 h-4\" />\r\n </Button>\r\n </DrawerClose>\r\n </DrawerHeader>\r\n {selectedSession && (\r\n <DetailPanel\r\n sessionId={selectedSession}\r\n projectPath={projectPath}\r\n />\r\n )}\r\n </DrawerContent>\r\n </Drawer>\r\n </div>\r\n );\r\n}\r\n\r\nexport default AnalysisPage;\r\n"],"names":["isObject","value","isArray","formatLabel","key","str","PrimitiveValue","jsx","Badge","ArrayView","items","displayName","expanded","setExpanded","useState","jsxs","Database","item","index","ChevronDown","ChevronRight","Card","ObjectView","data","depth","entries","CardItem","label","formattedLabel","cn","JsonCardView","className","PAGE_SIZE","SessionCard","session","onClick","onStatusClick","isStatusFiltered","handleStatusClick","e","Fragment","CheckCircle","Clock","FileText","DetailPanel","sessionId","projectPath","activeTab","setActiveTab","detail","isLoading","error","useQuery","fetchAnalysisDetail","Loader2","AlertCircle","tabs","MessageSquare","Code","tab","t","TabsNavigation","MessageRenderer","DATE_FILTERS","STATUS_FILTERS","FileSearch","AnalysisPage","useWorkflowStore","state","isImmersiveMode","useAppStore","toggleImmersiveMode","searchQuery","setSearchQuery","selectedSession","setSelectedSession","currentPage","setCurrentPage","dateFilter","setDateFilter","statusFilter","setStatusFilter","selectedDate","setSelectedDate","sessions","fetchAnalysisSessions","uniqueDates","useMemo","dateCounts","count","a","b","date","filteredSessions","now","today","weekAgo","monthAgo","matchesSearch","matchesStatus","matchesDate","handleDateSelect","status","totalPages","paginatedSessions","start","handleSearchChange","handleDateFilterChange","filter","handleStatusFilterChange","Button","Minimize2","Maximize2","Search","Input","p","ChevronLeft","Drawer","open","DrawerContent","DrawerHeader","DrawerTitle","DrawerClose","X"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnalysisPage-ds-w_nVO.js","sources":["../../src/components/shared/JsonCardView.tsx","../../src/pages/AnalysisPage.tsx"],"sourcesContent":["// ========================================\r\n// JsonCardView Component\r\n// ========================================\r\n// Renders JSON data as structured cards for better readability\r\n\r\nimport { useState } from 'react';\r\nimport { ChevronDown, ChevronRight, Database } from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface JsonCardViewProps {\r\n /** JSON data to render - accepts any object type */\r\n data: object | unknown[] | null;\r\n /** Additional CSS className */\r\n className?: string;\r\n /** Initial expanded state */\r\n defaultExpanded?: boolean;\r\n}\r\n\r\ninterface CardItemProps {\r\n label: string;\r\n value: unknown;\r\n depth?: number;\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\nfunction isObject(value: unknown): value is Record<string, unknown> {\r\n return typeof value === 'object' && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction isArray(value: unknown): value is unknown[] {\r\n return Array.isArray(value);\r\n}\r\n\r\nfunction formatLabel(key: string): string {\r\n return key\r\n .replace(/_/g, ' ')\r\n .replace(/([A-Z])/g, ' $1')\r\n .replace(/^./, (str) => str.toUpperCase())\r\n .trim();\r\n}\r\n\r\n// ========== Sub Components ==========\r\n\r\nfunction PrimitiveValue({ value }: { value: unknown }) {\r\n if (value === null || value === undefined) {\r\n return <span className=\"text-muted-foreground italic\">null</span>;\r\n }\r\n if (typeof value === 'boolean') {\r\n return (\r\n <Badge variant={value ? 'default' : 'secondary'}>\r\n {value ? 'true' : 'false'}\r\n </Badge>\r\n );\r\n }\r\n if (typeof value === 'number') {\r\n return <span className=\"text-blue-600 dark:text-blue-400 font-mono\">{value}</span>;\r\n }\r\n if (typeof value === 'string') {\r\n // Check if it's a URL\r\n if (value.startsWith('http://') || value.startsWith('https://')) {\r\n return (\r\n <a\r\n href={value}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"text-blue-600 dark:text-blue-400 hover:underline break-all\"\r\n >\r\n {value}\r\n </a>\r\n );\r\n }\r\n // Long text\r\n if (value.length > 100) {\r\n return (\r\n <div className=\"text-sm text-foreground bg-muted/50 p-2 rounded whitespace-pre-wrap break-words\">\r\n {value}\r\n </div>\r\n );\r\n }\r\n return <span className=\"text-foreground\">{value}</span>;\r\n }\r\n return <span>{String(value)}</span>;\r\n}\r\n\r\nfunction ArrayView({ items, displayName = 'items' }: { items: unknown[]; displayName?: string }) {\r\n const [expanded, setExpanded] = useState(true);\r\n\r\n if (items.length === 0) {\r\n return (\r\n <div className=\"text-muted-foreground text-sm flex items-center gap-2 p-3 bg-muted/30 rounded-md\">\r\n <Database className=\"w-4 h-4\" />\r\n <span>No {displayName} entries.</span>\r\n </div>\r\n );\r\n }\r\n\r\n // Simple array of primitives\r\n const allPrimitives = items.every(\r\n (item) => typeof item !== 'object' || item === null\r\n );\r\n\r\n if (allPrimitives) {\r\n return (\r\n <div className=\"flex flex-wrap gap-1.5\">\r\n {items.map((item, index) => (\r\n <Badge key={index} variant=\"outline\" className=\"font-normal\">\r\n {String(item)}\r\n </Badge>\r\n ))}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-2\">\r\n <button\r\n onClick={() => setExpanded(!expanded)}\r\n className=\"flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground\"\r\n >\r\n {expanded ? <ChevronDown className=\"w-4 h-4\" /> : <ChevronRight className=\"w-4 h-4\" />}\r\n {items.length} items\r\n </button>\r\n {expanded && (\r\n <div className=\"space-y-2 pl-4 border-l-2 border-border\">\r\n {items.map((item, index) => (\r\n <Card key={index} className=\"p-3\">\r\n <div className=\"text-xs text-muted-foreground mb-2\">#{index + 1}</div>\r\n {isObject(item) ? (\r\n <ObjectView data={item} />\r\n ) : (\r\n <PrimitiveValue value={item} />\r\n )}\r\n </Card>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction ObjectView({ data, depth = 0 }: { data: Record<string, unknown>; depth?: number }) {\r\n const entries = Object.entries(data);\r\n\r\n if (entries.length === 0) {\r\n return <div className=\"text-muted-foreground italic text-sm\">Empty object</div>;\r\n }\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {entries.map(([key, value]) => (\r\n <CardItem key={key} label={key} value={value} depth={depth} />\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\nfunction CardItem({ label, value, depth = 0 }: CardItemProps) {\r\n const formattedLabel = formatLabel(label);\r\n\r\n // Nested object\r\n if (isObject(value)) {\r\n return (\r\n <div className=\"space-y-2\">\r\n <div className=\"font-medium text-sm text-foreground\">{formattedLabel}</div>\r\n <div className={cn('pl-3 border-l-2 border-border', depth > 1 && 'ml-2')}>\r\n <ObjectView data={value} depth={depth + 1} />\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Array\r\n if (isArray(value)) {\r\n return (\r\n <div className=\"space-y-2\">\r\n <div className=\"font-medium text-sm text-foreground\">{formattedLabel}</div>\r\n <ArrayView items={value} displayName={formattedLabel.toLowerCase()} />\r\n </div>\r\n );\r\n }\r\n\r\n // Primitive value\r\n return (\r\n <div className=\"flex items-start gap-2\">\r\n <div className=\"font-medium text-sm text-muted-foreground min-w-[120px] shrink-0\">\r\n {formattedLabel}\r\n </div>\r\n <div className=\"flex-1 text-sm\">\r\n <PrimitiveValue value={value} />\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function JsonCardView({ data, className }: JsonCardViewProps) {\r\n if (!data) {\r\n return (\r\n <div className=\"text-muted-foreground italic text-sm\">No data available</div>\r\n );\r\n }\r\n\r\n // Handle array at root level\r\n if (isArray(data)) {\r\n return (\r\n <div className={cn('space-y-3', className)}>\r\n <ArrayView items={data} />\r\n </div>\r\n );\r\n }\r\n\r\n // Handle object\r\n return (\r\n <div className={cn('space-y-4', className)}>\r\n <ObjectView data={data as Record<string, unknown>} />\r\n </div>\r\n );\r\n}\r\n\r\nexport default JsonCardView;\r\n","// ========================================\r\n// Analysis Viewer Page\r\n// ========================================\r\n// View analysis sessions from /workflow:analyze-with-file command\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport {\r\n FileSearch,\r\n Search,\r\n CheckCircle,\r\n Clock,\r\n ChevronLeft,\r\n ChevronRight,\r\n Loader2,\r\n AlertCircle,\r\n X,\r\n FileText,\r\n Code,\r\n MessageSquare,\r\n Maximize2,\r\n Minimize2,\r\n} from 'lucide-react';\r\nimport { useWorkflowStore } from '@/stores/workflowStore';\r\nimport { useAppStore } from '@/stores/appStore';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\r\nimport {\r\n Drawer,\r\n DrawerContent,\r\n DrawerHeader,\r\n DrawerTitle,\r\n DrawerClose,\r\n} from '@/components/ui/Drawer';\r\nimport { fetchAnalysisSessions, fetchAnalysisDetail } from '@/lib/api';\r\nimport { MessageRenderer } from '@/components/shared/CliStreamMonitor/MessageRenderer';\r\nimport { JsonCardView } from '@/components/shared/JsonCardView';\r\nimport { cn } from '@/lib/utils';\r\nimport type { AnalysisSessionSummary } from '@/types/analysis';\r\n\r\nconst PAGE_SIZE = 16; // 4 rows × 4 columns\r\n\r\n// ========== Session Card Component (Compact) ==========\r\n\r\ninterface SessionCardProps {\r\n session: AnalysisSessionSummary;\r\n onClick: () => void;\r\n onStatusClick: (status: string) => void;\r\n isStatusFiltered: boolean;\r\n}\r\n\r\nfunction SessionCard({ session, onClick, onStatusClick, isStatusFiltered }: SessionCardProps) {\r\n const handleStatusClick = (e: React.MouseEvent) => {\r\n e.stopPropagation(); // Prevent card click\r\n onStatusClick(session.status);\r\n };\r\n\r\n return (\r\n <Card\r\n className=\"p-3 cursor-pointer transition-all hover:shadow-md hover:border-primary/50 h-full flex flex-col\"\r\n onClick={onClick}\r\n >\r\n {/* Topic - smaller font */}\r\n <h3 className=\"text-sm font-medium text-foreground line-clamp-2 mb-2 leading-snug\">\r\n {session.topic}\r\n </h3>\r\n\r\n {/* Session ID - truncate */}\r\n <p className=\"text-xs text-muted-foreground truncate mb-2\">\r\n {session.id}\r\n </p>\r\n\r\n {/* Status and Date */}\r\n <div className=\"flex items-center justify-between text-xs mt-auto pt-2 border-t\">\r\n <Badge\r\n variant={session.status === 'completed' ? 'success' : 'warning'}\r\n className={cn(\r\n \"text-[10px] px-1.5 py-0 cursor-pointer transition-all\",\r\n isStatusFiltered && \"ring-2 ring-primary ring-offset-1\"\r\n )}\r\n onClick={handleStatusClick}\r\n >\r\n {session.status === 'completed' ? (\r\n <><CheckCircle className=\"w-2.5 h-2.5 mr-0.5\" />完成</>\r\n ) : (\r\n <><Clock className=\"w-2.5 h-2.5 mr-0.5\" />进行中</>\r\n )}\r\n </Badge>\r\n <span className=\"text-muted-foreground\">{session.createdAt}</span>\r\n </div>\r\n\r\n {/* Conclusions indicator */}\r\n {session.hasConclusions && (\r\n <div className=\"flex items-center gap-1 text-[10px] text-muted-foreground mt-1\">\r\n <FileText className=\"w-2.5 h-2.5\" />\r\n <span>有结论</span>\r\n </div>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Detail Panel Component ==========\r\n\r\ninterface DetailPanelProps {\r\n sessionId: string;\r\n projectPath: string;\r\n}\r\n\r\nfunction DetailPanel({ sessionId, projectPath }: DetailPanelProps) {\r\n const [activeTab, setActiveTab] = useState('discussion');\r\n\r\n const { data: detail, isLoading, error } = useQuery({\r\n queryKey: ['analysis-detail', sessionId, projectPath],\r\n queryFn: () => fetchAnalysisDetail(sessionId, projectPath),\r\n });\r\n\r\n if (isLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-full\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-muted-foreground\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"flex items-center justify-center h-full p-4\">\r\n <div className=\"flex items-center gap-2 text-destructive\">\r\n <AlertCircle className=\"w-5 h-5\" />\r\n <span>加载失败: {(error as Error).message}</span>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!detail) return null;\r\n\r\n // Build available tabs based on content\r\n const tabs = [\r\n { value: 'discussion', label: '讨论记录', icon: <MessageSquare className=\"w-4 h-4\" /> },\r\n { value: 'conclusions', label: '结论', icon: <CheckCircle className=\"w-4 h-4\" /> },\r\n { value: 'explorations', label: '代码探索', icon: <Code className=\"w-4 h-4\" /> },\r\n { value: 'perspectives', label: '视角分析', icon: <FileText className=\"w-4 h-4\" /> },\r\n ].filter(tab => {\r\n const key = tab.value as keyof typeof detail;\r\n return detail[key];\r\n });\r\n\r\n // Ensure activeTab is valid\r\n const validTab = tabs.find(t => t.value === activeTab);\r\n if (!validTab && tabs.length > 0) {\r\n setActiveTab(tabs[0].value);\r\n }\r\n\r\n return (\r\n <div className=\"h-full flex flex-col\">\r\n {/* Session Info (in drawer, header is already shown) */}\r\n <div className=\"px-4 pb-3 border-b shrink-0\">\r\n <div className=\"min-w-0\">\r\n <h2 className=\"font-semibold truncate\">{detail.topic}</h2>\r\n <div className=\"flex items-center gap-2 mt-1\">\r\n <Badge variant={detail.status === 'completed' ? 'default' : 'secondary'} className=\"text-xs\">\r\n {detail.status === 'completed' ? '完成' : '进行中'}\r\n </Badge>\r\n <span className=\"text-xs text-muted-foreground\">{detail.createdAt}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Tabs Content */}\r\n {tabs.length > 0 ? (\r\n <>\r\n <TabsNavigation\r\n value={activeTab}\r\n onValueChange={setActiveTab}\r\n tabs={tabs}\r\n className=\"px-4\"\r\n />\r\n <div className=\"flex-1 overflow-auto min-h-0 p-4\">\r\n {/* Discussion Tab */}\r\n {activeTab === 'discussion' && detail.discussion && (\r\n <MessageRenderer content={detail.discussion} format=\"markdown\" />\r\n )}\r\n\r\n {/* Conclusions Tab */}\r\n {activeTab === 'conclusions' && detail.conclusions && (\r\n <JsonCardView data={detail.conclusions} />\r\n )}\r\n\r\n {/* Explorations Tab */}\r\n {activeTab === 'explorations' && detail.explorations && (\r\n <JsonCardView data={detail.explorations} />\r\n )}\r\n\r\n {/* Perspectives Tab */}\r\n {activeTab === 'perspectives' && detail.perspectives && (\r\n <JsonCardView data={detail.perspectives} />\r\n )}\r\n </div>\r\n </>\r\n ) : (\r\n <div className=\"flex-1 flex items-center justify-center text-muted-foreground\">\r\n 暂无分析内容\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\ntype DateFilter = 'all' | 'today' | 'week' | 'month';\r\ntype StatusFilter = 'all' | 'in_progress' | 'completed';\r\n\r\nconst DATE_FILTERS: { value: DateFilter; label: string }[] = [\r\n { value: 'all', label: '全部' },\r\n { value: 'today', label: '今天' },\r\n { value: 'week', label: '本周' },\r\n { value: 'month', label: '本月' },\r\n];\r\n\r\nconst STATUS_FILTERS: { value: StatusFilter; label: string; icon: React.ReactNode }[] = [\r\n { value: 'all', label: '全部', icon: <FileSearch className=\"w-4 h-4\" /> },\r\n { value: 'in_progress', label: '进行中', icon: <Clock className=\"w-4 h-4\" /> },\r\n { value: 'completed', label: '已完成', icon: <CheckCircle className=\"w-4 h-4\" /> },\r\n];\r\n\r\nexport function AnalysisPage() {\r\n const projectPath = useWorkflowStore((state) => state.projectPath);\r\n const isImmersiveMode = useAppStore((s) => s.isImmersiveMode);\r\n const toggleImmersiveMode = useAppStore((s) => s.toggleImmersiveMode);\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [selectedSession, setSelectedSession] = useState<string | null>(null);\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [dateFilter, setDateFilter] = useState<DateFilter>('all');\r\n const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');\r\n const [selectedDate, setSelectedDate] = useState<string | null>(null);\r\n\r\n const { data: sessions = [], isLoading, error } = useQuery({\r\n queryKey: ['analysis-sessions', projectPath],\r\n queryFn: () => fetchAnalysisSessions(projectPath),\r\n });\r\n\r\n // Get unique dates with counts for quick filter bubbles\r\n const uniqueDates = useMemo(() => {\r\n const dateCounts = new Map<string, number>();\r\n sessions.forEach((session) => {\r\n const count = dateCounts.get(session.createdAt) || 0;\r\n dateCounts.set(session.createdAt, count + 1);\r\n });\r\n // Sort by date descending, show top 10\r\n return Array.from(dateCounts.entries())\r\n .sort((a, b) => b[0].localeCompare(a[0]))\r\n .slice(0, 10)\r\n .map(([date, count]) => ({\r\n date,\r\n label: date.slice(5), // MM-DD format\r\n count,\r\n }));\r\n }, [sessions]);\r\n\r\n // Filter by date, status and search query\r\n const filteredSessions = useMemo(() => {\r\n const now = new Date();\r\n const today = now.toISOString().split('T')[0];\r\n const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];\r\n const monthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];\r\n\r\n let filtered = sessions.filter((session) => {\r\n // Search filter\r\n const matchesSearch = session.topic.toLowerCase().includes(searchQuery.toLowerCase()) ||\r\n session.id.toLowerCase().includes(searchQuery.toLowerCase());\r\n\r\n // Status filter\r\n const matchesStatus = statusFilter === 'all' || session.status === statusFilter;\r\n\r\n // Date filter\r\n let matchesDate = true;\r\n if (selectedDate) {\r\n matchesDate = session.createdAt === selectedDate;\r\n } else if (dateFilter === 'today') {\r\n matchesDate = session.createdAt === today;\r\n } else if (dateFilter === 'week') {\r\n matchesDate = session.createdAt >= weekAgo;\r\n } else if (dateFilter === 'month') {\r\n matchesDate = session.createdAt >= monthAgo;\r\n }\r\n\r\n return matchesSearch && matchesStatus && matchesDate;\r\n });\r\n\r\n // Sort by createdAt descending (newest first)\r\n return filtered.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\r\n }, [sessions, searchQuery, dateFilter, statusFilter, selectedDate]);\r\n\r\n // Handle date select\r\n const handleDateSelect = (date: string) => {\r\n if (selectedDate === date) {\r\n setSelectedDate(null);\r\n } else {\r\n setSelectedDate(date);\r\n setDateFilter('all');\r\n }\r\n setCurrentPage(1);\r\n };\r\n\r\n // Handle status filter from card click\r\n const handleStatusClick = (status: string) => {\r\n if (statusFilter === status) {\r\n setStatusFilter('all');\r\n } else {\r\n setStatusFilter(status as StatusFilter);\r\n }\r\n setCurrentPage(1);\r\n };\r\n\r\n // Pagination\r\n const totalPages = Math.ceil(filteredSessions.length / PAGE_SIZE);\r\n const paginatedSessions = useMemo(() => {\r\n const start = (currentPage - 1) * PAGE_SIZE;\r\n return filteredSessions.slice(start, start + PAGE_SIZE);\r\n }, [filteredSessions, currentPage]);\r\n\r\n // Reset to page 1 when filters change\r\n const handleSearchChange = (value: string) => {\r\n setSearchQuery(value);\r\n setCurrentPage(1);\r\n };\r\n\r\n const handleDateFilterChange = (filter: DateFilter) => {\r\n setDateFilter(filter);\r\n setCurrentPage(1);\r\n };\r\n\r\n const handleStatusFilterChange = (filter: StatusFilter) => {\r\n setStatusFilter(filter);\r\n setSelectedDate(null);\r\n setCurrentPage(1);\r\n };\r\n\r\n return (\r\n <div className={cn(\r\n \"h-full flex overflow-hidden\",\r\n isImmersiveMode && \"fixed inset-0 z-50 bg-background\"\r\n )}>\r\n {/* Main Content - List */}\r\n <div className=\"flex-1 flex flex-col p-4 space-y-3 overflow-auto\">\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between shrink-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <FileSearch className=\"w-5 h-5 text-primary\" />\r\n <div>\r\n <h1 className=\"text-xl font-semibold text-foreground\">\r\n Analysis Viewer\r\n </h1>\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">\r\n 查看 /workflow:analyze-with-file 命令的分析结果\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n 共 {filteredSessions.length} 个会话\r\n </span>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-7 w-7 p-0\"\r\n onClick={toggleImmersiveMode}\r\n title={isImmersiveMode ? '退出全屏' : '全屏模式'}\r\n >\r\n {isImmersiveMode ? (\r\n <Minimize2 className=\"w-4 h-4\" />\r\n ) : (\r\n <Maximize2 className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Filters */}\r\n <div className=\"flex items-center gap-4 shrink-0\">\r\n {/* Search */}\r\n <div className=\"relative flex-1 max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n <Input\r\n placeholder=\"搜索分析会话...\"\r\n value={searchQuery}\r\n onChange={(e) => handleSearchChange(e.target.value)}\r\n className=\"pl-9\"\r\n />\r\n </div>\r\n\r\n {/* Status Filter Tabs */}\r\n <div className=\"flex items-center gap-1 bg-muted/50 rounded-lg p-1\">\r\n {STATUS_FILTERS.map((filter) => (\r\n <Button\r\n key={filter.value}\r\n variant={statusFilter === filter.value ? 'default' : 'ghost'}\r\n size=\"sm\"\r\n className=\"h-7 px-3 text-xs gap-1\"\r\n onClick={() => handleStatusFilterChange(filter.value)}\r\n >\r\n {filter.icon}\r\n {filter.label}\r\n </Button>\r\n ))}\r\n </div>\r\n\r\n {/* Date Filter Tabs */}\r\n <div className=\"flex items-center gap-1 bg-muted/50 rounded-lg p-1\">\r\n {DATE_FILTERS.map((filter) => (\r\n <Button\r\n key={filter.value}\r\n variant={dateFilter === filter.value ? 'default' : 'ghost'}\r\n size=\"sm\"\r\n className=\"h-7 px-3 text-xs\"\r\n onClick={() => handleDateFilterChange(filter.value)}\r\n >\r\n {filter.label}\r\n </Button>\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Date Quick Filter Bubbles */}\r\n <div className=\"flex items-center gap-2 flex-wrap shrink-0\">\r\n {uniqueDates.map((date) => (\r\n <Button\r\n key={date.date}\r\n variant={selectedDate === date.date ? 'default' : 'outline'}\r\n size=\"sm\"\r\n className=\"h-7 px-2 text-xs gap-1\"\r\n onClick={() => handleDateSelect(date.date)}\r\n >\r\n <span>{date.label}</span>\r\n <Badge variant=\"secondary\" className=\"ml-1 px-1.5 py-0 text-[10px]\">\r\n {date.count}\r\n </Badge>\r\n </Button>\r\n ))}\r\n </div>\r\n\r\n {/* Content */}\r\n {isLoading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-muted-foreground\" />\r\n </div>\r\n ) : error ? (\r\n <Card className=\"p-6\">\r\n <div className=\"flex items-center gap-2 text-destructive\">\r\n <AlertCircle className=\"w-5 h-5\" />\r\n <span>加载失败: {(error as Error).message}</span>\r\n </div>\r\n </Card>\r\n ) : filteredSessions.length === 0 ? (\r\n <Card className=\"p-12 text-center\">\r\n <FileSearch className=\"w-12 h-12 mx-auto text-muted-foreground mb-4\" />\r\n <p className=\"text-muted-foreground\">\r\n {searchQuery ? '没有匹配的分析会话' : '暂无分析会话'}\r\n </p>\r\n <p className=\"text-sm text-muted-foreground mt-2\">\r\n 使用 /workflow:analyze-with-file 命令创建分析\r\n </p>\r\n </Card>\r\n ) : (\r\n <>\r\n {/* Grid - flex-1 to fill remaining space */}\r\n <div className=\"flex-1 grid grid-cols-4 gap-3 content-start\">\r\n {paginatedSessions.map((session) => (\r\n <SessionCard\r\n key={session.id}\r\n session={session}\r\n onClick={() => setSelectedSession(session.id)}\r\n onStatusClick={handleStatusClick}\r\n isStatusFiltered={statusFilter !== 'all'}\r\n />\r\n ))}\r\n </div>\r\n\r\n {/* Pagination */}\r\n {totalPages > 1 && (\r\n <div className=\"flex items-center justify-center gap-2 pt-4\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n disabled={currentPage === 1}\r\n onClick={() => setCurrentPage(p => p - 1)}\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </Button>\r\n <span className=\"text-sm text-muted-foreground px-3\">\r\n {currentPage} / {totalPages}\r\n </span>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n disabled={currentPage === totalPages}\r\n onClick={() => setCurrentPage(p => p + 1)}\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n\r\n {/* Detail Drawer */}\r\n <Drawer open={!!selectedSession} onOpenChange={(open) => !open && setSelectedSession(null)}>\r\n <DrawerContent side=\"right\" className=\"w-1/2 h-full max-w-none\">\r\n <DrawerHeader className=\"shrink-0\">\r\n <DrawerTitle>分析详情</DrawerTitle>\r\n <DrawerClose asChild>\r\n <Button variant=\"ghost\" size=\"sm\" className=\"absolute right-4 top-4\">\r\n <X className=\"w-4 h-4\" />\r\n </Button>\r\n </DrawerClose>\r\n </DrawerHeader>\r\n {selectedSession && (\r\n <DetailPanel\r\n sessionId={selectedSession}\r\n projectPath={projectPath}\r\n />\r\n )}\r\n </DrawerContent>\r\n </Drawer>\r\n </div>\r\n );\r\n}\r\n\r\nexport default AnalysisPage;\r\n"],"names":["isObject","value","isArray","formatLabel","key","str","PrimitiveValue","jsx","Badge","ArrayView","items","displayName","expanded","setExpanded","useState","jsxs","Database","item","index","ChevronDown","ChevronRight","Card","ObjectView","data","depth","entries","CardItem","label","formattedLabel","cn","JsonCardView","className","PAGE_SIZE","SessionCard","session","onClick","onStatusClick","isStatusFiltered","handleStatusClick","e","Fragment","CheckCircle","Clock","FileText","DetailPanel","sessionId","projectPath","activeTab","setActiveTab","detail","isLoading","error","useQuery","fetchAnalysisDetail","Loader2","AlertCircle","tabs","MessageSquare","Code","tab","t","TabsNavigation","MessageRenderer","DATE_FILTERS","STATUS_FILTERS","FileSearch","AnalysisPage","useWorkflowStore","state","isImmersiveMode","useAppStore","toggleImmersiveMode","searchQuery","setSearchQuery","selectedSession","setSelectedSession","currentPage","setCurrentPage","dateFilter","setDateFilter","statusFilter","setStatusFilter","selectedDate","setSelectedDate","sessions","fetchAnalysisSessions","uniqueDates","useMemo","dateCounts","count","a","b","date","filteredSessions","now","today","weekAgo","monthAgo","matchesSearch","matchesStatus","matchesDate","handleDateSelect","status","totalPages","paginatedSessions","start","handleSearchChange","handleDateFilterChange","filter","handleStatusFilterChange","Button","Minimize2","Maximize2","Search","Input","p","ChevronLeft","Drawer","open","DrawerContent","DrawerHeader","DrawerTitle","DrawerClose","X"],"mappings":"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"}
|
package/ccw/frontend/dist/assets/{ApiSettingsPage-CVK108u2.js → ApiSettingsPage-DlCbXxTz.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{u as W,al as ge,r as i,j as e,e as f,Z as xe,c as Ve,a7 as ie,C as Q,m as ks,k as ze,b as ps,I as N,K as Ms,D as us,d as js,f as vs,g as he,S as cs,h as fs,T as ye,B as ee,x as $e,y as Ge,z as qe,A as Qe,E as We,bu as m,aq as ve,ar as fe,as as Se,at as Ne,au as V,cy as os,ap as ms,bO as Ke,G as Ye,bq as Be,ck as Oe,bp as et,ae as Cs,N as ss,av as st,X as Ds,bf as tt,a2 as at,a3 as it,a4 as Es,a5 as Ts,an as Is,e0 as nt,e1 as lt,d6 as dt,R as rt}from"./index-B6I7GQC5.js";import{T as ct}from"./TabsNavigation-drSnu5jn.js";import{S as Z}from"./Switch-BgAFC-Wk.js";import{u as Ze,a as ot,b as Ss,c as mt,d as ht,e as xt,f as Ls,g as gt,h as Os,i as pt,j as ut,k as jt,l as vt,m as zs,n as ft,o as Bs,p as St,q as Nt,r as yt,s as Rs,t as bt,v as Ct,w as wt,x as Mt,y as Pt}from"./useApiSettings-CFPww7gU.js";import{E as Ns}from"./ellipsis-vertical-DIyoSEHx.js";import{S as ys}from"./square-pen-C7K13x4Z.js";import{C as hs,a as xs,b as gs}from"./Collapsible-B_xd1Qbg.js";import{E as ts}from"./eye-off-CGRUVRDR.js";import{E as as}from"./eye-DUy7aLEx.js";import{A as _s,a as Hs,b as Us,c as Js,d as Vs,e as $s,f as Gs,g as qs}from"./AlertDialog-gTMl4gSG.js";import{F as kt}from"./file-text-BoHsW2es.js";import{H as Et}from"./hard-drive-eCtll84F.js";import{S as Qs}from"./save-BFa03OnG.js";import{L as Tt}from"./link-CL4JmoHb.js";import"./useLocale-D2iHK44M.js";import"./errorSanitizer-IY9pf5g4.js";function It({provider:a,onEdit:r,onDelete:t,onTest:s,onMultiKeySettings:n,onSyncToCodexLens:h,onManageModels:o,onToggleEnabled:d,isDeleting:M,isTesting:u,isToggling:v}){var k,I;const{formatMessage:j}=W(),P=((k=a.apiKeys)==null?void 0:k.filter(C=>C.enabled).length)||0,F=(((I=a.apiKeys)==null?void 0:I.length)||0)>0,H=()=>{var K;if(!a.enabled)return e.jsx(ee,{variant:"secondary",children:j({id:"apiSettings.common.disabled"})});if(!((K=a.healthCheck)!=null&&K.enabled))return e.jsx(ee,{variant:"outline",children:j({id:"apiSettings.providers.unknown"})});const C=a.apiKeys||[];if(C.length===0)return e.jsx(ee,{variant:"info",children:j({id:"apiSettings.providers.unknown"})});const D=C.filter(g=>g.healthStatus==="healthy").length;return C.filter(g=>g.healthStatus==="unhealthy").length>0?e.jsx(ee,{variant:"destructive",children:j({id:"apiSettings.providers.unhealthy"})}):D===C.length?e.jsx(ee,{variant:"success",children:j({id:"apiSettings.providers.healthy"})}):e.jsx(ee,{variant:"warning",children:j({id:"apiSettings.providers.unknown"})})};return e.jsx(Q,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground truncate",children:a.name}),H()]}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-sm text-muted-foreground",children:[e.jsx("span",{className:"capitalize",children:a.type}),F&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(xe,{className:"w-3 h-3"}),P," ",j({id:"apiSettings.providers.apiKey"})]}),a.routingStrategy&&e.jsx("span",{className:"capitalize",children:a.routingStrategy.replace("-"," ")})]}),a.apiBase&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1 truncate",children:a.apiBase})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{checked:a.enabled,onCheckedChange:d,disabled:v}),e.jsxs(us,{children:[e.jsx(js,{asChild:!0,children:e.jsx(f,{variant:"ghost",size:"icon",children:e.jsx(Ns,{className:"w-4 h-4"})})}),e.jsxs(vs,{align:"end",children:[e.jsxs(he,{onClick:r,children:[e.jsx(ys,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.edit"})]}),e.jsxs(he,{onClick:s,disabled:u,children:[e.jsx(xe,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.test"})]}),e.jsxs(he,{onClick:o,children:[e.jsx(cs,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.manageModels"})]}),F&&e.jsxs(he,{onClick:n,children:[e.jsx(xe,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.multiKeySettings"})]}),e.jsxs(he,{onClick:h,children:[e.jsx(ze,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.syncToCodexLens"})]}),e.jsx(fs,{}),e.jsxs(he,{onClick:t,disabled:M,className:"text-destructive",children:[e.jsx(ye,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.delete"})]})]})]})]})]})})}function Ft({onAddProvider:a,onEditProvider:r,onMultiKeySettings:t,onSyncToCodexLens:s,onManageModels:n}){const{formatMessage:h}=W(),{error:o}=ge(),[d,M]=i.useState(""),[u,v]=i.useState(!1),{providers:j,isLoading:P,refetch:F}=Ze(),{deleteProvider:H,isDeleting:k}=ot(),{updateProvider:I,isUpdating:C}=Ss(),{testProvider:D,isTesting:w}=mt(),{triggerHealthCheck:K}=ht(),g=i.useMemo(()=>j.filter(S=>{const _=S.name.toLowerCase().includes(d.toLowerCase())||S.type.toLowerCase().includes(d.toLowerCase()),b=!u||!S.enabled;return _&&b}),[j,d,u]),c=async(S,_)=>{const b=h({id:"apiSettings.providers.deleteConfirm"},{name:_});if(window.confirm(b))try{await H(S)}catch{o(h({id:"apiSettings.providers.deleteError"}))}},A=async(S,_)=>{try{await I(S,{enabled:_})}catch{o(h({id:"apiSettings.providers.toggleError"}))}},L=async S=>{try{(await D(S)).success&&await K(S)}catch{o(h({id:"apiSettings.providers.testError"}))}},z=j.filter(S=>S.enabled).length,y=j.length;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-bold text-foreground",children:h({id:"apiSettings.providers.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:h({id:"apiSettings.providers.description"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(f,{variant:"outline",onClick:()=>F(),disabled:P,children:[e.jsx(xe,{className:Ve("w-4 h-4 mr-2",P&&"animate-spin")}),h({id:"common.actions.refresh"})]}),e.jsxs(f,{onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),h({id:"apiSettings.providers.actions.add"})]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs(Q,{className:"p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ks,{className:"w-5 h-5 text-primary"}),e.jsx("span",{className:"text-2xl font-bold",children:y})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:h({id:"apiSettings.providers.stats.total"})})]}),e.jsxs(Q,{className:"p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ze,{className:"w-5 h-5 text-success"}),e.jsx("span",{className:"text-2xl font-bold",children:z})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:h({id:"apiSettings.providers.stats.enabled"})})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(N,{placeholder:h({id:"apiSettings.common.searchPlaceholder"}),value:d,onChange:S=>M(S.target.value),className:"pl-9"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs(f,{variant:u?"default":"outline",size:"sm",onClick:()=>v(S=>!S),children:[u?e.jsx(Ms,{className:"w-4 h-4 mr-2"}):e.jsx(ze,{className:"w-4 h-4 mr-2"}),h(u?{id:"apiSettings.providers.actions.hideDisabled"}:{id:"apiSettings.providers.actions.showDisabled"})]})})]}),P?e.jsx("div",{className:"space-y-4",children:[1,2,3,4,5].map(S=>e.jsx("div",{className:"h-24 bg-muted animate-pulse rounded-lg"},S))}):g.length===0?e.jsxs(Q,{className:"p-8 text-center",children:[e.jsx(ks,{className:"w-12 h-12 mx-auto text-muted-foreground/50"}),e.jsx("h3",{className:"mt-4 text-lg font-medium text-foreground",children:h({id:"apiSettings.providers.emptyState.title"})}),e.jsx("p",{className:"mt-2 text-muted-foreground",children:h({id:"apiSettings.providers.emptyState.message"})}),e.jsxs(f,{className:"mt-4",onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),h({id:"apiSettings.providers.actions.add"})]})]}):e.jsx("div",{className:"space-y-3",children:g.map(S=>e.jsx(It,{provider:S,onEdit:()=>r(S.id),onDelete:()=>c(S.id,S.name),onTest:()=>L(S.id),onMultiKeySettings:()=>t(S.id),onSyncToCodexLens:()=>s(S.id),onManageModels:()=>n(S.id),onToggleEnabled:_=>A(S.id,_),isDeleting:k,isTesting:w,isToggling:C},S.id))})]})}function Kt({entry:a,showKey:r,onToggleShowKey:t,onUpdate:s,onRemove:n}){const{formatMessage:h}=W();return e.jsxs("div",{className:"grid grid-cols-12 gap-2 items-start p-3 bg-muted/30 rounded-lg",children:[e.jsxs("div",{className:"col-span-3",children:[e.jsx(m,{className:"text-xs",children:h({id:"apiSettings.providers.keyLabel"})}),e.jsx(N,{value:a.label||"",onChange:o=>s({label:o.target.value}),placeholder:"Key 1",className:"mt-1"})]}),e.jsxs("div",{className:"col-span-4",children:[e.jsx(m,{className:"text-xs",children:h({id:"apiSettings.providers.keyValue"})}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx(N,{type:r?"text":"password",value:a.key,onChange:o=>s({key:o.target.value}),placeholder:"sk-...",className:"pr-8"}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full px-2",onClick:t,children:r?e.jsx(ts,{className:"w-4 h-4"}):e.jsx(as,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsx(m,{className:"text-xs",children:h({id:"apiSettings.providers.keyWeight"})}),e.jsx(N,{type:"number",min:"0",max:"100",value:a.weight??1,onChange:o=>s({weight:parseInt(o.target.value)||1}),className:"mt-1"})]}),e.jsxs("div",{className:"col-span-2 flex items-center gap-2 pt-5",children:[e.jsx(Z,{checked:a.enabled,onCheckedChange:o=>s({enabled:o})}),e.jsx("span",{className:"text-sm text-muted-foreground",children:a.enabled?h({id:"apiSettings.common.enabled"}):h({id:"apiSettings.common.disabled"})})]}),e.jsx("div",{className:"col-span-1 flex items-center justify-end pt-5",children:e.jsx(f,{type:"button",variant:"ghost",size:"icon",onClick:n,className:"text-destructive",children:e.jsx(ye,{className:"w-4 h-4"})})})]})}function At({open:a,onClose:r,provider:t}){const{formatMessage:s}=W(),{error:n}=ge(),h=!!t,{createProvider:o,isCreating:d}=xt(),{updateProvider:M,isUpdating:u}=Ss(),[v,j]=i.useState(""),[P,F]=i.useState("openai"),[H,k]=i.useState(""),[I,C]=i.useState(""),[D,w]=i.useState(!0),[K,g]=i.useState(!1),[c,A]=i.useState(300),[L,z]=i.useState(0),[y,S]=i.useState(""),[_,b]=i.useState(""),[p,O]=i.useState(""),[X,ne]=i.useState(),[ue,le]=i.useState(),[be,E]=i.useState(""),[G,q]=i.useState(!1),[te,de]=i.useState([]),[Re,Me]=i.useState(new Set),[_e,Pe]=i.useState("simple-shuffle"),[Ce,we]=i.useState(!1),[ke,Ee]=i.useState(60),[Te,je]=i.useState(300),[Ae,Ie]=i.useState(5),[ce,B]=i.useState(!1),[se,re]=i.useState([]),[ae,oe]=i.useState([]);i.useEffect(()=>{if(t){j(t.name),F(t.type),k(t.apiKey),C(t.apiBase||""),w(t.enabled),Pe(t.routingStrategy||"simple-shuffle"),t.advancedSettings&&(A(t.advancedSettings.timeout||300),z(t.advancedSettings.maxRetries||0),S(t.advancedSettings.organization||""),b(t.advancedSettings.apiVersion||""),O(t.advancedSettings.customHeaders?JSON.stringify(t.advancedSettings.customHeaders,null,2):""),ne(t.advancedSettings.rpm),le(t.advancedSettings.tpm),E(t.advancedSettings.proxy||""));const x=!!(t.apiKeys&&t.apiKeys.length>0);q(x),x&&t.apiKeys&&de(t.apiKeys.map(T=>({id:T.id,key:T.key,label:T.label,weight:T.weight,enabled:T.enabled}))),t.healthCheck&&(we(t.healthCheck.enabled),Ee(t.healthCheck.intervalSeconds),je(t.healthCheck.cooldownSeconds),Ie(t.healthCheck.failureThreshold)),t.llmModels&&re(t.llmModels.map(T=>({id:T.id,name:T.name,series:T.series,description:T.description}))),t.embeddingModels&&oe(t.embeddingModels.map(T=>({id:T.id,name:T.name,series:T.series,description:T.description})))}else j(""),F("openai"),k(""),C(""),w(!0),A(300),z(0),S(""),b(""),O(""),ne(void 0),le(void 0),E(""),q(!1),de([]),Pe("simple-shuffle"),we(!1),Ee(60),je(300),Ie(5),re([]),oe([])},[t,a]);const me=()=>{const x={id:`key-${Date.now()}`,key:"",label:`Key ${te.length+1}`,weight:1,enabled:!0};de([...te,x])},De=(x,T)=>{de(te.map((R,U)=>U===x?{...R,...T}:R))},is=x=>{de(te.filter((T,R)=>R!==x))},Xe=x=>{Me(T=>{const R=new Set(T);return R.has(x)?R.delete(x):R.add(x),R})},He=()=>{const x={id:`llm-${Date.now()}`,name:"",series:""};re([...se,x])},ns=x=>{re(se.filter((T,R)=>R!==x))},Fe=(x,T,R)=>{re(se.map((U,Je)=>Je===x?{...U,[T]:R}:U))},ls=()=>{const x={id:`emb-${Date.now()}`,name:"",series:""};oe([...ae,x])},Y=x=>{oe(ae.filter((T,R)=>R!==x))},Le=(x,T,R)=>{oe(ae.map((U,Je)=>Je===x?{...U,[T]:R}:U))},ds=async()=>{try{let x;if(p.trim())try{x=JSON.parse(p)}catch{alert(s({id:"apiSettings.messages.invalidJsonHeaders"}));return}const T=new Date().toISOString(),R={name:v,type:P,apiKey:G?"":H,apiBase:I||void 0,enabled:D,advancedSettings:{timeout:c,maxRetries:L,organization:y||void 0,apiVersion:_||void 0,customHeaders:x,rpm:X,tpm:ue,proxy:be||void 0},apiKeys:G?te.map(U=>({id:U.id,key:U.key,label:U.label,weight:U.weight,enabled:U.enabled})):void 0,routingStrategy:G?_e:void 0,healthCheck:Ce?{enabled:!0,intervalSeconds:ke,cooldownSeconds:Te,failureThreshold:Ae}:void 0,llmModels:se.filter(U=>U.name.trim()).map(U=>({id:U.id,name:U.name,type:"llm",series:U.series||U.name.split("-")[0],enabled:!0,createdAt:T,updatedAt:T})),embeddingModels:ae.filter(U=>U.name.trim()).map(U=>({id:U.id,name:U.name,type:"embedding",series:U.series||U.name.split("-")[0],enabled:!0,createdAt:T,updatedAt:T}))};h&&t?await M(t.id,R):await o(R),r()}catch{n(s({id:"apiSettings.providers.saveError"}))}},Ue=d||u;return e.jsx($e,{open:a,onOpenChange:r,children:e.jsxs(Ge,{className:"max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(qe,{children:[e.jsx(Qe,{children:s(h?{id:"apiSettings.providers.actions.edit"}:{id:"apiSettings.providers.actions.add"})}),e.jsx(We,{children:s({id:"apiSettings.providers.description"})})]}),e.jsxs("div",{className:"space-y-6 py-4",children:[e.jsxs("div",{className:"space-y-4",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s({id:"apiSettings.providers.basicInfo"})}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"name",children:[s({id:"apiSettings.providers.displayName"})," *"]}),e.jsx(N,{id:"name",value:v,onChange:x=>j(x.target.value),placeholder:"My OpenAI"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"type",children:[s({id:"apiSettings.common.type"})," *"]}),e.jsxs(ve,{value:P,onValueChange:x=>F(x),children:[e.jsx(fe,{id:"type",children:e.jsx(Se,{})}),e.jsxs(Ne,{children:[e.jsx(V,{value:"openai",children:"OpenAI"}),e.jsx(V,{value:"anthropic",children:"Anthropic"}),e.jsx(V,{value:"custom",children:"Custom"})]})]})]})]}),!G&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"apiKey",children:[s({id:"apiSettings.providers.apiKey"})," *"]}),e.jsx(N,{id:"apiKey",type:"password",value:H,onChange:x=>k(x.target.value),placeholder:"sk-..."}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.useEnvVar"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"apiBase",children:s({id:"apiSettings.providers.apiBaseUrl"})}),e.jsx(N,{id:"apiBase",value:I,onChange:x=>C(x.target.value),placeholder:"https://api.openai.com/v1"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{id:"enabled",checked:D,onCheckedChange:w}),e.jsx(m,{htmlFor:"enabled",children:s({id:"apiSettings.providers.enableProvider"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{id:"useMultiKey",checked:G,onCheckedChange:q}),e.jsx(m,{htmlFor:"useMultiKey",children:s({id:"apiSettings.providers.multiKeySettings"})})]})]}),G&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s({id:"apiSettings.providers.multiKeySettings"})}),e.jsxs(f,{type:"button",size:"sm",onClick:me,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.providers.addKey"})]})]}),te.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"apiSettings.providers.noModels"})}):e.jsx("div",{className:"space-y-2",children:te.map((x,T)=>e.jsx(Kt,{entry:x,showKey:Re.has(T),onToggleShowKey:()=>Xe(T),onUpdate:R=>De(T,R),onRemove:()=>is(T)},x.id))}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"routingStrategy",children:s({id:"apiSettings.providers.routingStrategy"})}),e.jsxs(ve,{value:_e,onValueChange:x=>Pe(x),children:[e.jsx(fe,{id:"routingStrategy",children:e.jsx(Se,{})}),e.jsxs(Ne,{children:[e.jsx(V,{value:"simple-shuffle",children:s({id:"apiSettings.providers.simpleShuffle"})}),e.jsx(V,{value:"weighted",children:s({id:"apiSettings.providers.weighted"})}),e.jsx(V,{value:"latency-based",children:s({id:"apiSettings.providers.latencyBased"})}),e.jsx(V,{value:"cost-based",children:s({id:"apiSettings.providers.costBased"})}),e.jsx(V,{value:"least-busy",children:s({id:"apiSettings.providers.leastBusy"})})]})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(m,{children:s({id:"apiSettings.providers.healthCheck"})}),e.jsx(Z,{checked:Ce,onCheckedChange:we})]}),Ce&&e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"checkInterval",children:s({id:"apiSettings.providers.checkInterval"})}),e.jsx(N,{id:"checkInterval",type:"number",min:"10",value:ke,onChange:x=>Ee(parseInt(x.target.value)||60)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"cooldownPeriod",children:s({id:"apiSettings.providers.cooldownPeriod"})}),e.jsx(N,{id:"cooldownPeriod",type:"number",min:"10",value:Te,onChange:x=>je(parseInt(x.target.value)||300)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"failureThreshold",children:s({id:"apiSettings.providers.failureThreshold"})}),e.jsx(N,{id:"failureThreshold",type:"number",min:"1",value:Ae,onChange:x=>Ie(parseInt(x.target.value)||5)})]})]})]})]}),e.jsxs(hs,{open:K,onOpenChange:g,children:[e.jsx(xs,{asChild:!0,children:e.jsxs(f,{type:"button",variant:"ghost",className:"w-full justify-between",children:[e.jsx("span",{className:"font-semibold",children:s({id:"apiSettings.providers.advancedSettings"})}),K?e.jsx(os,{className:"w-4 h-4"}):e.jsx(ms,{className:"w-4 h-4"})]})}),e.jsxs(gs,{className:"space-y-4 pt-4",children:[e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"timeout",children:s({id:"apiSettings.providers.timeout"})}),e.jsx(N,{id:"timeout",type:"number",min:"1",value:c,onChange:x=>A(parseInt(x.target.value)||300)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.timeoutHint"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"maxRetries",children:s({id:"apiSettings.providers.maxRetries"})}),e.jsx(N,{id:"maxRetries",type:"number",min:"0",value:L,onChange:x=>z(parseInt(x.target.value)||0)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"organization",children:s({id:"apiSettings.providers.organization"})}),e.jsx(N,{id:"organization",value:y,onChange:x=>S(x.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.organizationHint"})})]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"apiVersion",children:s({id:"apiSettings.providers.apiVersion"})}),e.jsx(N,{id:"apiVersion",value:_,onChange:x=>b(x.target.value),placeholder:"2024-02-01"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.apiVersionHint"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"rpm",children:s({id:"apiSettings.providers.rpm"})}),e.jsx(N,{id:"rpm",type:"number",min:"0",value:X??"",onChange:x=>ne(x.target.value?parseInt(x.target.value):void 0),placeholder:s({id:"apiSettings.providers.unlimited"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"tpm",children:s({id:"apiSettings.providers.tpm"})}),e.jsx(N,{id:"tpm",type:"number",min:"0",value:ue??"",onChange:x=>le(x.target.value?parseInt(x.target.value):void 0),placeholder:s({id:"apiSettings.providers.unlimited"})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"proxy",children:s({id:"apiSettings.providers.proxy"})}),e.jsx(N,{id:"proxy",value:be,onChange:x=>E(x.target.value),placeholder:"http://proxy.example.com:8080"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"customHeaders",children:s({id:"apiSettings.providers.customHeaders"})}),e.jsx(Ke,{id:"customHeaders",value:p,onChange:x=>O(x.target.value),placeholder:`{
|
|
1
|
+
import{u as W,al as ge,r as i,j as e,e as f,Z as xe,c as Ve,a7 as ie,C as Q,m as ks,k as ze,b as ps,I as N,K as Ms,D as us,d as js,f as vs,g as he,S as cs,h as fs,T as ye,B as ee,x as $e,y as Ge,z as qe,A as Qe,E as We,bu as m,aq as ve,ar as fe,as as Se,at as Ne,au as V,cy as os,ap as ms,bO as Ke,G as Ye,bq as Be,ck as Oe,bp as et,ae as Cs,N as ss,av as st,X as Ds,bf as tt,a2 as at,a3 as it,a4 as Es,a5 as Ts,an as Is,e0 as nt,e1 as lt,d6 as dt,R as rt}from"./index-dWT2M6Ef.js";import{T as ct}from"./TabsNavigation-qqt70VYL.js";import{S as Z}from"./Switch-BPMdND9H.js";import{u as Ze,a as ot,b as Ss,c as mt,d as ht,e as xt,f as Ls,g as gt,h as Os,i as pt,j as ut,k as jt,l as vt,m as zs,n as ft,o as Bs,p as St,q as Nt,r as yt,s as Rs,t as bt,v as Ct,w as wt,x as Mt,y as Pt}from"./useApiSettings-CqP2BAJ7.js";import{E as Ns}from"./ellipsis-vertical-BpTysg-Y.js";import{S as ys}from"./square-pen-CnZgm6g-.js";import{C as hs,a as xs,b as gs}from"./Collapsible-CRNbykXN.js";import{E as ts}from"./eye-off-D8t3JfWG.js";import{E as as}from"./eye-DGY1rAZs.js";import{A as _s,a as Hs,b as Us,c as Js,d as Vs,e as $s,f as Gs,g as qs}from"./AlertDialog-BW9jiZ-p.js";import{F as kt}from"./file-text-DrJFiOUB.js";import{H as Et}from"./hard-drive-CmuTZpsB.js";import{S as Qs}from"./save-DuO6OF0C.js";import{L as Tt}from"./link-BZtPgLW0.js";import"./useLocale-sXTrdxcJ.js";import"./errorSanitizer-IY9pf5g4.js";function It({provider:a,onEdit:r,onDelete:t,onTest:s,onMultiKeySettings:n,onSyncToCodexLens:h,onManageModels:o,onToggleEnabled:d,isDeleting:M,isTesting:u,isToggling:v}){var k,I;const{formatMessage:j}=W(),P=((k=a.apiKeys)==null?void 0:k.filter(C=>C.enabled).length)||0,F=(((I=a.apiKeys)==null?void 0:I.length)||0)>0,H=()=>{var K;if(!a.enabled)return e.jsx(ee,{variant:"secondary",children:j({id:"apiSettings.common.disabled"})});if(!((K=a.healthCheck)!=null&&K.enabled))return e.jsx(ee,{variant:"outline",children:j({id:"apiSettings.providers.unknown"})});const C=a.apiKeys||[];if(C.length===0)return e.jsx(ee,{variant:"info",children:j({id:"apiSettings.providers.unknown"})});const D=C.filter(g=>g.healthStatus==="healthy").length;return C.filter(g=>g.healthStatus==="unhealthy").length>0?e.jsx(ee,{variant:"destructive",children:j({id:"apiSettings.providers.unhealthy"})}):D===C.length?e.jsx(ee,{variant:"success",children:j({id:"apiSettings.providers.healthy"})}):e.jsx(ee,{variant:"warning",children:j({id:"apiSettings.providers.unknown"})})};return e.jsx(Q,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground truncate",children:a.name}),H()]}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-sm text-muted-foreground",children:[e.jsx("span",{className:"capitalize",children:a.type}),F&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(xe,{className:"w-3 h-3"}),P," ",j({id:"apiSettings.providers.apiKey"})]}),a.routingStrategy&&e.jsx("span",{className:"capitalize",children:a.routingStrategy.replace("-"," ")})]}),a.apiBase&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1 truncate",children:a.apiBase})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{checked:a.enabled,onCheckedChange:d,disabled:v}),e.jsxs(us,{children:[e.jsx(js,{asChild:!0,children:e.jsx(f,{variant:"ghost",size:"icon",children:e.jsx(Ns,{className:"w-4 h-4"})})}),e.jsxs(vs,{align:"end",children:[e.jsxs(he,{onClick:r,children:[e.jsx(ys,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.edit"})]}),e.jsxs(he,{onClick:s,disabled:u,children:[e.jsx(xe,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.test"})]}),e.jsxs(he,{onClick:o,children:[e.jsx(cs,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.manageModels"})]}),F&&e.jsxs(he,{onClick:n,children:[e.jsx(xe,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.multiKeySettings"})]}),e.jsxs(he,{onClick:h,children:[e.jsx(ze,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.syncToCodexLens"})]}),e.jsx(fs,{}),e.jsxs(he,{onClick:t,disabled:M,className:"text-destructive",children:[e.jsx(ye,{className:"w-4 h-4 mr-2"}),j({id:"apiSettings.providers.actions.delete"})]})]})]})]})]})})}function Ft({onAddProvider:a,onEditProvider:r,onMultiKeySettings:t,onSyncToCodexLens:s,onManageModels:n}){const{formatMessage:h}=W(),{error:o}=ge(),[d,M]=i.useState(""),[u,v]=i.useState(!1),{providers:j,isLoading:P,refetch:F}=Ze(),{deleteProvider:H,isDeleting:k}=ot(),{updateProvider:I,isUpdating:C}=Ss(),{testProvider:D,isTesting:w}=mt(),{triggerHealthCheck:K}=ht(),g=i.useMemo(()=>j.filter(S=>{const _=S.name.toLowerCase().includes(d.toLowerCase())||S.type.toLowerCase().includes(d.toLowerCase()),b=!u||!S.enabled;return _&&b}),[j,d,u]),c=async(S,_)=>{const b=h({id:"apiSettings.providers.deleteConfirm"},{name:_});if(window.confirm(b))try{await H(S)}catch{o(h({id:"apiSettings.providers.deleteError"}))}},A=async(S,_)=>{try{await I(S,{enabled:_})}catch{o(h({id:"apiSettings.providers.toggleError"}))}},L=async S=>{try{(await D(S)).success&&await K(S)}catch{o(h({id:"apiSettings.providers.testError"}))}},z=j.filter(S=>S.enabled).length,y=j.length;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-bold text-foreground",children:h({id:"apiSettings.providers.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:h({id:"apiSettings.providers.description"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(f,{variant:"outline",onClick:()=>F(),disabled:P,children:[e.jsx(xe,{className:Ve("w-4 h-4 mr-2",P&&"animate-spin")}),h({id:"common.actions.refresh"})]}),e.jsxs(f,{onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),h({id:"apiSettings.providers.actions.add"})]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs(Q,{className:"p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ks,{className:"w-5 h-5 text-primary"}),e.jsx("span",{className:"text-2xl font-bold",children:y})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:h({id:"apiSettings.providers.stats.total"})})]}),e.jsxs(Q,{className:"p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ze,{className:"w-5 h-5 text-success"}),e.jsx("span",{className:"text-2xl font-bold",children:z})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:h({id:"apiSettings.providers.stats.enabled"})})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(N,{placeholder:h({id:"apiSettings.common.searchPlaceholder"}),value:d,onChange:S=>M(S.target.value),className:"pl-9"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs(f,{variant:u?"default":"outline",size:"sm",onClick:()=>v(S=>!S),children:[u?e.jsx(Ms,{className:"w-4 h-4 mr-2"}):e.jsx(ze,{className:"w-4 h-4 mr-2"}),h(u?{id:"apiSettings.providers.actions.hideDisabled"}:{id:"apiSettings.providers.actions.showDisabled"})]})})]}),P?e.jsx("div",{className:"space-y-4",children:[1,2,3,4,5].map(S=>e.jsx("div",{className:"h-24 bg-muted animate-pulse rounded-lg"},S))}):g.length===0?e.jsxs(Q,{className:"p-8 text-center",children:[e.jsx(ks,{className:"w-12 h-12 mx-auto text-muted-foreground/50"}),e.jsx("h3",{className:"mt-4 text-lg font-medium text-foreground",children:h({id:"apiSettings.providers.emptyState.title"})}),e.jsx("p",{className:"mt-2 text-muted-foreground",children:h({id:"apiSettings.providers.emptyState.message"})}),e.jsxs(f,{className:"mt-4",onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),h({id:"apiSettings.providers.actions.add"})]})]}):e.jsx("div",{className:"space-y-3",children:g.map(S=>e.jsx(It,{provider:S,onEdit:()=>r(S.id),onDelete:()=>c(S.id,S.name),onTest:()=>L(S.id),onMultiKeySettings:()=>t(S.id),onSyncToCodexLens:()=>s(S.id),onManageModels:()=>n(S.id),onToggleEnabled:_=>A(S.id,_),isDeleting:k,isTesting:w,isToggling:C},S.id))})]})}function Kt({entry:a,showKey:r,onToggleShowKey:t,onUpdate:s,onRemove:n}){const{formatMessage:h}=W();return e.jsxs("div",{className:"grid grid-cols-12 gap-2 items-start p-3 bg-muted/30 rounded-lg",children:[e.jsxs("div",{className:"col-span-3",children:[e.jsx(m,{className:"text-xs",children:h({id:"apiSettings.providers.keyLabel"})}),e.jsx(N,{value:a.label||"",onChange:o=>s({label:o.target.value}),placeholder:"Key 1",className:"mt-1"})]}),e.jsxs("div",{className:"col-span-4",children:[e.jsx(m,{className:"text-xs",children:h({id:"apiSettings.providers.keyValue"})}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx(N,{type:r?"text":"password",value:a.key,onChange:o=>s({key:o.target.value}),placeholder:"sk-...",className:"pr-8"}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full px-2",onClick:t,children:r?e.jsx(ts,{className:"w-4 h-4"}):e.jsx(as,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsx(m,{className:"text-xs",children:h({id:"apiSettings.providers.keyWeight"})}),e.jsx(N,{type:"number",min:"0",max:"100",value:a.weight??1,onChange:o=>s({weight:parseInt(o.target.value)||1}),className:"mt-1"})]}),e.jsxs("div",{className:"col-span-2 flex items-center gap-2 pt-5",children:[e.jsx(Z,{checked:a.enabled,onCheckedChange:o=>s({enabled:o})}),e.jsx("span",{className:"text-sm text-muted-foreground",children:a.enabled?h({id:"apiSettings.common.enabled"}):h({id:"apiSettings.common.disabled"})})]}),e.jsx("div",{className:"col-span-1 flex items-center justify-end pt-5",children:e.jsx(f,{type:"button",variant:"ghost",size:"icon",onClick:n,className:"text-destructive",children:e.jsx(ye,{className:"w-4 h-4"})})})]})}function At({open:a,onClose:r,provider:t}){const{formatMessage:s}=W(),{error:n}=ge(),h=!!t,{createProvider:o,isCreating:d}=xt(),{updateProvider:M,isUpdating:u}=Ss(),[v,j]=i.useState(""),[P,F]=i.useState("openai"),[H,k]=i.useState(""),[I,C]=i.useState(""),[D,w]=i.useState(!0),[K,g]=i.useState(!1),[c,A]=i.useState(300),[L,z]=i.useState(0),[y,S]=i.useState(""),[_,b]=i.useState(""),[p,O]=i.useState(""),[X,ne]=i.useState(),[ue,le]=i.useState(),[be,E]=i.useState(""),[G,q]=i.useState(!1),[te,de]=i.useState([]),[Re,Me]=i.useState(new Set),[_e,Pe]=i.useState("simple-shuffle"),[Ce,we]=i.useState(!1),[ke,Ee]=i.useState(60),[Te,je]=i.useState(300),[Ae,Ie]=i.useState(5),[ce,B]=i.useState(!1),[se,re]=i.useState([]),[ae,oe]=i.useState([]);i.useEffect(()=>{if(t){j(t.name),F(t.type),k(t.apiKey),C(t.apiBase||""),w(t.enabled),Pe(t.routingStrategy||"simple-shuffle"),t.advancedSettings&&(A(t.advancedSettings.timeout||300),z(t.advancedSettings.maxRetries||0),S(t.advancedSettings.organization||""),b(t.advancedSettings.apiVersion||""),O(t.advancedSettings.customHeaders?JSON.stringify(t.advancedSettings.customHeaders,null,2):""),ne(t.advancedSettings.rpm),le(t.advancedSettings.tpm),E(t.advancedSettings.proxy||""));const x=!!(t.apiKeys&&t.apiKeys.length>0);q(x),x&&t.apiKeys&&de(t.apiKeys.map(T=>({id:T.id,key:T.key,label:T.label,weight:T.weight,enabled:T.enabled}))),t.healthCheck&&(we(t.healthCheck.enabled),Ee(t.healthCheck.intervalSeconds),je(t.healthCheck.cooldownSeconds),Ie(t.healthCheck.failureThreshold)),t.llmModels&&re(t.llmModels.map(T=>({id:T.id,name:T.name,series:T.series,description:T.description}))),t.embeddingModels&&oe(t.embeddingModels.map(T=>({id:T.id,name:T.name,series:T.series,description:T.description})))}else j(""),F("openai"),k(""),C(""),w(!0),A(300),z(0),S(""),b(""),O(""),ne(void 0),le(void 0),E(""),q(!1),de([]),Pe("simple-shuffle"),we(!1),Ee(60),je(300),Ie(5),re([]),oe([])},[t,a]);const me=()=>{const x={id:`key-${Date.now()}`,key:"",label:`Key ${te.length+1}`,weight:1,enabled:!0};de([...te,x])},De=(x,T)=>{de(te.map((R,U)=>U===x?{...R,...T}:R))},is=x=>{de(te.filter((T,R)=>R!==x))},Xe=x=>{Me(T=>{const R=new Set(T);return R.has(x)?R.delete(x):R.add(x),R})},He=()=>{const x={id:`llm-${Date.now()}`,name:"",series:""};re([...se,x])},ns=x=>{re(se.filter((T,R)=>R!==x))},Fe=(x,T,R)=>{re(se.map((U,Je)=>Je===x?{...U,[T]:R}:U))},ls=()=>{const x={id:`emb-${Date.now()}`,name:"",series:""};oe([...ae,x])},Y=x=>{oe(ae.filter((T,R)=>R!==x))},Le=(x,T,R)=>{oe(ae.map((U,Je)=>Je===x?{...U,[T]:R}:U))},ds=async()=>{try{let x;if(p.trim())try{x=JSON.parse(p)}catch{alert(s({id:"apiSettings.messages.invalidJsonHeaders"}));return}const T=new Date().toISOString(),R={name:v,type:P,apiKey:G?"":H,apiBase:I||void 0,enabled:D,advancedSettings:{timeout:c,maxRetries:L,organization:y||void 0,apiVersion:_||void 0,customHeaders:x,rpm:X,tpm:ue,proxy:be||void 0},apiKeys:G?te.map(U=>({id:U.id,key:U.key,label:U.label,weight:U.weight,enabled:U.enabled})):void 0,routingStrategy:G?_e:void 0,healthCheck:Ce?{enabled:!0,intervalSeconds:ke,cooldownSeconds:Te,failureThreshold:Ae}:void 0,llmModels:se.filter(U=>U.name.trim()).map(U=>({id:U.id,name:U.name,type:"llm",series:U.series||U.name.split("-")[0],enabled:!0,createdAt:T,updatedAt:T})),embeddingModels:ae.filter(U=>U.name.trim()).map(U=>({id:U.id,name:U.name,type:"embedding",series:U.series||U.name.split("-")[0],enabled:!0,createdAt:T,updatedAt:T}))};h&&t?await M(t.id,R):await o(R),r()}catch{n(s({id:"apiSettings.providers.saveError"}))}},Ue=d||u;return e.jsx($e,{open:a,onOpenChange:r,children:e.jsxs(Ge,{className:"max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(qe,{children:[e.jsx(Qe,{children:s(h?{id:"apiSettings.providers.actions.edit"}:{id:"apiSettings.providers.actions.add"})}),e.jsx(We,{children:s({id:"apiSettings.providers.description"})})]}),e.jsxs("div",{className:"space-y-6 py-4",children:[e.jsxs("div",{className:"space-y-4",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s({id:"apiSettings.providers.basicInfo"})}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"name",children:[s({id:"apiSettings.providers.displayName"})," *"]}),e.jsx(N,{id:"name",value:v,onChange:x=>j(x.target.value),placeholder:"My OpenAI"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"type",children:[s({id:"apiSettings.common.type"})," *"]}),e.jsxs(ve,{value:P,onValueChange:x=>F(x),children:[e.jsx(fe,{id:"type",children:e.jsx(Se,{})}),e.jsxs(Ne,{children:[e.jsx(V,{value:"openai",children:"OpenAI"}),e.jsx(V,{value:"anthropic",children:"Anthropic"}),e.jsx(V,{value:"custom",children:"Custom"})]})]})]})]}),!G&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"apiKey",children:[s({id:"apiSettings.providers.apiKey"})," *"]}),e.jsx(N,{id:"apiKey",type:"password",value:H,onChange:x=>k(x.target.value),placeholder:"sk-..."}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.useEnvVar"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"apiBase",children:s({id:"apiSettings.providers.apiBaseUrl"})}),e.jsx(N,{id:"apiBase",value:I,onChange:x=>C(x.target.value),placeholder:"https://api.openai.com/v1"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{id:"enabled",checked:D,onCheckedChange:w}),e.jsx(m,{htmlFor:"enabled",children:s({id:"apiSettings.providers.enableProvider"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{id:"useMultiKey",checked:G,onCheckedChange:q}),e.jsx(m,{htmlFor:"useMultiKey",children:s({id:"apiSettings.providers.multiKeySettings"})})]})]}),G&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s({id:"apiSettings.providers.multiKeySettings"})}),e.jsxs(f,{type:"button",size:"sm",onClick:me,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.providers.addKey"})]})]}),te.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"apiSettings.providers.noModels"})}):e.jsx("div",{className:"space-y-2",children:te.map((x,T)=>e.jsx(Kt,{entry:x,showKey:Re.has(T),onToggleShowKey:()=>Xe(T),onUpdate:R=>De(T,R),onRemove:()=>is(T)},x.id))}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"routingStrategy",children:s({id:"apiSettings.providers.routingStrategy"})}),e.jsxs(ve,{value:_e,onValueChange:x=>Pe(x),children:[e.jsx(fe,{id:"routingStrategy",children:e.jsx(Se,{})}),e.jsxs(Ne,{children:[e.jsx(V,{value:"simple-shuffle",children:s({id:"apiSettings.providers.simpleShuffle"})}),e.jsx(V,{value:"weighted",children:s({id:"apiSettings.providers.weighted"})}),e.jsx(V,{value:"latency-based",children:s({id:"apiSettings.providers.latencyBased"})}),e.jsx(V,{value:"cost-based",children:s({id:"apiSettings.providers.costBased"})}),e.jsx(V,{value:"least-busy",children:s({id:"apiSettings.providers.leastBusy"})})]})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(m,{children:s({id:"apiSettings.providers.healthCheck"})}),e.jsx(Z,{checked:Ce,onCheckedChange:we})]}),Ce&&e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"checkInterval",children:s({id:"apiSettings.providers.checkInterval"})}),e.jsx(N,{id:"checkInterval",type:"number",min:"10",value:ke,onChange:x=>Ee(parseInt(x.target.value)||60)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"cooldownPeriod",children:s({id:"apiSettings.providers.cooldownPeriod"})}),e.jsx(N,{id:"cooldownPeriod",type:"number",min:"10",value:Te,onChange:x=>je(parseInt(x.target.value)||300)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"failureThreshold",children:s({id:"apiSettings.providers.failureThreshold"})}),e.jsx(N,{id:"failureThreshold",type:"number",min:"1",value:Ae,onChange:x=>Ie(parseInt(x.target.value)||5)})]})]})]})]}),e.jsxs(hs,{open:K,onOpenChange:g,children:[e.jsx(xs,{asChild:!0,children:e.jsxs(f,{type:"button",variant:"ghost",className:"w-full justify-between",children:[e.jsx("span",{className:"font-semibold",children:s({id:"apiSettings.providers.advancedSettings"})}),K?e.jsx(os,{className:"w-4 h-4"}):e.jsx(ms,{className:"w-4 h-4"})]})}),e.jsxs(gs,{className:"space-y-4 pt-4",children:[e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"timeout",children:s({id:"apiSettings.providers.timeout"})}),e.jsx(N,{id:"timeout",type:"number",min:"1",value:c,onChange:x=>A(parseInt(x.target.value)||300)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.timeoutHint"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"maxRetries",children:s({id:"apiSettings.providers.maxRetries"})}),e.jsx(N,{id:"maxRetries",type:"number",min:"0",value:L,onChange:x=>z(parseInt(x.target.value)||0)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"organization",children:s({id:"apiSettings.providers.organization"})}),e.jsx(N,{id:"organization",value:y,onChange:x=>S(x.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.organizationHint"})})]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"apiVersion",children:s({id:"apiSettings.providers.apiVersion"})}),e.jsx(N,{id:"apiVersion",value:_,onChange:x=>b(x.target.value),placeholder:"2024-02-01"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.apiVersionHint"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"rpm",children:s({id:"apiSettings.providers.rpm"})}),e.jsx(N,{id:"rpm",type:"number",min:"0",value:X??"",onChange:x=>ne(x.target.value?parseInt(x.target.value):void 0),placeholder:s({id:"apiSettings.providers.unlimited"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"tpm",children:s({id:"apiSettings.providers.tpm"})}),e.jsx(N,{id:"tpm",type:"number",min:"0",value:ue??"",onChange:x=>le(x.target.value?parseInt(x.target.value):void 0),placeholder:s({id:"apiSettings.providers.unlimited"})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"proxy",children:s({id:"apiSettings.providers.proxy"})}),e.jsx(N,{id:"proxy",value:be,onChange:x=>E(x.target.value),placeholder:"http://proxy.example.com:8080"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"customHeaders",children:s({id:"apiSettings.providers.customHeaders"})}),e.jsx(Ke,{id:"customHeaders",value:p,onChange:x=>O(x.target.value),placeholder:`{
|
|
2
2
|
"X-Custom": "value"
|
|
3
3
|
}`,rows:3}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.providers.customHeadersHint"})})]})]})]}),e.jsxs(hs,{open:ce,onOpenChange:B,children:[e.jsx(xs,{asChild:!0,children:e.jsxs(f,{type:"button",variant:"ghost",className:"w-full justify-between",children:[e.jsx("span",{className:"font-semibold",children:s({id:"apiSettings.providers.modelSettings"})}),ce?e.jsx(os,{className:"w-4 h-4"}):e.jsx(ms,{className:"w-4 h-4"})]})}),e.jsxs(gs,{className:"space-y-4 pt-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h4",{className:"text-sm font-medium",children:s({id:"apiSettings.providers.llmModels"})}),e.jsxs(f,{type:"button",size:"sm",onClick:He,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.providers.addLlmModel"})]})]}),se.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"apiSettings.providers.noModels"})}):e.jsx("div",{className:"space-y-2",children:se.map((x,T)=>e.jsxs("div",{className:"flex items-start gap-2 p-3 bg-muted/30 rounded-lg",children:[e.jsxs("div",{className:"flex-1 grid grid-cols-2 gap-2",children:[e.jsx(N,{value:x.name,onChange:R=>Fe(T,"name",R.target.value),placeholder:s({id:"apiSettings.providers.modelId"})}),e.jsx(N,{value:x.series||"",onChange:R=>Fe(T,"series",R.target.value),placeholder:s({id:"apiSettings.providers.modelSeries"})})]}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",onClick:()=>ns(T),className:"text-destructive",children:e.jsx(ye,{className:"w-4 h-4"})})]},x.id))})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h4",{className:"text-sm font-medium",children:s({id:"apiSettings.providers.embeddingModels"})}),e.jsxs(f,{type:"button",size:"sm",onClick:ls,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.providers.addEmbeddingModel"})]})]}),ae.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"apiSettings.providers.noModels"})}):e.jsx("div",{className:"space-y-2",children:ae.map((x,T)=>e.jsxs("div",{className:"flex items-start gap-2 p-3 bg-muted/30 rounded-lg",children:[e.jsxs("div",{className:"flex-1 grid grid-cols-2 gap-2",children:[e.jsx(N,{value:x.name,onChange:R=>Le(T,"name",R.target.value),placeholder:s({id:"apiSettings.providers.modelId"})}),e.jsx(N,{value:x.series||"",onChange:R=>Le(T,"series",R.target.value),placeholder:s({id:"apiSettings.providers.modelSeries"})})]}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",onClick:()=>Y(T),className:"text-destructive",children:e.jsx(ye,{className:"w-4 h-4"})})]},x.id))})]})]})]})]}),e.jsxs(Ye,{children:[e.jsx(f,{type:"button",variant:"outline",onClick:r,disabled:Ue,children:s({id:"apiSettings.common.cancel"})}),e.jsxs(f,{onClick:ds,disabled:Ue||!v.trim(),children:[Ue?e.jsx(xe,{className:"w-4 h-4 mr-2 animate-spin"}):e.jsx(Be,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.common.save"})]})]})]})})}function Dt({endpoint:a,onEdit:r,onDelete:t,onToggleEnabled:s,isDeleting:n,isToggling:h}){var d,M;const{formatMessage:o}=W();return e.jsx(Q,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground font-mono",children:a.id}),a.enabled?e.jsx(ee,{variant:"success",children:o({id:"apiSettings.common.enabled"})}):e.jsx(ee,{variant:"secondary",children:o({id:"apiSettings.common.disabled"})}),a.cacheStrategy.enabled&&e.jsxs(ee,{variant:"info",className:"flex items-center gap-1",children:[e.jsx(Oe,{className:"w-3 h-3"}),o({id:"apiSettings.endpoints.cacheStrategy"})]})]}),e.jsx("p",{className:"text-sm font-medium text-foreground mt-1",children:a.name}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-sm text-muted-foreground",children:[e.jsxs("span",{children:[o({id:"apiSettings.endpoints.provider"}),": ",a.providerId]}),e.jsxs("span",{children:[o({id:"apiSettings.endpoints.model"}),": ",a.model]})]}),a.description&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:a.description}),a.cacheStrategy.enabled&&e.jsxs("div",{className:"flex items-center gap-3 mt-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:[o({id:"apiSettings.endpoints.cacheTTL"}),": ",a.cacheStrategy.ttlMinutes,"m"]}),e.jsxs("span",{children:[o({id:"apiSettings.endpoints.cacheMaxSize"}),": ",a.cacheStrategy.maxSizeKB,"KB"]}),(((d=a.cacheStrategy.filePatterns)==null?void 0:d.length)||0)>0&&e.jsxs("span",{children:[o({id:"apiSettings.endpoints.filePatterns"}),": ",((M=a.cacheStrategy.filePatterns)==null?void 0:M.length)||0]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{checked:a.enabled,onCheckedChange:s,disabled:h}),e.jsxs(us,{children:[e.jsx(js,{asChild:!0,children:e.jsx(f,{variant:"ghost",size:"icon",children:e.jsx(Ns,{className:"w-4 h-4"})})}),e.jsxs(vs,{align:"end",children:[e.jsxs(he,{onClick:r,children:[e.jsx(ys,{className:"w-4 h-4 mr-2"}),o({id:"apiSettings.endpoints.actions.edit"})]}),e.jsx(fs,{}),e.jsxs(he,{onClick:t,disabled:n,className:"text-destructive",children:[e.jsx(ye,{className:"w-4 h-4 mr-2"}),o({id:"apiSettings.endpoints.actions.delete"})]})]})]})]})]})})}function Lt({onAddEndpoint:a,onEditEndpoint:r}){const{formatMessage:t}=W(),{error:s}=ge(),[n,h]=i.useState(""),[o,d]=i.useState(!1),[M,u]=i.useState(!1),{endpoints:v,cachedCount:j,isLoading:P,refetch:F}=Ls(),{deleteEndpoint:H,isDeleting:k}=gt(),{updateEndpoint:I,isUpdating:C}=Os(),D=i.useMemo(()=>v.filter(c=>{const A=c.id.toLowerCase().includes(n.toLowerCase())||c.name.toLowerCase().includes(n.toLowerCase())||c.model.toLowerCase().includes(n.toLowerCase()),L=!o||!c.enabled,z=!M||c.cacheStrategy.enabled;return A&&L&&z}),[v,n,o,M]),w=async(c,A)=>{const L=t({id:"apiSettings.endpoints.deleteConfirm"},{id:A});if(window.confirm(L))try{await H(c)}catch{s(t({id:"apiSettings.endpoints.deleteError"}))}},K=async(c,A)=>{try{await I(c,{enabled:A})}catch{s(t({id:"apiSettings.endpoints.toggleError"}))}},g=v.length;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-bold text-foreground",children:t({id:"apiSettings.endpoints.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:t({id:"apiSettings.endpoints.description"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(f,{variant:"outline",onClick:()=>F(),disabled:P,children:[e.jsx(xe,{className:Ve("w-4 h-4 mr-2",P&&"animate-spin")}),t({id:"common.actions.refresh"})]}),e.jsxs(f,{onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),t({id:"apiSettings.endpoints.actions.add"})]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs(Q,{className:"p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(xe,{className:"w-5 h-5 text-primary"}),e.jsx("span",{className:"text-2xl font-bold",children:g})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:t({id:"apiSettings.endpoints.stats.totalEndpoints"})})]}),e.jsxs(Q,{className:"p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Oe,{className:"w-5 h-5 text-info"}),e.jsx("span",{className:"text-2xl font-bold",children:j})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:t({id:"apiSettings.endpoints.stats.cachedEndpoints"})})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(N,{placeholder:t({id:"apiSettings.common.searchPlaceholder"}),value:n,onChange:c=>h(c.target.value),className:"pl-9"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(f,{variant:o?"default":"outline",size:"sm",onClick:()=>d(c=>!c),children:[o?e.jsx(Ms,{className:"w-4 h-4 mr-2"}):e.jsx(ze,{className:"w-4 h-4 mr-2"}),t(o?{id:"apiSettings.endpoints.actions.showAll"}:{id:"apiSettings.endpoints.actions.showDisabled"})]}),e.jsxs(f,{variant:M?"default":"outline",size:"sm",onClick:()=>u(c=>!c),children:[e.jsx(Oe,{className:"w-4 h-4 mr-2"}),t(M?{id:"apiSettings.endpoints.actions.showAll"}:{id:"apiSettings.endpoints.cacheStrategy"})]})]})]}),P?e.jsx("div",{className:"space-y-4",children:[1,2,3,4,5].map(c=>e.jsx("div",{className:"h-24 bg-muted animate-pulse rounded-lg"},c))}):D.length===0?e.jsxs(Q,{className:"p-8 text-center",children:[e.jsx(Oe,{className:"w-12 h-12 mx-auto text-muted-foreground/50"}),e.jsx("h3",{className:"mt-4 text-lg font-medium text-foreground",children:t({id:"apiSettings.endpoints.emptyState.title"})}),e.jsx("p",{className:"mt-2 text-muted-foreground",children:t({id:"apiSettings.endpoints.emptyState.message"})}),e.jsxs(f,{className:"mt-4",onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),t({id:"apiSettings.endpoints.actions.add"})]})]}):e.jsx("div",{className:"space-y-3",children:D.map(c=>e.jsx(Dt,{endpoint:c,onEdit:()=>r(c.id),onDelete:()=>w(c.id,c.name),onToggleEnabled:A=>K(c.id,A),isDeleting:k,isToggling:C},c.id))})]})}function Ot({value:a,onChange:r,placeholder:t}){const[s,n]=i.useState(""),h=()=>{s.trim()&&!a.includes(s.trim())&&(r([...a,s.trim()]),n(""))},o=d=>{r(a.filter(M=>M!==d))};return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(N,{value:s,onChange:d=>n(d.target.value),onKeyDown:d=>{d.key==="Enter"&&(d.preventDefault(),h())},placeholder:t}),e.jsx(f,{type:"button",size:"sm",onClick:h,children:e.jsx(Be,{className:"w-4 h-4"})})]}),a.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2",children:a.map(d=>e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-muted rounded-md text-xs",children:[d,e.jsx("button",{type:"button",onClick:()=>o(d),className:"hover:text-destructive",children:"×"})]},d))})]})}function zt({open:a,onClose:r,endpoint:t}){const{formatMessage:s}=W(),{error:n}=ge(),h=!!t,{createEndpoint:o,isCreating:d}=pt(),{updateEndpoint:M,isUpdating:u}=Os(),{providers:v}=Ze(),[j,P]=i.useState(""),[F,H]=i.useState(""),[k,I]=i.useState(""),[C,D]=i.useState(""),[w,K]=i.useState(""),[g,c]=i.useState(!0),[A,L]=i.useState(!1),[z,y]=i.useState(!1),[S,_]=i.useState(60),[b,p]=i.useState(1024),[O,X]=i.useState([]),ne=i.useMemo(()=>{if(!k)return[];const E=v.find(q=>q.id===k);if(!E)return[];const G=[];return E.llmModels&&G.push(...E.llmModels.filter(q=>q.enabled).map(q=>q.id)),E.embeddingModels&&G.push(...E.embeddingModels.filter(q=>q.enabled).map(q=>q.id)),E.rerankerModels&&G.push(...E.rerankerModels.filter(q=>q.enabled).map(q=>q.id)),G},[k,v]);i.useEffect(()=>{t?(P(t.id),H(t.name),I(t.providerId),D(t.model),K(t.description||""),c(t.enabled),y(t.cacheStrategy.enabled),_(t.cacheStrategy.ttlMinutes),p(t.cacheStrategy.maxSizeKB),X(t.cacheStrategy.filePatterns||[])):(P(""),H(""),I(""),D(""),K(""),c(!0),y(!1),_(60),p(1024),X([]))},[t,a]),i.useEffect(()=>{if(!h&&k){const E=v.find(G=>G.id===k);E&&E.llmModels&&E.llmModels.length>0&&D(E.llmModels[0].id)}},[k,v,h]);const ue=async()=>{try{const G={id:j,name:F,providerId:k,model:C,description:w||void 0,enabled:g,cacheStrategy:{enabled:z,ttlMinutes:S,maxSizeKB:b,filePatterns:z?O:[]}};h&&t?await M(t.id,G):await o(G),r()}catch{n(s({id:"apiSettings.endpoints.saveError"}))}},le=d||u,be=j.trim()&&F.trim()&&k&&C.trim();return e.jsx($e,{open:a,onOpenChange:r,children:e.jsxs(Ge,{className:"max-w-2xl",children:[e.jsxs(qe,{children:[e.jsx(Qe,{children:s(h?{id:"apiSettings.endpoints.actions.edit"}:{id:"apiSettings.endpoints.actions.add"})}),e.jsx(We,{children:s({id:"apiSettings.endpoints.description"})})]}),e.jsxs("div",{className:"space-y-6 py-4",children:[e.jsxs("div",{className:"space-y-4",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s({id:"apiSettings.providers.basicInfo"})}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"endpointId",children:[s({id:"apiSettings.endpoints.endpointId"})," *"]}),e.jsx(N,{id:"endpointId",value:j,onChange:E=>P(E.target.value),placeholder:"my-gpt4o",disabled:h,className:"font-mono"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.endpoints.endpointIdHint"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"name",children:[s({id:"apiSettings.endpoints.name"})," *"]}),e.jsx(N,{id:"name",value:F,onChange:E=>H(E.target.value),placeholder:"My GPT-4o"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"providerId",children:[s({id:"apiSettings.endpoints.provider"})," *"]}),e.jsxs(ve,{value:k,onValueChange:I,disabled:h,children:[e.jsx(fe,{id:"providerId",children:e.jsx(Se,{placeholder:v.length===0?s({id:"apiSettings.providers.addProviderFirst"}):s({id:"apiSettings.endpoints.selectProvider"})})}),e.jsx(Ne,{children:v.map(E=>e.jsxs(V,{value:E.id,disabled:!E.enabled,children:[E.name,!E.enabled&&` (${s({id:"apiSettings.common.disabled"})})`]},E.id))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"model",children:[s({id:"apiSettings.endpoints.model"})," *"]}),ne.length===0&&k?e.jsx(N,{id:"model",value:C,onChange:E=>D(E.target.value),placeholder:"",className:"font-mono"}):e.jsxs(ve,{value:C,onValueChange:D,children:[e.jsx(fe,{id:"model",children:e.jsx(Se,{placeholder:s(k?{id:"apiSettings.endpoints.selectModel"}:{id:"apiSettings.endpoints.selectProvider"})})}),e.jsx(Ne,{children:ne.map(E=>e.jsx(V,{value:E,children:E},E))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"description",children:s({id:"apiSettings.common.description"})}),e.jsx(Ke,{id:"description",value:w,onChange:E=>K(E.target.value),placeholder:s({id:"apiSettings.common.optional"}),rows:2})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{id:"enabled",checked:g,onCheckedChange:c}),e.jsx(m,{htmlFor:"enabled",children:s({id:"apiSettings.endpoints.enabled"})})]})]}),e.jsxs(hs,{open:A,onOpenChange:L,children:[e.jsx(xs,{asChild:!0,children:e.jsxs(f,{type:"button",variant:"ghost",className:"w-full justify-between",children:[e.jsxs("span",{className:"flex items-center gap-2 font-semibold",children:[e.jsx(Oe,{className:"w-4 h-4"}),s({id:"apiSettings.endpoints.cacheStrategy"})]}),A?e.jsx(os,{className:"w-4 h-4"}):e.jsx(ms,{className:"w-4 h-4"})]})}),e.jsxs(gs,{className:"space-y-4 pt-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(m,{children:s({id:"apiSettings.endpoints.enableContextCaching"})}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:s({id:"apiSettings.endpoints.cacheStrategy"})})]}),e.jsx(Z,{checked:z,onCheckedChange:y})]}),z&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"cacheTTL",children:s({id:"apiSettings.endpoints.cacheTTL"})}),e.jsx(N,{id:"cacheTTL",type:"number",min:"1",value:S,onChange:E=>_(parseInt(E.target.value)||60)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"cacheMaxSize",children:s({id:"apiSettings.endpoints.cacheMaxSize"})}),e.jsx(N,{id:"cacheMaxSize",type:"number",min:"1",value:b,onChange:E=>p(parseInt(E.target.value)||1024)})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{children:s({id:"apiSettings.endpoints.autoCachePatterns"})}),e.jsx(Ot,{value:O,onChange:X,placeholder:"*.md,*.ts"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.endpoints.filePatternsHint"})})]})]})]})]})]}),e.jsxs(Ye,{children:[e.jsx(f,{type:"button",variant:"outline",onClick:r,disabled:le,children:s({id:"apiSettings.common.cancel"})}),e.jsxs(f,{onClick:ue,disabled:le||!be,children:[le?e.jsx(Oe,{className:"w-4 h-4 mr-2 animate-spin"}):e.jsx(Be,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.common.save"})]})]})]})})}function Bt({used:a,total:r}){const{formatMessage:t}=W(),s=r>0?Math.round(a/r*100):0;return e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:t({id:"apiSettings.cache.settings.cacheUsage"})}),e.jsxs("span",{className:"font-medium",children:[s,"%"]})]}),e.jsx(et,{value:s,className:"h-2"}),e.jsxs("div",{className:"flex items-center justify-between text-xs text-muted-foreground",children:[e.jsxs("span",{children:[t({id:"apiSettings.cache.settings.used"})," ",(a/1024/1024).toFixed(2)," MB"]}),e.jsxs("span",{children:[t({id:"apiSettings.cache.settings.total"})," ",(r/1024/1024).toFixed(2)," MB"]})]})]})}function ws({icon:a,label:r,value:t,className:s}){return e.jsx(Q,{className:Ve("p-4",s),children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-primary/10 rounded-md text-primary",children:a}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:r}),e.jsx("p",{className:"text-2xl font-semibold",children:t})]})]})})}function Rt({className:a}){const{formatMessage:r}=W(),{success:t,error:s}=ge(),{stats:n,refetch:h}=ut(),{updateCacheSettings:o,isUpdating:d}=jt(),{clearCache:M,isClearing:u}=vt(),[v,j]=i.useState({enabled:!0,cacheDir:"",maxTotalSizeMB:1024}),[P,F]=i.useState(!1);i.useEffect(()=>{},[n]);const H=async()=>{try{await o(v),t(r({id:"apiSettings.cache.messages.cacheSettingsUpdated"})),await h()}catch(I){s(r({id:"common.error"}),I instanceof Error?I.message:r({id:"common.error"}))}},k=async()=>{try{await M(),F(!1),t(r({id:"apiSettings.cache.messages.cacheCleared"})),await h()}catch(I){s(r({id:"common.error"}),I instanceof Error?I.message:r({id:"common.error"}))}};return e.jsxs("div",{className:Ve("space-y-6",a),children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsx(ws,{icon:e.jsx(kt,{className:"w-5 h-5"}),label:r({id:"apiSettings.cache.settings.cacheEntries"}),value:(n==null?void 0:n.entries)??0}),e.jsx(ws,{icon:e.jsx(Et,{className:"w-5 h-5"}),label:r({id:"apiSettings.cache.settings.cacheSize"}),value:`${(((n==null?void 0:n.totalSize)??0)/1024/1024).toFixed(2)} MB`}),e.jsx(ws,{icon:e.jsx(Oe,{className:"w-5 h-5"}),label:r({id:"apiSettings.cache.settings.maxSize"}),value:`${(((n==null?void 0:n.maxSize)??0)/1024/1024).toFixed(2)} MB`})]}),n&&e.jsx(Q,{className:"p-4",children:e.jsx(Bt,{used:n.totalSize,total:n.maxSize})}),e.jsxs(Q,{className:"p-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:r({id:"apiSettings.cache.settings.title"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"space-y-0.5",children:e.jsx(m,{htmlFor:"cache-enabled",children:r({id:"apiSettings.cache.settings.enableGlobalCaching"})})}),e.jsx(Z,{id:"cache-enabled",checked:v.enabled??!0,onCheckedChange:I=>j({...v,enabled:I}),disabled:d})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"cache-dir",children:r({id:"apiSettings.cache.settings.cacheDirectory"})}),e.jsx(N,{id:"cache-dir",value:v.cacheDir??"",onChange:I=>j({...v,cacheDir:I.target.value}),disabled:d,placeholder:"/path/to/cache"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"cache-max-size",children:r({id:"apiSettings.cache.settings.maxSize"})}),e.jsx(N,{id:"cache-max-size",type:"number",min:1,value:v.maxTotalSizeMB??1024,onChange:I=>j({...v,maxTotalSizeMB:parseInt(I.target.value)||1024}),disabled:d})]}),e.jsxs("div",{className:"flex items-center justify-between pt-4 border-t",children:[e.jsxs(f,{variant:"destructive",onClick:()=>F(!0),disabled:u,children:[e.jsx(ye,{className:"w-4 h-4 mr-2"}),r({id:"apiSettings.cache.settings.actions.clearCache"})]}),e.jsxs(f,{onClick:H,disabled:d,children:[e.jsx(Qs,{className:"w-4 h-4 mr-2"}),r({id:"common.save"})]})]})]})]}),e.jsx(_s,{open:P,onOpenChange:F,children:e.jsxs(Hs,{children:[e.jsxs(Us,{children:[e.jsx(Js,{children:r({id:"apiSettings.cache.settings.actions.clearCache"})}),e.jsx(Vs,{children:r({id:"apiSettings.cache.settings.confirmClearCache"})})]}),e.jsxs($s,{children:[e.jsx(Gs,{disabled:u,children:r({id:"common.cancel"})}),e.jsx(qs,{onClick:k,disabled:u,children:r(u?{id:"common.loading"}:{id:"common.confirm"})})]})]})})]})}function _t({pool:a,onEdit:r,onDelete:t,onToggleEnabled:s,isDeleting:n,isToggling:h}){const{formatMessage:o}=W(),d=()=>{const u={embedding:"success",llm:"default",reranker:"info"},v={embedding:"apiSettings.modelPools.embedding",llm:"apiSettings.modelPools.llm",reranker:"apiSettings.modelPools.reranker"};return e.jsx(ee,{variant:u[a.modelType],children:o({id:v[a.modelType]})})},M=()=>o({id:{round_robin:"apiSettings.modelPools.roundRobin",latency_aware:"apiSettings.modelPools.latencyAware",weighted_random:"apiSettings.modelPools.weightedRandom"}[a.strategy]});return e.jsx(Q,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground truncate",children:a.name||a.id}),d(),a.enabled?e.jsxs(ee,{variant:"success",children:[e.jsx(ze,{className:"w-3 h-3 mr-1"}),o({id:"apiSettings.common.enabled"})]}):e.jsxs(ee,{variant:"secondary",children:[e.jsx(Ms,{className:"w-3 h-3 mr-1"}),o({id:"apiSettings.common.disabled"})]})]}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-sm text-muted-foreground",children:[e.jsx("span",{className:"capitalize",children:M()}),a.autoDiscover&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(xe,{className:"w-3 h-3"}),o({id:"apiSettings.modelPools.autoDiscover"})]})]}),e.jsx("div",{className:"mt-2 text-sm",children:e.jsxs("p",{className:"text-muted-foreground",children:[o({id:"apiSettings.modelPools.targetModel"}),": ",e.jsx("span",{className:"font-medium",children:a.targetModel})]})}),a.description&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:a.description}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:[o({id:"apiSettings.modelPools.defaultCooldown"}),": ",a.defaultCooldown,"s"]}),e.jsxs("span",{children:[o({id:"apiSettings.modelPools.defaultConcurrent"}),": ",a.defaultMaxConcurrentPerKey]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{checked:a.enabled,onCheckedChange:s,disabled:h}),e.jsxs(us,{children:[e.jsx(js,{asChild:!0,children:e.jsx(f,{variant:"ghost",size:"icon",children:e.jsx(Ns,{className:"w-4 h-4"})})}),e.jsxs(vs,{align:"end",children:[e.jsxs(he,{onClick:r,children:[e.jsx(ys,{className:"w-4 h-4 mr-2"}),o({id:"apiSettings.modelPools.actions.edit"})]}),e.jsx(fs,{}),e.jsxs(he,{onClick:t,disabled:n,className:"text-destructive",children:[e.jsx(ye,{className:"w-4 h-4 mr-2"}),o({id:"apiSettings.modelPools.actions.delete"})]})]})]})]})]})})}function rs({label:a,value:r,icon:t,className:s}){return e.jsx(Q,{className:Ve("p-4",s),children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-primary/10 rounded-md text-primary",children:t}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:a}),e.jsx("p",{className:"text-2xl font-semibold",children:r})]})]})})}function Ht({onAddPool:a,onEditPool:r}){var z;const{formatMessage:t}=W(),{success:s,error:n}=ge(),{pools:h,totalCount:o,enabledCount:d,isLoading:M,refetch:u}=zs(),{deleteModelPool:v,isDeleting:j}=ft(),{updateModelPool:P}=Bs(),[F,H]=i.useState(""),[k,I]=i.useState("all"),[C,D]=i.useState(null),[w,K]=i.useState(null),g=i.useMemo(()=>h.filter(y=>{var b;const S=!F||y.id.toLowerCase().includes(F.toLowerCase())||((b=y.name)==null?void 0:b.toLowerCase().includes(F.toLowerCase()))||y.targetModel.toLowerCase().includes(F.toLowerCase()),_=k==="all"||y.modelType===k;return S&&_}),[h,F,k]),c=i.useMemo(()=>({embedding:h.filter(y=>y.modelType==="embedding").length,llm:h.filter(y=>y.modelType==="llm").length,reranker:h.filter(y=>y.modelType==="reranker").length}),[h]),A=async()=>{if(C)try{await v(C),s(t({id:"apiSettings.messages.settingsDeleted"})),D(null),await u()}catch(y){n(t({id:"common.error"}),y instanceof Error?y.message:t({id:"common.error"}))}},L=async(y,S)=>{K(y);try{await P(y,{enabled:S}),await u()}catch(_){n(t({id:"common.error"}),_ instanceof Error?_.message:t({id:"common.error"}))}finally{K(null)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsx(rs,{label:t({id:"apiSettings.modelPools.stats.total"}),value:o,icon:e.jsx(Cs,{className:"w-5 h-5"})}),e.jsx(rs,{label:t({id:"apiSettings.modelPools.stats.enabled"}),value:d,icon:e.jsx(ze,{className:"w-5 h-5"})}),e.jsx(rs,{label:t({id:"apiSettings.modelPools.embedding"}),value:c.embedding,icon:e.jsx(xe,{className:"w-5 h-5"})}),e.jsx(rs,{label:t({id:"apiSettings.modelPools.llm"}),value:c.llm,icon:e.jsx(Cs,{className:"w-5 h-5"})})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-4 items-start sm:items-center justify-between",children:[e.jsx("div",{className:"flex-1 w-full sm:max-w-md",children:e.jsxs("div",{className:"relative",children:[e.jsx(ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(N,{placeholder:t({id:"apiSettings.common.searchPlaceholder"}),value:F,onChange:y=>H(y.target.value),className:"pl-9"})]})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"flex items-center bg-muted rounded-lg p-1",children:Object.keys({all:null,embedding:null,llm:null,reranker:null}).map(y=>e.jsx("button",{onClick:()=>I(y),className:Ve("px-3 py-1.5 text-sm font-medium rounded-md transition-colors",k===y?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"),children:t(y==="all"?{id:"apiSettings.common.showAll"}:{id:`apiSettings.modelPools.${y}`})},y))}),e.jsxs(f,{onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),t({id:"apiSettings.modelPools.actions.add"})]})]})]}),M?e.jsx("div",{className:"text-center py-12 text-muted-foreground",children:t({id:"common.loading"})}):g.length===0?e.jsxs(Q,{className:"p-12 text-center",children:[e.jsx(Cs,{className:"w-12 h-12 mx-auto mb-4 text-muted-foreground"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:t({id:"apiSettings.modelPools.emptyState.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:t({id:"apiSettings.modelPools.emptyState.message"})}),e.jsxs(f,{onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),t({id:"apiSettings.modelPools.actions.add"})]})]}):e.jsx("div",{className:"grid gap-4",children:g.map(y=>e.jsx(_t,{pool:y,onEdit:()=>r(y.id),onDelete:()=>D(y.id),onToggleEnabled:S=>L(y.id,S),isDeleting:j&&C===y.id,isToggling:w===y.id},y.id))}),e.jsx(_s,{open:!!C,onOpenChange:()=>D(null),children:e.jsxs(Hs,{children:[e.jsxs(Us,{children:[e.jsx(Js,{children:t({id:"apiSettings.modelPools.actions.delete"})}),e.jsx(Vs,{children:t({id:"apiSettings.modelPools.deleteConfirm"},{name:((z=h.find(y=>y.id===C))==null?void 0:z.name)||C||""})})]}),e.jsxs($s,{children:[e.jsx(Gs,{disabled:j,children:t({id:"common.cancel"})}),e.jsx(qs,{onClick:A,disabled:j,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:t(j?{id:"common.loading"}:{id:"common.confirm"})})]})]})})]})}const Fs={modelType:"",targetModel:"",strategy:"round_robin",autoDiscover:!0,excludedProviderIds:[],defaultCooldown:60,defaultMaxConcurrentPerKey:5,name:"",description:""};function Ut({provider:a,excluded:r,onToggle:t}){const{formatMessage:s}=W();return e.jsxs("div",{className:"flex items-center justify-between p-3 bg-muted/50 rounded-md",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(tt,{id:`provider-${a.providerId}`,checked:!r,onCheckedChange:()=>t(a.providerId)}),e.jsx(m,{htmlFor:`provider-${a.providerId}`,className:"font-medium cursor-pointer",children:a.providerName})]}),e.jsx("div",{className:"ml-6 mt-1 flex flex-wrap gap-1",children:a.models.map(n=>e.jsx("span",{className:"text-xs px-2 py-0.5 bg-background rounded text-muted-foreground",children:n},n))})]}),e.jsx(f,{variant:"ghost",size:"sm",onClick:()=>t(a.providerId),children:r?e.jsx("span",{className:"text-xs text-muted-foreground",children:s({id:"apiSettings.modelPools.excludeProvider"})}):e.jsx("span",{className:"text-xs text-primary",children:s({id:"apiSettings.modelPools.includeProvider"})})})]})}function Jt({open:a,onClose:r,pool:t}){var b;const{formatMessage:s}=W(),{success:n,error:h,warning:o}=ge(),[d,M]=i.useState(Fs),[u,v]=i.useState(!1),{createModelPool:j,isCreating:P}=St(),{updateModelPool:F,isUpdating:H}=Bs(),{discoverModels:k,isDiscovering:I,data:C}=Nt(),{data:D,isLoading:w}=yt(d.modelType||"embedding"),K=!!t,g=P||H;i.useEffect(()=>{M(t?{modelType:t.modelType,targetModel:t.targetModel,strategy:t.strategy,autoDiscover:t.autoDiscover,excludedProviderIds:t.excludedProviderIds??[],defaultCooldown:t.defaultCooldown,defaultMaxConcurrentPerKey:t.defaultMaxConcurrentPerKey,name:t.name??"",description:t.description??""}:Fs),v(!1)},[t,a]);const c=(p,O)=>{M(X=>({...X,[p]:O})),(p==="modelType"||p==="targetModel")&&v(!1)},A=async()=>{if(!d.modelType||!d.targetModel){o("Please select model type and target model first");return}try{await k(d.modelType,d.targetModel),v(!0)}catch(p){h(s({id:"common.error"}),p instanceof Error?p.message:"Failed to discover providers")}},L=p=>{M(O=>({...O,excludedProviderIds:O.excludedProviderIds.includes(p)?O.excludedProviderIds.filter(X=>X!==p):[...O.excludedProviderIds,p]}))},z=i.useMemo(()=>!!d.modelType&&!!d.targetModel,[d.modelType,d.targetModel]),y=async()=>{if(z)try{const p={modelType:d.modelType,targetModel:d.targetModel,strategy:d.strategy,autoDiscover:d.autoDiscover,excludedProviderIds:d.excludedProviderIds,defaultCooldown:d.defaultCooldown,defaultMaxConcurrentPerKey:d.defaultMaxConcurrentPerKey,name:d.name||void 0,description:d.description||void 0,enabled:!0};K&&t?await F(t.id,p):await j(p),n(s({id:"apiSettings.modelPools.poolSaved"})),r()}catch(p){h(s({id:"common.error"}),p instanceof Error?p.message:"Failed to save model pool")}},S=(C==null?void 0:C.discovered)??[],_=i.useMemo(()=>!C||!S?0:S.length-d.excludedProviderIds.filter(p=>S.some(O=>O.providerId===p)).length,[C,S,d.excludedProviderIds]);return e.jsx($e,{open:a,onOpenChange:r,children:e.jsxs(Ge,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(qe,{children:[e.jsx(Qe,{children:s(K?{id:"apiSettings.modelPools.actions.edit"}:{id:"apiSettings.modelPools.actions.add"})}),e.jsx(We,{children:s({id:"apiSettings.modelPools.embeddingPoolDesc"})})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"pool-model-type",children:[s({id:"apiSettings.modelPools.modelType"})," *"]}),e.jsxs(ve,{value:d.modelType,onValueChange:p=>c("modelType",p),disabled:K,children:[e.jsx(fe,{id:"pool-model-type",children:e.jsx(Se,{placeholder:s({id:"apiSettings.modelPools.selectTargetModel"})})}),e.jsxs(Ne,{children:[e.jsx(V,{value:"embedding",children:s({id:"apiSettings.modelPools.embedding"})}),e.jsx(V,{value:"llm",children:s({id:"apiSettings.modelPools.llm"})}),e.jsx(V,{value:"reranker",children:s({id:"apiSettings.modelPools.reranker"})})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"pool-target-model",children:[s({id:"apiSettings.modelPools.targetModel"})," *"]}),w?e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(ss,{className:"w-4 h-4 animate-spin"}),s({id:"common.loading"})]}):e.jsxs(ve,{value:d.targetModel,onValueChange:p=>c("targetModel",p),disabled:!d.modelType,children:[e.jsx(fe,{id:"pool-target-model",children:e.jsx(Se,{placeholder:s({id:"apiSettings.modelPools.selectTargetModel"})})}),e.jsx(Ne,{children:(b=D==null?void 0:D.availableModels)==null?void 0:b.map(p=>e.jsx(V,{value:p.modelId,children:p.modelName},p.modelId))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"pool-strategy",children:s({id:"apiSettings.modelPools.strategy"})}),e.jsxs(ve,{value:d.strategy,onValueChange:p=>c("strategy",p),children:[e.jsx(fe,{id:"pool-strategy",children:e.jsx(Se,{})}),e.jsxs(Ne,{children:[e.jsx(V,{value:"round_robin",children:s({id:"apiSettings.modelPools.roundRobin"})}),e.jsx(V,{value:"latency_aware",children:s({id:"apiSettings.modelPools.latencyAware"})}),e.jsx(V,{value:"weighted_random",children:s({id:"apiSettings.modelPools.weightedRandom"})})]})]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(m,{htmlFor:"pool-auto-discover",children:s({id:"apiSettings.modelPools.autoDiscover"})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Automatically find providers offering this model"})]}),e.jsx(Z,{id:"pool-auto-discover",checked:d.autoDiscover,onCheckedChange:p=>c("autoDiscover",p)})]}),d.autoDiscover&&d.modelType&&d.targetModel&&e.jsxs("div",{className:"space-y-3",children:[e.jsx(f,{type:"button",variant:"outline",onClick:A,disabled:I,className:"w-full",children:I?e.jsxs(e.Fragment,{children:[e.jsx(ss,{className:"w-4 h-4 mr-2 animate-spin"}),s({id:"common.loading"})]}):e.jsxs(e.Fragment,{children:[e.jsx(xe,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.modelPools.actions.autoDiscover"})]})}),u&&S.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(st,{className:"w-4 h-4"}),e.jsxs("span",{children:[s({id:"apiSettings.modelPools.discovered"})," ",S.length," ",s({id:"apiSettings.modelPools.providers"})," •"," ",_," ",s({id:"apiSettings.modelPools.discovered"}).toLowerCase()]})]}),S.map(p=>e.jsx(Ut,{provider:p,excluded:d.excludedProviderIds.includes(p.providerId),onToggle:L},p.providerId))]}),u&&S.length===0&&e.jsx("div",{className:"text-center py-6 text-muted-foreground",children:e.jsx("p",{className:"text-sm",children:s({id:"apiSettings.modelPools.noProvidersFound"})})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"pool-cooldown",children:s({id:"apiSettings.modelPools.defaultCooldown"})}),e.jsx(N,{id:"pool-cooldown",type:"number",min:0,value:d.defaultCooldown,onChange:p=>c("defaultCooldown",parseInt(p.target.value)||0)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"pool-concurrent",children:s({id:"apiSettings.modelPools.defaultConcurrent"})}),e.jsx(N,{id:"pool-concurrent",type:"number",min:1,value:d.defaultMaxConcurrentPerKey,onChange:p=>c("defaultMaxConcurrentPerKey",parseInt(p.target.value)||1)})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"pool-name",children:s({id:"apiSettings.common.name"})}),e.jsx(N,{id:"pool-name",value:d.name,onChange:p=>c("name",p.target.value),placeholder:s({id:"apiSettings.common.optional"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"pool-description",children:s({id:"apiSettings.common.description"})}),e.jsx(Ke,{id:"pool-description",value:d.description,onChange:p=>c("description",p.target.value),placeholder:s({id:"apiSettings.common.optional"}),rows:3})]})]}),e.jsxs(Ye,{children:[e.jsxs(f,{variant:"outline",onClick:r,disabled:g,children:[e.jsx(Ds,{className:"w-4 h-4 mr-2"}),s({id:"common.cancel"})]}),e.jsx(f,{onClick:y,disabled:!z||g,children:g?e.jsxs(e.Fragment,{children:[e.jsx(ss,{className:"w-4 h-4 mr-2 animate-spin"}),s({id:"common.loading"})]}):e.jsxs(e.Fragment,{children:[e.jsx(Qs,{className:"w-4 h-4 mr-2"}),s({id:"common.save"})]})})]})]})})}function Vt({cliSettings:a,onEdit:r,onDelete:t,onToggleEnabled:s,isDeleting:n,isToggling:h}){const{formatMessage:o}=W(),d=()=>{const v=a.provider||"claude",j={claude:{variant:"secondary",label:"Claude"},codex:{variant:"outline",label:"Codex"},gemini:{variant:"default",label:"Gemini"}},P=j[v]||j.claude;return e.jsx(ee,{variant:P.variant,className:"text-xs",children:P.label})},M=()=>a.enabled?e.jsx(ee,{variant:"success",children:o({id:"apiSettings.common.enabled"})}):e.jsx(ee,{variant:"secondary",children:o({id:"apiSettings.common.disabled"})}),u=(()=>{const v=a.settings.env;return v.ANTHROPIC_BASE_URL||v.OPENAI_BASE_URL||""})();return e.jsx(Q,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground truncate",children:a.name}),M(),d()]}),a.description&&e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:a.description}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-sm text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(cs,{className:"w-3 h-3"}),a.settings.model||"default"]}),u&&e.jsxs("span",{className:"flex items-center gap-1 truncate max-w-[200px]",title:u,children:[e.jsx(Tt,{className:"w-3 h-3 flex-shrink-0"}),u]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{checked:a.enabled,onCheckedChange:s,disabled:h}),e.jsxs(us,{children:[e.jsx(js,{asChild:!0,children:e.jsx(f,{variant:"ghost",size:"icon",children:e.jsx(Ns,{className:"w-4 h-4"})})}),e.jsxs(vs,{align:"end",children:[e.jsxs(he,{onClick:r,children:[e.jsx(ys,{className:"w-4 h-4 mr-2"}),o({id:"apiSettings.cliSettings.actions.edit"})]}),e.jsx(fs,{}),e.jsxs(he,{onClick:t,disabled:n,className:"text-destructive",children:[e.jsx(ye,{className:"w-4 h-4 mr-2"}),o({id:"apiSettings.cliSettings.actions.delete"})]})]})]})]})]})})}function $t({onAddCliSettings:a,onEditCliSettings:r}){const{formatMessage:t}=W(),{error:s}=ge(),[n,h]=i.useState(""),{cliSettings:o,totalCount:d,enabledCount:M,providerCounts:u,isLoading:v,refetch:j}=Rs(),{deleteCliSettings:P,isDeleting:F}=bt(),{toggleCliSettings:H,isToggling:k}=Ct(),I=i.useMemo(()=>{if(!n)return o;const w=n.toLowerCase();return o.filter(K=>{var g;return K.name.toLowerCase().includes(w)||((g=K.description)==null?void 0:g.toLowerCase().includes(w))||K.id.toLowerCase().includes(w)})},[o,n]),C=async w=>{const K=o.find(c=>c.id===w);if(!K)return;const g=t({id:"apiSettings.cliSettings.deleteConfirm"},{name:K.name});if(confirm(g))try{await P(w)}catch{s(t({id:"apiSettings.cliSettings.deleteError"}))}},D=async(w,K)=>{try{await H(w,K)}catch{s(t({id:"apiSettings.cliSettings.toggleError"}))}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-5 gap-4",children:[e.jsxs(Q,{className:"p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(cs,{className:"w-5 h-5 text-primary"}),e.jsx("span",{className:"text-2xl font-bold",children:d})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:t({id:"apiSettings.cliSettings.stats.total"})})]}),e.jsxs(Q,{className:"p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ze,{className:"w-5 h-5 text-success"}),e.jsx("span",{className:"text-2xl font-bold",children:M})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:t({id:"apiSettings.cliSettings.stats.enabled"})})]}),e.jsxs(Q,{className:"p-4",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("span",{className:"text-2xl font-bold",children:u.claude||0})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Claude"})]}),e.jsxs(Q,{className:"p-4",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("span",{className:"text-2xl font-bold",children:u.codex||0})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Codex"})]}),e.jsxs(Q,{className:"p-4",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("span",{className:"text-2xl font-bold",children:u.gemini||0})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Gemini"})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(ps,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(N,{placeholder:t({id:"apiSettings.cliSettings.searchPlaceholder"}),value:n,onChange:w=>h(w.target.value),className:"pl-9"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(f,{variant:"outline",onClick:()=>j(),disabled:v,children:t({id:"common.actions.refresh"})}),e.jsxs(f,{onClick:a,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),t({id:"apiSettings.cliSettings.actions.add"})]})]})]}),v?e.jsx("div",{className:"space-y-4",children:[1,2,3].map(w=>e.jsx("div",{className:"h-32 bg-muted animate-pulse rounded-lg"},w))}):I.length===0?e.jsxs(Q,{className:"p-8 text-center",children:[e.jsx(cs,{className:"w-12 h-12 mx-auto text-muted-foreground/50"}),e.jsx("h3",{className:"mt-4 text-lg font-medium text-foreground",children:t({id:"apiSettings.cliSettings.emptyState.title"})}),e.jsx("p",{className:"mt-2 text-muted-foreground",children:t({id:"apiSettings.cliSettings.emptyState.message"})})]}):e.jsx("div",{className:"space-y-3",children:I.map(w=>e.jsx(Vt,{cliSettings:w,onEdit:()=>r(w.id),onDelete:()=>C(w.id),onToggleEnabled:K=>D(w.id,K),isDeleting:F,isToggling:k},w.id))})]})}function Ks(a,r="json"){const t=a.trim();if(!t)return{ok:!0,value:""};if(r==="json")try{return JSON.parse(t),{ok:!0,value:t}}catch{return{ok:!1,errorKey:"invalidJson"}}return{ok:!0,value:t}}function Gt({open:a,onClose:r,cliSettings:t,defaultProvider:s}){const{formatMessage:n}=W(),{error:h}=ge(),o=!!t,{createCliSettings:d,isCreating:M}=wt(),{updateCliSettings:u,isUpdating:v}=Mt(),{providers:j}=Ze(),[P,F]=i.useState(""),[H,k]=i.useState(""),[I,C]=i.useState(!0),[D,w]=i.useState("claude"),[K,g]=i.useState("direct"),[c,A]=i.useState(""),[L,z]=i.useState(""),[y,S]=i.useState(""),[_,b]=i.useState(!1),[p,O]=i.useState(""),[X,ne]=i.useState(""),[ue,le]=i.useState(""),[be,E]=i.useState(""),[G,q]=i.useState(!1),[te,de]=i.useState(""),[Re,Me]=i.useState(""),[_e,Pe]=i.useState(!1),[Ce,we]=i.useState(""),[ke,Ee]=i.useState(!1),[Te,je]=i.useState(""),[Ae,Ie]=i.useState(!1),[ce,B]=i.useState(""),[se,re]=i.useState([]),[ae,oe]=i.useState(""),[me,De]=i.useState([]),[is,Xe]=i.useState(""),[He,ns]=i.useState("{}"),[Fe,ls]=i.useState(!1),[Y,Le]=i.useState({}),[ds,Ue]=i.useState(!1);i.useEffect(()=>{if(t){F(t.name),k(t.description||""),C(t.enabled),w(t.provider||"claude"),B(t.settings.model||""),re(t.settings.availableModels||[]),De(t.settings.tags||[]);const l=t.provider||"claude";if(l==="claude"){O(t.settings.settingsFile||"");const J=t.settings.env;if(!!(J.ANTHROPIC_BASE_URL&&!J.ANTHROPIC_BASE_URL.includes("api.anthropic.com")))g("direct"),S(J.ANTHROPIC_BASE_URL||""),z(J.ANTHROPIC_AUTH_TOKEN||"");else{g("provider-based");const pe=j.find(bs=>bs.apiBase===J.ANTHROPIC_BASE_URL);pe&&A(pe.id)}}else if(l==="codex"){const J=t.settings;ne(J.env.OPENAI_API_KEY||""),le(J.env.OPENAI_BASE_URL||""),E(J.profile||""),de(J.authJson||""),Me(J.configToml||"")}else l==="gemini"&&we(t.settings.env.GEMINI_API_KEY||t.settings.env.GOOGLE_API_KEY||"")}else{const l=s||"claude";F(""),k(""),C(!0),w(l),g("direct"),A(""),B(""),O(""),z(""),S(""),ne(""),le(""),E(""),q(!1),de(""),Me(""),Pe(!1),we(""),Ee(!1),je(""),re([]),oe(""),De([]),Xe(""),ns("{}"),ls(!1),Le({})}},[t,a,j,s]);const x=()=>{const l={};if(P.trim()?(/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(P.trim())||(l.name=n({id:"apiSettings.cliSettings.nameFormatHint"})),P.trim().length>32&&(l.name=n({id:"apiSettings.cliSettings.nameTooLong"},{max:32}))):l.name=n({id:"apiSettings.validation.nameRequired"}),D==="claude"&&(K==="provider-based"&&!c&&(l.providerId=n({id:"apiSettings.cliSettings.validation.providerRequired"})),K==="direct"&&!L.trim()&&!y.trim()&&(l.direct=n({id:"apiSettings.cliSettings.validation.authOrBaseUrlRequired"}))),te.trim()){const J=Ks(te,"json");J.ok||(l.authJson=n({id:`apiSettings.cliSettings.${J.errorKey}`}))}if(Fe){const J=Ks(He,"json");J.ok||(l.configJson=n({id:`apiSettings.cliSettings.${J.errorKey}`}))}return Le(l),Object.keys(l).length===0},T=async()=>{Ue(!0);try{const l=await nt();l.success?(l.configToml&&Me(l.configToml),l.authJson&&de(l.authJson)):h(n({id:"apiSettings.cliSettings.loadConfigError"})||"Failed to load config")}catch{h(n({id:"apiSettings.cliSettings.loadConfigError"})||"Failed to load config")}finally{Ue(!1)}},R=async()=>{Ie(!0);try{const l=await lt();l.success?l.settingsJson&&je(l.settingsJson):h(n({id:"apiSettings.cliSettings.loadConfigError"})||"Failed to load config")}catch{h(n({id:"apiSettings.cliSettings.loadConfigError"})||"Failed to load config")}finally{Ie(!1)}},U=async()=>{if(x())try{let l;if(D==="claude"){const $={DISABLE_AUTOUPDATER:"1"};if(K==="provider-based"){const pe=j.find(bs=>bs.id===c);pe!=null&&pe.apiBase&&($.ANTHROPIC_BASE_URL=pe.apiBase),pe!=null&&pe.apiKey&&($.ANTHROPIC_AUTH_TOKEN=pe.apiKey)}else L.trim()&&($.ANTHROPIC_AUTH_TOKEN=L.trim()),y.trim()&&($.ANTHROPIC_BASE_URL=y.trim());l={env:$,model:ce||void 0,settingsFile:p.trim()||void 0,availableModels:se,tags:me}}else if(D==="codex"){const $={};X.trim()&&($.OPENAI_API_KEY=X.trim()),ue.trim()&&($.OPENAI_BASE_URL=ue.trim()),l={env:$,model:ce||void 0,profile:be.trim()||void 0,authJson:te.trim()||void 0,configToml:Re.trim()||void 0,availableModels:se,tags:me}}else{const $={};Ce.trim()&&($.GEMINI_API_KEY=Ce.trim()),l={env:$,model:ce||void 0,availableModels:se,tags:me}}if(Fe&&He.trim())try{const $=JSON.parse(He);$&&typeof $=="object"&&!Array.isArray($)&&Object.assign(l,$)}catch{}const J={id:t==null?void 0:t.id,name:P.trim(),description:H.trim()||void 0,provider:D,enabled:I,settings:l};o&&t?await u(t.id,J):await d(J),r()}catch{h(n({id:"apiSettings.cliSettings.saveError"}))}},Je=()=>{const l=ae.trim();l&&!se.includes(l)&&(re([...se,l]),oe(""))},Ws=l=>re(se.filter(J=>J!==l)),Ps=()=>{const l=is.trim();l&&!me.includes(l)&&(De([...me,l]),Xe(""))},Ys=l=>De(me.filter(J=>J!==l)),Zs=["分析","Debug","implementation","refactoring","testing"],es=j.find(l=>l.id===c),Xs={claude:"Claude",codex:"Codex",gemini:"Gemini"};return e.jsx($e,{open:a,onOpenChange:r,children:e.jsxs(Ge,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(qe,{children:[e.jsxs(Qe,{children:[n(o?{id:"apiSettings.cliSettings.actions.edit"}:{id:"apiSettings.cliSettings.actions.add"})," - ",Xs[D]]}),e.jsx(We,{children:n({id:"apiSettings.cliSettings.modalDescription"})})]}),e.jsxs("div",{className:"space-y-6 py-4",children:[e.jsxs("div",{className:"space-y-4",children:[!o&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{children:"CLI Provider"}),e.jsxs(ve,{value:D,onValueChange:l=>w(l),children:[e.jsx(fe,{children:e.jsx(Se,{})}),e.jsxs(Ne,{children:[e.jsx(V,{value:"claude",children:"Claude"}),e.jsx(V,{value:"codex",children:"Codex"}),e.jsx(V,{value:"gemini",children:"Gemini"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"name",children:[n({id:"apiSettings.common.name"}),e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(N,{id:"name",value:P,onChange:l=>F(l.target.value),placeholder:n({id:"apiSettings.cliSettings.namePlaceholder"}),className:Y.name?"border-destructive":"",maxLength:32}),e.jsx("p",{className:"text-xs text-muted-foreground",children:n({id:"apiSettings.cliSettings.nameFormatHint"})}),Y.name&&e.jsx("p",{className:"text-sm text-destructive",children:Y.name})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"description",children:n({id:"apiSettings.common.description"})}),e.jsx(Ke,{id:"description",value:H,onChange:l=>k(l.target.value),placeholder:n({id:"apiSettings.cliSettings.descriptionPlaceholder"}),rows:2})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{id:"enabled",checked:I,onCheckedChange:C}),e.jsx(m,{htmlFor:"enabled",className:"cursor-pointer",children:n({id:"apiSettings.common.enableThis"})})]})]}),D==="claude"&&e.jsxs(e.Fragment,{children:[e.jsxs(at,{value:K,onValueChange:l=>g(l),className:"w-full",children:[e.jsxs(it,{className:"grid w-full grid-cols-2",children:[e.jsx(Es,{value:"provider-based",children:n({id:"apiSettings.cliSettings.providerBased"})}),e.jsx(Es,{value:"direct",children:n({id:"apiSettings.cliSettings.direct"})})]}),e.jsxs(Ts,{value:"provider-based",className:"space-y-4 mt-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs(m,{htmlFor:"providerId",children:[n({id:"apiSettings.common.provider"}),e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsxs(ve,{value:c,onValueChange:A,children:[e.jsx(fe,{className:Y.providerId?"border-destructive":"",children:e.jsx(Se,{placeholder:n({id:"apiSettings.cliSettings.selectProvider"})})}),e.jsx(Ne,{children:j.map(l=>e.jsx(V,{value:l.id,children:l.name},l.id))})]}),Y.providerId&&e.jsx("p",{className:"text-sm text-destructive",children:Y.providerId})]}),es&&e.jsxs("div",{className:"p-4 bg-muted/50 rounded-lg space-y-2",children:[e.jsx("p",{className:"text-sm font-medium",children:es.name}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[n({id:"apiSettings.common.type"}),": ",es.type]}),es.apiBase&&e.jsxs("p",{className:"text-xs text-muted-foreground truncate",children:[n({id:"apiSettings.providers.apiBaseUrl"}),": ",es.apiBase]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"model-pb",children:n({id:"apiSettings.cliSettings.model"})}),e.jsx(N,{id:"model-pb",value:ce,onChange:l=>B(l.target.value),placeholder:""})]})]}),e.jsxs(Ts,{value:"direct",className:"space-y-4 mt-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"authToken",children:n({id:"apiSettings.cliSettings.authToken"})}),e.jsxs("div",{className:"relative",children:[e.jsx(N,{id:"authToken",type:_?"text":"password",value:L,onChange:l=>z(l.target.value),placeholder:"sk-ant-...",className:Y.direct?"border-destructive pr-10":"pr-10"}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full px-2",onClick:()=>b(!_),children:_?e.jsx(ts,{className:"w-4 h-4"}):e.jsx(as,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"baseUrl",children:n({id:"apiSettings.cliSettings.baseUrl"})}),e.jsx(N,{id:"baseUrl",value:y,onChange:l=>S(l.target.value),placeholder:"https://api.anthropic.com",className:Y.direct?"border-destructive":""})]}),Y.direct&&e.jsx("p",{className:"text-sm text-destructive",children:Y.direct}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"model-direct",children:n({id:"apiSettings.cliSettings.model"})}),e.jsx(N,{id:"model-direct",value:ce,onChange:l=>B(l.target.value),placeholder:""})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"settingsFile",children:n({id:"apiSettings.cliSettings.settingsFile"})}),e.jsx(N,{id:"settingsFile",value:p,onChange:l=>O(l.target.value),placeholder:n({id:"apiSettings.cliSettings.settingsFilePlaceholder"})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:n({id:"apiSettings.cliSettings.settingsFileHint"})})]})]}),D==="codex"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between p-3 bg-muted/30 rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Load Global Config"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Load config.toml and auth.json from global Codex config directory"})]}),e.jsx(f,{type:"button",variant:"outline",size:"sm",onClick:T,disabled:ds,children:ds?e.jsxs(e.Fragment,{children:[e.jsx(ss,{className:"w-4 h-4 mr-2 animate-spin"}),"Loading..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Is,{className:"w-4 h-4 mr-2"}),"Load Config"]})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"codex-apikey",children:"API Key"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"只需要填这里,下方 auth.json 会自动填充"}),e.jsxs("div",{className:"relative",children:[e.jsx(N,{id:"codex-apikey",type:G?"text":"password",value:X,onChange:l=>ne(l.target.value),placeholder:"sk-...",className:"pr-10"}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full px-2",onClick:()=>q(!G),children:G?e.jsx(ts,{className:"w-4 h-4"}):e.jsx(as,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"codex-baseurl",children:"API 请求地址"}),e.jsx(N,{id:"codex-baseurl",value:ue,onChange:l=>le(l.target.value),placeholder:"https://your-api-endpoint.com/v1"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"填写兼容 OpenAI Response 格式的服务端点地址"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"codex-model",children:n({id:"apiSettings.cliSettings.model"})}),e.jsx(N,{id:"codex-model",value:ce,onChange:l=>B(l.target.value),placeholder:""}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"指定使用的模型,将自动更新到 config.toml 中"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"codex-profile",children:"Profile"}),e.jsx(N,{id:"codex-profile",value:be,onChange:l=>E(l.target.value),placeholder:"default"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Codex profile 名称,通过 --profile 参数传递"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"codex-authjson",children:"auth.json (JSON) *"}),e.jsx(Ke,{id:"codex-authjson",value:te,onChange:l=>{de(l.target.value),Y.authJson&&Le(J=>{const $={...J};return delete $.authJson,$})},placeholder:'{"OPENAI_API_KEY": "..."}',className:`font-mono text-sm ${Y.authJson?"border-destructive":""}`,rows:8}),Y.authJson&&e.jsx("p",{className:"text-xs text-destructive",children:Y.authJson}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Codex auth.json 配置内容"}),e.jsx(f,{type:"button",variant:"ghost",size:"sm",onClick:()=>{try{const l=JSON.stringify(JSON.parse(te),null,2);de(l)}catch{}},children:"格式化"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(m,{htmlFor:"codex-configtoml",children:"config.toml (TOML)"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Z,{id:"writeCommon",checked:_e,onCheckedChange:Pe}),e.jsx(m,{htmlFor:"writeCommon",className:"text-xs cursor-pointer",children:"写入通用配置"})]})]}),e.jsx(Ke,{id:"codex-configtoml",value:Re,onChange:l=>Me(l.target.value),placeholder:"",className:"font-mono text-sm",rows:6})]})]}),D==="gemini"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between p-3 bg-muted/30 rounded-lg",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Load Global Config"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Load settings.json from global Gemini config directory"})]}),e.jsx(f,{type:"button",variant:"outline",size:"sm",onClick:R,disabled:Ae,children:Ae?e.jsxs(e.Fragment,{children:[e.jsx(ss,{className:"w-4 h-4 mr-2 animate-spin"}),"Loading..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Is,{className:"w-4 h-4 mr-2"}),"Load Config"]})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"gemini-apikey",children:"API Key"}),e.jsxs("div",{className:"relative",children:[e.jsx(N,{id:"gemini-apikey",type:ke?"text":"password",value:Ce,onChange:l=>we(l.target.value),placeholder:"AIza...",className:"pr-10"}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full px-2",onClick:()=>Ee(!ke),children:ke?e.jsx(ts,{className:"w-4 h-4"}):e.jsx(as,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"gemini-model",children:n({id:"apiSettings.cliSettings.model"})}),e.jsx(N,{id:"gemini-model",value:ce,onChange:l=>B(l.target.value),placeholder:""})]}),Te&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(m,{htmlFor:"gemini-settingsjson",children:"settings.json (Preview)"}),e.jsx(f,{type:"button",variant:"ghost",size:"sm",onClick:()=>{try{const l=JSON.stringify(JSON.parse(Te),null,2);je(l)}catch{}},children:"Format"})]}),e.jsx(Ke,{id:"gemini-settingsjson",value:Te,onChange:l=>je(l.target.value),placeholder:"{}",className:"font-mono text-sm",rows:8,readOnly:!0}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Gemini settings.json content (read-only preview)"})]})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"availableModels",children:n({id:"apiSettings.cliSettings.availableModels"})}),e.jsxs("div",{className:"flex flex-wrap gap-2 p-3 bg-muted/30 rounded-lg min-h-[60px]",children:[se.map(l=>e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary/10 text-primary rounded-md text-sm",children:[l,e.jsx("button",{type:"button",onClick:()=>Ws(l),className:"hover:text-destructive transition-colors",children:"×"})]},l)),e.jsxs("div",{className:"flex gap-2 flex-1",children:[e.jsx(N,{id:"availableModels",value:ae,onChange:l=>oe(l.target.value),onKeyDown:l=>{l.key==="Enter"&&(l.preventDefault(),Je())},placeholder:n({id:"apiSettings.cliSettings.availableModelsPlaceholder"}),className:"flex-1 min-w-[120px]"}),e.jsx(f,{type:"button",size:"sm",onClick:Je,variant:"outline",children:e.jsx(Be,{className:"w-4 h-4"})})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:n({id:"apiSettings.cliSettings.availableModelsHint"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"tags",children:n({id:"apiSettings.cliSettings.tags"})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:n({id:"apiSettings.cliSettings.tagsDescription"})}),e.jsxs("div",{className:"flex flex-wrap gap-2 p-3 bg-muted/30 rounded-lg min-h-[60px]",children:[me.map(l=>e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary/10 text-primary rounded-md text-sm",children:[l,e.jsx("button",{type:"button",onClick:()=>Ys(l),className:"hover:text-destructive transition-colors","aria-label":n({id:"apiSettings.cliSettings.removeTag"}),children:e.jsx(Ds,{className:"w-3 h-3"})})]},l)),e.jsxs("div",{className:"flex gap-2 flex-1",children:[e.jsx(N,{id:"tags",value:is,onChange:l=>Xe(l.target.value),onKeyDown:l=>{l.key==="Enter"&&(l.preventDefault(),Ps())},placeholder:n({id:"apiSettings.cliSettings.tagInputPlaceholder"}),className:"flex-1 min-w-[120px]"}),e.jsx(f,{type:"button",size:"sm",onClick:Ps,variant:"outline",children:e.jsx(ie,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-1",children:[e.jsxs("span",{className:"text-xs text-muted-foreground",children:[n({id:"apiSettings.cliSettings.predefinedTags"}),":"]}),Zs.map(l=>e.jsx("button",{type:"button",onClick:()=>{me.includes(l)||De([...me,l])},disabled:me.includes(l),className:"text-xs px-2 py-0.5 rounded border border-border hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:l},l))]})]}),e.jsxs("div",{className:"space-y-2 pt-4 border-t border-border",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(m,{htmlFor:"configJson",className:"cursor-pointer",children:n({id:"apiSettings.cliSettings.configJson"})}),e.jsx(f,{type:"button",variant:"ghost",size:"sm",onClick:()=>ls(!Fe),children:Fe?n({id:"common.actions.close"}):n({id:"common.actions.expand"},{value:"JSON"})})]}),Fe&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(Ke,{id:"configJson",value:He,onChange:l=>{ns(l.target.value),Y.configJson&&Le(J=>{const $={...J};return delete $.configJson,$})},placeholder:n({id:"apiSettings.cliSettings.configJsonPlaceholder"}),className:Y.configJson?"font-mono border-destructive":"font-mono",rows:8}),Y.configJson&&e.jsx("p",{className:"text-xs text-destructive",children:Y.configJson}),e.jsx("p",{className:"text-xs text-muted-foreground",children:n({id:"apiSettings.cliSettings.configJsonHint"})})]})]})]})]}),e.jsxs(Ye,{children:[e.jsx(f,{variant:"outline",onClick:r,children:n({id:"common.actions.cancel"})}),e.jsx(f,{onClick:U,disabled:M||v,children:M||v?n({id:"common.actions.saving"}):e.jsxs(e.Fragment,{children:[e.jsx(Be,{className:"w-4 h-4 mr-2"}),n({id:"common.actions.save"})]})})]})]})})}function qt({entry:a,showKey:r,onToggleShowKey:t,onUpdate:s,onRemove:n,index:h}){const{formatMessage:o}=W();return e.jsxs("div",{className:"grid grid-cols-12 gap-2 items-start p-3 bg-muted/30 rounded-lg",children:[e.jsxs("div",{className:"col-span-3",children:[e.jsx(m,{className:"text-xs",children:o({id:"apiSettings.providers.keyLabel"})}),e.jsx(N,{value:a.label||"",onChange:d=>s({label:d.target.value}),placeholder:`Key ${h+1}`,className:"mt-1"})]}),e.jsxs("div",{className:"col-span-4",children:[e.jsx(m,{className:"text-xs",children:o({id:"apiSettings.providers.keyValue"})}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx(N,{type:r?"text":"password",value:a.key,onChange:d=>s({key:d.target.value}),placeholder:"sk-...",className:"pr-8"}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",className:"absolute right-0 top-0 h-full px-2",onClick:t,children:r?e.jsx(ts,{className:"w-4 h-4"}):e.jsx(as,{className:"w-4 h-4"})})]})]}),e.jsxs("div",{className:"col-span-2",children:[e.jsx(m,{className:"text-xs",children:o({id:"apiSettings.providers.keyWeight"})}),e.jsx(N,{type:"number",min:"0",max:"100",value:a.weight??1,onChange:d=>s({weight:parseInt(d.target.value)||1}),className:"mt-1"})]}),e.jsxs("div",{className:"col-span-2 flex items-center gap-2 pt-5",children:[e.jsx(Z,{checked:a.enabled,onCheckedChange:d=>s({enabled:d})}),e.jsx("span",{className:"text-sm text-muted-foreground",children:a.enabled?o({id:"apiSettings.common.enabled"}):o({id:"apiSettings.common.disabled"})})]}),e.jsx("div",{className:"col-span-1 flex items-center justify-end pt-5",children:e.jsx(f,{type:"button",variant:"ghost",size:"icon",onClick:n,className:"text-destructive",children:e.jsx(ye,{className:"w-4 h-4"})})})]})}function Qt({open:a,onClose:r,providerId:t}){const{formatMessage:s}=W(),{success:n,error:h}=ge(),{providers:o}=Ze(),{updateProvider:d,isUpdating:M}=Ss(),u=o.find(b=>b.id===t),[v,j]=i.useState([]),[P,F]=i.useState(new Set),[H,k]=i.useState("simple-shuffle"),[I,C]=i.useState(!1),[D,w]=i.useState(60),[K,g]=i.useState(300),[c,A]=i.useState(5);i.useEffect(()=>{u&&(!!(u.apiKeys&&u.apiKeys.length>0)&&u.apiKeys?j(u.apiKeys.map(p=>({id:p.id,key:p.key,label:p.label,weight:p.weight,enabled:p.enabled}))):u.apiKey?j([{id:"key-1",key:u.apiKey,label:"Key 1",weight:1,enabled:!0}]):j([]),k(u.routingStrategy||"simple-shuffle"),u.healthCheck&&(C(u.healthCheck.enabled),w(u.healthCheck.intervalSeconds),g(u.healthCheck.cooldownSeconds),A(u.healthCheck.failureThreshold)))},[u,a]);const L=()=>{const b={id:`key-${Date.now()}`,key:"",label:`Key ${v.length+1}`,weight:1,enabled:!0};j([...v,b])},z=(b,p)=>{j(v.map((O,X)=>X===b?{...O,...p}:O))},y=b=>{j(v.filter((p,O)=>O!==b))},S=b=>{F(p=>{const O=new Set(p);return O.has(b)?O.delete(b):O.add(b),O})},_=async()=>{if(u)try{await d(t,{apiKey:"",apiKeys:v.map(b=>({id:b.id,key:b.key,label:b.label,weight:b.weight,enabled:b.enabled})),routingStrategy:H,healthCheck:I?{enabled:!0,intervalSeconds:D,cooldownSeconds:K,failureThreshold:c}:void 0}),n(s({id:"apiSettings.providers.actions.save"})),r()}catch{h(s({id:"apiSettings.providers.saveError"}))}};return u?e.jsx($e,{open:a,onOpenChange:r,children:e.jsxs(Ge,{className:"max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(qe,{children:[e.jsx(Qe,{children:s({id:"apiSettings.providers.multiKeySettings"})}),e.jsxs(We,{children:[s({id:"apiSettings.providers.description"}),": ",u.name]})]}),e.jsxs("div",{className:"space-y-6 py-4",children:[e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s({id:"apiSettings.providers.actions.multiKeySettings"})}),e.jsxs(f,{type:"button",size:"sm",onClick:L,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.providers.addKey"})]})]}),v.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"apiSettings.providers.noModels"})}):e.jsx("div",{className:"space-y-2",children:v.map((b,p)=>e.jsx(qt,{entry:b,showKey:P.has(p),onToggleShowKey:()=>S(p),onUpdate:O=>z(p,O),onRemove:()=>y(p),index:p},b.id))})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"routingStrategy",children:s({id:"apiSettings.providers.routingStrategy"})}),e.jsxs(ve,{value:H,onValueChange:b=>k(b),children:[e.jsx(fe,{id:"routingStrategy",children:e.jsx(Se,{})}),e.jsxs(Ne,{children:[e.jsx(V,{value:"simple-shuffle",children:s({id:"apiSettings.providers.simpleShuffle"})}),e.jsx(V,{value:"weighted",children:s({id:"apiSettings.providers.weighted"})}),e.jsx(V,{value:"latency-based",children:s({id:"apiSettings.providers.latencyBased"})}),e.jsx(V,{value:"cost-based",children:s({id:"apiSettings.providers.costBased"})}),e.jsx(V,{value:"least-busy",children:s({id:"apiSettings.providers.leastBusy"})})]})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(m,{children:s({id:"apiSettings.providers.healthCheck"})}),e.jsx(Z,{checked:I,onCheckedChange:C})]}),I&&e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"checkInterval",children:s({id:"apiSettings.providers.checkInterval"})}),e.jsx(N,{id:"checkInterval",type:"number",min:"10",value:D,onChange:b=>w(parseInt(b.target.value)||60)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"cooldownPeriod",children:s({id:"apiSettings.providers.cooldownPeriod"})}),e.jsx(N,{id:"cooldownPeriod",type:"number",min:"10",value:K,onChange:b=>g(parseInt(b.target.value)||300)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"failureThreshold",children:s({id:"apiSettings.providers.failureThreshold"})}),e.jsx(N,{id:"failureThreshold",type:"number",min:"1",value:c,onChange:b=>A(parseInt(b.target.value)||5)})]})]})]})]}),e.jsxs(Ye,{children:[e.jsx(f,{type:"button",variant:"outline",onClick:r,disabled:M,children:s({id:"apiSettings.common.cancel"})}),e.jsxs(f,{onClick:_,disabled:M||v.length===0,children:[M?e.jsx(xe,{className:"w-4 h-4 mr-2 animate-spin"}):e.jsx(Be,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.common.save"})]})]})]})}):null}function As({model:a,onRemove:r,onUpdate:t,index:s}){const{formatMessage:n}=W(),[h,o]=i.useState(!1);return e.jsx("div",{className:"border rounded-lg p-3 space-y-2",children:e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex-1 grid grid-cols-2 gap-2",children:[e.jsx(N,{value:a.name,onChange:d=>t("name",d.target.value),placeholder:n({id:"apiSettings.providers.modelId"}),className:"font-medium"}),e.jsx(N,{value:a.series||"",onChange:d=>t("series",d.target.value),placeholder:n({id:"apiSettings.providers.modelSeries"})})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsxs(hs,{open:h,onOpenChange:o,children:[e.jsx(xs,{asChild:!0,children:e.jsx(f,{type:"button",variant:"ghost",size:"icon",children:h?e.jsx(os,{className:"w-4 h-4"}):e.jsx(ms,{className:"w-4 h-4"})})}),e.jsxs(gs,{className:"w-full",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2 mt-2 pt-2 border-t",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(m,{className:"text-xs",children:n({id:"apiSettings.providers.contextWindow"})}),e.jsx(N,{type:"number",value:a.contextWindow||"",onChange:d=>t("contextWindow",parseInt(d.target.value)||void 0),placeholder:"200000"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(m,{className:"text-xs",children:n({id:"apiSettings.providers.description"})}),e.jsx(N,{value:a.description||"",onChange:d=>t("description",d.target.value),placeholder:"Optional description"})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 mt-2",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(Z,{checked:a.streaming,onCheckedChange:d=>t("streaming",d),id:`streaming-${s}`}),e.jsx(m,{htmlFor:`streaming-${s}`,className:"text-xs cursor-pointer",children:n({id:"apiSettings.providers.streaming"})})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(Z,{checked:a.functionCalling,onCheckedChange:d=>t("functionCalling",d),id:`fc-${s}`}),e.jsx(m,{htmlFor:`fc-${s}`,className:"text-xs cursor-pointer",children:n({id:"apiSettings.providers.functionCalling"})})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(Z,{checked:a.vision,onCheckedChange:d=>t("vision",d),id:`vision-${s}`}),e.jsx(m,{htmlFor:`vision-${s}`,className:"text-xs cursor-pointer",children:n({id:"apiSettings.providers.vision"})})]})]})]})]}),e.jsx(f,{type:"button",variant:"ghost",size:"icon",onClick:r,className:"text-destructive",children:e.jsx(ye,{className:"w-4 h-4"})})]})]})})}function Wt({open:a,onClose:r,providerId:t}){const{formatMessage:s}=W(),{success:n,error:h}=ge(),{providers:o}=Ze(),{updateProvider:d,isUpdating:M}=Ss(),u=o.find(g=>g.id===t),[v,j]=i.useState([]),[P,F]=i.useState([]);i.useEffect(()=>{u&&(u.llmModels&&j(u.llmModels.map(g=>({id:g.id,name:g.name,series:g.series,description:g.description}))),u.embeddingModels&&F(u.embeddingModels.map(g=>({id:g.id,name:g.name,series:g.series,description:g.description}))))},[u,a]);const H=()=>{const g={id:`llm-${Date.now()}`,name:"",series:""};j([...v,g])},k=g=>{j(v.filter((c,A)=>A!==g))},I=(g,c,A)=>{j(v.map((L,z)=>z===g?{...L,[c]:A}:L))},C=()=>{const g={id:`emb-${Date.now()}`,name:"",series:""};F([...P,g])},D=g=>{F(P.filter((c,A)=>A!==g))},w=(g,c,A)=>{F(P.map((L,z)=>z===g?{...L,[c]:A}:L))},K=async()=>{if(u)try{const g=new Date().toISOString();await d(t,{llmModels:v.filter(c=>c.name.trim()).map(c=>({id:c.id,name:c.name,type:"llm",series:c.series||c.name.split("-")[0],enabled:!0,createdAt:g,updatedAt:g})),embeddingModels:P.filter(c=>c.name.trim()).map(c=>({id:c.id,name:c.name,type:"embedding",series:c.series||c.name.split("-")[0],enabled:!0,createdAt:g,updatedAt:g}))}),n(s({id:"apiSettings.providers.actions.save"})),r()}catch{h(s({id:"apiSettings.providers.saveError"}))}};return u?e.jsx($e,{open:a,onOpenChange:r,children:e.jsxs(Ge,{className:"max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(qe,{children:[e.jsx(Qe,{children:s({id:"apiSettings.providers.actions.manageModels"})}),e.jsxs(We,{children:[s({id:"apiSettings.providers.description"}),": ",u.name]})]}),e.jsxs("div",{className:"space-y-6 py-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s({id:"apiSettings.providers.llmModels"})}),e.jsx(ee,{variant:"secondary",children:v.length})]}),e.jsxs(f,{type:"button",size:"sm",onClick:H,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.providers.addLlmModel"})]})]}),v.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"apiSettings.providers.noModels"})}):e.jsx("div",{className:"space-y-2",children:v.map((g,c)=>e.jsx(As,{model:g,onRemove:()=>k(c),onUpdate:(A,L)=>I(c,A,L),index:c},g.id))})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s({id:"apiSettings.providers.embeddingModels"})}),e.jsx(ee,{variant:"secondary",children:P.length})]}),e.jsxs(f,{type:"button",size:"sm",onClick:C,children:[e.jsx(ie,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.providers.addEmbeddingModel"})]})]}),P.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"apiSettings.providers.noModels"})}):e.jsx("div",{className:"space-y-2",children:P.map((g,c)=>e.jsx(As,{model:g,onRemove:()=>D(c),onUpdate:(A,L)=>w(c,A,L),index:c},g.id))})]})]}),e.jsxs(Ye,{children:[e.jsx(f,{type:"button",variant:"outline",onClick:r,disabled:M,children:s({id:"apiSettings.common.cancel"})}),e.jsxs(f,{onClick:K,disabled:M,children:[M?e.jsx(xe,{className:"w-4 h-4 mr-2 animate-spin"}):e.jsx(Be,{className:"w-4 h-4 mr-2"}),s({id:"apiSettings.common.save"})]})]})]})}):null}function xa(){const{formatMessage:a}=W(),{success:r,error:t}=ge(),[s,n]=i.useState("providers"),h=Pt(),{providers:o}=Ze(),{endpoints:d}=Ls(),{pools:M}=zs(),{cliSettings:u}=Rs(),[v,j]=i.useState(!1),[P,F]=i.useState(null),[H,k]=i.useState(!1),[I,C]=i.useState(null),[D,w]=i.useState(!1),[K,g]=i.useState(null),[c,A]=i.useState(!1),[L,z]=i.useState(null),[y,S]=i.useState(!1),[_,b]=i.useState(null),[p,O]=i.useState(!1),[X,ne]=i.useState(null),ue=i.useMemo(()=>o.find(B=>B.id===P)||null,[o,P]),le=i.useMemo(()=>d.find(B=>B.id===I)||null,[d,I]),be=i.useMemo(()=>M.find(B=>B.id===K)||null,[M,K]),E=i.useMemo(()=>u.find(B=>B.id===L)||null,[u,L]),G=()=>{F(null),j(!0)},q=B=>{F(B),j(!0)},te=()=>{j(!1),F(null)},de=()=>{C(null),k(!0)},Re=B=>{C(B),k(!0)},Me=()=>{k(!1),C(null)},_e=()=>{g(null),w(!0)},Pe=B=>{g(B),w(!0)},Ce=()=>{w(!1),g(null)},we=()=>{z(null),A(!0)},ke=B=>{z(B),A(!0)},Ee=()=>{A(!1),z(null)},Te=B=>{b(B),S(!0)},je=()=>{S(!1),b(null)},Ae=B=>{ne(B),O(!0)},Ie=()=>{O(!1),ne(null)},ce=async B=>{var re;const se=((re=o.find(ae=>ae.id===B))==null?void 0:re.name)??B;try{const ae=await h.mutateAsync(),oe=[se,ae.yamlPath??ae.message].filter(Boolean);r(a({id:"apiSettings.messages.configSynced"}),oe.length>0?oe.join(`
|
|
4
4
|
`):void 0)}catch{t(a({id:"apiSettings.providers.saveError"}))}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold text-foreground flex items-center gap-2",children:[e.jsx(dt,{className:"w-6 h-6 text-primary"}),a({id:"apiSettings.title"})]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:a({id:"apiSettings.description"})})]}),e.jsxs(f,{variant:"outline",onClick:()=>window.location.reload(),children:[e.jsx(rt,{className:"w-4 h-4 mr-2"}),a({id:"common.actions.refresh"})]})]}),e.jsx(ct,{value:s,onValueChange:B=>n(B),tabs:[{value:"providers",label:a({id:"apiSettings.tabs.providers"})},{value:"endpoints",label:a({id:"apiSettings.tabs.endpoints"})},{value:"cache",label:a({id:"apiSettings.tabs.cache"})},{value:"modelPools",label:a({id:"apiSettings.tabs.modelPools"})},{value:"cliSettings",label:a({id:"apiSettings.tabs.cliSettings"})}]}),s==="providers"&&e.jsx("div",{className:"mt-4",children:e.jsx(Ft,{onAddProvider:G,onEditProvider:q,onMultiKeySettings:Te,onSyncToCodexLens:ce,onManageModels:Ae})}),s==="endpoints"&&e.jsx("div",{className:"mt-4",children:e.jsx(Lt,{onAddEndpoint:de,onEditEndpoint:Re})}),s==="cache"&&e.jsx("div",{className:"mt-4",children:e.jsx(Rt,{})}),s==="modelPools"&&e.jsx("div",{className:"mt-4",children:e.jsx(Ht,{onAddPool:_e,onEditPool:Pe})}),s==="cliSettings"&&e.jsx("div",{className:"mt-4",children:e.jsx($t,{onAddCliSettings:we,onEditCliSettings:ke})}),e.jsx(At,{open:v,onClose:te,provider:ue}),e.jsx(zt,{open:H,onClose:Me,endpoint:le}),e.jsx(Jt,{open:D,onClose:Ce,pool:be}),e.jsx(Gt,{open:c,onClose:Ee,cliSettings:E}),e.jsx(Qt,{open:y,onClose:je,providerId:_||""}),e.jsx(Wt,{open:p,onClose:Ie,providerId:X||""})]})}export{xa as ApiSettingsPage,xa as default};
|
|
5
|
-
//# sourceMappingURL=ApiSettingsPage-
|
|
5
|
+
//# sourceMappingURL=ApiSettingsPage-DlCbXxTz.js.map
|