claude-code-workflow 7.2.5 → 7.2.7
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/commands/workflow/analyze-with-file.md +11 -10
- package/.claude/skills/ccw-help/command.json +3 -3
- package/.claude/skills/ccw-help/index/all-commands.json +3 -3
- package/.claude/skills/ccw-help/index/by-category.json +3 -3
- package/.claude/skills/ccw-help/index/by-use-case.json +3 -3
- package/.claude/skills/skill-iter-tune/SKILL.md +382 -0
- package/.claude/skills/skill-iter-tune/phases/01-setup.md +144 -0
- package/.claude/skills/skill-iter-tune/phases/02-execute.md +292 -0
- package/.claude/skills/skill-iter-tune/phases/03-evaluate.md +312 -0
- package/.claude/skills/skill-iter-tune/phases/04-improve.md +186 -0
- package/.claude/skills/skill-iter-tune/phases/05-report.md +166 -0
- package/.claude/skills/skill-iter-tune/specs/evaluation-criteria.md +63 -0
- package/.claude/skills/skill-iter-tune/templates/eval-prompt.md +134 -0
- package/.claude/skills/skill-iter-tune/templates/execute-prompt.md +97 -0
- package/.claude/skills/team-roadmap-dev/SKILL.md +1 -1
- package/.claude/skills/team-roadmap-dev/roles/coordinator/role.md +1 -1
- package/.claude/skills/team-roadmap-dev/specs/team-config.json +1 -1
- package/ccw/dist/commands/install.d.ts.map +1 -1
- package/ccw/dist/commands/install.js +11 -9
- package/ccw/dist/commands/install.js.map +1 -1
- package/ccw/dist/core/routes/codexlens/config-handlers.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens/config-handlers.js +4 -0
- package/ccw/dist/core/routes/codexlens/config-handlers.js.map +1 -1
- package/ccw/dist/mcp-server/index.js +85 -8
- package/ccw/dist/mcp-server/index.js.map +1 -1
- package/ccw/dist/tools/cli-executor-core.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor-core.js +0 -25
- package/ccw/dist/tools/cli-executor-core.js.map +1 -1
- package/ccw/dist/tools/cli-executor-state.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor-state.js +0 -31
- package/ccw/dist/tools/cli-executor-state.js.map +1 -1
- package/ccw/dist/tools/cli-history-store.d.ts.map +1 -1
- package/ccw/dist/tools/cli-history-store.js +1 -30
- package/ccw/dist/tools/cli-history-store.js.map +1 -1
- package/ccw/dist/tools/smart-search.d.ts +72 -1
- package/ccw/dist/tools/smart-search.d.ts.map +1 -1
- package/ccw/dist/tools/smart-search.js +726 -117
- package/ccw/dist/tools/smart-search.js.map +1 -1
- package/ccw/frontend/dist/assets/{AlertDialog-CFGtc76Y.js → AlertDialog-CSZq4WHZ.js} +2 -2
- package/ccw/frontend/dist/assets/{AlertDialog-CFGtc76Y.js.map → AlertDialog-CSZq4WHZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{AnalysisPage-Duxia_dG.js → AnalysisPage-DVDvLHqI.js} +2 -2
- package/ccw/frontend/dist/assets/{AnalysisPage-Duxia_dG.js.map → AnalysisPage-DVDvLHqI.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ApiSettingsPage-CU9hesAE.js → ApiSettingsPage-D69j8mI6.js} +2 -2
- package/ccw/frontend/dist/assets/{ApiSettingsPage-CU9hesAE.js.map → ApiSettingsPage-D69j8mI6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliModeToggle-DcdOFSvM.js → CliModeToggle-fF9xHeGR.js} +2 -2
- package/ccw/frontend/dist/assets/{CliModeToggle-DcdOFSvM.js.map → CliModeToggle-fF9xHeGR.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliSessionSharePage-oKN-GRIT.js → CliSessionSharePage-Ce8tOQNx.js} +2 -2
- package/ccw/frontend/dist/assets/{CliSessionSharePage-oKN-GRIT.js.map → CliSessionSharePage-Ce8tOQNx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliViewerPage-_wUoHaY-.js → CliViewerPage-Bsp1zmfD.js} +2 -2
- package/ccw/frontend/dist/assets/{CliViewerPage-_wUoHaY-.js.map → CliViewerPage-Bsp1zmfD.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CodexLensManagerPage-ClPNashJ.js → CodexLensManagerPage-DUMzbrr9.js} +9 -9
- package/ccw/frontend/dist/assets/CodexLensManagerPage-DUMzbrr9.js.map +1 -0
- package/ccw/frontend/dist/assets/{Collapsible-Dladh9Eu.js → Collapsible-I5pixbHb.js} +2 -2
- package/ccw/frontend/dist/assets/{Collapsible-Dladh9Eu.js.map → Collapsible-I5pixbHb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CommandsManagerPage-B6DBb_Ew.js → CommandsManagerPage-BH2xukdx.js} +2 -2
- package/ccw/frontend/dist/assets/{CommandsManagerPage-B6DBb_Ew.js.map → CommandsManagerPage-BH2xukdx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{DeepWikiPage-CDA3xm3R.js → DeepWikiPage-D41ccWzY.js} +2 -2
- package/ccw/frontend/dist/assets/{DeepWikiPage-CDA3xm3R.js.map → DeepWikiPage-D41ccWzY.js.map} +1 -1
- package/ccw/frontend/dist/assets/{EndpointsPage-Bu7iU0Wy.js → EndpointsPage-5a8jfEWN.js} +2 -2
- package/ccw/frontend/dist/assets/{EndpointsPage-Bu7iU0Wy.js.map → EndpointsPage-5a8jfEWN.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ExplorerPage-xim2cboZ.js → ExplorerPage-YCqIOu1v.js} +2 -2
- package/ccw/frontend/dist/assets/{ExplorerPage-xim2cboZ.js.map → ExplorerPage-YCqIOu1v.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FixSessionPage-BTFYoFQF.js → FixSessionPage-wK1s4kbo.js} +2 -2
- package/ccw/frontend/dist/assets/{FixSessionPage-BTFYoFQF.js.map → FixSessionPage-wK1s4kbo.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-B30ANzTJ.js → FloatingFileBrowser-B1U6uk_5.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-B30ANzTJ.js.map → FloatingFileBrowser-B1U6uk_5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingPanel-Ds84B7Ob.js → FloatingPanel-D51p5jNy.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingPanel-Ds84B7Ob.js.map → FloatingPanel-D51p5jNy.js.map} +1 -1
- package/ccw/frontend/dist/assets/{GraphExplorerPage-DJ4YnFOQ.js → GraphExplorerPage-DpIWrpWH.js} +2 -2
- package/ccw/frontend/dist/assets/{GraphExplorerPage-DJ4YnFOQ.js.map → GraphExplorerPage-DpIWrpWH.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HistoryPage-rzLVsw11.js → HistoryPage-C09lyJGN.js} +2 -2
- package/ccw/frontend/dist/assets/{HistoryPage-rzLVsw11.js.map → HistoryPage-C09lyJGN.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HookManagerPage-DizO_dCP.js → HookManagerPage-CFBe8F_G.js} +2 -2
- package/ccw/frontend/dist/assets/{HookManagerPage-DizO_dCP.js.map → HookManagerPage-CFBe8F_G.js.map} +1 -1
- package/ccw/frontend/dist/assets/{InstallationsPage-BFamuE4y.js → InstallationsPage-qt7NxnsB.js} +2 -2
- package/ccw/frontend/dist/assets/{InstallationsPage-BFamuE4y.js.map → InstallationsPage-qt7NxnsB.js.map} +1 -1
- package/ccw/frontend/dist/assets/{IssueHubPage-DHwQWuUc.js → IssueHubPage-CHol1-Ap.js} +2 -2
- package/ccw/frontend/dist/assets/{IssueHubPage-DHwQWuUc.js.map → IssueHubPage-CHol1-Ap.js.map} +1 -1
- package/ccw/frontend/dist/assets/{LiteTasksPage-DMDkG7pi.js → LiteTasksPage-jH00SLnZ.js} +2 -2
- package/ccw/frontend/dist/assets/{LiteTasksPage-DMDkG7pi.js.map → LiteTasksPage-jH00SLnZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{McpManagerPage-CS2v_1OG.js → McpManagerPage-BS-HgeQJ.js} +11 -11
- package/ccw/frontend/dist/assets/McpManagerPage-BS-HgeQJ.js.map +1 -0
- package/ccw/frontend/dist/assets/{MemoryPage-DhYPE-VC.js → MemoryPage-1UahrmRX.js} +2 -2
- package/ccw/frontend/dist/assets/{MemoryPage-DhYPE-VC.js.map → MemoryPage-1UahrmRX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{NotFoundPage-BLmC7-ot.js → NotFoundPage-5FVm_IkS.js} +2 -2
- package/ccw/frontend/dist/assets/{NotFoundPage-BLmC7-ot.js.map → NotFoundPage-5FVm_IkS.js.map} +1 -1
- package/ccw/frontend/dist/assets/{OrchestratorPage-1jzSUFZW.js → OrchestratorPage-ThBG24Gg.js} +2 -2
- package/ccw/frontend/dist/assets/{OrchestratorPage-1jzSUFZW.js.map → OrchestratorPage-ThBG24Gg.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-gWuAj-Cn.js → ProjectOverviewPage-CrmW0IxI.js} +2 -2
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-gWuAj-Cn.js.map → ProjectOverviewPage-CrmW0IxI.js.map} +1 -1
- package/ccw/frontend/dist/assets/{PromptHistoryPage-q7ySVNHM.js → PromptHistoryPage-1cCGwS3s.js} +2 -2
- package/ccw/frontend/dist/assets/{PromptHistoryPage-q7ySVNHM.js.map → PromptHistoryPage-1cCGwS3s.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ReviewSessionPage-DX1uT_nH.js → ReviewSessionPage-DxiEc9HK.js} +2 -2
- package/ccw/frontend/dist/assets/{ReviewSessionPage-DX1uT_nH.js.map → ReviewSessionPage-DxiEc9HK.js.map} +1 -1
- package/ccw/frontend/dist/assets/{RulesManagerPage-Bg6T5W-W.js → RulesManagerPage-BpplliZF.js} +2 -2
- package/ccw/frontend/dist/assets/{RulesManagerPage-Bg6T5W-W.js.map → RulesManagerPage-BpplliZF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionDetailPage-C_ig6JSh.js → SessionDetailPage-crDIiysh.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionDetailPage-C_ig6JSh.js.map → SessionDetailPage-crDIiysh.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionsPage-BENFqFDn.js → SessionsPage-DThweYY8.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionsPage-BENFqFDn.js.map → SessionsPage-DThweYY8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SettingsPage-2c-oTxfz.js → SettingsPage-OCdOz5-z.js} +4 -4
- package/ccw/frontend/dist/assets/{SettingsPage-2c-oTxfz.js.map → SettingsPage-OCdOz5-z.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SkillsManagerPage-GLo6DXnt.js → SkillsManagerPage-BJd3bK1G.js} +2 -2
- package/ccw/frontend/dist/assets/{SkillsManagerPage-GLo6DXnt.js.map → SkillsManagerPage-BJd3bK1G.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-CRqMV90p.js → SpecsSettingsPage-BAWL2cpO.js} +2 -2
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-CRqMV90p.js.map → SpecsSettingsPage-BAWL2cpO.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Switch-vlMavMRD.js → Switch-w0I3JCcC.js} +2 -2
- package/ccw/frontend/dist/assets/{Switch-vlMavMRD.js.map → Switch-w0I3JCcC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TabsNavigation-CLKz7pWP.js → TabsNavigation-jhUge9YV.js} +2 -2
- package/ccw/frontend/dist/assets/{TabsNavigation-CLKz7pWP.js.map → TabsNavigation-jhUge9YV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TaskDrawer-BAFvNqF8.js → TaskDrawer-APWpZulm.js} +2 -2
- package/ccw/frontend/dist/assets/{TaskDrawer-BAFvNqF8.js.map → TaskDrawer-APWpZulm.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TeamPage-C2IsDkAv.js → TeamPage-8OnLsAfJ.js} +2 -2
- package/ccw/frontend/dist/assets/{TeamPage-C2IsDkAv.js.map → TeamPage-8OnLsAfJ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-mgS-iKDm.js → TerminalDashboardPage-Be1hcN4p.js} +2 -2
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-mgS-iKDm.js.map → TerminalDashboardPage-Be1hcN4p.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-CxxK_YIp.js → archive-Bo1tC9yo.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-CxxK_YIp.js.map → archive-Bo1tC9yo.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-restore-DZsrBaeG.js → archive-restore-DYx41yLJ.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-restore-DZsrBaeG.js.map → archive-restore-DYx41yLJ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{arrow-right-BotRHOhr.js → arrow-right-C6pOqWF1.js} +2 -2
- package/ccw/frontend/dist/assets/{arrow-right-BotRHOhr.js.map → arrow-right-C6pOqWF1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bookmark-plus-C0MWZ3S9.js → bookmark-plus-4Qpa6hMJ.js} +2 -2
- package/ccw/frontend/dist/assets/{bookmark-plus-C0MWZ3S9.js.map → bookmark-plus-4Qpa6hMJ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bot-BcHFJXqD.js → bot-HXJTmx8r.js} +2 -2
- package/ccw/frontend/dist/assets/{bot-BcHFJXqD.js.map → bot-HXJTmx8r.js.map} +1 -1
- package/ccw/frontend/dist/assets/{braces-D_p0IZhP.js → braces-Dj2IdY7I.js} +2 -2
- package/ccw/frontend/dist/assets/{braces-D_p0IZhP.js.map → braces-Dj2IdY7I.js.map} +1 -1
- package/ccw/frontend/dist/assets/{circle-stop-Bt634NUt.js → circle-stop-M29TJKHc.js} +2 -2
- package/ccw/frontend/dist/assets/{circle-stop-Bt634NUt.js.map → circle-stop-M29TJKHc.js.map} +1 -1
- package/ccw/frontend/dist/assets/{cpu-DjeGKtvT.js → cpu-DX15mzMT.js} +2 -2
- package/ccw/frontend/dist/assets/{cpu-DjeGKtvT.js.map → cpu-DX15mzMT.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ellipsis-vertical-BmNPuatq.js → ellipsis-vertical-Fs6bysWx.js} +2 -2
- package/ccw/frontend/dist/assets/{ellipsis-vertical-BmNPuatq.js.map → ellipsis-vertical-Fs6bysWx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-B0-xkP67.js → eye-D6BRlJ1r.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-B0-xkP67.js.map → eye-D6BRlJ1r.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-off-Bz0Fkli3.js → eye-off-DjbIj5iN.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-off-Bz0Fkli3.js.map → eye-off-DjbIj5iN.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-json-PUAS4vBm.js → file-json-kg4Lid-H.js} +2 -2
- package/ccw/frontend/dist/assets/{file-json-PUAS4vBm.js.map → file-json-kg4Lid-H.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-text-BMeW5-Sb.js → file-text-BMy5pXNV.js} +2 -2
- package/ccw/frontend/dist/assets/{file-text-BMeW5-Sb.js.map → file-text-BMy5pXNV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{filter-B4wgMvwi.js → filter-BTN-lUUb.js} +2 -2
- package/ccw/frontend/dist/assets/{filter-B4wgMvwi.js.map → filter-BTN-lUUb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{folder-BSHjjjND.js → folder-ChYtty7V.js} +2 -2
- package/ccw/frontend/dist/assets/{folder-BSHjjjND.js.map → folder-ChYtty7V.js.map} +1 -1
- package/ccw/frontend/dist/assets/{gauge-7VRNEl22.js → gauge-C0VJbjRb.js} +2 -2
- package/ccw/frontend/dist/assets/{gauge-7VRNEl22.js.map → gauge-C0VJbjRb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{globe-PvVHBjbW.js → globe-DbNfDXnv.js} +2 -2
- package/ccw/frontend/dist/assets/{globe-PvVHBjbW.js.map → globe-DbNfDXnv.js.map} +1 -1
- package/ccw/frontend/dist/assets/{grid-3x3-CsmmDlhN.js → grid-3x3-xWcpBNxo.js} +2 -2
- package/ccw/frontend/dist/assets/{grid-3x3-CsmmDlhN.js.map → grid-3x3-xWcpBNxo.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hard-drive-D88EZgTY.js → hard-drive-BTACzgUO.js} +2 -2
- package/ccw/frontend/dist/assets/{hard-drive-D88EZgTY.js.map → hard-drive-BTACzgUO.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hash-CZpNRWqt.js → hash-B0dYlmyB.js} +2 -2
- package/ccw/frontend/dist/assets/{hash-CZpNRWqt.js.map → hash-B0dYlmyB.js.map} +1 -1
- package/ccw/frontend/dist/assets/{history-DxN1mopa.js → history-CRRLu6ck.js} +2 -2
- package/ccw/frontend/dist/assets/{history-DxN1mopa.js.map → history-CRRLu6ck.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-BzGEkwIf.js → index-BJIIo0B3.js} +2 -2
- package/ccw/frontend/dist/assets/{index-BzGEkwIf.js.map → index-BJIIo0B3.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-DlcRFzFq.js → index-BP-D3Wv6.js} +2 -2
- package/ccw/frontend/dist/assets/{index-DlcRFzFq.js.map → index-BP-D3Wv6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-BUiq2PUK.js → index-B_QzEioU.js} +2 -2
- package/ccw/frontend/dist/assets/{index-BUiq2PUK.js.map → index-B_QzEioU.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-C04xeBGC.js → index-BpoRYgiq.js} +3 -3
- package/ccw/frontend/dist/assets/{index-C04xeBGC.js.map → index-BpoRYgiq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-CIoWWkDn.js → index-CeESlrZb.js} +8 -8
- package/ccw/frontend/dist/assets/{index-CIoWWkDn.js.map → index-CeESlrZb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-bSgtHHOF.js → index-DzTbMyaS.js} +4 -4
- package/ccw/frontend/dist/assets/{index-bSgtHHOF.js.map → index-DzTbMyaS.js.map} +1 -1
- package/ccw/frontend/dist/assets/{layout-grid-BZqfuNG0.js → layout-grid-ZN26YcTM.js} +2 -2
- package/ccw/frontend/dist/assets/{layout-grid-BZqfuNG0.js.map → layout-grid-ZN26YcTM.js.map} +1 -1
- package/ccw/frontend/dist/assets/{lightbulb-DqJ4OHRL.js → lightbulb-BHrwx9j6.js} +2 -2
- package/ccw/frontend/dist/assets/{lightbulb-DqJ4OHRL.js.map → lightbulb-BHrwx9j6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-2-Bq7fLkC9.js → link-2-zZRu2j4G.js} +2 -2
- package/ccw/frontend/dist/assets/{link-2-Bq7fLkC9.js.map → link-2-zZRu2j4G.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-dSLYjCIG.js → link-8lz-HgnZ.js} +2 -2
- package/ccw/frontend/dist/assets/{link-dSLYjCIG.js.map → link-8lz-HgnZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{list-Bm_CnR56.js → list-DlablIjt.js} +2 -2
- package/ccw/frontend/dist/assets/{list-Bm_CnR56.js.map → list-DlablIjt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{map-pin-B5TELa0z.js → map-pin-JAsCUplr.js} +2 -2
- package/ccw/frontend/dist/assets/{map-pin-B5TELa0z.js.map → map-pin-JAsCUplr.js.map} +1 -1
- package/ccw/frontend/dist/assets/{messages-square-B9sWItdK.js → messages-square-D0iSFb2Y.js} +2 -2
- package/ccw/frontend/dist/assets/{messages-square-B9sWItdK.js.map → messages-square-D0iSFb2Y.js.map} +1 -1
- package/ccw/frontend/dist/assets/{minimize-2-Z1MYs_Tp.js → minimize-2-BJmkU9CE.js} +2 -2
- package/ccw/frontend/dist/assets/{minimize-2-Z1MYs_Tp.js.map → minimize-2-BJmkU9CE.js.map} +1 -1
- package/ccw/frontend/dist/assets/{package-EEv4N_Qk.js → package-DYrbBCxk.js} +2 -2
- package/ccw/frontend/dist/assets/{package-EEv4N_Qk.js.map → package-DYrbBCxk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{plug-CEkvvYXh.js → plug-VG7-23M-.js} +2 -2
- package/ccw/frontend/dist/assets/{plug-CEkvvYXh.js.map → plug-VG7-23M-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{power-B6Rod0u_.js → power-zPFYNx7u.js} +2 -2
- package/ccw/frontend/dist/assets/{power-B6Rod0u_.js.map → power-zPFYNx7u.js.map} +1 -1
- package/ccw/frontend/dist/assets/{save-DULWrB2g.js → save-D4XQY9i9.js} +2 -2
- package/ccw/frontend/dist/assets/{save-DULWrB2g.js.map → save-D4XQY9i9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{send-C4z974WG.js → send-ClSnDjj-.js} +2 -2
- package/ccw/frontend/dist/assets/{send-C4z974WG.js.map → send-ClSnDjj-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-check-big-CqEEw-V0.js → square-check-big-Bffh_MFc.js} +2 -2
- package/ccw/frontend/dist/assets/{square-check-big-CqEEw-V0.js.map → square-check-big-Bffh_MFc.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-pen-D-4BrMtQ.js → square-pen-DsOvAvME.js} +2 -2
- package/ccw/frontend/dist/assets/{square-pen-D-4BrMtQ.js.map → square-pen-DsOvAvME.js.map} +1 -1
- package/ccw/frontend/dist/assets/{star-CDVVM69o.js → star-TLJjvoy2.js} +2 -2
- package/ccw/frontend/dist/assets/{star-CDVVM69o.js.map → star-TLJjvoy2.js.map} +1 -1
- package/ccw/frontend/dist/assets/{style-CumJ7XC8.js → style-BXKXgpOY.js} +2 -2
- package/ccw/frontend/dist/assets/{style-CumJ7XC8.js.map → style-BXKXgpOY.js.map} +1 -1
- package/ccw/frontend/dist/assets/{target-Dr9SuV1Y.js → target-FDuAB6SF.js} +2 -2
- package/ccw/frontend/dist/assets/{target-Dr9SuV1Y.js.map → target-FDuAB6SF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{test-tube-DzDRKk8F.js → test-tube-B9vj-Im8.js} +2 -2
- package/ccw/frontend/dist/assets/{test-tube-DzDRKk8F.js.map → test-tube-B9vj-Im8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{upload-CihSmIM7.js → upload-CHgTrVN5.js} +2 -2
- package/ccw/frontend/dist/assets/{upload-CihSmIM7.js.map → upload-CHgTrVN5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useApiSettings-CevxWX2z.js → useApiSettings-XsHrqf-L.js} +2 -2
- package/ccw/frontend/dist/assets/{useApiSettings-CevxWX2z.js.map → useApiSettings-XsHrqf-L.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCli-jVaF89uU.js → useCli-DOlWtux5.js} +2 -2
- package/ccw/frontend/dist/assets/{useCli-jVaF89uU.js.map → useCli-DOlWtux5.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCommands-D4uGmNpF.js → useCommands-DazCajiX.js} +2 -2
- package/ccw/frontend/dist/assets/{useCommands-D4uGmNpF.js.map → useCommands-DazCajiX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useDebounce-BEYmuZYP.js → useDebounce-Cah-bua6.js} +2 -2
- package/ccw/frontend/dist/assets/{useDebounce-BEYmuZYP.js.map → useDebounce-Cah-bua6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useFileExplorer-DEv0DVy7.js → useFileExplorer-B9SCPhhl.js} +2 -2
- package/ccw/frontend/dist/assets/{useFileExplorer-DEv0DVy7.js.map → useFileExplorer-B9SCPhhl.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useLocale-BRJreqvl.js → useLocale-CmG6pxZe.js} +2 -2
- package/ccw/frontend/dist/assets/{useLocale-BRJreqvl.js.map → useLocale-CmG6pxZe.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSkills-lnfeXe9l.js → useSkills-DvEJ0JOv.js} +3 -3
- package/ccw/frontend/dist/assets/{useSkills-lnfeXe9l.js.map → useSkills-DvEJ0JOv.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSystemSettings-PlxVdbXI.js → useSystemSettings-BDpwSa04.js} +2 -2
- package/ccw/frontend/dist/assets/{useSystemSettings-PlxVdbXI.js.map → useSystemSettings-BDpwSa04.js.map} +1 -1
- package/ccw/frontend/dist/assets/{wand-sparkles-BbqUxeEg.js → wand-sparkles-T2KGCRiy.js} +2 -2
- package/ccw/frontend/dist/assets/{wand-sparkles-BbqUxeEg.js.map → wand-sparkles-T2KGCRiy.js.map} +1 -1
- package/ccw/frontend/dist/index.html +1 -1
- package/codex-lens/src/codexlens/cli/commands.py +12 -1
- package/codex-lens/src/codexlens/config.py +12 -0
- package/codex-lens/src/codexlens/env_config.py +1 -0
- package/package.json +1 -1
- package/ccw/frontend/dist/assets/CodexLensManagerPage-ClPNashJ.js.map +0 -1
- package/ccw/frontend/dist/assets/McpManagerPage-CS2v_1OG.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CodexLensManagerPage-ClPNashJ.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/arrow-up-down.js","../../../../node_modules/lucide-react/dist/esm/icons/box.js","../../../../node_modules/lucide-react/dist/esm/icons/rotate-cw.js","../../../../node_modules/lucide-react/dist/esm/icons/scissors.js","../../src/hooks/useCodexLens.ts","../../src/components/codexlens/IndexOperations.tsx","../../src/components/codexlens/FileWatcherCard.tsx","../../src/components/codexlens/LspServerCard.tsx","../../src/components/codexlens/OverviewTab.tsx","../../src/components/codexlens/envVarSchema.ts","../../src/components/codexlens/ModelSelectField.tsx","../../src/components/codexlens/SchemaFormRenderer.tsx","../../src/components/codexlens/SettingsTab.tsx","../../src/components/codexlens/CcwToolsCard.tsx","../../src/components/codexlens/AdvancedTab.tsx","../../src/components/codexlens/ModelCard.tsx","../../src/components/codexlens/ModelsTab.tsx","../../src/components/codexlens/SearchTab.tsx","../../src/components/codexlens/SemanticInstallDialog.tsx","../../src/components/codexlens/InstallProgressOverlay.tsx","../../src/pages/CodexLensManagerPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ArrowUpDown = createLucideIcon(\"ArrowUpDown\", [\n [\"path\", { d: \"m21 16-4 4-4-4\", key: \"f6ql7i\" }],\n [\"path\", { d: \"M17 20V4\", key: \"1ejh1v\" }],\n [\"path\", { d: \"m3 8 4-4 4 4\", key: \"11wl7u\" }],\n [\"path\", { d: \"M7 4v16\", key: \"1glfcx\" }]\n]);\n\nexport { ArrowUpDown as default };\n//# sourceMappingURL=arrow-up-down.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Box = createLucideIcon(\"Box\", [\n [\n \"path\",\n {\n d: \"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\",\n key: \"hh9hay\"\n }\n ],\n [\"path\", { d: \"m3.3 7 8.7 5 8.7-5\", key: \"g66t2b\" }],\n [\"path\", { d: \"M12 22V12\", key: \"d0xqtd\" }]\n]);\n\nexport { Box as default };\n//# sourceMappingURL=box.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RotateCw = createLucideIcon(\"RotateCw\", [\n [\"path\", { d: \"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\", key: \"1p45f6\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }]\n]);\n\nexport { RotateCw as default };\n//# sourceMappingURL=rotate-cw.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Scissors = createLucideIcon(\"Scissors\", [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n]);\n\nexport { Scissors as default };\n//# sourceMappingURL=scissors.js.map\n","// ========================================\r\n// useCodexLens Hook\r\n// ========================================\r\n// TanStack Query hooks for CodexLens management\r\n\r\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { useFormatMessage } from '../hooks/useLocale';\r\nimport { useNotifications } from '../hooks/useNotifications';\r\nimport { sanitizeErrorMessage } from '../utils/errorSanitizer';\r\nimport {\r\n fetchCodexLensDashboardInit,\r\n fetchCodexLensStatus,\r\n fetchCodexLensWorkspaceStatus,\r\n fetchCodexLensConfig,\r\n updateCodexLensConfig,\r\n bootstrapCodexLens,\r\n installCodexLensSemantic,\r\n uninstallCodexLens,\r\n fetchCodexLensModels,\r\n fetchCodexLensModelInfo,\r\n downloadCodexLensModel,\r\n downloadCodexLensCustomModel,\r\n deleteCodexLensModel,\r\n deleteCodexLensModelByPath,\r\n fetchCodexLensEnv,\r\n updateCodexLensEnv,\r\n fetchCodexLensGpuDetect,\r\n fetchCodexLensGpuList,\r\n selectCodexLensGpu,\r\n resetCodexLensGpu,\r\n fetchCodexLensIgnorePatterns,\r\n updateCodexLensIgnorePatterns,\r\n searchCodexLens,\r\n searchFilesCodexLens,\r\n searchSymbolCodexLens,\r\n fetchCodexLensIndexes,\r\n rebuildCodexLensIndex,\r\n updateCodexLensIndex,\r\n cancelCodexLensIndexing,\r\n checkCodexLensIndexingStatus,\r\n fetchCodexLensWatcherStatus,\r\n startCodexLensWatcher,\r\n stopCodexLensWatcher,\r\n type CodexLensDashboardInitResponse,\r\n type CodexLensVenvStatus,\r\n type CodexLensConfig,\r\n type CodexLensModelsResponse,\r\n type CodexLensModelInfoResponse,\r\n type CodexLensEnvResponse,\r\n type CodexLensUpdateEnvResponse,\r\n type CodexLensGpuDetectResponse,\r\n type CodexLensGpuListResponse,\r\n type CodexLensIgnorePatternsResponse,\r\n type CodexLensUpdateEnvRequest,\r\n type CodexLensUpdateIgnorePatternsRequest,\r\n type CodexLensWorkspaceStatus,\r\n type CodexLensSearchParams,\r\n type CodexLensSearchResponse,\r\n type CodexLensFileSearchResponse,\r\n type CodexLensSymbolSearchResponse,\r\n type CodexLensIndexesResponse,\r\n type CodexLensIndexingStatusResponse,\r\n type CodexLensWatcherStatusResponse,\r\n type CodexLensLspStatusResponse,\r\n type CodexLensSemanticSearchParams,\r\n type CodexLensSemanticSearchResponse,\r\n type RerankerConfigResponse,\r\n type RerankerConfigUpdateRequest,\r\n type RerankerConfigUpdateResponse,\r\n fetchCodexLensLspStatus,\r\n startCodexLensLsp,\r\n stopCodexLensLsp,\r\n restartCodexLensLsp,\r\n semanticSearchCodexLens,\r\n fetchRerankerConfig,\r\n updateRerankerConfig,\r\n fetchCcwTools,\r\n type CcwToolInfo,\r\n} from '../lib/api';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// Query key factory\r\nexport const codexLensKeys = {\r\n all: ['codexLens'] as const,\r\n dashboard: () => [...codexLensKeys.all, 'dashboard'] as const,\r\n status: () => [...codexLensKeys.all, 'status'] as const,\r\n workspace: (path?: string) => [...codexLensKeys.all, 'workspace', path] as const,\r\n config: () => [...codexLensKeys.all, 'config'] as const,\r\n models: () => [...codexLensKeys.all, 'models'] as const,\r\n modelInfo: (profile: string) => [...codexLensKeys.models(), 'info', profile] as const,\r\n env: () => [...codexLensKeys.all, 'env'] as const,\r\n gpu: () => [...codexLensKeys.all, 'gpu'] as const,\r\n gpuList: () => [...codexLensKeys.gpu(), 'list'] as const,\r\n gpuDetect: () => [...codexLensKeys.gpu(), 'detect'] as const,\r\n ignorePatterns: () => [...codexLensKeys.all, 'ignorePatterns'] as const,\r\n indexes: () => [...codexLensKeys.all, 'indexes'] as const,\r\n indexingStatus: () => [...codexLensKeys.all, 'indexingStatus'] as const,\r\n search: (params: CodexLensSearchParams) => [...codexLensKeys.all, 'search', params] as const,\r\n filesSearch: (params: CodexLensSearchParams) => [...codexLensKeys.all, 'filesSearch', params] as const,\r\n symbolSearch: (params: Pick<CodexLensSearchParams, 'query' | 'limit'>) => [...codexLensKeys.all, 'symbolSearch', params] as const,\r\n lspStatus: () => [...codexLensKeys.all, 'lspStatus'] as const,\r\n semanticSearch: (params: CodexLensSemanticSearchParams) => [...codexLensKeys.all, 'semanticSearch', params] as const,\r\n watcher: () => [...codexLensKeys.all, 'watcher'] as const,\r\n rerankerConfig: () => [...codexLensKeys.all, 'rerankerConfig'] as const,\r\n ccwTools: () => [...codexLensKeys.all, 'ccwTools'] as const,\r\n};\r\n\r\n// Default stale times\r\nconst STALE_TIME_SHORT = 30 * 1000; // 30 seconds for frequently changing data\r\nconst STALE_TIME_MEDIUM = 2 * 60 * 1000; // 2 minutes for moderately changing data\r\nconst STALE_TIME_LONG = 10 * 60 * 1000; // 10 minutes for rarely changing data\r\n\r\n// ========== Query Hooks ==========\r\n\r\nexport interface UseCodexLensDashboardOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensDashboardReturn {\r\n data: CodexLensDashboardInitResponse | undefined;\r\n installed: boolean;\r\n status: CodexLensVenvStatus | undefined;\r\n config: CodexLensConfig | undefined;\r\n semantic: { available: boolean } | undefined;\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens dashboard initialization data\r\n */\r\nexport function useCodexLensDashboard(options: UseCodexLensDashboardOptions = {}): UseCodexLensDashboardReturn {\r\n const { enabled = true, staleTime = STALE_TIME_SHORT } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.dashboard(),\r\n queryFn: fetchCodexLensDashboardInit,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n installed: query.data?.installed ?? false,\r\n status: query.data?.status,\r\n config: query.data?.config,\r\n semantic: query.data?.semantic,\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensStatusOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensStatusReturn {\r\n status: CodexLensVenvStatus | undefined;\r\n ready: boolean;\r\n installed: boolean;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens venv status\r\n */\r\nexport function useCodexLensStatus(options: UseCodexLensStatusOptions = {}): UseCodexLensStatusReturn {\r\n const { enabled = true, staleTime = STALE_TIME_SHORT } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.status(),\r\n queryFn: fetchCodexLensStatus,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n status: query.data,\r\n ready: query.data?.ready ?? false,\r\n installed: query.data?.installed ?? false,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensWorkspaceStatusOptions {\r\n projectPath?: string;\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensWorkspaceStatusReturn {\r\n data: CodexLensWorkspaceStatus | undefined;\r\n hasIndex: boolean;\r\n ftsPercent: number;\r\n vectorPercent: number;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens workspace index status\r\n */\r\nexport function useCodexLensWorkspaceStatus(options: UseCodexLensWorkspaceStatusOptions = {}): UseCodexLensWorkspaceStatusReturn {\r\n const { projectPath, enabled = true, staleTime = STALE_TIME_SHORT } = options;\r\n const projectPathFromStore = useWorkflowStore(selectProjectPath);\r\n const actualProjectPath = projectPath ?? projectPathFromStore;\r\n const queryEnabled = enabled && !!actualProjectPath;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.workspace(actualProjectPath),\r\n queryFn: () => fetchCodexLensWorkspaceStatus(actualProjectPath),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n hasIndex: query.data?.hasIndex ?? false,\r\n ftsPercent: query.data?.fts.percent ?? 0,\r\n vectorPercent: query.data?.vector.percent ?? 0,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensConfigOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensConfigReturn {\r\n config: CodexLensConfig | undefined;\r\n indexDir: string;\r\n indexCount: number;\r\n apiMaxWorkers: number;\r\n apiBatchSize: number;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens configuration\r\n */\r\nexport function useCodexLensConfig(options: UseCodexLensConfigOptions = {}): UseCodexLensConfigReturn {\r\n const { enabled = true, staleTime = STALE_TIME_MEDIUM } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.config(),\r\n queryFn: fetchCodexLensConfig,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n config: query.data,\r\n indexDir: query.data?.index_dir ?? '~/.codexlens/indexes',\r\n indexCount: query.data?.index_count ?? 0,\r\n apiMaxWorkers: query.data?.api_max_workers ?? 4,\r\n apiBatchSize: query.data?.api_batch_size ?? 8,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensModelsOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensModelsReturn {\r\n models: CodexLensModelsResponse['models'] | undefined;\r\n embeddingModels: CodexLensModelsResponse['models'] | undefined;\r\n rerankerModels: CodexLensModelsResponse['models'] | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens models list\r\n */\r\nexport function useCodexLensModels(options: UseCodexLensModelsOptions = {}): UseCodexLensModelsReturn {\r\n const { enabled = true, staleTime = STALE_TIME_MEDIUM } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.models(),\r\n queryFn: fetchCodexLensModels,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n const models = query.data?.models ?? [];\r\n const embeddingModels = models?.filter(m => m.type === 'embedding');\r\n const rerankerModels = models?.filter(m => m.type === 'reranker');\r\n\r\n return {\r\n models,\r\n embeddingModels,\r\n rerankerModels,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensModelInfoOptions {\r\n profile: string;\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensModelInfoReturn {\r\n info: CodexLensModelInfoResponse['info'] | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens model info by profile\r\n */\r\nexport function useCodexLensModelInfo(options: UseCodexLensModelInfoOptions): UseCodexLensModelInfoReturn {\r\n const { profile, enabled = true, staleTime = STALE_TIME_LONG } = options;\r\n const queryEnabled = enabled && !!profile;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.modelInfo(profile),\r\n queryFn: () => fetchCodexLensModelInfo(profile),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n info: query.data?.info,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensEnvOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensEnvReturn {\r\n data: CodexLensEnvResponse | undefined;\r\n env: Record<string, string> | undefined;\r\n settings: Record<string, string> | undefined;\r\n raw: string | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens environment variables\r\n */\r\nexport function useCodexLensEnv(options: UseCodexLensEnvOptions = {}): UseCodexLensEnvReturn {\r\n const { enabled = true, staleTime = STALE_TIME_MEDIUM } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.env(),\r\n queryFn: fetchCodexLensEnv,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n env: query.data?.env,\r\n settings: query.data?.settings,\r\n raw: query.data?.raw,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensGpuOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensGpuReturn {\r\n detectData: CodexLensGpuDetectResponse | undefined;\r\n listData: CodexLensGpuListResponse | undefined;\r\n supported: boolean;\r\n devices: CodexLensGpuListResponse['devices'] | undefined;\r\n selectedDeviceId: string | number | undefined;\r\n isLoadingDetect: boolean;\r\n isLoadingList: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens GPU information\r\n * Combines both detect and list queries\r\n */\r\nexport function useCodexLensGpu(options: UseCodexLensGpuOptions = {}): UseCodexLensGpuReturn {\r\n const { enabled = true, staleTime = STALE_TIME_LONG } = options;\r\n\r\n const detectQuery = useQuery({\r\n queryKey: codexLensKeys.gpuDetect(),\r\n queryFn: fetchCodexLensGpuDetect,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const listQuery = useQuery({\r\n queryKey: codexLensKeys.gpuList(),\r\n queryFn: fetchCodexLensGpuList,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await Promise.all([detectQuery.refetch(), listQuery.refetch()]);\r\n };\r\n\r\n return {\r\n detectData: detectQuery.data,\r\n listData: listQuery.data,\r\n supported: detectQuery.data?.supported ?? false,\r\n devices: listQuery.data?.devices,\r\n selectedDeviceId: listQuery.data?.selected_device_id,\r\n isLoadingDetect: detectQuery.isLoading,\r\n isLoadingList: listQuery.isLoading,\r\n error: detectQuery.error || listQuery.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensIgnorePatternsOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensIgnorePatternsReturn {\r\n data: CodexLensIgnorePatternsResponse | undefined;\r\n patterns: string[] | undefined;\r\n extensionFilters: string[] | undefined;\r\n defaults: CodexLensIgnorePatternsResponse['defaults'] | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens ignore patterns\r\n */\r\nexport function useCodexLensIgnorePatterns(options: UseCodexLensIgnorePatternsOptions = {}): UseCodexLensIgnorePatternsReturn {\r\n const { enabled = true, staleTime = STALE_TIME_LONG } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.ignorePatterns(),\r\n queryFn: fetchCodexLensIgnorePatterns,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n patterns: query.data?.patterns,\r\n extensionFilters: query.data?.extensionFilters,\r\n defaults: query.data?.defaults,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\n// ========== Mutation Hooks ==========\r\n\r\nexport interface UseUpdateCodexLensConfigReturn {\r\n updateConfig: (config: { index_dir: string; api_max_workers?: number; api_batch_size?: number }) => Promise<{ success: boolean; message?: string }>;\r\n isUpdating: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for updating CodexLens configuration\r\n */\r\nexport function useUpdateCodexLensConfig(): UseUpdateCodexLensConfigReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: updateCodexLensConfig,\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.status.inProgress' }),\r\n formatMessage({ id: 'common.feedback.codexLensConfigUpdate.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.config() });\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.dashboard() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensConfigUpdate.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensConfigUpdate');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n updateConfig: mutation.mutateAsync,\r\n isUpdating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseBootstrapCodexLensReturn {\r\n bootstrap: () => Promise<{ success: boolean; message?: string; version?: string }>;\r\n isBootstrapping: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for bootstrapping/installing CodexLens\r\n */\r\nexport function useBootstrapCodexLens(): UseBootstrapCodexLensReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: bootstrapCodexLens,\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'codexlens.bootstrapping' }),\r\n formatMessage({ id: 'common.feedback.codexLensBootstrap.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.all });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensBootstrap.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensBootstrap');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n bootstrap: mutation.mutateAsync,\r\n isBootstrapping: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseInstallSemanticReturn {\r\n installSemantic: (gpuMode: 'cpu' | 'cuda' | 'directml') => Promise<{ success: boolean; message?: string; gpuMode?: string }>;\r\n isInstalling: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for installing CodexLens semantic dependencies\r\n */\r\nexport function useInstallSemantic(): UseInstallSemanticReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: installCodexLensSemantic,\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'codexlens.semantic.installing' }),\r\n formatMessage({ id: 'common.feedback.codexLensInstallSemantic.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.all });\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.dashboard() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensInstallSemantic.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensInstallSemantic');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n installSemantic: mutation.mutateAsync,\r\n isInstalling: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseUninstallCodexLensReturn {\r\n uninstall: () => Promise<{ success: boolean; message?: string }>;\r\n isUninstalling: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for uninstalling CodexLens\r\n */\r\nexport function useUninstallCodexLens(): UseUninstallCodexLensReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: uninstallCodexLens,\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'codexlens.uninstalling' }),\r\n formatMessage({ id: 'common.feedback.codexLensUninstall.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.all });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensUninstall.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensUninstall');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n uninstall: mutation.mutateAsync,\r\n isUninstalling: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDownloadModelReturn {\r\n downloadModel: (profile: string) => Promise<{ success: boolean; message?: string }>;\r\n downloadCustomModel: (modelName: string, modelType?: string) => Promise<{ success: boolean; message?: string }>;\r\n isDownloading: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for downloading CodexLens models\r\n */\r\nexport function useDownloadModel(): UseDownloadModelReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: async ({ profile, modelName, modelType }: { profile?: string; modelName?: string; modelType?: string }) => {\r\n if (profile) return downloadCodexLensModel(profile);\r\n if (modelName) return downloadCodexLensCustomModel(modelName, modelType);\r\n throw new Error('Either profile or modelName must be provided');\r\n },\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'codexlens.models.downloading' }),\r\n formatMessage({ id: 'common.feedback.codexLensDownloadModel.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.models() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensDownloadModel.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensDownloadModel');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n downloadModel: (profile) => mutation.mutateAsync({ profile }),\r\n downloadCustomModel: (modelName, modelType) => mutation.mutateAsync({ modelName, modelType }),\r\n isDownloading: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeleteModelReturn {\r\n deleteModel: (profile: string) => Promise<{ success: boolean; message?: string }>;\r\n deleteModelByPath: (cachePath: string) => Promise<{ success: boolean; message?: string }>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for deleting CodexLens models\r\n */\r\nexport function useDeleteModel(): UseDeleteModelReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: async ({ profile, cachePath }: { profile?: string; cachePath?: string }) => {\r\n if (profile) return deleteCodexLensModel(profile);\r\n if (cachePath) return deleteCodexLensModelByPath(cachePath);\r\n throw new Error('Either profile or cachePath must be provided');\r\n },\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.actions.deleting' }),\r\n formatMessage({ id: 'common.feedback.codexLensDeleteModel.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.models() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensDeleteModel.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensDeleteModel');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n deleteModel: (profile) => mutation.mutateAsync({ profile }),\r\n deleteModelByPath: (cachePath) => mutation.mutateAsync({ cachePath }),\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseUpdateCodexLensEnvReturn {\r\n updateEnv: (request: CodexLensUpdateEnvRequest) => Promise<CodexLensUpdateEnvResponse>;\r\n isUpdating: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for updating CodexLens environment variables\r\n */\r\nexport function useUpdateCodexLensEnv(): UseUpdateCodexLensEnvReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: (request: CodexLensUpdateEnvRequest) => updateCodexLensEnv(request),\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.status.inProgress' }),\r\n formatMessage({ id: 'common.feedback.codexLensUpdateEnv.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.env() });\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.dashboard() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensUpdateEnv.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensUpdateEnv');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n updateEnv: mutation.mutateAsync,\r\n isUpdating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseSelectGpuReturn {\r\n selectGpu: (deviceId: string | number) => Promise<{ success: boolean; message?: string }>;\r\n resetGpu: () => Promise<{ success: boolean; message?: string }>;\r\n isSelecting: boolean;\r\n isResetting: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for selecting/resetting GPU for CodexLens\r\n */\r\nexport function useSelectGpu(): UseSelectGpuReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const selectMutation = useMutation({\r\n mutationFn: (deviceId: string | number) => selectCodexLensGpu(deviceId),\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.status.inProgress' }),\r\n formatMessage({ id: 'common.feedback.codexLensSelectGpu.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.gpu() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensSelectGpu.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensSelectGpu');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n const resetMutation = useMutation({\r\n mutationFn: () => resetCodexLensGpu(),\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.status.inProgress' }),\r\n formatMessage({ id: 'common.feedback.codexLensResetGpu.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.gpu() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensResetGpu.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensResetGpu');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n selectGpu: selectMutation.mutateAsync,\r\n resetGpu: resetMutation.mutateAsync,\r\n isSelecting: selectMutation.isPending,\r\n isResetting: resetMutation.isPending,\r\n error: selectMutation.error || resetMutation.error,\r\n };\r\n}\r\n\r\nexport interface UseUpdateIgnorePatternsReturn {\r\n updatePatterns: (request: CodexLensUpdateIgnorePatternsRequest) => Promise<CodexLensIgnorePatternsResponse>;\r\n isUpdating: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for updating CodexLens ignore patterns\r\n */\r\nexport function useUpdateIgnorePatterns(): UseUpdateIgnorePatternsReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: updateCodexLensIgnorePatterns,\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.status.inProgress' }),\r\n formatMessage({ id: 'common.feedback.codexLensUpdatePatterns.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.ignorePatterns() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensUpdatePatterns.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensUpdatePatterns');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n updatePatterns: mutation.mutateAsync,\r\n isUpdating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n// ========== Index Management Hooks ==========\r\n\r\nexport interface UseCodexLensIndexesOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensIndexesReturn {\r\n data: CodexLensIndexesResponse | undefined;\r\n indexes: CodexLensIndexesResponse['indexes'] | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching CodexLens indexes\r\n */\r\nexport function useCodexLensIndexes(options: UseCodexLensIndexesOptions = {}): UseCodexLensIndexesReturn {\r\n const { enabled = true, staleTime = STALE_TIME_MEDIUM } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.indexes(),\r\n queryFn: fetchCodexLensIndexes,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n indexes: query.data?.indexes,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensIndexingStatusReturn {\r\n data: CodexLensIndexingStatusResponse | undefined;\r\n inProgress: boolean;\r\n isLoading: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for checking CodexLens indexing status\r\n */\r\nexport function useCodexLensIndexingStatus(): UseCodexLensIndexingStatusReturn {\r\n const query = useQuery({\r\n queryKey: codexLensKeys.indexingStatus(),\r\n queryFn: checkCodexLensIndexingStatus,\r\n staleTime: STALE_TIME_SHORT,\r\n refetchInterval: (query) => ((query.state.data as any)?.inProgress ? 2000 : false), // Poll every 2s when indexing\r\n retry: false,\r\n });\r\n\r\n return {\r\n data: query.data,\r\n inProgress: query.data?.inProgress ?? false,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n };\r\n}\r\n\r\nexport interface UseRebuildIndexReturn {\r\n rebuildIndex: (projectPath: string, options?: {\r\n indexType?: 'normal' | 'vector';\r\n embeddingModel?: string;\r\n embeddingBackend?: 'fastembed' | 'litellm';\r\n maxWorkers?: number;\r\n }) => Promise<{ success: boolean; message?: string; error?: string }>;\r\n isRebuilding: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for rebuilding CodexLens index (full rebuild)\r\n */\r\nexport function useRebuildIndex(): UseRebuildIndexReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: async ({\r\n projectPath,\r\n options = {},\r\n }: {\r\n projectPath: string;\r\n options?: {\r\n indexType?: 'normal' | 'vector';\r\n embeddingModel?: string;\r\n embeddingBackend?: 'fastembed' | 'litellm';\r\n maxWorkers?: number;\r\n };\r\n }) => rebuildCodexLensIndex(projectPath, options),\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.status.inProgress' }),\r\n formatMessage({ id: 'common.feedback.codexLensRebuildIndex.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.indexes() });\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.dashboard() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensRebuildIndex.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensRebuildIndex');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n rebuildIndex: (projectPath, options) =>\r\n mutation.mutateAsync({ projectPath, options }),\r\n isRebuilding: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseUpdateIndexReturn {\r\n updateIndex: (projectPath: string, options?: {\r\n indexType?: 'normal' | 'vector';\r\n embeddingModel?: string;\r\n embeddingBackend?: 'fastembed' | 'litellm';\r\n maxWorkers?: number;\r\n }) => Promise<{ success: boolean; message?: string; error?: string }>;\r\n isUpdating: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for updating CodexLens index (incremental update)\r\n */\r\nexport function useUpdateIndex(): UseUpdateIndexReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: async ({\r\n projectPath,\r\n options = {},\r\n }: {\r\n projectPath: string;\r\n options?: {\r\n indexType?: 'normal' | 'vector';\r\n embeddingModel?: string;\r\n embeddingBackend?: 'fastembed' | 'litellm';\r\n maxWorkers?: number;\r\n };\r\n }) => updateCodexLensIndex(projectPath, options),\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.status.inProgress' }),\r\n formatMessage({ id: 'common.feedback.codexLensUpdateIndex.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.indexes() });\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.dashboard() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensUpdateIndex.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensUpdateIndex');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n updateIndex: (projectPath, options) =>\r\n mutation.mutateAsync({ projectPath, options }),\r\n isUpdating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseCancelIndexingReturn {\r\n cancelIndexing: () => Promise<{ success: boolean; error?: string }>;\r\n isCancelling: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for canceling CodexLens indexing\r\n */\r\nexport function useCancelIndexing(): UseCancelIndexingReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, info, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: cancelCodexLensIndexing,\r\n onMutate: () => {\r\n info(\r\n formatMessage({ id: 'common.status.inProgress' }),\r\n formatMessage({ id: 'common.feedback.codexLensCancelIndexing.success' })\r\n );\r\n },\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.indexingStatus() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'common.feedback.codexLensCancelIndexing.success' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensCancelIndexing');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n cancelIndexing: mutation.mutateAsync,\r\n isCancelling: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Combined hook for all CodexLens mutations\r\n */\r\nexport function useCodexLensMutations() {\r\n const updateConfig = useUpdateCodexLensConfig();\r\n const bootstrap = useBootstrapCodexLens();\r\n const installSemantic = useInstallSemantic();\r\n const uninstall = useUninstallCodexLens();\r\n const download = useDownloadModel();\r\n const deleteModel = useDeleteModel();\r\n const updateEnv = useUpdateCodexLensEnv();\r\n const gpu = useSelectGpu();\r\n const updatePatterns = useUpdateIgnorePatterns();\r\n const rebuildIndex = useRebuildIndex();\r\n const updateIndex = useUpdateIndex();\r\n const cancelIndexing = useCancelIndexing();\r\n\r\n return {\r\n updateConfig: updateConfig.updateConfig,\r\n isUpdatingConfig: updateConfig.isUpdating,\r\n bootstrap: bootstrap.bootstrap,\r\n isBootstrapping: bootstrap.isBootstrapping,\r\n installSemantic: installSemantic.installSemantic,\r\n isInstallingSemantic: installSemantic.isInstalling,\r\n uninstall: uninstall.uninstall,\r\n isUninstalling: uninstall.isUninstalling,\r\n downloadModel: download.downloadModel,\r\n downloadCustomModel: download.downloadCustomModel,\r\n isDownloading: download.isDownloading,\r\n deleteModel: deleteModel.deleteModel,\r\n deleteModelByPath: deleteModel.deleteModelByPath,\r\n isDeleting: deleteModel.isDeleting,\r\n updateEnv: updateEnv.updateEnv,\r\n isUpdatingEnv: updateEnv.isUpdating,\r\n selectGpu: gpu.selectGpu,\r\n resetGpu: gpu.resetGpu,\r\n isSelectingGpu: gpu.isSelecting || gpu.isResetting,\r\n updatePatterns: updatePatterns.updatePatterns,\r\n isUpdatingPatterns: updatePatterns.isUpdating,\r\n rebuildIndex: rebuildIndex.rebuildIndex,\r\n isRebuildingIndex: rebuildIndex.isRebuilding,\r\n updateIndex: updateIndex.updateIndex,\r\n isUpdatingIndex: updateIndex.isUpdating,\r\n cancelIndexing: cancelIndexing.cancelIndexing,\r\n isCancellingIndexing: cancelIndexing.isCancelling,\r\n isMutating:\r\n updateConfig.isUpdating ||\r\n bootstrap.isBootstrapping ||\r\n installSemantic.isInstalling ||\r\n uninstall.isUninstalling ||\r\n download.isDownloading ||\r\n deleteModel.isDeleting ||\r\n updateEnv.isUpdating ||\r\n gpu.isSelecting ||\r\n gpu.isResetting ||\r\n updatePatterns.isUpdating ||\r\n rebuildIndex.isRebuilding ||\r\n updateIndex.isUpdating ||\r\n cancelIndexing.isCancelling,\r\n };\r\n}\r\n\r\n// ========== Search Hooks ==========\r\n\r\nexport interface UseCodexLensSearchOptions {\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseCodexLensSearchReturn {\r\n data: CodexLensSearchResponse | undefined;\r\n results: CodexLensSearchResponse['results'] | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for content search using CodexLens\r\n */\r\nexport function useCodexLensSearch(params: CodexLensSearchParams, options: UseCodexLensSearchOptions = {}): UseCodexLensSearchReturn {\r\n const { enabled = false } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.search(params),\r\n queryFn: () => searchCodexLens(params),\r\n enabled,\r\n staleTime: STALE_TIME_SHORT,\r\n retry: 1,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n results: query.data?.results,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensFileSearchReturn {\r\n data: CodexLensFileSearchResponse | undefined;\r\n files: string[] | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for file search using CodexLens\r\n */\r\nexport function useCodexLensFilesSearch(params: CodexLensSearchParams, options: UseCodexLensSearchOptions = {}): UseCodexLensFileSearchReturn {\r\n const { enabled = false } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.filesSearch(params),\r\n queryFn: () => searchFilesCodexLens(params),\r\n enabled,\r\n staleTime: STALE_TIME_SHORT,\r\n retry: 1,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n files: query.data?.files,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensSymbolSearchOptions {\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseCodexLensSymbolSearchReturn {\r\n data: CodexLensSymbolSearchResponse | undefined;\r\n symbols: CodexLensSymbolSearchResponse['symbols'] | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for symbol search using CodexLens\r\n */\r\nexport function useCodexLensSymbolSearch(\r\n params: Pick<CodexLensSearchParams, 'query' | 'limit'>,\r\n options: UseCodexLensSymbolSearchOptions = {}\r\n): UseCodexLensSymbolSearchReturn {\r\n const { enabled = false } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.symbolSearch(params),\r\n queryFn: () => searchSymbolCodexLens(params),\r\n enabled,\r\n staleTime: STALE_TIME_SHORT,\r\n retry: 1,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n symbols: query.data?.symbols,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\n// ========== LSP / Semantic Search Hooks ==========\r\n\r\nexport interface UseCodexLensLspStatusOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensLspStatusReturn {\r\n data: CodexLensLspStatusResponse | undefined;\r\n available: boolean;\r\n semanticAvailable: boolean;\r\n vectorIndex: boolean;\r\n projectCount: number;\r\n embeddings: Record<string, unknown> | undefined;\r\n modes: string[];\r\n strategies: string[];\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for checking CodexLens LSP/semantic search availability\r\n * Polls every 5 seconds when the LSP server is available\r\n */\r\nexport function useCodexLensLspStatus(options: UseCodexLensLspStatusOptions = {}): UseCodexLensLspStatusReturn {\r\n const { enabled = true, staleTime = STALE_TIME_MEDIUM } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.lspStatus(),\r\n queryFn: fetchCodexLensLspStatus,\r\n staleTime,\r\n enabled,\r\n refetchInterval: (query) => {\r\n const data = query.state.data as CodexLensLspStatusResponse | undefined;\r\n return data?.available ? 5000 : false;\r\n },\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n available: query.data?.available ?? false,\r\n semanticAvailable: query.data?.semantic_available ?? false,\r\n vectorIndex: query.data?.vector_index ?? false,\r\n projectCount: query.data?.project_count ?? 0,\r\n embeddings: query.data?.embeddings,\r\n modes: query.data?.modes ?? [],\r\n strategies: query.data?.strategies ?? [],\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensLspMutationsReturn {\r\n startLsp: (path?: string) => Promise<{ success: boolean; message?: string; error?: string }>;\r\n stopLsp: (path?: string) => Promise<{ success: boolean; message?: string; error?: string }>;\r\n restartLsp: (path?: string) => Promise<{ success: boolean; message?: string; error?: string }>;\r\n isStarting: boolean;\r\n isStopping: boolean;\r\n isRestarting: boolean;\r\n}\r\n\r\n/**\r\n * Hook for LSP server start/stop/restart mutations\r\n */\r\nexport function useCodexLensLspMutations(): UseCodexLensLspMutationsReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, error: errorToast } = useNotifications();\r\n\r\n const startMutation = useMutation({\r\n mutationFn: ({ path }: { path?: string }) => startCodexLensLsp(path),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.lspStatus() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'codexlens.lsp.started' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensLspStart');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n const stopMutation = useMutation({\r\n mutationFn: ({ path }: { path?: string }) => stopCodexLensLsp(path),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.lspStatus() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'codexlens.lsp.stopped' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensLspStop');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n const restartMutation = useMutation({\r\n mutationFn: ({ path }: { path?: string }) => restartCodexLensLsp(path),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.lspStatus() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'codexlens.lsp.restarted' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensLspRestart');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n startLsp: (path?: string) => startMutation.mutateAsync({ path }),\r\n stopLsp: (path?: string) => stopMutation.mutateAsync({ path }),\r\n restartLsp: (path?: string) => restartMutation.mutateAsync({ path }),\r\n isStarting: startMutation.isPending,\r\n isStopping: stopMutation.isPending,\r\n isRestarting: restartMutation.isPending,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensSemanticSearchOptions {\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseCodexLensSemanticSearchReturn {\r\n data: CodexLensSemanticSearchResponse | undefined;\r\n results: CodexLensSemanticSearchResponse['results'] | undefined;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for semantic search using CodexLens Python API\r\n */\r\nexport function useCodexLensSemanticSearch(\r\n params: CodexLensSemanticSearchParams,\r\n options: UseCodexLensSemanticSearchOptions = {}\r\n): UseCodexLensSemanticSearchReturn {\r\n const { enabled = false } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.semanticSearch(params),\r\n queryFn: () => semanticSearchCodexLens(params),\r\n enabled,\r\n staleTime: STALE_TIME_SHORT,\r\n retry: 1,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n results: query.data?.results,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\n// ========== File Watcher Hooks ==========\r\n\r\nexport interface UseCodexLensWatcherOptions {\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseCodexLensWatcherReturn {\r\n data: CodexLensWatcherStatusResponse | undefined;\r\n running: boolean;\r\n rootPath: string;\r\n eventsProcessed: number;\r\n uptimeSeconds: number;\r\n isLoading: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for checking CodexLens file watcher status\r\n * Polls every 3 seconds when watcher is running\r\n */\r\nexport function useCodexLensWatcher(options: UseCodexLensWatcherOptions = {}): UseCodexLensWatcherReturn {\r\n const { enabled = true } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.watcher(),\r\n queryFn: fetchCodexLensWatcherStatus,\r\n staleTime: STALE_TIME_SHORT,\r\n enabled,\r\n refetchInterval: (query) => {\r\n const data = query.state.data as CodexLensWatcherStatusResponse | undefined;\r\n return data?.running ? 3000 : false;\r\n },\r\n retry: 2,\r\n });\r\n\r\n return {\r\n data: query.data,\r\n running: query.data?.running ?? false,\r\n rootPath: query.data?.root_path ?? '',\r\n eventsProcessed: query.data?.events_processed ?? 0,\r\n uptimeSeconds: query.data?.uptime_seconds ?? 0,\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n };\r\n}\r\n\r\nexport interface UseCodexLensWatcherMutationsReturn {\r\n startWatcher: (path?: string, debounceMs?: number) => Promise<{ success: boolean; message?: string; error?: string }>;\r\n stopWatcher: () => Promise<{ success: boolean; message?: string; error?: string }>;\r\n isStarting: boolean;\r\n isStopping: boolean;\r\n}\r\n\r\n/**\r\n * Hook for file watcher start/stop mutations\r\n */\r\nexport function useCodexLensWatcherMutations(): UseCodexLensWatcherMutationsReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, error: errorToast } = useNotifications();\r\n\r\n const startMutation = useMutation({\r\n mutationFn: ({ path, debounceMs }: { path?: string; debounceMs?: number }) =>\r\n startCodexLensWatcher(path, debounceMs),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.watcher() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'codexlens.watcher.started' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensWatcherStart');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n const stopMutation = useMutation({\r\n mutationFn: () => stopCodexLensWatcher(),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.watcher() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'codexlens.watcher.stopped' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'codexLensWatcherStop');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n startWatcher: (path?: string, debounceMs?: number) =>\r\n startMutation.mutateAsync({ path, debounceMs }),\r\n stopWatcher: () => stopMutation.mutateAsync(),\r\n isStarting: startMutation.isPending,\r\n isStopping: stopMutation.isPending,\r\n };\r\n}\r\n\r\n// ========== Reranker Config Hooks ==========\r\n\r\nexport interface UseCodexLensRerankerConfigOptions {\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport interface UseCodexLensRerankerConfigReturn {\r\n data: RerankerConfigResponse | undefined;\r\n backend: string;\r\n modelName: string;\r\n apiProvider: string;\r\n apiKeySet: boolean;\r\n availableBackends: string[];\r\n apiProviders: string[];\r\n litellmModels: RerankerConfigResponse['litellm_models'];\r\n configSource: string;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching reranker configuration (backends, models, providers)\r\n */\r\nexport function useCodexLensRerankerConfig(\r\n options: UseCodexLensRerankerConfigOptions = {}\r\n): UseCodexLensRerankerConfigReturn {\r\n const { enabled = true, staleTime = STALE_TIME_MEDIUM } = options;\r\n\r\n const query = useQuery({\r\n queryKey: codexLensKeys.rerankerConfig(),\r\n queryFn: fetchRerankerConfig,\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n return {\r\n data: query.data,\r\n backend: query.data?.backend ?? 'fastembed',\r\n modelName: query.data?.model_name ?? '',\r\n apiProvider: query.data?.api_provider ?? '',\r\n apiKeySet: query.data?.api_key_set ?? false,\r\n availableBackends: query.data?.available_backends ?? [],\r\n apiProviders: query.data?.api_providers ?? [],\r\n litellmModels: query.data?.litellm_models,\r\n configSource: query.data?.config_source ?? 'default',\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n refetch,\r\n };\r\n}\r\n\r\nexport interface UseUpdateRerankerConfigReturn {\r\n updateConfig: (request: RerankerConfigUpdateRequest) => Promise<RerankerConfigUpdateResponse>;\r\n isUpdating: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for updating reranker configuration\r\n */\r\nexport function useUpdateRerankerConfig(): UseUpdateRerankerConfigReturn {\r\n const queryClient = useQueryClient();\r\n const formatMessage = useFormatMessage();\r\n const { success, error: errorToast } = useNotifications();\r\n\r\n const mutation = useMutation({\r\n mutationFn: (request: RerankerConfigUpdateRequest) => updateRerankerConfig(request),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.rerankerConfig() });\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.env() });\r\n success(\r\n formatMessage({ id: 'common.success' }),\r\n formatMessage({ id: 'codexlens.reranker.saveSuccess' })\r\n );\r\n },\r\n onError: (err) => {\r\n const sanitized = sanitizeErrorMessage(err, 'rerankerConfigUpdate');\r\n const message = formatMessage({ id: sanitized.messageKey });\r\n const title = formatMessage({ id: 'common.error' });\r\n errorToast(title, message);\r\n },\r\n });\r\n\r\n return {\r\n updateConfig: mutation.mutateAsync,\r\n isUpdating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n// ========== CCW Tools Hook ==========\r\n\r\nexport interface UseCcwToolsListReturn {\r\n tools: CcwToolInfo[];\r\n isLoading: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for fetching all registered CCW tools\r\n * Uses LONG stale time since tool list rarely changes\r\n */\r\nexport function useCcwToolsList(): UseCcwToolsListReturn {\r\n const query = useQuery({\r\n queryKey: codexLensKeys.ccwTools(),\r\n queryFn: fetchCcwTools,\r\n staleTime: STALE_TIME_LONG,\r\n retry: 2,\r\n });\r\n\r\n return {\r\n tools: query.data ?? [],\r\n isLoading: query.isLoading,\r\n error: query.error,\r\n };\r\n}\r\n","// ========================================\r\n// CodexLens Index Operations Component\r\n// ========================================\r\n// Index management operations with progress tracking\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { useEffect, useState } from 'react';\r\nimport {\r\n RotateCw,\r\n Zap,\r\n AlertCircle,\r\n CheckCircle2,\r\n X,\r\n} from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Progress } from '@/components/ui/Progress';\r\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card';\r\nimport { cn } from '@/lib/utils';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\nimport {\r\n useCodexLensIndexingStatus,\r\n useRebuildIndex,\r\n useUpdateIndex,\r\n useCancelIndexing,\r\n} from '@/hooks';\r\nimport { useNotifications } from '@/hooks/useNotifications';\r\nimport { useWebSocket } from '@/hooks/useWebSocket';\r\n\r\ninterface IndexOperationsProps {\r\n disabled?: boolean;\r\n onRefresh?: () => void;\r\n}\r\n\r\ninterface IndexProgress {\r\n stage: string;\r\n message: string;\r\n percent: number;\r\n path?: string;\r\n}\r\n\r\ntype IndexOperation = {\r\n id: string;\r\n type: 'fts_full' | 'fts_incremental' | 'vector_full' | 'vector_incremental';\r\n label: string;\r\n description: string;\r\n icon: React.ReactNode;\r\n};\r\n\r\nexport function IndexOperations({ disabled = false, onRefresh }: IndexOperationsProps) {\r\n const { formatMessage } = useIntl();\r\n const { success, error: showError, wsLastMessage } = useNotifications();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const { inProgress } = useCodexLensIndexingStatus();\r\n const { rebuildIndex, isRebuilding } = useRebuildIndex();\r\n const { updateIndex, isUpdating } = useUpdateIndex();\r\n const { cancelIndexing, isCancelling } = useCancelIndexing();\r\n useWebSocket();\r\n\r\n const [indexProgress, setIndexProgress] = useState<IndexProgress | null>(null);\r\n const [activeOperation, setActiveOperation] = useState<string | null>(null);\r\n\r\n // Listen for WebSocket progress updates\r\n useEffect(() => {\r\n if (wsLastMessage?.type === 'CODEXLENS_INDEX_PROGRESS') {\r\n const progress = wsLastMessage.payload as IndexProgress;\r\n setIndexProgress(progress);\r\n\r\n // Clear active operation when complete or error\r\n if (progress.stage === 'complete' || progress.stage === 'error' || progress.stage === 'cancelled') {\r\n if (progress.stage === 'complete') {\r\n success(\r\n formatMessage({ id: 'codexlens.index.operationComplete' }),\r\n progress.message\r\n );\r\n onRefresh?.();\r\n } else if (progress.stage === 'error') {\r\n showError(\r\n formatMessage({ id: 'codexlens.index.operationFailed' }),\r\n progress.message\r\n );\r\n }\r\n setActiveOperation(null);\r\n setIndexProgress(null);\r\n }\r\n }\r\n }, [wsLastMessage, formatMessage, success, showError, onRefresh]);\r\n\r\n const isOperating = isRebuilding || isUpdating || inProgress || !!activeOperation;\r\n\r\n const handleOperation = async (operation: IndexOperation) => {\r\n if (!projectPath) {\r\n showError(\r\n formatMessage({ id: 'codexlens.index.noProject' }),\r\n formatMessage({ id: 'codexlens.index.noProjectDesc' })\r\n );\r\n return;\r\n }\r\n\r\n setActiveOperation(operation.id);\r\n setIndexProgress({ stage: 'start', message: formatMessage({ id: 'codexlens.index.starting' }), percent: 0 });\r\n\r\n try {\r\n // Determine index type and operation\r\n const isVector = operation.type.includes('vector');\r\n const isIncremental = operation.type.includes('incremental');\r\n\r\n if (isIncremental) {\r\n const result = await updateIndex(projectPath, {\r\n indexType: isVector ? 'vector' : 'normal',\r\n });\r\n if (!result.success) {\r\n throw new Error(result.error || 'Update failed');\r\n }\r\n } else {\r\n const result = await rebuildIndex(projectPath, {\r\n indexType: isVector ? 'vector' : 'normal',\r\n });\r\n if (!result.success) {\r\n throw new Error(result.error || 'Rebuild failed');\r\n }\r\n }\r\n } catch (err) {\r\n setActiveOperation(null);\r\n setIndexProgress(null);\r\n showError(\r\n formatMessage({ id: 'codexlens.index.operationFailed' }),\r\n err instanceof Error ? err.message : formatMessage({ id: 'codexlens.index.unknownError' })\r\n );\r\n }\r\n };\r\n\r\n const handleCancel = async () => {\r\n const result = await cancelIndexing();\r\n if (result.success) {\r\n setActiveOperation(null);\r\n setIndexProgress(null);\r\n } else {\r\n showError(\r\n formatMessage({ id: 'codexlens.index.cancelFailed' }),\r\n result.error || formatMessage({ id: 'codexlens.index.unknownError' })\r\n );\r\n }\r\n };\r\n\r\n const operations: IndexOperation[] = [\r\n {\r\n id: 'fts_full',\r\n type: 'fts_full',\r\n label: formatMessage({ id: 'codexlens.overview.actions.ftsFull' }),\r\n description: formatMessage({ id: 'codexlens.overview.actions.ftsFullDesc' }),\r\n icon: <RotateCw className=\"w-4 h-4\" />,\r\n },\r\n {\r\n id: 'fts_incremental',\r\n type: 'fts_incremental',\r\n label: formatMessage({ id: 'codexlens.overview.actions.ftsIncremental' }),\r\n description: formatMessage({ id: 'codexlens.overview.actions.ftsIncrementalDesc' }),\r\n icon: <Zap className=\"w-4 h-4\" />,\r\n },\r\n {\r\n id: 'vector_full',\r\n type: 'vector_full',\r\n label: formatMessage({ id: 'codexlens.overview.actions.vectorFull' }),\r\n description: formatMessage({ id: 'codexlens.overview.actions.vectorFullDesc' }),\r\n icon: <RotateCw className=\"w-4 h-4\" />,\r\n },\r\n {\r\n id: 'vector_incremental',\r\n type: 'vector_incremental',\r\n label: formatMessage({ id: 'codexlens.overview.actions.vectorIncremental' }),\r\n description: formatMessage({ id: 'codexlens.overview.actions.vectorIncrementalDesc' }),\r\n icon: <Zap className=\"w-4 h-4\" />,\r\n },\r\n ];\r\n\r\n if (indexProgress && activeOperation) {\r\n const operation = operations.find((op) => op.id === activeOperation);\r\n const isComplete = indexProgress.stage === 'complete';\r\n const isError = indexProgress.stage === 'error';\r\n const isCancelled = indexProgress.stage === 'cancelled';\r\n\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className=\"text-base flex items-center justify-between\">\r\n <span>{operation?.label}</span>\r\n {!isComplete && !isError && !isCancelled && (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={handleCancel}\r\n disabled={isCancelling}\r\n >\r\n <X className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n )}\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n {/* Status Icon */}\r\n <div className=\"flex items-center gap-3\">\r\n {isComplete ? (\r\n <CheckCircle2 className=\"w-6 h-6 text-success\" />\r\n ) : isError || isCancelled ? (\r\n <AlertCircle className=\"w-6 h-6 text-destructive\" />\r\n ) : (\r\n <RotateCw className=\"w-6 h-6 text-primary animate-spin\" />\r\n )}\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium text-foreground\">\r\n {isComplete\r\n ? formatMessage({ id: 'codexlens.index.complete' })\r\n : isError\r\n ? formatMessage({ id: 'codexlens.index.failed' })\r\n : isCancelled\r\n ? formatMessage({ id: 'codexlens.index.cancelled' })\r\n : formatMessage({ id: 'codexlens.index.inProgress' })}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground mt-1\">{indexProgress.message}</p>\r\n </div>\r\n </div>\r\n\r\n {/* Progress Bar */}\r\n {!isComplete && !isError && !isCancelled && (\r\n <div className=\"space-y-2\">\r\n <Progress value={indexProgress.percent} className=\"h-2\" />\r\n <p className=\"text-xs text-muted-foreground text-right\">\r\n {indexProgress.percent}%\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Close Button */}\r\n {(isComplete || isError || isCancelled) && (\r\n <div className=\"flex justify-end\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => {\r\n setActiveOperation(null);\r\n setIndexProgress(null);\r\n }}\r\n >\r\n {formatMessage({ id: 'common.actions.close' })}\r\n </Button>\r\n </div>\r\n )}\r\n </CardContent>\r\n </Card>\r\n );\r\n }\r\n\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className=\"text-base\">\r\n {formatMessage({ id: 'codexlens.overview.actions.title' })}\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-3\">\r\n {operations.map((operation) => (\r\n <Button\r\n key={operation.id}\r\n variant=\"outline\"\r\n className=\"h-auto p-4 flex flex-col items-start gap-2 text-left\"\r\n onClick={() => handleOperation(operation)}\r\n disabled={disabled || isOperating}\r\n >\r\n <div className=\"flex items-center gap-2 w-full\">\r\n <span className={cn('text-muted-foreground', (disabled || isOperating) && 'opacity-50')}>\r\n {operation.icon}\r\n </span>\r\n <span className=\"font-medium\">{operation.label}</span>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">{operation.description}</p>\r\n </Button>\r\n ))}\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\nexport default IndexOperations;\r\n","// ========================================\r\n// CodexLens File Watcher Card\r\n// ========================================\r\n// Displays file watcher status, stats, and toggle control\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Eye,\r\n EyeOff,\r\n Activity,\r\n Clock,\r\n FolderOpen,\r\n} from 'lucide-react';\r\nimport { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { cn } from '@/lib/utils';\r\nimport { useCodexLensWatcher, useCodexLensWatcherMutations } from '@/hooks';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\nfunction formatUptime(seconds: number): string {\r\n if (seconds < 60) return `${seconds}s`;\r\n if (seconds < 3600) {\r\n const m = Math.floor(seconds / 60);\r\n const s = seconds % 60;\r\n return `${m}m ${s}s`;\r\n }\r\n const h = Math.floor(seconds / 3600);\r\n const m = Math.floor((seconds % 3600) / 60);\r\n return `${h}h ${m}m`;\r\n}\r\n\r\ninterface FileWatcherCardProps {\r\n disabled?: boolean;\r\n}\r\n\r\nexport function FileWatcherCard({ disabled = false }: FileWatcherCardProps) {\r\n const { formatMessage } = useIntl();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const { running, rootPath, eventsProcessed, uptimeSeconds, isLoading } = useCodexLensWatcher();\r\n const { startWatcher, stopWatcher, isStarting, isStopping } = useCodexLensWatcherMutations();\r\n\r\n const isMutating = isStarting || isStopping;\r\n\r\n const handleToggle = async () => {\r\n if (running) {\r\n await stopWatcher();\r\n } else {\r\n await startWatcher(projectPath);\r\n }\r\n };\r\n\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className=\"text-base flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Activity className=\"w-4 h-4\" />\r\n <span>{formatMessage({ id: 'codexlens.watcher.title' })}</span>\r\n </div>\r\n <Badge variant={running ? 'success' : 'secondary'}>\r\n {running\r\n ? formatMessage({ id: 'codexlens.watcher.status.running' })\r\n : formatMessage({ id: 'codexlens.watcher.status.stopped' })\r\n }\r\n </Badge>\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n {/* Stats Grid */}\r\n <div className=\"grid grid-cols-2 gap-3\">\r\n <div className=\"flex items-center gap-2 text-sm\">\r\n <Activity className={cn('w-4 h-4', running ? 'text-success' : 'text-muted-foreground')} />\r\n <div>\r\n <p className=\"text-muted-foreground text-xs\">\r\n {formatMessage({ id: 'codexlens.watcher.eventsProcessed' })}\r\n </p>\r\n <p className=\"font-semibold text-foreground\">{eventsProcessed}</p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 text-sm\">\r\n <Clock className={cn('w-4 h-4', running ? 'text-info' : 'text-muted-foreground')} />\r\n <div>\r\n <p className=\"text-muted-foreground text-xs\">\r\n {formatMessage({ id: 'codexlens.watcher.uptime' })}\r\n </p>\r\n <p className=\"font-semibold text-foreground\">\r\n {running ? formatUptime(uptimeSeconds) : '--'}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Watched Path */}\r\n {running && rootPath && (\r\n <div className=\"flex items-center gap-2 text-sm\">\r\n <FolderOpen className=\"w-4 h-4 text-muted-foreground flex-shrink-0\" />\r\n <span className=\"text-muted-foreground truncate\" title={rootPath}>\r\n {rootPath}\r\n </span>\r\n </div>\r\n )}\r\n\r\n {/* Toggle Button */}\r\n <Button\r\n variant={running ? 'outline' : 'default'}\r\n size=\"sm\"\r\n className=\"w-full\"\r\n onClick={handleToggle}\r\n disabled={disabled || isMutating || isLoading}\r\n >\r\n {running ? (\r\n <>\r\n <EyeOff className=\"w-4 h-4 mr-2\" />\r\n {isStopping\r\n ? formatMessage({ id: 'codexlens.watcher.stopping' })\r\n : formatMessage({ id: 'codexlens.watcher.stop' })\r\n }\r\n </>\r\n ) : (\r\n <>\r\n <Eye className=\"w-4 h-4 mr-2\" />\r\n {isStarting\r\n ? formatMessage({ id: 'codexlens.watcher.starting' })\r\n : formatMessage({ id: 'codexlens.watcher.start' })\r\n }\r\n </>\r\n )}\r\n </Button>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\nexport default FileWatcherCard;\r\n","// ========================================\r\n// CodexLens LSP Server Card\r\n// ========================================\r\n// Displays LSP server status, stats, and start/stop/restart controls\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Server,\r\n Power,\r\n PowerOff,\r\n RotateCw,\r\n FolderOpen,\r\n Layers,\r\n Cpu,\r\n} from 'lucide-react';\r\nimport { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { cn } from '@/lib/utils';\r\nimport { useCodexLensLspStatus, useCodexLensLspMutations } from '@/hooks';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\ninterface LspServerCardProps {\r\n disabled?: boolean;\r\n}\r\n\r\nexport function LspServerCard({ disabled = false }: LspServerCardProps) {\r\n const { formatMessage } = useIntl();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const {\r\n available,\r\n semanticAvailable,\r\n projectCount,\r\n modes,\r\n isLoading,\r\n } = useCodexLensLspStatus();\r\n const { startLsp, stopLsp, restartLsp, isStarting, isStopping, isRestarting } = useCodexLensLspMutations();\r\n\r\n const isMutating = isStarting || isStopping || isRestarting;\r\n\r\n const handleToggle = async () => {\r\n if (available) {\r\n await stopLsp(projectPath);\r\n } else {\r\n await startLsp(projectPath);\r\n }\r\n };\r\n\r\n const handleRestart = async () => {\r\n await restartLsp(projectPath);\r\n };\r\n\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className=\"text-base flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Server className=\"w-4 h-4\" />\r\n <span>{formatMessage({ id: 'codexlens.lsp.title' })}</span>\r\n </div>\r\n <Badge variant={available ? 'success' : 'secondary'}>\r\n {available\r\n ? formatMessage({ id: 'codexlens.lsp.status.running' })\r\n : formatMessage({ id: 'codexlens.lsp.status.stopped' })\r\n }\r\n </Badge>\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n {/* Stats Grid */}\r\n <div className=\"grid grid-cols-3 gap-3\">\r\n <div className=\"flex items-center gap-2 text-sm\">\r\n <FolderOpen className={cn('w-4 h-4', available ? 'text-success' : 'text-muted-foreground')} />\r\n <div>\r\n <p className=\"text-muted-foreground text-xs\">\r\n {formatMessage({ id: 'codexlens.lsp.projects' })}\r\n </p>\r\n <p className=\"font-semibold text-foreground\">\r\n {available ? projectCount : '--'}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 text-sm\">\r\n <Cpu className={cn('w-4 h-4', semanticAvailable ? 'text-info' : 'text-muted-foreground')} />\r\n <div>\r\n <p className=\"text-muted-foreground text-xs\">\r\n {formatMessage({ id: 'codexlens.lsp.semanticAvailable' })}\r\n </p>\r\n <p className=\"font-semibold text-foreground\">\r\n {semanticAvailable\r\n ? formatMessage({ id: 'codexlens.lsp.available' })\r\n : formatMessage({ id: 'codexlens.lsp.unavailable' })\r\n }\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2 text-sm\">\r\n <Layers className={cn('w-4 h-4', available && modes.length > 0 ? 'text-accent' : 'text-muted-foreground')} />\r\n <div>\r\n <p className=\"text-muted-foreground text-xs\">\r\n {formatMessage({ id: 'codexlens.lsp.modes' })}\r\n </p>\r\n <p className=\"font-semibold text-foreground\">\r\n {available ? modes.length : '--'}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex gap-2\">\r\n <Button\r\n variant={available ? 'outline' : 'default'}\r\n size=\"sm\"\r\n className=\"flex-1\"\r\n onClick={handleToggle}\r\n disabled={disabled || isMutating || isLoading}\r\n >\r\n {available ? (\r\n <>\r\n <PowerOff className=\"w-4 h-4 mr-2\" />\r\n {isStopping\r\n ? formatMessage({ id: 'codexlens.lsp.stopping' })\r\n : formatMessage({ id: 'codexlens.lsp.stop' })\r\n }\r\n </>\r\n ) : (\r\n <>\r\n <Power className=\"w-4 h-4 mr-2\" />\r\n {isStarting\r\n ? formatMessage({ id: 'codexlens.lsp.starting' })\r\n : formatMessage({ id: 'codexlens.lsp.start' })\r\n }\r\n </>\r\n )}\r\n </Button>\r\n {available && (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleRestart}\r\n disabled={disabled || isMutating || isLoading}\r\n >\r\n <RotateCw className={cn('w-4 h-4 mr-2', isRestarting && 'animate-spin')} />\r\n {isRestarting\r\n ? formatMessage({ id: 'codexlens.lsp.restarting' })\r\n : formatMessage({ id: 'codexlens.lsp.restart' })\r\n }\r\n </Button>\r\n )}\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\nexport default LspServerCard;\r\n","// ========================================\r\n// CodexLens Overview Tab\r\n// ========================================\r\n// Overview status display and quick actions for CodexLens\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Database,\r\n FileText,\r\n CheckCircle2,\r\n XCircle,\r\n Zap,\r\n} from 'lucide-react';\r\nimport { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';\r\nimport { cn } from '@/lib/utils';\r\nimport type { CodexLensVenvStatus, CodexLensConfig } from '@/lib/api';\r\nimport { IndexOperations } from './IndexOperations';\r\nimport { FileWatcherCard } from './FileWatcherCard';\r\nimport { LspServerCard } from './LspServerCard';\r\n\r\ninterface OverviewTabProps {\r\n installed: boolean;\r\n status?: CodexLensVenvStatus;\r\n config?: CodexLensConfig;\r\n isLoading: boolean;\r\n onRefresh?: () => void;\r\n}\r\n\r\nexport function OverviewTab({ installed, status, config, isLoading, onRefresh }: OverviewTabProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n if (isLoading) {\r\n return (\r\n <div className=\"space-y-4\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\">\r\n {[1, 2, 3, 4].map((i) => (\r\n <Card key={i} className=\"p-4\">\r\n <div className=\"animate-pulse\">\r\n <div className=\"h-4 bg-muted rounded w-20 mb-2\" />\r\n <div className=\"h-8 bg-muted rounded w-16\" />\r\n </div>\r\n </Card>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!installed) {\r\n return (\r\n <Card className=\"p-8 text-center\">\r\n <Database className=\"w-12 h-12 mx-auto text-muted-foreground/50 mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-2\">\r\n {formatMessage({ id: 'codexlens.overview.notInstalled.title' })}\r\n </h3>\r\n <p className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.overview.notInstalled.message' })}\r\n </p>\r\n </Card>\r\n );\r\n }\r\n\r\n const isReady = status?.ready ?? false;\r\n const version = status?.version ?? 'Unknown';\r\n const indexDir = config?.index_dir ?? '~/.codexlens/indexes';\r\n const indexCount = config?.index_count ?? 0;\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Status Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\">\r\n {/* Installation Status */}\r\n <Card className=\"p-4\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className={cn(\r\n 'p-2 rounded-lg',\r\n isReady ? 'bg-success/10' : 'bg-warning/10'\r\n )}>\r\n {isReady ? (\r\n <CheckCircle2 className=\"w-5 h-5 text-success\" />\r\n ) : (\r\n <XCircle className=\"w-5 h-5 text-warning\" />\r\n )}\r\n </div>\r\n <div>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.overview.status.installation' })}\r\n </p>\r\n <p className=\"text-lg font-semibold text-foreground\">\r\n {isReady\r\n ? formatMessage({ id: 'codexlens.overview.status.ready' })\r\n : formatMessage({ id: 'codexlens.overview.status.notReady' })\r\n }\r\n </p>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Version */}\r\n <Card className=\"p-4\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-primary/10\">\r\n <Database className=\"w-5 h-5 text-primary\" />\r\n </div>\r\n <div>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.overview.status.version' })}\r\n </p>\r\n <p className=\"text-lg font-semibold text-foreground\">{version}</p>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Index Path */}\r\n <Card className=\"p-4\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-info/10\">\r\n <FileText className=\"w-5 h-5 text-info\" />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.overview.status.indexPath' })}\r\n </p>\r\n <p className=\"text-sm font-semibold text-foreground truncate\" title={indexDir}>\r\n {indexDir}\r\n </p>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Index Count */}\r\n <Card className=\"p-4\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"p-2 rounded-lg bg-accent/10\">\r\n <Zap className=\"w-5 h-5 text-accent\" />\r\n </div>\r\n <div>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.overview.status.indexCount' })}\r\n </p>\r\n <p className=\"text-lg font-semibold text-foreground\">{indexCount}</p>\r\n </div>\r\n </div>\r\n </Card>\r\n </div>\r\n\r\n {/* Service Management */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <FileWatcherCard disabled={!isReady} />\r\n <LspServerCard disabled={!isReady} />\r\n </div>\r\n\r\n {/* Index Operations */}\r\n <IndexOperations disabled={!isReady} onRefresh={onRefresh} />\r\n\r\n {/* Venv Details */}\r\n {status && (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className=\"text-base\">\r\n {formatMessage({ id: 'codexlens.overview.venv.title' })}\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent>\r\n <div className=\"space-y-2 text-sm\">\r\n <div className=\"flex justify-between\">\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.overview.venv.pythonVersion' })}\r\n </span>\r\n <span className=\"text-foreground font-mono\">{status.pythonVersion || 'Unknown'}</span>\r\n </div>\r\n <div className=\"flex justify-between\">\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.overview.venv.venvPath' })}\r\n </span>\r\n <span className=\"text-foreground font-mono truncate ml-4\" title={status.venvPath}>\r\n {status.venvPath || 'Unknown'}\r\n </span>\r\n </div>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n )}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// CodexLens Environment Variable Schema\r\n// ========================================\r\n// TypeScript port of ENV_VAR_GROUPS from codexlens-manager.js\r\n// Defines structured groups for CodexLens configuration\r\n\r\nimport type { EnvVarGroupsSchema } from '@/types/codexlens';\r\n\r\nexport const envVarGroupsSchema: EnvVarGroupsSchema = {\r\n embedding: {\r\n id: 'embedding',\r\n labelKey: 'codexlens.envGroup.embedding',\r\n icon: 'box',\r\n vars: {\r\n CODEXLENS_EMBEDDING_BACKEND: {\r\n key: 'CODEXLENS_EMBEDDING_BACKEND',\r\n labelKey: 'codexlens.envField.backend',\r\n type: 'select',\r\n options: ['local', 'api'],\r\n default: 'local',\r\n settingsPath: 'embedding.backend',\r\n },\r\n CODEXLENS_EMBEDDING_MODEL: {\r\n key: 'CODEXLENS_EMBEDDING_MODEL',\r\n labelKey: 'codexlens.envField.model',\r\n type: 'model-select',\r\n placeholder: 'Select or enter model...',\r\n default: 'fast',\r\n settingsPath: 'embedding.model',\r\n localModels: [\r\n {\r\n group: 'FastEmbed Profiles',\r\n items: ['fast', 'code', 'base', 'minilm', 'multilingual', 'balanced'],\r\n },\r\n ],\r\n apiModels: [\r\n {\r\n group: 'OpenAI',\r\n items: ['text-embedding-3-small', 'text-embedding-3-large', 'text-embedding-ada-002'],\r\n },\r\n {\r\n group: 'Cohere',\r\n items: ['embed-english-v3.0', 'embed-multilingual-v3.0', 'embed-english-light-v3.0'],\r\n },\r\n {\r\n group: 'Voyage',\r\n items: ['voyage-3', 'voyage-3-lite', 'voyage-code-3', 'voyage-multilingual-2'],\r\n },\r\n {\r\n group: 'SiliconFlow',\r\n items: ['BAAI/bge-m3', 'BAAI/bge-large-zh-v1.5', 'BAAI/bge-large-en-v1.5'],\r\n },\r\n {\r\n group: 'Jina',\r\n items: ['jina-embeddings-v3', 'jina-embeddings-v2-base-en', 'jina-embeddings-v2-base-zh'],\r\n },\r\n ],\r\n },\r\n CODEXLENS_USE_GPU: {\r\n key: 'CODEXLENS_USE_GPU',\r\n labelKey: 'codexlens.envField.useGpu',\r\n type: 'select',\r\n options: ['true', 'false'],\r\n default: 'true',\r\n settingsPath: 'embedding.use_gpu',\r\n showWhen: (env) => env['CODEXLENS_EMBEDDING_BACKEND'] === 'local',\r\n },\r\n CODEXLENS_EMBEDDING_POOL_ENABLED: {\r\n key: 'CODEXLENS_EMBEDDING_POOL_ENABLED',\r\n labelKey: 'codexlens.envField.highAvailability',\r\n type: 'select',\r\n options: ['true', 'false'],\r\n default: 'false',\r\n settingsPath: 'embedding.pool_enabled',\r\n showWhen: (env) => env['CODEXLENS_EMBEDDING_BACKEND'] === 'api',\r\n },\r\n CODEXLENS_EMBEDDING_STRATEGY: {\r\n key: 'CODEXLENS_EMBEDDING_STRATEGY',\r\n labelKey: 'codexlens.envField.loadBalanceStrategy',\r\n type: 'select',\r\n options: ['round_robin', 'latency_aware', 'weighted_random'],\r\n default: 'latency_aware',\r\n settingsPath: 'embedding.strategy',\r\n showWhen: (env) =>\r\n env['CODEXLENS_EMBEDDING_BACKEND'] === 'api' &&\r\n env['CODEXLENS_EMBEDDING_POOL_ENABLED'] === 'true',\r\n },\r\n CODEXLENS_EMBEDDING_COOLDOWN: {\r\n key: 'CODEXLENS_EMBEDDING_COOLDOWN',\r\n labelKey: 'codexlens.envField.rateLimitCooldown',\r\n type: 'number',\r\n placeholder: '60',\r\n default: '60',\r\n settingsPath: 'embedding.cooldown',\r\n min: 0,\r\n max: 300,\r\n showWhen: (env) =>\r\n env['CODEXLENS_EMBEDDING_BACKEND'] === 'api' &&\r\n env['CODEXLENS_EMBEDDING_POOL_ENABLED'] === 'true',\r\n },\r\n },\r\n },\r\n reranker: {\r\n id: 'reranker',\r\n labelKey: 'codexlens.envGroup.reranker',\r\n icon: 'arrow-up-down',\r\n vars: {\r\n CODEXLENS_RERANKER_ENABLED: {\r\n key: 'CODEXLENS_RERANKER_ENABLED',\r\n labelKey: 'codexlens.envField.enabled',\r\n type: 'select',\r\n options: ['true', 'false'],\r\n default: 'true',\r\n settingsPath: 'reranker.enabled',\r\n },\r\n CODEXLENS_RERANKER_BACKEND: {\r\n key: 'CODEXLENS_RERANKER_BACKEND',\r\n labelKey: 'codexlens.envField.backend',\r\n type: 'select',\r\n options: ['onnx', 'api', 'litellm', 'legacy'],\r\n default: 'onnx',\r\n settingsPath: 'reranker.backend',\r\n },\r\n CODEXLENS_RERANKER_MODEL: {\r\n key: 'CODEXLENS_RERANKER_MODEL',\r\n labelKey: 'codexlens.envField.model',\r\n type: 'model-select',\r\n placeholder: 'Select or enter model...',\r\n default: 'Xenova/ms-marco-MiniLM-L-6-v2',\r\n settingsPath: 'reranker.model',\r\n localModels: [\r\n {\r\n group: 'FastEmbed/ONNX',\r\n items: [\r\n 'Xenova/ms-marco-MiniLM-L-6-v2',\r\n 'cross-encoder/ms-marco-MiniLM-L-6-v2',\r\n 'BAAI/bge-reranker-base',\r\n ],\r\n },\r\n ],\r\n apiModels: [\r\n {\r\n group: 'Cohere',\r\n items: ['rerank-english-v3.0', 'rerank-multilingual-v3.0', 'rerank-english-v2.0'],\r\n },\r\n {\r\n group: 'Voyage',\r\n items: ['rerank-2', 'rerank-2-lite', 'rerank-1'],\r\n },\r\n {\r\n group: 'SiliconFlow',\r\n items: ['BAAI/bge-reranker-v2-m3', 'BAAI/bge-reranker-large', 'BAAI/bge-reranker-base'],\r\n },\r\n {\r\n group: 'Jina',\r\n items: ['jina-reranker-v2-base-multilingual', 'jina-reranker-v1-base-en'],\r\n },\r\n ],\r\n },\r\n CODEXLENS_RERANKER_TOP_K: {\r\n key: 'CODEXLENS_RERANKER_TOP_K',\r\n labelKey: 'codexlens.envField.topKResults',\r\n type: 'number',\r\n placeholder: '50',\r\n default: '50',\r\n settingsPath: 'reranker.top_k',\r\n min: 5,\r\n max: 200,\r\n },\r\n CODEXLENS_RERANKER_POOL_ENABLED: {\r\n key: 'CODEXLENS_RERANKER_POOL_ENABLED',\r\n labelKey: 'codexlens.envField.highAvailability',\r\n type: 'select',\r\n options: ['true', 'false'],\r\n default: 'false',\r\n settingsPath: 'reranker.pool_enabled',\r\n showWhen: (env) => env['CODEXLENS_RERANKER_BACKEND'] === 'api' || env['CODEXLENS_RERANKER_BACKEND'] === 'litellm',\r\n },\r\n CODEXLENS_RERANKER_STRATEGY: {\r\n key: 'CODEXLENS_RERANKER_STRATEGY',\r\n labelKey: 'codexlens.envField.loadBalanceStrategy',\r\n type: 'select',\r\n options: ['round_robin', 'latency_aware', 'weighted_random'],\r\n default: 'latency_aware',\r\n settingsPath: 'reranker.strategy',\r\n showWhen: (env) =>\r\n (env['CODEXLENS_RERANKER_BACKEND'] === 'api' || env['CODEXLENS_RERANKER_BACKEND'] === 'litellm') &&\r\n env['CODEXLENS_RERANKER_POOL_ENABLED'] === 'true',\r\n },\r\n CODEXLENS_RERANKER_COOLDOWN: {\r\n key: 'CODEXLENS_RERANKER_COOLDOWN',\r\n labelKey: 'codexlens.envField.rateLimitCooldown',\r\n type: 'number',\r\n placeholder: '60',\r\n default: '60',\r\n settingsPath: 'reranker.cooldown',\r\n min: 0,\r\n max: 300,\r\n showWhen: (env) =>\r\n (env['CODEXLENS_RERANKER_BACKEND'] === 'api' || env['CODEXLENS_RERANKER_BACKEND'] === 'litellm') &&\r\n env['CODEXLENS_RERANKER_POOL_ENABLED'] === 'true',\r\n },\r\n },\r\n },\r\n concurrency: {\r\n id: 'concurrency',\r\n labelKey: 'codexlens.envGroup.concurrency',\r\n icon: 'cpu',\r\n vars: {\r\n CODEXLENS_API_MAX_WORKERS: {\r\n key: 'CODEXLENS_API_MAX_WORKERS',\r\n labelKey: 'codexlens.envField.maxWorkers',\r\n type: 'number',\r\n placeholder: '4',\r\n default: '4',\r\n settingsPath: 'api.max_workers',\r\n min: 1,\r\n max: 32,\r\n },\r\n CODEXLENS_API_BATCH_SIZE: {\r\n key: 'CODEXLENS_API_BATCH_SIZE',\r\n labelKey: 'codexlens.envField.batchSize',\r\n type: 'number',\r\n placeholder: '8',\r\n default: '8',\r\n settingsPath: 'api.batch_size',\r\n min: 1,\r\n max: 64,\r\n showWhen: (env) => env['CODEXLENS_API_BATCH_SIZE_DYNAMIC'] !== 'true',\r\n },\r\n CODEXLENS_API_BATCH_SIZE_DYNAMIC: {\r\n key: 'CODEXLENS_API_BATCH_SIZE_DYNAMIC',\r\n labelKey: 'codexlens.envField.dynamicBatchSize',\r\n type: 'checkbox',\r\n default: 'false',\r\n settingsPath: 'api.batch_size_dynamic',\r\n },\r\n CODEXLENS_API_BATCH_SIZE_UTILIZATION: {\r\n key: 'CODEXLENS_API_BATCH_SIZE_UTILIZATION',\r\n labelKey: 'codexlens.envField.batchSizeUtilization',\r\n type: 'number',\r\n placeholder: '0.8',\r\n default: '0.8',\r\n settingsPath: 'api.batch_size_utilization_factor',\r\n min: 0.1,\r\n max: 0.95,\r\n step: 0.05,\r\n showWhen: (env) => env['CODEXLENS_API_BATCH_SIZE_DYNAMIC'] === 'true',\r\n },\r\n CODEXLENS_API_BATCH_SIZE_MAX: {\r\n key: 'CODEXLENS_API_BATCH_SIZE_MAX',\r\n labelKey: 'codexlens.envField.batchSizeMax',\r\n type: 'number',\r\n placeholder: '2048',\r\n default: '2048',\r\n settingsPath: 'api.batch_size_max',\r\n min: 1,\r\n max: 4096,\r\n showWhen: (env) => env['CODEXLENS_API_BATCH_SIZE_DYNAMIC'] === 'true',\r\n },\r\n CODEXLENS_CHARS_PER_TOKEN: {\r\n key: 'CODEXLENS_CHARS_PER_TOKEN',\r\n labelKey: 'codexlens.envField.charsPerToken',\r\n type: 'number',\r\n placeholder: '4',\r\n default: '4',\r\n settingsPath: 'api.chars_per_token_estimate',\r\n min: 1,\r\n max: 10,\r\n showWhen: (env) => env['CODEXLENS_API_BATCH_SIZE_DYNAMIC'] === 'true',\r\n },\r\n },\r\n },\r\n cascade: {\r\n id: 'cascade',\r\n labelKey: 'codexlens.envGroup.cascade',\r\n icon: 'git-branch',\r\n vars: {\r\n CODEXLENS_CASCADE_STRATEGY: {\r\n key: 'CODEXLENS_CASCADE_STRATEGY',\r\n labelKey: 'codexlens.envField.searchStrategy',\r\n type: 'select',\r\n options: ['binary', 'hybrid', 'binary_rerank', 'dense_rerank', 'staged'],\r\n default: 'dense_rerank',\r\n settingsPath: 'cascade.strategy',\r\n },\r\n CODEXLENS_CASCADE_COARSE_K: {\r\n key: 'CODEXLENS_CASCADE_COARSE_K',\r\n labelKey: 'codexlens.envField.coarseK',\r\n type: 'number',\r\n placeholder: '100',\r\n default: '100',\r\n settingsPath: 'cascade.coarse_k',\r\n min: 10,\r\n max: 500,\r\n },\r\n CODEXLENS_CASCADE_FINE_K: {\r\n key: 'CODEXLENS_CASCADE_FINE_K',\r\n labelKey: 'codexlens.envField.fineK',\r\n type: 'number',\r\n placeholder: '10',\r\n default: '10',\r\n settingsPath: 'cascade.fine_k',\r\n min: 1,\r\n max: 100,\r\n },\r\n CODEXLENS_STAGED_STAGE2_MODE: {\r\n key: 'CODEXLENS_STAGED_STAGE2_MODE',\r\n labelKey: 'codexlens.envField.stagedStage2Mode',\r\n type: 'select',\r\n options: ['precomputed', 'realtime', 'static_global_graph'],\r\n default: 'precomputed',\r\n settingsPath: 'staged.stage2_mode',\r\n showWhen: (env) => env['CODEXLENS_CASCADE_STRATEGY'] === 'staged',\r\n },\r\n CODEXLENS_STAGED_CLUSTERING_STRATEGY: {\r\n key: 'CODEXLENS_STAGED_CLUSTERING_STRATEGY',\r\n labelKey: 'codexlens.envField.stagedClusteringStrategy',\r\n type: 'select',\r\n options: ['auto', 'hdbscan', 'dbscan', 'frequency', 'noop', 'score', 'dir_rr', 'path'],\r\n default: 'auto',\r\n settingsPath: 'staged.clustering_strategy',\r\n showWhen: (env) => env['CODEXLENS_CASCADE_STRATEGY'] === 'staged',\r\n },\r\n CODEXLENS_STAGED_CLUSTERING_MIN_SIZE: {\r\n key: 'CODEXLENS_STAGED_CLUSTERING_MIN_SIZE',\r\n labelKey: 'codexlens.envField.stagedClusteringMinSize',\r\n type: 'number',\r\n placeholder: '3',\r\n default: '3',\r\n settingsPath: 'staged.clustering_min_size',\r\n min: 1,\r\n max: 50,\r\n showWhen: (env) => env['CODEXLENS_CASCADE_STRATEGY'] === 'staged',\r\n },\r\n CODEXLENS_ENABLE_STAGED_RERANK: {\r\n key: 'CODEXLENS_ENABLE_STAGED_RERANK',\r\n labelKey: 'codexlens.envField.enableStagedRerank',\r\n type: 'checkbox',\r\n default: 'true',\r\n settingsPath: 'staged.enable_rerank',\r\n showWhen: (env) => env['CODEXLENS_CASCADE_STRATEGY'] === 'staged',\r\n },\r\n },\r\n },\r\n indexing: {\r\n id: 'indexing',\r\n labelKey: 'codexlens.envGroup.indexing',\r\n icon: 'git-branch',\r\n vars: {\r\n CODEXLENS_USE_ASTGREP: {\r\n key: 'CODEXLENS_USE_ASTGREP',\r\n labelKey: 'codexlens.envField.useAstGrep',\r\n type: 'checkbox',\r\n default: 'false',\r\n settingsPath: 'parsing.use_astgrep',\r\n },\r\n CODEXLENS_STATIC_GRAPH_ENABLED: {\r\n key: 'CODEXLENS_STATIC_GRAPH_ENABLED',\r\n labelKey: 'codexlens.envField.staticGraphEnabled',\r\n type: 'checkbox',\r\n default: 'false',\r\n settingsPath: 'indexing.static_graph_enabled',\r\n },\r\n CODEXLENS_STATIC_GRAPH_RELATIONSHIP_TYPES: {\r\n key: 'CODEXLENS_STATIC_GRAPH_RELATIONSHIP_TYPES',\r\n labelKey: 'codexlens.envField.staticGraphRelationshipTypes',\r\n type: 'text',\r\n placeholder: 'imports,inherits,calls',\r\n default: 'imports,inherits',\r\n settingsPath: 'indexing.static_graph_relationship_types',\r\n showWhen: (env) => env['CODEXLENS_STATIC_GRAPH_ENABLED'] === 'true',\r\n },\r\n },\r\n },\r\n chunking: {\r\n id: 'chunking',\r\n labelKey: 'codexlens.envGroup.chunking',\r\n icon: 'scissors',\r\n vars: {\r\n CHUNK_STRIP_COMMENTS: {\r\n key: 'CHUNK_STRIP_COMMENTS',\r\n labelKey: 'codexlens.envField.stripComments',\r\n type: 'select',\r\n options: ['true', 'false'],\r\n default: 'true',\r\n settingsPath: 'chunking.strip_comments',\r\n },\r\n CHUNK_STRIP_DOCSTRINGS: {\r\n key: 'CHUNK_STRIP_DOCSTRINGS',\r\n labelKey: 'codexlens.envField.stripDocstrings',\r\n type: 'select',\r\n options: ['true', 'false'],\r\n default: 'true',\r\n settingsPath: 'chunking.strip_docstrings',\r\n },\r\n RERANKER_TEST_FILE_PENALTY: {\r\n key: 'RERANKER_TEST_FILE_PENALTY',\r\n labelKey: 'codexlens.envField.testFilePenalty',\r\n type: 'number',\r\n placeholder: '0.0',\r\n default: '0.0',\r\n settingsPath: 'reranker.test_file_penalty',\r\n min: 0,\r\n max: 1,\r\n step: 0.1,\r\n },\r\n RERANKER_DOCSTRING_WEIGHT: {\r\n key: 'RERANKER_DOCSTRING_WEIGHT',\r\n labelKey: 'codexlens.envField.docstringWeight',\r\n type: 'number',\r\n placeholder: '1.0',\r\n default: '1.0',\r\n settingsPath: 'reranker.docstring_weight',\r\n min: 0,\r\n max: 1,\r\n step: 0.1,\r\n },\r\n },\r\n },\r\n};\r\n\r\n/**\r\n * Get all env var keys from the schema\r\n */\r\nexport function getAllEnvVarKeys(): string[] {\r\n const keys: string[] = [];\r\n for (const group of Object.values(envVarGroupsSchema)) {\r\n for (const key of Object.keys(group.vars)) {\r\n keys.push(key);\r\n }\r\n }\r\n return keys;\r\n}\r\n\r\n/**\r\n * Evaluate showWhen condition for a field\r\n */\r\nexport function evaluateShowWhen(\r\n field: { showWhen?: (env: Record<string, string>) => boolean },\r\n values: Record<string, string>\r\n): boolean {\r\n if (!field.showWhen) return true;\r\n return field.showWhen(values);\r\n}\r\n\r\n/**\r\n * Get default values for all env vars in the schema\r\n */\r\nexport function getSchemaDefaults(): Record<string, string> {\r\n const defaults: Record<string, string> = {};\r\n for (const group of Object.values(envVarGroupsSchema)) {\r\n for (const [key, field] of Object.entries(group.vars)) {\r\n if (field.default !== undefined) {\r\n defaults[key] = field.default;\r\n }\r\n }\r\n }\r\n return defaults;\r\n}\r\n","// ========================================\r\n// ModelSelectField Component\r\n// ========================================\r\n// Combobox-style input for selecting models from local + API sources\r\n\r\nimport { useState, useRef, useEffect, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { ChevronDown } from 'lucide-react';\r\nimport { cn } from '@/lib/utils';\r\nimport type { EnvVarFieldSchema, ModelGroup } from '@/types/codexlens';\r\nimport type { CodexLensModel } from '@/lib/api';\r\n\r\ninterface ModelSelectFieldProps {\r\n field: EnvVarFieldSchema;\r\n value: string;\r\n onChange: (value: string) => void;\r\n /** Currently loaded local models (installed) */\r\n localModels?: CodexLensModel[];\r\n /** Backend type determines which model list to show */\r\n backendType: 'local' | 'api';\r\n disabled?: boolean;\r\n}\r\n\r\ninterface ModelOption {\r\n id: string;\r\n label: string;\r\n group: string;\r\n}\r\n\r\nexport function ModelSelectField({\r\n field,\r\n value,\r\n onChange,\r\n localModels = [],\r\n backendType,\r\n disabled = false,\r\n}: ModelSelectFieldProps) {\r\n const { formatMessage } = useIntl();\r\n const [open, setOpen] = useState(false);\r\n const [search, setSearch] = useState('');\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n\r\n // Close on outside click\r\n useEffect(() => {\r\n function handleClickOutside(e: MouseEvent) {\r\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\r\n setOpen(false);\r\n }\r\n }\r\n if (open) {\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => document.removeEventListener('mousedown', handleClickOutside);\r\n }\r\n }, [open]);\r\n\r\n // Build model options based on backend type\r\n const options = useMemo<ModelOption[]>(() => {\r\n const result: ModelOption[] = [];\r\n\r\n if (backendType === 'api') {\r\n // API mode: show preset API models from schema\r\n const apiGroups: ModelGroup[] = field.apiModels || [];\r\n for (const group of apiGroups) {\r\n for (const item of group.items) {\r\n result.push({ id: item, label: item, group: group.group });\r\n }\r\n }\r\n } else {\r\n // Local mode: show installed local models, then preset profiles as fallback\r\n if (localModels.length > 0) {\r\n for (const model of localModels) {\r\n const modelId = model.profile || model.name;\r\n const displayText =\r\n model.profile && model.name && model.profile !== model.name\r\n ? `${model.profile} (${model.name})`\r\n : model.name || model.profile;\r\n result.push({\r\n id: modelId,\r\n label: displayText,\r\n group: formatMessage({ id: 'codexlens.downloadedModels', defaultMessage: 'Downloaded Models' }),\r\n });\r\n }\r\n } else {\r\n // Fallback to preset local models from schema\r\n const localGroups: ModelGroup[] = field.localModels || [];\r\n for (const group of localGroups) {\r\n for (const item of group.items) {\r\n result.push({ id: item, label: item, group: group.group });\r\n }\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n }, [backendType, field.apiModels, field.localModels, localModels, formatMessage]);\r\n\r\n // Filter by search\r\n const filtered = useMemo(() => {\r\n if (!search) return options;\r\n const q = search.toLowerCase();\r\n return options.filter(\r\n (opt) => opt.id.toLowerCase().includes(q) || opt.label.toLowerCase().includes(q)\r\n );\r\n }, [options, search]);\r\n\r\n // Group filtered options\r\n const grouped = useMemo(() => {\r\n const groups: Record<string, ModelOption[]> = {};\r\n for (const opt of filtered) {\r\n if (!groups[opt.group]) groups[opt.group] = [];\r\n groups[opt.group].push(opt);\r\n }\r\n return groups;\r\n }, [filtered]);\r\n\r\n const handleSelect = (modelId: string) => {\r\n onChange(modelId);\r\n setOpen(false);\r\n setSearch('');\r\n };\r\n\r\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const val = e.target.value;\r\n setSearch(val);\r\n onChange(val);\r\n if (!open) setOpen(true);\r\n };\r\n\r\n return (\r\n <div ref={containerRef} className=\"relative flex-1\">\r\n <div className=\"relative\">\r\n <input\r\n ref={inputRef}\r\n type=\"text\"\r\n value={open ? search || value : value}\r\n onChange={handleInputChange}\r\n onFocus={() => {\r\n setOpen(true);\r\n setSearch('');\r\n }}\r\n placeholder={field.placeholder || 'Select model...'}\r\n disabled={disabled}\r\n className={cn(\r\n 'flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 pr-8 text-sm',\r\n 'ring-offset-background placeholder:text-muted-foreground',\r\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\r\n 'disabled:cursor-not-allowed disabled:opacity-50'\r\n )}\r\n />\r\n <ChevronDown\r\n className=\"absolute right-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none\"\r\n />\r\n </div>\r\n\r\n {open && !disabled && (\r\n <div className=\"absolute z-50 mt-1 w-full rounded-md border border-border bg-card shadow-md\">\r\n <div className=\"max-h-56 overflow-y-auto p-1\">\r\n {Object.keys(grouped).length === 0 ? (\r\n <div className=\"py-3 text-center text-xs text-muted-foreground\">\r\n {backendType === 'api'\r\n ? formatMessage({ id: 'codexlens.noConfiguredModels', defaultMessage: 'No models configured' })\r\n : formatMessage({ id: 'codexlens.noLocalModels', defaultMessage: 'No models downloaded' })}\r\n </div>\r\n ) : (\r\n Object.entries(grouped).map(([group, items]) => (\r\n <div key={group}>\r\n <div className=\"px-2 py-1 text-xs font-medium text-muted-foreground\">\r\n {group}\r\n </div>\r\n {items.map((item) => (\r\n <button\r\n key={item.id}\r\n type=\"button\"\r\n onClick={() => handleSelect(item.id)}\r\n className={cn(\r\n 'flex w-full items-center rounded-sm px-2 py-1.5 text-xs cursor-pointer',\r\n 'hover:bg-accent hover:text-accent-foreground',\r\n value === item.id && 'bg-accent/50'\r\n )}\r\n >\r\n {item.label}\r\n </button>\r\n ))}\r\n </div>\r\n ))\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default ModelSelectField;\r\n","// ========================================\r\n// SchemaFormRenderer Component\r\n// ========================================\r\n// Renders structured form groups from EnvVarGroupsSchema definition\r\n// Supports select, number, checkbox, text, and model-select field types\r\n\r\nimport { useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Box,\r\n ArrowUpDown,\r\n Cpu,\r\n GitBranch,\r\n Scissors,\r\n type LucideIcon,\r\n} from 'lucide-react';\r\nimport { Label } from '@/components/ui/Label';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Checkbox } from '@/components/ui/Checkbox';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport {\r\n Collapsible,\r\n CollapsibleContent,\r\n CollapsibleTrigger,\r\n} from '@/components/ui/Collapsible';\r\nimport { cn } from '@/lib/utils';\r\nimport { evaluateShowWhen } from './envVarSchema';\r\nimport { ModelSelectField } from './ModelSelectField';\r\nimport type { EnvVarGroupsSchema, EnvVarFieldSchema } from '@/types/codexlens';\r\nimport type { CodexLensModel } from '@/lib/api';\r\n\r\n// Icon mapping for group icons\r\nconst iconMap: Record<string, LucideIcon> = {\r\n box: Box,\r\n 'arrow-up-down': ArrowUpDown,\r\n cpu: Cpu,\r\n 'git-branch': GitBranch,\r\n scissors: Scissors,\r\n};\r\n\r\ninterface SchemaFormRendererProps {\r\n /** The schema defining all groups and fields */\r\n groups: EnvVarGroupsSchema;\r\n /** Current form values keyed by env var name */\r\n values: Record<string, string>;\r\n /** Called when a field value changes */\r\n onChange: (key: string, value: string) => void;\r\n /** Whether the form is disabled (loading state) */\r\n disabled?: boolean;\r\n /** Local embedding models (installed) for model-select */\r\n localEmbeddingModels?: CodexLensModel[];\r\n /** Local reranker models (installed) for model-select */\r\n localRerankerModels?: CodexLensModel[];\r\n}\r\n\r\nexport function SchemaFormRenderer({\r\n groups,\r\n values,\r\n onChange,\r\n disabled = false,\r\n localEmbeddingModels = [],\r\n localRerankerModels = [],\r\n}: SchemaFormRendererProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const groupEntries = useMemo(() => Object.entries(groups), [groups]);\r\n\r\n return (\r\n <div className=\"space-y-3\">\r\n {groupEntries.map(([groupKey, group]) => {\r\n const IconComponent = iconMap[group.icon] || Box;\r\n\r\n return (\r\n <Collapsible key={groupKey} defaultOpen>\r\n <div className=\"border border-border rounded-lg\">\r\n <CollapsibleTrigger className=\"flex w-full items-center gap-2 p-3 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors\">\r\n <IconComponent className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: group.labelKey, defaultMessage: groupKey })}\r\n </CollapsibleTrigger>\r\n <CollapsibleContent>\r\n <div className=\"px-3 pb-3 space-y-2\">\r\n {Object.entries(group.vars).map(([varKey, field]) => {\r\n const visible = evaluateShowWhen(field, values);\r\n if (!visible) return null;\r\n\r\n return (\r\n <FieldRenderer\r\n key={varKey}\r\n field={field}\r\n value={values[varKey] ?? field.default ?? ''}\r\n onChange={(val) => onChange(varKey, val)}\r\n allValues={values}\r\n disabled={disabled}\r\n localModels={\r\n varKey.includes('EMBEDDING')\r\n ? localEmbeddingModels\r\n : localRerankerModels\r\n }\r\n formatMessage={formatMessage}\r\n />\r\n );\r\n })}\r\n </div>\r\n </CollapsibleContent>\r\n </div>\r\n </Collapsible>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n\r\n// ========================================\r\n// Individual Field Renderer\r\n// ========================================\r\n\r\ninterface FieldRendererProps {\r\n field: EnvVarFieldSchema;\r\n value: string;\r\n onChange: (value: string) => void;\r\n allValues: Record<string, string>;\r\n disabled: boolean;\r\n localModels: CodexLensModel[];\r\n formatMessage: (descriptor: { id: string; defaultMessage?: string }) => string;\r\n}\r\n\r\nfunction FieldRenderer({\r\n field,\r\n value,\r\n onChange,\r\n allValues,\r\n disabled,\r\n localModels,\r\n formatMessage,\r\n}: FieldRendererProps) {\r\n const label = formatMessage({ id: field.labelKey, defaultMessage: field.key });\r\n\r\n switch (field.type) {\r\n case 'select':\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <Label\r\n className=\"text-xs text-muted-foreground w-28 flex-shrink-0\"\r\n title={field.key}\r\n >\r\n {label}\r\n </Label>\r\n <Select\r\n value={value}\r\n onValueChange={onChange}\r\n disabled={disabled}\r\n >\r\n <SelectTrigger className={cn('flex-1 h-8 text-xs')}>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {(field.options || []).map((opt) => (\r\n <SelectItem key={opt} value={opt} className=\"text-xs\">\r\n {opt}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n );\r\n\r\n case 'number':\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <Label\r\n className=\"text-xs text-muted-foreground w-28 flex-shrink-0\"\r\n title={field.key}\r\n >\r\n {label}\r\n </Label>\r\n <Input\r\n type=\"number\"\r\n className=\"flex-1 h-8 text-xs\"\r\n value={value}\r\n onChange={(e) => onChange(e.target.value)}\r\n placeholder={field.placeholder}\r\n min={field.min}\r\n max={field.max}\r\n step={field.step ?? 1}\r\n disabled={disabled}\r\n />\r\n </div>\r\n );\r\n\r\n case 'checkbox':\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <Label\r\n className=\"text-xs text-muted-foreground w-28 flex-shrink-0\"\r\n title={field.key}\r\n >\r\n {label}\r\n </Label>\r\n <div className=\"flex-1 flex items-center h-8\">\r\n <Checkbox\r\n checked={value === 'true'}\r\n onCheckedChange={(checked) => onChange(checked ? 'true' : 'false')}\r\n disabled={disabled}\r\n />\r\n </div>\r\n </div>\r\n );\r\n\r\n case 'model-select': {\r\n // Determine backend type from related backend env var\r\n const isEmbedding = field.key.includes('EMBEDDING');\r\n const backendKey = isEmbedding\r\n ? 'CODEXLENS_EMBEDDING_BACKEND'\r\n : 'CODEXLENS_RERANKER_BACKEND';\r\n const backendValue = allValues[backendKey];\r\n const backendType = (backendValue === 'api' || backendValue === 'litellm') ? 'api' : 'local';\r\n\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <Label\r\n className=\"text-xs text-muted-foreground w-28 flex-shrink-0\"\r\n title={field.key}\r\n >\r\n {label}\r\n </Label>\r\n <ModelSelectField\r\n field={field}\r\n value={value}\r\n onChange={onChange}\r\n localModels={localModels}\r\n backendType={backendType}\r\n disabled={disabled}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n case 'text':\r\n default:\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <Label\r\n className=\"text-xs text-muted-foreground w-28 flex-shrink-0\"\r\n title={field.key}\r\n >\r\n {label}\r\n </Label>\r\n <Input\r\n type=\"text\"\r\n className=\"flex-1 h-8 text-xs\"\r\n value={value}\r\n onChange={(e) => onChange(e.target.value)}\r\n placeholder={field.placeholder}\r\n disabled={disabled}\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n\r\nexport default SchemaFormRenderer;\r\n","// ========================================\r\n// CodexLens Settings Tab\r\n// ========================================\r\n// Structured form for CodexLens env configuration\r\n// Renders 5 groups: embedding, reranker, concurrency, cascade, chunking\r\n// Plus a general config section (index_dir)\r\n\r\nimport { useState, useEffect, useCallback, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Save, RefreshCw } from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Label } from '@/components/ui/Label';\r\nimport {\r\n useCodexLensConfig,\r\n useCodexLensEnv,\r\n useUpdateCodexLensEnv,\r\n useCodexLensModels,\r\n} from '@/hooks';\r\nimport { useNotifications } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\nimport { SchemaFormRenderer } from './SchemaFormRenderer';\r\nimport { envVarGroupsSchema, getSchemaDefaults } from './envVarSchema';\r\n\r\n// ========== Settings Tab ==========\r\n\r\ninterface SettingsTabProps {\r\n enabled?: boolean;\r\n}\r\n\r\nexport function SettingsTab({ enabled = true }: SettingsTabProps) {\r\n const { formatMessage } = useIntl();\r\n const { success, error: showError } = useNotifications();\r\n\r\n // Fetch current config (index_dir, workers, batch_size)\r\n const {\r\n config,\r\n indexCount,\r\n apiMaxWorkers,\r\n apiBatchSize,\r\n isLoading: isLoadingConfig,\r\n refetch: refetchConfig,\r\n } = useCodexLensConfig({ enabled });\r\n\r\n // Fetch env vars and settings\r\n const {\r\n env: serverEnv,\r\n settings: serverSettings,\r\n isLoading: isLoadingEnv,\r\n refetch: refetchEnv,\r\n } = useCodexLensEnv({ enabled });\r\n\r\n // Fetch local models for model-select fields\r\n const {\r\n embeddingModels: localEmbeddingModels,\r\n rerankerModels: localRerankerModels,\r\n } = useCodexLensModels({ enabled });\r\n\r\n const { updateEnv, isUpdating } = useUpdateCodexLensEnv();\r\n\r\n // General form state (index_dir)\r\n const [indexDir, setIndexDir] = useState('');\r\n const [indexDirError, setIndexDirError] = useState('');\r\n\r\n // Schema-driven env var form state\r\n const [envValues, setEnvValues] = useState<Record<string, string>>({});\r\n const [hasChanges, setHasChanges] = useState(false);\r\n\r\n // Store the initial values for change detection\r\n const [initialEnvValues, setInitialEnvValues] = useState<Record<string, string>>({});\r\n const [initialIndexDir, setInitialIndexDir] = useState('');\r\n\r\n // Initialize form from server data\r\n useEffect(() => {\r\n if (config) {\r\n setIndexDir(config.index_dir || '');\r\n setInitialIndexDir(config.index_dir || '');\r\n }\r\n }, [config]);\r\n\r\n useEffect(() => {\r\n if (serverEnv || serverSettings) {\r\n const defaults = getSchemaDefaults();\r\n const merged: Record<string, string> = { ...defaults };\r\n\r\n // Settings.json values override defaults\r\n if (serverSettings) {\r\n for (const [key, val] of Object.entries(serverSettings)) {\r\n if (val) merged[key] = val;\r\n }\r\n }\r\n\r\n // .env values override settings\r\n if (serverEnv) {\r\n for (const [key, val] of Object.entries(serverEnv)) {\r\n if (val) merged[key] = val;\r\n }\r\n }\r\n\r\n setEnvValues(merged);\r\n setInitialEnvValues(merged);\r\n setHasChanges(false);\r\n }\r\n }, [serverEnv, serverSettings]);\r\n\r\n // Check for changes\r\n const detectChanges = useCallback(\r\n (currentEnv: Record<string, string>, currentIndexDir: string) => {\r\n if (currentIndexDir !== initialIndexDir) return true;\r\n for (const key of Object.keys(currentEnv)) {\r\n if (currentEnv[key] !== initialEnvValues[key]) return true;\r\n }\r\n return false;\r\n },\r\n [initialEnvValues, initialIndexDir]\r\n );\r\n\r\n const handleEnvChange = useCallback(\r\n (key: string, value: string) => {\r\n setEnvValues((prev) => {\r\n const next = { ...prev, [key]: value };\r\n setHasChanges(detectChanges(next, indexDir));\r\n return next;\r\n });\r\n },\r\n [detectChanges, indexDir]\r\n );\r\n\r\n const handleIndexDirChange = useCallback(\r\n (value: string) => {\r\n setIndexDir(value);\r\n setIndexDirError('');\r\n setHasChanges(detectChanges(envValues, value));\r\n },\r\n [detectChanges, envValues]\r\n );\r\n\r\n // Installed local models filtered to installed-only\r\n const installedEmbeddingModels = useMemo(\r\n () => (localEmbeddingModels || []).filter((m) => m.installed),\r\n [localEmbeddingModels]\r\n );\r\n const installedRerankerModels = useMemo(\r\n () => (localRerankerModels || []).filter((m) => m.installed),\r\n [localRerankerModels]\r\n );\r\n\r\n const handleSave = async () => {\r\n // Validate index_dir\r\n if (!indexDir.trim()) {\r\n setIndexDirError(\r\n formatMessage({ id: 'codexlens.settings.validation.indexDirRequired' })\r\n );\r\n return;\r\n }\r\n\r\n try {\r\n const result = await updateEnv({ env: envValues });\r\n\r\n if (result.success) {\r\n success(\r\n formatMessage({ id: 'codexlens.settings.saveSuccess' }),\r\n result.message ||\r\n formatMessage({ id: 'codexlens.settings.configUpdated' })\r\n );\r\n refetchEnv();\r\n refetchConfig();\r\n setHasChanges(false);\r\n setInitialEnvValues(envValues);\r\n setInitialIndexDir(indexDir);\r\n } else {\r\n showError(\r\n formatMessage({ id: 'codexlens.settings.saveFailed' }),\r\n result.message ||\r\n formatMessage({ id: 'codexlens.settings.saveError' })\r\n );\r\n }\r\n } catch (err) {\r\n showError(\r\n formatMessage({ id: 'codexlens.settings.saveFailed' }),\r\n err instanceof Error\r\n ? err.message\r\n : formatMessage({ id: 'codexlens.settings.unknownError' })\r\n );\r\n }\r\n };\r\n\r\n const handleReset = () => {\r\n setEnvValues(initialEnvValues);\r\n setIndexDir(initialIndexDir);\r\n setIndexDirError('');\r\n setHasChanges(false);\r\n };\r\n\r\n const isLoading = isLoadingConfig || isLoadingEnv;\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Current Info Card */}\r\n <Card className=\"p-4 bg-muted/30\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4 text-sm\">\r\n <div>\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.settings.currentCount' })}\r\n </span>\r\n <p className=\"text-foreground font-medium\">{indexCount}</p>\r\n </div>\r\n <div>\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.settings.currentWorkers' })}\r\n </span>\r\n <p className=\"text-foreground font-medium\">{apiMaxWorkers}</p>\r\n </div>\r\n <div>\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.settings.currentBatchSize' })}\r\n </span>\r\n <p className=\"text-foreground font-medium\">{apiBatchSize}</p>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* General Configuration */}\r\n <Card className=\"p-6\">\r\n <h3 className=\"text-lg font-semibold text-foreground mb-4\">\r\n {formatMessage({ id: 'codexlens.settings.configTitle' })}\r\n </h3>\r\n\r\n {/* Index Directory */}\r\n <div className=\"space-y-2 mb-4\">\r\n <Label htmlFor=\"index_dir\">\r\n {formatMessage({ id: 'codexlens.settings.indexDir.label' })}\r\n </Label>\r\n <Input\r\n id=\"index_dir\"\r\n value={indexDir}\r\n onChange={(e) => handleIndexDirChange(e.target.value)}\r\n placeholder={formatMessage({\r\n id: 'codexlens.settings.indexDir.placeholder',\r\n })}\r\n error={!!indexDirError}\r\n disabled={isLoading}\r\n />\r\n {indexDirError && (\r\n <p className=\"text-sm text-destructive\">{indexDirError}</p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.settings.indexDir.hint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Schema-driven Env Var Groups */}\r\n <SchemaFormRenderer\r\n groups={envVarGroupsSchema}\r\n values={envValues}\r\n onChange={handleEnvChange}\r\n disabled={isLoading}\r\n localEmbeddingModels={installedEmbeddingModels}\r\n localRerankerModels={installedRerankerModels}\r\n />\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-2 mt-6\">\r\n <Button\r\n onClick={handleSave}\r\n disabled={isLoading || isUpdating || !hasChanges}\r\n >\r\n <Save\r\n className={cn('w-4 h-4 mr-2', isUpdating && 'animate-spin')}\r\n />\r\n {isUpdating\r\n ? formatMessage({ id: 'codexlens.settings.saving' })\r\n : formatMessage({ id: 'codexlens.settings.save' })}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleReset}\r\n disabled={isLoading || !hasChanges}\r\n >\r\n <RefreshCw className=\"w-4 h-4 mr-2\" />\r\n {formatMessage({ id: 'codexlens.settings.reset' })}\r\n </Button>\r\n </div>\r\n </Card>\r\n </div>\r\n );\r\n}\r\n\r\nexport default SettingsTab;\r\n","// ========================================\r\n// CCW Tools Card Component\r\n// ========================================\r\n// Displays all registered CCW tools, highlighting codex-lens related tools\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Wrench, AlertCircle, Loader2 } from 'lucide-react';\r\nimport { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { useCcwToolsList } from '@/hooks';\r\nimport type { CcwToolInfo } from '@/lib/api';\r\n\r\nconst CODEX_LENS_PREFIX = 'codex_lens';\r\n\r\nfunction isCodexLensTool(tool: CcwToolInfo): boolean {\r\n return tool.name.startsWith(CODEX_LENS_PREFIX);\r\n}\r\n\r\nexport function CcwToolsCard() {\r\n const { formatMessage } = useIntl();\r\n const { tools, isLoading, error } = useCcwToolsList();\r\n\r\n const codexLensTools = tools.filter(isCodexLensTool);\r\n const otherTools = tools.filter((t) => !isCodexLensTool(t));\r\n\r\n if (isLoading) {\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className=\"text-base flex items-center gap-2\">\r\n <Wrench className=\"w-4 h-4\" />\r\n <span>{formatMessage({ id: 'codexlens.mcp.title' })}</span>\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent>\r\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n <span>{formatMessage({ id: 'codexlens.mcp.loading' })}</span>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <Card className=\"border-destructive/20\">\r\n <CardHeader>\r\n <CardTitle className=\"text-base flex items-center gap-2\">\r\n <Wrench className=\"w-4 h-4\" />\r\n <span>{formatMessage({ id: 'codexlens.mcp.title' })}</span>\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent>\r\n <div className=\"flex items-start gap-2 text-sm\">\r\n <AlertCircle className=\"w-4 h-4 text-destructive flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <p className=\"font-medium text-destructive\">\r\n {formatMessage({ id: 'codexlens.mcp.error' })}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'codexlens.mcp.errorDesc' })}\r\n </p>\r\n </div>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n }\r\n\r\n if (tools.length === 0) {\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className=\"text-base flex items-center gap-2\">\r\n <Wrench className=\"w-4 h-4\" />\r\n <span>{formatMessage({ id: 'codexlens.mcp.title' })}</span>\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.mcp.emptyDesc' })}\r\n </p>\r\n </CardContent>\r\n </Card>\r\n );\r\n }\r\n\r\n return (\r\n <Card>\r\n <CardHeader>\r\n <CardTitle className=\"text-base flex items-center justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Wrench className=\"w-4 h-4\" />\r\n <span>{formatMessage({ id: 'codexlens.mcp.title' })}</span>\r\n </div>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {formatMessage({ id: 'codexlens.mcp.totalCount' }, { count: tools.length })}\r\n </Badge>\r\n </CardTitle>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n {/* CodexLens Tools Section */}\r\n {codexLensTools.length > 0 && (\r\n <div>\r\n <p className=\"text-xs font-medium text-muted-foreground uppercase mb-2\">\r\n {formatMessage({ id: 'codexlens.mcp.codexLensSection' })}\r\n </p>\r\n <div className=\"space-y-1.5\">\r\n {codexLensTools.map((tool) => (\r\n <ToolRow key={tool.name} tool={tool} variant=\"default\" />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Other Tools Section */}\r\n {otherTools.length > 0 && (\r\n <div>\r\n <p className=\"text-xs font-medium text-muted-foreground uppercase mb-2\">\r\n {formatMessage({ id: 'codexlens.mcp.otherSection' })}\r\n </p>\r\n <div className=\"space-y-1.5\">\r\n {otherTools.map((tool) => (\r\n <ToolRow key={tool.name} tool={tool} variant=\"secondary\" />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\ninterface ToolRowProps {\r\n tool: CcwToolInfo;\r\n variant: 'default' | 'secondary';\r\n}\r\n\r\nfunction ToolRow({ tool, variant }: ToolRowProps) {\r\n return (\r\n <div className=\"flex items-center gap-2 py-1 px-2 rounded-md hover:bg-muted/50 transition-colors\">\r\n <Badge variant={variant} className=\"text-xs font-mono shrink-0\">\r\n {tool.name}\r\n </Badge>\r\n <span className=\"text-xs text-muted-foreground truncate\" title={tool.description}>\r\n {tool.description}\r\n </span>\r\n </div>\r\n );\r\n}\r\n\r\nexport default CcwToolsCard;\r\n","// ========================================\r\n// CodexLens Advanced Tab\r\n// ========================================\r\n// Advanced settings including .env editor and ignore patterns\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Save, RefreshCw, AlertTriangle, FileCode, AlertCircle, Filter } from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Textarea } from '@/components/ui/Textarea';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Label } from '@/components/ui/Label';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n useCodexLensEnv,\r\n useCodexLensIgnorePatterns,\r\n useUpdateCodexLensEnv,\r\n useUpdateIgnorePatterns,\r\n} from '@/hooks';\r\nimport { useNotifications } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\nimport { CcwToolsCard } from './CcwToolsCard';\r\n\r\ninterface AdvancedTabProps {\r\n enabled?: boolean;\r\n}\r\n\r\ninterface FormErrors {\r\n env?: string;\r\n ignorePatterns?: string;\r\n extensionFilters?: string;\r\n}\r\n\r\nconst FILTER_ENTRY_PATTERN = /^[-\\w.*\\\\/]+$/;\r\n\r\nfunction parseListEntries(text: string): string[] {\r\n return text\r\n .split(/[\\n,]/)\r\n .map((entry) => entry.trim())\r\n .filter(Boolean);\r\n}\r\n\r\nfunction normalizeListEntries(entries: string[]): string {\r\n return entries\r\n .map((entry) => entry.trim())\r\n .filter(Boolean)\r\n .join('\\n');\r\n}\r\n\r\nfunction normalizeListText(text: string): string {\r\n return normalizeListEntries(parseListEntries(text));\r\n}\r\n\r\nexport function AdvancedTab({ enabled = true }: AdvancedTabProps) {\r\n const { formatMessage } = useIntl();\r\n const { success, error: showError } = useNotifications();\r\n\r\n const {\r\n raw,\r\n env,\r\n settings,\r\n isLoading: isLoadingEnv,\r\n error: envError,\r\n refetch,\r\n } = useCodexLensEnv({ enabled });\r\n\r\n const {\r\n patterns,\r\n extensionFilters,\r\n defaults,\r\n isLoading: isLoadingPatterns,\r\n error: patternsError,\r\n refetch: refetchPatterns,\r\n } = useCodexLensIgnorePatterns({ enabled });\r\n\r\n const { updateEnv, isUpdating } = useUpdateCodexLensEnv();\r\n const { updatePatterns, isUpdating: isUpdatingPatterns } = useUpdateIgnorePatterns();\r\n\r\n // Form state\r\n const [envInput, setEnvInput] = useState('');\r\n const [ignorePatternsInput, setIgnorePatternsInput] = useState('');\r\n const [extensionFiltersInput, setExtensionFiltersInput] = useState('');\r\n const [errors, setErrors] = useState<FormErrors>({});\r\n const [hasChanges, setHasChanges] = useState(false);\r\n const [hasFilterChanges, setHasFilterChanges] = useState(false);\r\n const [showWarning, setShowWarning] = useState(false);\r\n\r\n const currentIgnorePatterns = patterns ?? [];\r\n const currentExtensionFilters = extensionFilters ?? [];\r\n const defaultIgnorePatterns = defaults?.patterns ?? [];\r\n const defaultExtensionFilters = defaults?.extensionFilters ?? [];\r\n\r\n // Initialize form from env - handles both undefined (loading) and empty string (empty file)\r\n // The hook returns raw directly, so we check if it's been set (not undefined means data loaded)\r\n useEffect(() => {\r\n // Initialize when data is loaded (raw may be empty string but not undefined during loading)\r\n // Note: During initial load, raw is undefined. After load completes, raw is set (even if empty string)\r\n if (!isLoadingEnv) {\r\n setEnvInput(raw ?? ''); // Use empty string if raw is undefined/null\r\n setErrors({});\r\n setHasChanges(false);\r\n setShowWarning(false);\r\n }\r\n }, [raw, isLoadingEnv]);\r\n\r\n useEffect(() => {\r\n if (!isLoadingPatterns) {\r\n const nextIgnorePatterns = patterns ?? [];\r\n const nextExtensionFilters = extensionFilters ?? [];\r\n setIgnorePatternsInput(nextIgnorePatterns.join('\\n'));\r\n setExtensionFiltersInput(nextExtensionFilters.join('\\n'));\r\n setErrors((prev) => ({\r\n ...prev,\r\n ignorePatterns: undefined,\r\n extensionFilters: undefined,\r\n }));\r\n setHasFilterChanges(false);\r\n }\r\n }, [extensionFilters, isLoadingPatterns, patterns]);\r\n\r\n const updateFilterChangeState = (nextIgnorePatternsInput: string, nextExtensionFiltersInput: string) => {\r\n const normalizedCurrentIgnorePatterns = normalizeListEntries(currentIgnorePatterns);\r\n const normalizedCurrentExtensionFilters = normalizeListEntries(currentExtensionFilters);\r\n\r\n setHasFilterChanges(\r\n normalizeListText(nextIgnorePatternsInput) !== normalizedCurrentIgnorePatterns\r\n || normalizeListText(nextExtensionFiltersInput) !== normalizedCurrentExtensionFilters\r\n );\r\n };\r\n\r\n const handleEnvChange = (value: string) => {\r\n setEnvInput(value);\r\n // Check if there are changes - compare with raw value (handle undefined as empty)\r\n const currentRaw = raw ?? '';\r\n setHasChanges(value !== currentRaw);\r\n setShowWarning(value !== currentRaw);\r\n if (errors.env) {\r\n setErrors((prev) => ({ ...prev, env: undefined }));\r\n }\r\n };\r\n\r\n const handleIgnorePatternsChange = (value: string) => {\r\n setIgnorePatternsInput(value);\r\n updateFilterChangeState(value, extensionFiltersInput);\r\n if (errors.ignorePatterns) {\r\n setErrors((prev) => ({ ...prev, ignorePatterns: undefined }));\r\n }\r\n };\r\n\r\n const handleExtensionFiltersChange = (value: string) => {\r\n setExtensionFiltersInput(value);\r\n updateFilterChangeState(ignorePatternsInput, value);\r\n if (errors.extensionFilters) {\r\n setErrors((prev) => ({ ...prev, extensionFilters: undefined }));\r\n }\r\n };\r\n\r\n const parseEnvVariables = (text: string): Record<string, string> => {\r\n const envObj: Record<string, string> = {};\r\n const lines = text.split('\\n');\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (trimmed && !trimmed.startsWith('#') && trimmed.includes('=')) {\r\n const [key, ...valParts] = trimmed.split('=');\r\n const val = valParts.join('=');\r\n if (key) {\r\n envObj[key.trim()] = val.trim();\r\n }\r\n }\r\n }\r\n return envObj;\r\n };\r\n\r\n const validateForm = (): boolean => {\r\n const newErrors: FormErrors = {};\r\n const parsed = parseEnvVariables(envInput);\r\n\r\n // Check for invalid variable names\r\n const invalidKeys = Object.keys(parsed).filter(\r\n (key) => !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)\r\n );\r\n\r\n if (invalidKeys.length > 0) {\r\n newErrors.env = formatMessage(\r\n { id: 'codexlens.advanced.validation.invalidKeys' },\r\n { keys: invalidKeys.join(', ') }\r\n );\r\n }\r\n\r\n setErrors((prev) => ({ ...prev, env: newErrors.env }));\r\n return Object.keys(newErrors).length === 0;\r\n };\r\n\r\n const validateFilterForm = (): boolean => {\r\n const nextErrors: Pick<FormErrors, 'ignorePatterns' | 'extensionFilters'> = {};\r\n const parsedIgnorePatterns = parseListEntries(ignorePatternsInput);\r\n const parsedExtensionFilters = parseListEntries(extensionFiltersInput);\r\n\r\n const invalidIgnorePatterns = parsedIgnorePatterns.filter(\r\n (entry) => !FILTER_ENTRY_PATTERN.test(entry)\r\n );\r\n if (invalidIgnorePatterns.length > 0) {\r\n nextErrors.ignorePatterns = formatMessage(\r\n {\r\n id: 'codexlens.advanced.validation.invalidIgnorePatterns',\r\n defaultMessage: 'Invalid ignore patterns: {values}',\r\n },\r\n { values: invalidIgnorePatterns.join(', ') }\r\n );\r\n }\r\n\r\n const invalidExtensionFilters = parsedExtensionFilters.filter(\r\n (entry) => !FILTER_ENTRY_PATTERN.test(entry)\r\n );\r\n if (invalidExtensionFilters.length > 0) {\r\n nextErrors.extensionFilters = formatMessage(\r\n {\r\n id: 'codexlens.advanced.validation.invalidExtensionFilters',\r\n defaultMessage: 'Invalid file filters: {values}',\r\n },\r\n { values: invalidExtensionFilters.join(', ') }\r\n );\r\n }\r\n\r\n setErrors((prev) => ({\r\n ...prev,\r\n ignorePatterns: nextErrors.ignorePatterns,\r\n extensionFilters: nextErrors.extensionFilters,\r\n }));\r\n\r\n return Object.values(nextErrors).every((value) => !value);\r\n };\r\n\r\n const handleSave = async () => {\r\n if (!validateForm()) {\r\n return;\r\n }\r\n\r\n try {\r\n const parsed = parseEnvVariables(envInput);\r\n const result = await updateEnv({ env: parsed });\r\n\r\n if (result.success) {\r\n success(\r\n formatMessage({ id: 'codexlens.advanced.saveSuccess' }),\r\n result.message || formatMessage({ id: 'codexlens.advanced.envUpdated' })\r\n );\r\n refetch();\r\n setShowWarning(false);\r\n } else {\r\n showError(\r\n formatMessage({ id: 'codexlens.advanced.saveFailed' }),\r\n result.message || formatMessage({ id: 'codexlens.advanced.saveError' })\r\n );\r\n }\r\n } catch (err) {\r\n showError(\r\n formatMessage({ id: 'codexlens.advanced.saveFailed' }),\r\n err instanceof Error ? err.message : formatMessage({ id: 'codexlens.advanced.unknownError' })\r\n );\r\n }\r\n };\r\n\r\n const handleReset = () => {\r\n // Reset to current raw value (handle undefined as empty)\r\n setEnvInput(raw ?? '');\r\n setErrors((prev) => ({ ...prev, env: undefined }));\r\n setHasChanges(false);\r\n setShowWarning(false);\r\n };\r\n\r\n const handleSaveFilters = async () => {\r\n if (!validateFilterForm()) {\r\n return;\r\n }\r\n\r\n const parsedIgnorePatterns = parseListEntries(ignorePatternsInput);\r\n const parsedExtensionFilters = parseListEntries(extensionFiltersInput);\r\n\r\n try {\r\n const result = await updatePatterns({\r\n patterns: parsedIgnorePatterns,\r\n extensionFilters: parsedExtensionFilters,\r\n });\r\n\r\n if (result.success) {\r\n setIgnorePatternsInput((result.patterns ?? parsedIgnorePatterns).join('\\n'));\r\n setExtensionFiltersInput((result.extensionFilters ?? parsedExtensionFilters).join('\\n'));\r\n setHasFilterChanges(false);\r\n setErrors((prev) => ({\r\n ...prev,\r\n ignorePatterns: undefined,\r\n extensionFilters: undefined,\r\n }));\r\n await refetchPatterns();\r\n }\r\n } catch {\r\n // Hook-level mutation already reports the error.\r\n }\r\n };\r\n\r\n const handleResetFilters = () => {\r\n setIgnorePatternsInput(currentIgnorePatterns.join('\\n'));\r\n setExtensionFiltersInput(currentExtensionFilters.join('\\n'));\r\n setErrors((prev) => ({\r\n ...prev,\r\n ignorePatterns: undefined,\r\n extensionFilters: undefined,\r\n }));\r\n setHasFilterChanges(false);\r\n };\r\n\r\n const handleRestoreDefaultFilters = () => {\r\n const defaultIgnoreText = defaultIgnorePatterns.join('\\n');\r\n const defaultExtensionText = defaultExtensionFilters.join('\\n');\r\n\r\n setIgnorePatternsInput(defaultIgnoreText);\r\n setExtensionFiltersInput(defaultExtensionText);\r\n setErrors((prev) => ({\r\n ...prev,\r\n ignorePatterns: undefined,\r\n extensionFilters: undefined,\r\n }));\r\n updateFilterChangeState(defaultIgnoreText, defaultExtensionText);\r\n };\r\n\r\n const isLoading = isLoadingEnv;\r\n const isLoadingFilters = isLoadingPatterns;\r\n\r\n // Get current env variables as array for display\r\n const currentEnvVars = env\r\n ? Object.entries(env).map(([key, value]) => ({ key, value }))\r\n : [];\r\n\r\n // Get settings variables\r\n const settingsVars = settings\r\n ? Object.entries(settings).map(([key, value]) => ({ key, value }))\r\n : [];\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Error Card */}\r\n {envError && (\r\n <Card className=\"p-4 bg-destructive/10 border-destructive/20\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertCircle className=\"w-5 h-5 text-destructive flex-shrink-0 mt-0.5\" />\r\n <div className=\"flex-1\">\r\n <h4 className=\"text-sm font-medium text-destructive-foreground\">\r\n {formatMessage({ id: 'codexlens.advanced.loadError' })}\r\n </h4>\r\n <p className=\"text-xs text-destructive-foreground/80 mt-1\">\r\n {envError.message || formatMessage({ id: 'codexlens.advanced.loadErrorDesc' })}\r\n </p>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => refetch()}\r\n className=\"mt-2\"\r\n >\r\n <RefreshCw className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'common.actions.retry' })}\r\n </Button>\r\n </div>\r\n </div>\r\n </Card>\r\n )}\r\n\r\n {/* Sensitivity Warning Card */}\r\n {showWarning && (\r\n <Card className=\"p-4 bg-warning/10 border-warning/20\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-warning flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <h4 className=\"text-sm font-medium text-warning-foreground\">\r\n {formatMessage({ id: 'codexlens.advanced.warningTitle' })}\r\n </h4>\r\n <p className=\"text-xs text-warning-foreground/80 mt-1\">\r\n {formatMessage({ id: 'codexlens.advanced.warningMessage' })}\r\n </p>\r\n </div>\r\n </div>\r\n </Card>\r\n )}\r\n\r\n {/* Current Variables Summary */}\r\n {(currentEnvVars.length > 0 || settingsVars.length > 0) && (\r\n <Card className=\"p-4 bg-muted/30\">\r\n <h4 className=\"text-sm font-medium text-foreground mb-3\">\r\n {formatMessage({ id: 'codexlens.advanced.currentVars' })}\r\n </h4>\r\n <div className=\"space-y-3\">\r\n {settingsVars.length > 0 && (\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-2\">\r\n {formatMessage({ id: 'codexlens.advanced.settingsVars' })}\r\n </p>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {settingsVars.map(({ key }) => (\r\n <Badge key={key} variant=\"outline\" className=\"font-mono text-xs\">\r\n {key}\r\n </Badge>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n {currentEnvVars.length > 0 && (\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-2\">\r\n {formatMessage({ id: 'codexlens.advanced.customVars' })}\r\n </p>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {currentEnvVars.map(({ key }) => (\r\n <Badge key={key} variant=\"secondary\" className=\"font-mono text-xs\">\r\n {key}\r\n </Badge>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </Card>\r\n )}\r\n\r\n {/* CCW Tools Card */}\r\n <CcwToolsCard />\r\n\r\n {/* Index Filters */}\r\n <Card className=\"p-6\">\r\n <div className=\"flex flex-col gap-3 mb-4 lg:flex-row lg:items-center lg:justify-between\">\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-5 h-5 text-muted-foreground\" />\r\n <h3 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({\r\n id: 'codexlens.advanced.indexFilters',\r\n defaultMessage: 'Index Filters',\r\n })}\r\n </h3>\r\n </div>\r\n <div className=\"flex flex-wrap items-center gap-2\">\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {formatMessage(\r\n {\r\n id: 'codexlens.advanced.ignorePatternCount',\r\n defaultMessage: 'Directory filters: {count}',\r\n },\r\n { count: currentIgnorePatterns.length }\r\n )}\r\n </Badge>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {formatMessage(\r\n {\r\n id: 'codexlens.advanced.extensionFilterCount',\r\n defaultMessage: 'File filters: {count}',\r\n },\r\n { count: currentExtensionFilters.length }\r\n )}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n <div className=\"space-y-4\">\r\n {patternsError && (\r\n <div className=\"rounded-md border border-destructive/20 bg-destructive/5 p-3\">\r\n <div className=\"flex items-start gap-2\">\r\n <AlertCircle className=\"w-4 h-4 mt-0.5 text-destructive\" />\r\n <div>\r\n <p className=\"text-sm font-medium text-destructive\">\r\n {formatMessage({\r\n id: 'codexlens.advanced.filtersLoadError',\r\n defaultMessage: 'Unable to load current filter settings',\r\n })}\r\n </p>\r\n <p className=\"text-xs text-destructive/80 mt-1\">{patternsError.message}</p>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div className=\"grid gap-4 xl:grid-cols-2\">\r\n <div className=\"space-y-2\">\r\n <Label htmlFor=\"ignore-patterns-input\">\r\n {formatMessage({\r\n id: 'codexlens.advanced.ignorePatterns',\r\n defaultMessage: 'Ignored directories / paths',\r\n })}\r\n </Label>\r\n <Textarea\r\n id=\"ignore-patterns-input\"\r\n value={ignorePatternsInput}\r\n onChange={(event) => handleIgnorePatternsChange(event.target.value)}\r\n placeholder={formatMessage({\r\n id: 'codexlens.advanced.ignorePatternsPlaceholder',\r\n defaultMessage: 'dist\\nfrontend/dist\\ncoverage',\r\n })}\r\n className={cn(\r\n 'min-h-[220px] font-mono text-sm',\r\n errors.ignorePatterns && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n disabled={isLoadingFilters || isUpdatingPatterns}\r\n />\r\n {errors.ignorePatterns && (\r\n <p className=\"text-sm text-destructive\">{errors.ignorePatterns}</p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({\r\n id: 'codexlens.advanced.ignorePatternsHint',\r\n defaultMessage: 'One entry per line. Supports exact names, relative paths, and glob patterns.',\r\n })}\r\n </p>\r\n </div>\r\n\r\n <div className=\"space-y-2\">\r\n <Label htmlFor=\"extension-filters-input\">\r\n {formatMessage({\r\n id: 'codexlens.advanced.extensionFilters',\r\n defaultMessage: 'Skipped files / globs',\r\n })}\r\n </Label>\r\n <Textarea\r\n id=\"extension-filters-input\"\r\n value={extensionFiltersInput}\r\n onChange={(event) => handleExtensionFiltersChange(event.target.value)}\r\n placeholder={formatMessage({\r\n id: 'codexlens.advanced.extensionFiltersPlaceholder',\r\n defaultMessage: '*.min.js\\n*.map\\npackage-lock.json',\r\n })}\r\n className={cn(\r\n 'min-h-[220px] font-mono text-sm',\r\n errors.extensionFilters && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n disabled={isLoadingFilters || isUpdatingPatterns}\r\n />\r\n {errors.extensionFilters && (\r\n <p className=\"text-sm text-destructive\">{errors.extensionFilters}</p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({\r\n id: 'codexlens.advanced.extensionFiltersHint',\r\n defaultMessage: 'Use this for generated or low-value files that should stay out of the index.',\r\n })}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <div className=\"grid gap-3 rounded-md border border-border/60 bg-muted/30 p-3 md:grid-cols-2\">\r\n <div>\r\n <p className=\"text-xs font-medium text-foreground\">\r\n {formatMessage({\r\n id: 'codexlens.advanced.defaultIgnorePatterns',\r\n defaultMessage: 'Default directory filters',\r\n })}\r\n </p>\r\n <div className=\"mt-2 flex flex-wrap gap-2\">\r\n {defaultIgnorePatterns.slice(0, 6).map((pattern) => (\r\n <Badge key={pattern} variant=\"secondary\" className=\"font-mono text-xs\">\r\n {pattern}\r\n </Badge>\r\n ))}\r\n {defaultIgnorePatterns.length > 6 && (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n +{defaultIgnorePatterns.length - 6}\r\n </Badge>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <p className=\"text-xs font-medium text-foreground\">\r\n {formatMessage({\r\n id: 'codexlens.advanced.defaultExtensionFilters',\r\n defaultMessage: 'Default file filters',\r\n })}\r\n </p>\r\n <div className=\"mt-2 flex flex-wrap gap-2\">\r\n {defaultExtensionFilters.slice(0, 6).map((pattern) => (\r\n <Badge key={pattern} variant=\"secondary\" className=\"font-mono text-xs\">\r\n {pattern}\r\n </Badge>\r\n ))}\r\n {defaultExtensionFilters.length > 6 && (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n +{defaultExtensionFilters.length - 6}\r\n </Badge>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex flex-wrap items-center gap-2\">\r\n <Button\r\n onClick={handleSaveFilters}\r\n disabled={isLoadingFilters || isUpdatingPatterns || !hasFilterChanges}\r\n >\r\n <Save className={cn('w-4 h-4 mr-2', isUpdatingPatterns && 'animate-spin')} />\r\n {isUpdatingPatterns\r\n ? formatMessage({ id: 'codexlens.advanced.saving', defaultMessage: 'Saving...' })\r\n : formatMessage({\r\n id: 'codexlens.advanced.saveFilters',\r\n defaultMessage: 'Save filters',\r\n })\r\n }\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleResetFilters}\r\n disabled={isLoadingFilters || !hasFilterChanges}\r\n >\r\n <RefreshCw className=\"w-4 h-4 mr-2\" />\r\n {formatMessage({ id: 'codexlens.advanced.reset', defaultMessage: 'Reset' })}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleRestoreDefaultFilters}\r\n disabled={isLoadingFilters || isUpdatingPatterns}\r\n >\r\n {formatMessage({\r\n id: 'codexlens.advanced.restoreDefaults',\r\n defaultMessage: 'Restore defaults',\r\n })}\r\n </Button>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Environment Variables Editor */}\r\n <Card className=\"p-6\">\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <FileCode className=\"w-5 h-5 text-muted-foreground\" />\r\n <h3 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: 'codexlens.advanced.envEditor' })}\r\n </h3>\r\n </div>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {formatMessage({ id: 'codexlens.advanced.envFile' })}: .env\r\n </Badge>\r\n </div>\r\n\r\n <div className=\"space-y-4\">\r\n {/* Env Textarea */}\r\n <div className=\"space-y-2\">\r\n <Label htmlFor=\"env-input\">\r\n {formatMessage({ id: 'codexlens.advanced.envContent' })}\r\n </Label>\r\n <Textarea\r\n id=\"env-input\"\r\n value={envInput}\r\n onChange={(e) => handleEnvChange(e.target.value)}\r\n placeholder={formatMessage({ id: 'codexlens.advanced.envPlaceholder' })}\r\n className={cn(\r\n 'min-h-[300px] font-mono text-sm',\r\n errors.env && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n disabled={isLoading}\r\n />\r\n {errors.env && (\r\n <p className=\"text-sm text-destructive\">{errors.env}</p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.advanced.envHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n onClick={handleSave}\r\n disabled={isLoading || isUpdating || !hasChanges}\r\n >\r\n <Save className={cn('w-4 h-4 mr-2', isUpdating && 'animate-spin')} />\r\n {isUpdating\r\n ? formatMessage({ id: 'codexlens.advanced.saving' })\r\n : formatMessage({ id: 'codexlens.advanced.save' })\r\n }\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleReset}\r\n disabled={isLoading || !hasChanges}\r\n >\r\n <RefreshCw className=\"w-4 h-4 mr-2\" />\r\n {formatMessage({ id: 'codexlens.advanced.reset' })}\r\n </Button>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Help Card */}\r\n <Card className=\"p-4 bg-info/10 border-info/20\">\r\n <h4 className=\"text-sm font-medium text-info-foreground mb-2\">\r\n {formatMessage({ id: 'codexlens.advanced.helpTitle' })}\r\n </h4>\r\n <ul className=\"text-xs text-info-foreground/80 space-y-1\">\r\n <li>• {formatMessage({ id: 'codexlens.advanced.helpComment' })}</li>\r\n <li>• {formatMessage({ id: 'codexlens.advanced.helpFormat' })}</li>\r\n <li>• {formatMessage({ id: 'codexlens.advanced.helpQuotes' })}</li>\r\n <li>• {formatMessage({ id: 'codexlens.advanced.helpRestart' })}</li>\r\n </ul>\r\n </Card>\r\n </div>\r\n );\r\n}\r\n\r\nexport default AdvancedTab;\r\n","// ========================================\r\n// Model Card Component\r\n// ========================================\r\n// Individual model display card with actions\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Download,\r\n Trash2,\r\n Package,\r\n HardDrive,\r\n X,\r\n Loader2,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Progress } from '@/components/ui/Progress';\r\nimport { Input } from '@/components/ui/Input';\r\nimport type { CodexLensModel } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface ModelCardProps {\r\n model: CodexLensModel;\r\n isDownloading?: boolean;\r\n downloadProgress?: number;\r\n isDeleting?: boolean;\r\n onDownload: (profile: string) => void;\r\n onDelete: (profile: string) => void;\r\n onCancelDownload?: () => void;\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\nfunction getModelTypeVariant(type: 'embedding' | 'reranker'): 'default' | 'secondary' {\r\n return type === 'embedding' ? 'default' : 'secondary';\r\n}\r\n\r\nfunction formatSize(size?: string): string {\r\n if (!size) return '-';\r\n return size;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function ModelCard({\r\n model,\r\n isDownloading = false,\r\n downloadProgress = 0,\r\n isDeleting = false,\r\n onDownload,\r\n onDelete,\r\n onCancelDownload,\r\n}: ModelCardProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const handleDownload = () => {\r\n onDownload(model.profile);\r\n };\r\n\r\n const handleDelete = () => {\r\n if (confirm(formatMessage({ id: 'codexlens.models.deleteConfirm' }, { modelName: model.name }))) {\r\n onDelete(model.profile);\r\n }\r\n };\r\n\r\n return (\r\n <Card className={cn('overflow-hidden hover-glow', !model.installed && 'opacity-80')}>\r\n {/* Header */}\r\n <div className=\"p-4\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-center gap-3 flex-1 min-w-0\">\r\n <div className={cn(\r\n 'p-2 rounded-lg flex-shrink-0',\r\n model.installed ? 'bg-success/10' : 'bg-muted'\r\n )}>\r\n {model.installed ? (\r\n <HardDrive className=\"w-4 h-4 text-success\" />\r\n ) : (\r\n <Package className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {model.name}\r\n </span>\r\n <Badge\r\n variant={getModelTypeVariant(model.type)}\r\n className=\"text-xs flex-shrink-0\"\r\n >\r\n {model.type}\r\n </Badge>\r\n <Badge\r\n variant={model.installed ? 'success' : 'outline'}\r\n className=\"text-xs flex-shrink-0\"\r\n >\r\n {model.installed\r\n ? formatMessage({ id: 'codexlens.models.status.downloaded' })\r\n : formatMessage({ id: 'codexlens.models.status.available' })\r\n }\r\n </Badge>\r\n </div>\r\n <div className=\"flex items-center gap-3 mt-1 text-xs text-muted-foreground\">\r\n {model.dimensions && <span>{model.dimensions}d</span>}\r\n <span>{formatSize(model.size)}</span>\r\n {model.recommended && (\r\n <Badge variant=\"success\" className=\"text-[10px] px-1 py-0\">Rec</Badge>\r\n )}\r\n </div>\r\n {model.description && (\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {model.description}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-1 flex-shrink-0\">\r\n {isDownloading ? (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0 text-destructive hover:text-destructive hover:bg-destructive/10\"\r\n onClick={onCancelDownload}\r\n title={formatMessage({ id: 'codexlens.models.actions.cancel' })}\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </Button>\r\n ) : model.installed ? (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0 text-destructive hover:text-destructive hover:bg-destructive/10\"\r\n onClick={handleDelete}\r\n disabled={isDeleting}\r\n title={formatMessage({ id: 'codexlens.models.actions.delete' })}\r\n >\r\n {isDeleting ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Trash2 className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n ) : (\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 px-2\"\r\n onClick={handleDownload}\r\n title={formatMessage({ id: 'codexlens.models.actions.download' })}\r\n >\r\n <Download className=\"w-4 h-4 mr-1\" />\r\n <span className=\"text-xs\">{formatMessage({ id: 'codexlens.models.actions.download' })}</span>\r\n </Button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Download Progress */}\r\n {isDownloading && (\r\n <div className=\"mt-3 space-y-1\">\r\n <div className=\"flex items-center justify-between text-xs\">\r\n <span className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.models.downloading' })}\r\n </span>\r\n <span className=\"font-medium\">{downloadProgress}%</span>\r\n </div>\r\n <Progress value={downloadProgress} className=\"h-2\" />\r\n </div>\r\n )}\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Custom Model Input ==========\r\n\r\nexport interface CustomModelInputProps {\r\n isDownloading: boolean;\r\n onDownload: (modelName: string, modelType: 'embedding' | 'reranker') => void;\r\n}\r\n\r\nexport function CustomModelInput({ isDownloading, onDownload }: CustomModelInputProps) {\r\n const { formatMessage } = useIntl();\r\n const [modelName, setModelName] = useState('');\r\n const [modelType, setModelType] = useState<'embedding' | 'reranker'>('embedding');\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (modelName.trim()) {\r\n onDownload(modelName.trim(), modelType);\r\n setModelName('');\r\n }\r\n };\r\n\r\n return (\r\n <Card className=\"p-4 bg-primary/5 border-primary/20\">\r\n <h3 className=\"text-sm font-medium text-foreground mb-3 flex items-center gap-2\">\r\n <Package className=\"w-4 h-4 text-primary\" />\r\n {formatMessage({ id: 'codexlens.models.custom.title' })}\r\n </h3>\r\n <form onSubmit={handleSubmit} className=\"space-y-3\">\r\n <div className=\"flex gap-2\">\r\n <Input\r\n placeholder={formatMessage({ id: 'codexlens.models.custom.placeholder' })}\r\n value={modelName}\r\n onChange={(e) => setModelName(e.target.value)}\r\n disabled={isDownloading}\r\n className=\"flex-1\"\r\n />\r\n <select\r\n value={modelType}\r\n onChange={(e) => setModelType(e.target.value as 'embedding' | 'reranker')}\r\n disabled={isDownloading}\r\n className=\"px-3 py-2 text-sm rounded-md border border-input bg-background\"\r\n >\r\n <option value=\"embedding\">{formatMessage({ id: 'codexlens.models.types.embedding' })}</option>\r\n <option value=\"reranker\">{formatMessage({ id: 'codexlens.models.types.reranker' })}</option>\r\n </select>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.models.custom.description' })}\r\n </p>\r\n </form>\r\n </Card>\r\n );\r\n}\r\n\r\nexport default ModelCard;\r\n","// ========================================\r\n// Models Tab Component\r\n// ========================================\r\n// Model management tab with list, search, and download actions\r\n\r\nimport { useState, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Search,\r\n RefreshCw,\r\n Package,\r\n Filter,\r\n AlertCircle,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { ModelCard, CustomModelInput } from './ModelCard';\r\nimport { useCodexLensModels, useCodexLensMutations } from '@/hooks';\r\nimport type { CodexLensModel } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\ntype FilterType = 'all' | 'embedding' | 'reranker' | 'downloaded' | 'available';\r\n\r\n// ========== Helper Functions ==========\r\n\r\nfunction filterModels(models: CodexLensModel[], filter: FilterType, search: string): CodexLensModel[] {\r\n let filtered = models;\r\n\r\n // Apply type/status filter\r\n if (filter === 'embedding') {\r\n filtered = filtered.filter(m => m.type === 'embedding');\r\n } else if (filter === 'reranker') {\r\n filtered = filtered.filter(m => m.type === 'reranker');\r\n } else if (filter === 'downloaded') {\r\n filtered = filtered.filter(m => m.installed);\r\n } else if (filter === 'available') {\r\n filtered = filtered.filter(m => !m.installed);\r\n }\r\n\r\n // Apply search filter\r\n if (search.trim()) {\r\n const query = search.toLowerCase();\r\n filtered = filtered.filter(m =>\r\n m.name.toLowerCase().includes(query) ||\r\n m.profile.toLowerCase().includes(query) ||\r\n (m.description?.toLowerCase().includes(query) ?? false)\r\n );\r\n }\r\n\r\n return filtered;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport interface ModelsTabProps {\r\n installed?: boolean;\r\n}\r\n\r\nexport function ModelsTab({ installed = false }: ModelsTabProps) {\r\n const { formatMessage } = useIntl();\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [filterType, setFilterType] = useState<FilterType>('all');\r\n const [downloadingProfile, setDownloadingProfile] = useState<string | null>(null);\r\n const [downloadProgress, setDownloadProgress] = useState(0);\r\n\r\n const {\r\n models,\r\n isLoading,\r\n error,\r\n refetch,\r\n } = useCodexLensModels({\r\n enabled: installed,\r\n });\r\n\r\n const {\r\n downloadModel,\r\n downloadCustomModel,\r\n deleteModel,\r\n isDownloading,\r\n isDeleting,\r\n } = useCodexLensMutations();\r\n\r\n // Filter models based on search and filter\r\n const filteredModels = useMemo(() => {\r\n if (!models) return [];\r\n return filterModels(models, filterType, searchQuery);\r\n }, [models, filterType, searchQuery]);\r\n\r\n // Count models by type and status\r\n const stats = useMemo(() => {\r\n if (!models) return null;\r\n return {\r\n total: models.length,\r\n embedding: models.filter(m => m.type === 'embedding').length,\r\n reranker: models.filter(m => m.type === 'reranker').length,\r\n downloaded: models.filter(m => m.installed).length,\r\n available: models.filter(m => !m.installed).length,\r\n };\r\n }, [models]);\r\n\r\n // Handle model download\r\n const handleDownload = async (profile: string) => {\r\n setDownloadingProfile(profile);\r\n setDownloadProgress(0);\r\n\r\n // Simulate progress for demo (in real implementation, use WebSocket or polling)\r\n const progressInterval = setInterval(() => {\r\n setDownloadProgress(prev => {\r\n if (prev >= 95) {\r\n clearInterval(progressInterval);\r\n return 95;\r\n }\r\n return prev + 5;\r\n });\r\n }, 500);\r\n\r\n try {\r\n const result = await downloadModel(profile);\r\n if (result.success) {\r\n setDownloadProgress(100);\r\n setTimeout(() => {\r\n setDownloadingProfile(null);\r\n setDownloadProgress(0);\r\n refetch();\r\n }, 500);\r\n } else {\r\n setDownloadingProfile(null);\r\n setDownloadProgress(0);\r\n }\r\n } catch (error) {\r\n setDownloadingProfile(null);\r\n setDownloadProgress(0);\r\n } finally {\r\n clearInterval(progressInterval);\r\n }\r\n };\r\n\r\n // Handle custom model download\r\n const handleCustomDownload = async (modelName: string, modelType: 'embedding' | 'reranker') => {\r\n try {\r\n const result = await downloadCustomModel(modelName, modelType);\r\n if (result.success) {\r\n refetch();\r\n }\r\n } catch (error) {\r\n console.error('Failed to download custom model:', error);\r\n }\r\n };\r\n\r\n // Handle model delete\r\n const handleDelete = async (profile: string) => {\r\n const result = await deleteModel(profile);\r\n if (result.success) {\r\n refetch();\r\n }\r\n };\r\n\r\n // Filter buttons\r\n const filterButtons: Array<{ type: FilterType; label: string; count: number | undefined }> = [\r\n { type: 'all', label: formatMessage({ id: 'codexlens.models.filters.all' }), count: stats?.total },\r\n { type: 'embedding', label: formatMessage({ id: 'codexlens.models.types.embedding' }), count: stats?.embedding },\r\n { type: 'reranker', label: formatMessage({ id: 'codexlens.models.types.reranker' }), count: stats?.reranker },\r\n { type: 'downloaded', label: formatMessage({ id: 'codexlens.models.status.downloaded' }), count: stats?.downloaded },\r\n { type: 'available', label: formatMessage({ id: 'codexlens.models.status.available' }), count: stats?.available },\r\n ];\r\n\r\n if (!installed) {\r\n return (\r\n <Card className=\"p-12 text-center\">\r\n <Package className=\"w-16 h-16 mx-auto text-muted-foreground/30 mb-4\" />\r\n <h3 className=\"text-lg font-semibold text-foreground mb-2\">\r\n {formatMessage({ id: 'codexlens.models.notInstalled.title' })}\r\n </h3>\r\n <p className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.models.notInstalled.description' })}\r\n </p>\r\n </Card>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Header with Search and Actions */}\r\n <Card className=\"p-4\">\r\n <div className=\"flex flex-col sm:flex-row sm:items-center justify-between gap-4\">\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={formatMessage({ id: 'codexlens.models.searchPlaceholder' })}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n className=\"pl-9\"\r\n />\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => refetch()}\r\n disabled={isLoading}\r\n >\r\n <RefreshCw className={cn('w-4 h-4 mr-1', isLoading && 'animate-spin')} />\r\n {formatMessage({ id: 'common.actions.refresh' })}\r\n </Button>\r\n </div>\r\n </div>\r\n </Card>\r\n\r\n {/* Stats and Filters */}\r\n <Card className=\"p-4\">\r\n <div className=\"flex items-center gap-2 mb-3\">\r\n <Filter className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'codexlens.models.filters.label' })}\r\n </span>\r\n </div>\r\n <div className=\"flex flex-wrap gap-2\">\r\n {filterButtons.map(({ type, label, count }) => (\r\n <Button\r\n key={type}\r\n variant={filterType === type ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setFilterType(type)}\r\n className=\"relative\"\r\n >\r\n {label}\r\n {count !== undefined && (\r\n <Badge variant={filterType === type ? 'secondary' : 'default'} className=\"ml-2\">\r\n {count}\r\n </Badge>\r\n )}\r\n </Button>\r\n ))}\r\n </div>\r\n </Card>\r\n\r\n {/* Custom Model Input */}\r\n <CustomModelInput\r\n isDownloading={isDownloading}\r\n onDownload={handleCustomDownload}\r\n />\r\n\r\n {/* Model List */}\r\n {error ? (\r\n <Card className=\"p-8 text-center\">\r\n <AlertCircle className=\"w-12 h-12 mx-auto text-destructive/50 mb-3\" />\r\n <h3 className=\"text-sm font-medium text-destructive-foreground mb-1\">\r\n {formatMessage({ id: 'codexlens.models.error.title' })}\r\n </h3>\r\n <p className=\"text-xs text-muted-foreground mb-3\">\r\n {error.message || formatMessage({ id: 'codexlens.models.error.description' })}\r\n </p>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => refetch()}\r\n >\r\n <RefreshCw className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'common.actions.retry' })}\r\n </Button>\r\n </Card>\r\n ) : isLoading ? (\r\n <Card className=\"p-8 text-center\">\r\n <p className=\"text-muted-foreground\">{formatMessage({ id: 'common.actions.loading' })}</p>\r\n </Card>\r\n ) : filteredModels.length === 0 ? (\r\n <Card className=\"p-8 text-center\">\r\n <Package className=\"w-12 h-12 mx-auto text-muted-foreground/30 mb-3\" />\r\n <h3 className=\"text-sm font-medium text-foreground mb-1\">\r\n {models && models.length > 0\r\n ? formatMessage({ id: 'codexlens.models.empty.filtered' })\r\n : formatMessage({ id: 'codexlens.models.empty.title' })\r\n }\r\n </h3>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {models && models.length > 0\r\n ? formatMessage({ id: 'codexlens.models.empty.filteredDesc' })\r\n : formatMessage({ id: 'codexlens.models.empty.description' })\r\n }\r\n </p>\r\n </Card>\r\n ) : (\r\n <div className=\"space-y-3\">\r\n {filteredModels.map((model) => (\r\n <ModelCard\r\n key={model.profile}\r\n model={model}\r\n isDownloading={downloadingProfile === model.profile}\r\n downloadProgress={downloadProgress}\r\n isDeleting={isDeleting && downloadingProfile !== model.profile}\r\n onDownload={handleDownload}\r\n onDelete={handleDelete}\r\n onCancelDownload={() => {\r\n setDownloadingProfile(null);\r\n setDownloadProgress(0);\r\n }}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default ModelsTab;\r\n","// ========================================\r\n// CodexLens Search Tab\r\n// ========================================\r\n// Semantic code search interface with multiple search types\r\n// Includes LSP availability check and hybrid search mode switching\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Search, FileCode, Code, Sparkles, CheckCircle, AlertTriangle } from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Label } from '@/components/ui/Label';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport {\r\n useCodexLensSearch,\r\n useCodexLensFilesSearch,\r\n useCodexLensSymbolSearch,\r\n useCodexLensLspStatus,\n useCodexLensSemanticSearch,\n} from '@/hooks/useCodexLens';\nimport type {\n CodexLensSearchParams,\n CodexLensSemanticSearchMode,\n CodexLensFusionStrategy,\n CodexLensStagedStage2Mode,\n} from '@/lib/api';\nimport { cn } from '@/lib/utils';\n\r\ntype SearchType = 'search' | 'search_files' | 'symbol' | 'semantic';\r\ntype SearchMode = 'dense_rerank' | 'fts' | 'fuzzy';\r\n\r\ninterface SearchTabProps {\r\n enabled: boolean;\r\n}\r\n\r\nexport function SearchTab({ enabled }: SearchTabProps) {\r\n const { formatMessage } = useIntl();\r\n const [searchType, setSearchType] = useState<SearchType>('search');\r\n const [searchMode, setSearchMode] = useState<SearchMode>('dense_rerank');\n const [semanticMode, setSemanticMode] = useState<CodexLensSemanticSearchMode>('fusion');\n const [fusionStrategy, setFusionStrategy] = useState<CodexLensFusionStrategy>('rrf');\n const [stagedStage2Mode, setStagedStage2Mode] = useState<CodexLensStagedStage2Mode>('precomputed');\n const [query, setQuery] = useState('');\n const [hasSearched, setHasSearched] = useState(false);\n\r\n // LSP status check\r\n const lspStatus = useCodexLensLspStatus({ enabled });\r\n\r\n // Build search params based on search type\r\n const searchParams: CodexLensSearchParams = {\r\n query,\r\n limit: 20,\r\n mode: searchType !== 'symbol' && searchType !== 'semantic' ? searchMode : undefined,\r\n max_content_length: 200,\r\n extra_files_count: 10,\r\n };\r\n\r\n // Search hooks - only enable when hasSearched is true and query is not empty\r\n const contentSearch = useCodexLensSearch(\r\n searchParams,\r\n { enabled: enabled && hasSearched && searchType === 'search' && query.trim().length > 0 }\r\n );\r\n\r\n const fileSearch = useCodexLensFilesSearch(\r\n searchParams,\r\n { enabled: enabled && hasSearched && searchType === 'search_files' && query.trim().length > 0 }\r\n );\r\n\r\n const symbolSearch = useCodexLensSymbolSearch(\r\n { query, limit: 20 },\r\n { enabled: enabled && hasSearched && searchType === 'symbol' && query.trim().length > 0 }\r\n );\r\n\r\n const semanticSearch = useCodexLensSemanticSearch(\n {\n query,\n mode: semanticMode,\n fusion_strategy: semanticMode === 'fusion' ? fusionStrategy : undefined,\n staged_stage2_mode: semanticMode === 'fusion' && fusionStrategy === 'staged' ? stagedStage2Mode : undefined,\n limit: 20,\n include_match_reason: true,\n },\n { enabled: enabled && hasSearched && searchType === 'semantic' && query.trim().length > 0 }\n );\n\r\n // Get loading state based on search type\r\n const isLoading = searchType === 'search'\r\n ? contentSearch.isLoading\r\n : searchType === 'search_files'\r\n ? fileSearch.isLoading\r\n : searchType === 'symbol'\r\n ? symbolSearch.isLoading\r\n : semanticSearch.isLoading;\r\n\r\n const handleSearch = () => {\r\n if (query.trim()) {\r\n setHasSearched(true);\r\n }\r\n };\r\n\r\n const handleKeyPress = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter') {\r\n handleSearch();\r\n }\r\n };\r\n\r\n const handleSearchTypeChange = (value: SearchType) => {\r\n setSearchType(value);\r\n setHasSearched(false);\r\n };\r\n\r\n const handleSearchModeChange = (value: SearchMode) => {\r\n setSearchMode(value);\r\n setHasSearched(false);\r\n };\r\n\r\n const handleSemanticModeChange = (value: CodexLensSemanticSearchMode) => {\r\n setSemanticMode(value);\r\n setHasSearched(false);\r\n };\r\n\r\n const handleFusionStrategyChange = (value: CodexLensFusionStrategy) => {\n setFusionStrategy(value);\n setHasSearched(false);\n };\n\n const handleStagedStage2ModeChange = (value: CodexLensStagedStage2Mode) => {\n setStagedStage2Mode(value);\n setHasSearched(false);\n };\n\n const handleQueryChange = (value: string) => {\n setQuery(value);\n setHasSearched(false);\n };\n\r\n // Get result count for display\r\n const getResultCount = (): string => {\r\n if (searchType === 'symbol') {\r\n return symbolSearch.data?.success\r\n ? `${symbolSearch.data.symbols?.length ?? 0} ${formatMessage({ id: 'codexlens.search.resultsCount' })}`\r\n : '';\r\n }\r\n if (searchType === 'search') {\r\n return contentSearch.data?.success\r\n ? `${contentSearch.data.results?.length ?? 0} ${formatMessage({ id: 'codexlens.search.resultsCount' })}`\r\n : '';\r\n }\r\n if (searchType === 'search_files') {\r\n return fileSearch.data?.success\r\n ? `${fileSearch.data.files?.length ?? 0} ${formatMessage({ id: 'codexlens.search.resultsCount' })}`\r\n : '';\r\n }\r\n if (searchType === 'semantic') {\r\n return semanticSearch.data?.success\r\n ? `${semanticSearch.data.count ?? 0} ${formatMessage({ id: 'codexlens.search.resultsCount' })}`\r\n : '';\r\n }\r\n return '';\r\n };\r\n\r\n if (!enabled) {\r\n return (\r\n <div className=\"flex items-center justify-center p-12\">\r\n <div className=\"text-center\">\r\n <Search className=\"w-12 h-12 mx-auto text-muted-foreground/50 mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-2\">\r\n {formatMessage({ id: 'codexlens.search.notInstalled.title' })}\r\n </h3>\r\n <p className=\"text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.search.notInstalled.description' })}\r\n </p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* LSP Status Indicator */}\r\n <div className=\"flex items-center gap-2 text-sm\">\r\n <span className=\"text-muted-foreground\">{formatMessage({ id: 'codexlens.search.lspStatus' })}:</span>\r\n {lspStatus.isLoading ? (\r\n <span className=\"text-muted-foreground\">...</span>\r\n ) : lspStatus.available ? (\r\n <span className=\"flex items-center gap-1 text-green-600 dark:text-green-400\">\r\n <CheckCircle className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'codexlens.search.lspAvailable' })}\r\n </span>\r\n ) : !lspStatus.semanticAvailable ? (\r\n <span className=\"flex items-center gap-1 text-yellow-600 dark:text-yellow-400\">\r\n <AlertTriangle className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'codexlens.search.lspNoSemantic' })}\r\n </span>\r\n ) : (\r\n <span className=\"flex items-center gap-1 text-yellow-600 dark:text-yellow-400\">\r\n <AlertTriangle className=\"w-3.5 h-3.5\" />\r\n {formatMessage({ id: 'codexlens.search.lspNoVector' })}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Search Options */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {/* Search Type */}\r\n <div className=\"space-y-2\">\r\n <Label>{formatMessage({ id: 'codexlens.search.type' })}</Label>\r\n <Select value={searchType} onValueChange={handleSearchTypeChange}>\r\n <SelectTrigger>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"search\">\r\n <div className=\"flex items-center gap-2\">\r\n <Search className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'codexlens.search.content' })}\r\n </div>\r\n </SelectItem>\r\n <SelectItem value=\"search_files\">\r\n <div className=\"flex items-center gap-2\">\r\n <FileCode className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'codexlens.search.files' })}\r\n </div>\r\n </SelectItem>\r\n <SelectItem value=\"symbol\">\r\n <div className=\"flex items-center gap-2\">\r\n <Code className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'codexlens.search.symbol' })}\r\n </div>\r\n </SelectItem>\r\n <SelectItem value=\"semantic\" disabled={!lspStatus.available}>\r\n <div className=\"flex items-center gap-2\">\r\n <Sparkles className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'codexlens.search.semantic' })}\r\n </div>\r\n </SelectItem>\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Search Mode - for CLI search types (content / file) */}\r\n {(searchType === 'search' || searchType === 'search_files') && (\r\n <div className=\"space-y-2\">\r\n <Label>{formatMessage({ id: 'codexlens.search.mode' })}</Label>\r\n <Select value={searchMode} onValueChange={handleSearchModeChange}>\r\n <SelectTrigger>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"dense_rerank\">\r\n {formatMessage({ id: 'codexlens.search.mode.semantic' })}\r\n </SelectItem>\r\n <SelectItem value=\"fts\">\r\n {formatMessage({ id: 'codexlens.search.mode.exact' })}\r\n </SelectItem>\r\n <SelectItem value=\"fuzzy\">\r\n {formatMessage({ id: 'codexlens.search.mode.fuzzy' })}\r\n </SelectItem>\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n )}\r\n\r\n {/* Semantic Search Mode - for semantic search type */}\r\n {searchType === 'semantic' && (\r\n <div className=\"space-y-2\">\r\n <Label>{formatMessage({ id: 'codexlens.search.semanticMode' })}</Label>\r\n <Select value={semanticMode} onValueChange={handleSemanticModeChange}>\r\n <SelectTrigger>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"fusion\">\r\n {formatMessage({ id: 'codexlens.search.semanticMode.fusion' })}\r\n </SelectItem>\r\n <SelectItem value=\"vector\">\r\n {formatMessage({ id: 'codexlens.search.semanticMode.vector' })}\r\n </SelectItem>\r\n <SelectItem value=\"structural\">\r\n {formatMessage({ id: 'codexlens.search.semanticMode.structural' })}\r\n </SelectItem>\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Fusion Strategy - only when semantic + fusion mode */}\r\n {searchType === 'semantic' && semanticMode === 'fusion' && (\n <div className=\"space-y-2\">\n <Label>{formatMessage({ id: 'codexlens.search.fusionStrategy' })}</Label>\n <Select value={fusionStrategy} onValueChange={handleFusionStrategyChange}>\n <SelectTrigger>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"rrf\">\r\n {formatMessage({ id: 'codexlens.search.fusionStrategy.rrf' })}\r\n </SelectItem>\r\n <SelectItem value=\"dense_rerank\">\r\n {formatMessage({ id: 'codexlens.search.fusionStrategy.dense_rerank' })}\r\n </SelectItem>\r\n <SelectItem value=\"binary\">\r\n {formatMessage({ id: 'codexlens.search.fusionStrategy.binary' })}\r\n </SelectItem>\r\n <SelectItem value=\"hybrid\">\r\n {formatMessage({ id: 'codexlens.search.fusionStrategy.hybrid' })}\r\n </SelectItem>\r\n <SelectItem value=\"staged\">\r\n {formatMessage({ id: 'codexlens.search.fusionStrategy.staged' })}\r\n </SelectItem>\r\n </SelectContent>\r\n </Select>\n </div>\n )}\n\n {/* Staged Stage-2 Mode - only when semantic + fusion + staged */}\n {searchType === 'semantic' && semanticMode === 'fusion' && fusionStrategy === 'staged' && (\n <div className=\"space-y-2\">\n <Label>{formatMessage({ id: 'codexlens.search.stagedStage2Mode' })}</Label>\n <Select value={stagedStage2Mode} onValueChange={handleStagedStage2ModeChange}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"precomputed\">\n {formatMessage({ id: 'codexlens.search.stagedStage2Mode.precomputed' })}\n </SelectItem>\n <SelectItem value=\"realtime\">\n {formatMessage({ id: 'codexlens.search.stagedStage2Mode.realtime' })}\n </SelectItem>\n <SelectItem value=\"static_global_graph\">\n {formatMessage({ id: 'codexlens.search.stagedStage2Mode.static_global_graph' })}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n\n {/* Query Input */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"search-query\">{formatMessage({ id: 'codexlens.search.query' })}</Label>\n <Input\n id=\"search-query\"\r\n placeholder={formatMessage({ id: 'codexlens.search.queryPlaceholder' })}\r\n value={query}\r\n onChange={(e) => handleQueryChange(e.target.value)}\r\n onKeyPress={handleKeyPress}\r\n disabled={isLoading}\r\n />\r\n </div>\r\n\r\n {/* Search Button */}\r\n <Button\r\n onClick={handleSearch}\r\n disabled={!query.trim() || isLoading}\r\n className=\"w-full\"\r\n >\r\n <Search className={cn('w-4 h-4 mr-2', isLoading && 'animate-spin')} />\r\n {isLoading\r\n ? formatMessage({ id: 'codexlens.search.searching' })\r\n : formatMessage({ id: 'codexlens.search.button' })\r\n }\r\n </Button>\r\n\r\n {/* Results */}\r\n {hasSearched && !isLoading && (\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-sm font-medium\">\r\n {formatMessage({ id: 'codexlens.search.results' })}\r\n </h3>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {getResultCount()}\r\n </span>\r\n </div>\r\n\r\n {searchType === 'symbol' && symbolSearch.data && (\r\n symbolSearch.data.success ? (\r\n <div className=\"rounded-lg border bg-muted/50 p-4\">\r\n <pre className=\"text-xs overflow-auto max-h-96\">\r\n {JSON.stringify(symbolSearch.data.symbols, null, 2)}\r\n </pre>\r\n </div>\r\n ) : (\r\n <div className=\"text-sm text-destructive\">\r\n {symbolSearch.data.error || formatMessage({ id: 'common.error' })}\r\n </div>\r\n )\r\n )}\r\n\r\n {searchType === 'search' && contentSearch.data && (\r\n contentSearch.data.success ? (\r\n <div className=\"rounded-lg border bg-muted/50 p-4\">\r\n <pre className=\"text-xs overflow-auto max-h-96\">\r\n {JSON.stringify(contentSearch.data.results, null, 2)}\r\n </pre>\r\n </div>\r\n ) : (\r\n <div className=\"text-sm text-destructive\">\r\n {contentSearch.data.error || formatMessage({ id: 'common.error' })}\r\n </div>\r\n )\r\n )}\r\n\r\n {searchType === 'search_files' && fileSearch.data && (\r\n fileSearch.data.success ? (\r\n <div className=\"rounded-lg border bg-muted/50 p-4\">\r\n <pre className=\"text-xs overflow-auto max-h-96\">\r\n {JSON.stringify(fileSearch.data.files, null, 2)}\r\n </pre>\r\n </div>\r\n ) : (\r\n <div className=\"text-sm text-destructive\">\r\n {fileSearch.data.error || formatMessage({ id: 'common.error' })}\r\n </div>\r\n )\r\n )}\r\n\r\n {searchType === 'semantic' && semanticSearch.data && (\r\n semanticSearch.data.success ? (\r\n <div className=\"rounded-lg border bg-muted/50 p-4\">\r\n <pre className=\"text-xs overflow-auto max-h-96\">\r\n {JSON.stringify(semanticSearch.data.results, null, 2)}\r\n </pre>\r\n </div>\r\n ) : (\r\n <div className=\"text-sm text-destructive\">\r\n {semanticSearch.data.error || formatMessage({ id: 'common.error' })}\r\n </div>\r\n )\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default SearchTab;\r\n","// ========================================\r\n// CodexLens Semantic Install Dialog\r\n// ========================================\r\n// Dialog for installing semantic search dependencies with GPU mode selection\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Cpu,\r\n Zap,\r\n Monitor,\r\n CheckCircle2,\r\n AlertCircle,\r\n} from 'lucide-react';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogDescription,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/ui/Dialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/RadioGroup';\r\nimport { Label } from '@/components/ui/Label';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { useNotifications } from '@/hooks/useNotifications';\r\nimport { useCodexLensMutations } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\n\r\ntype GpuMode = 'cpu' | 'cuda' | 'directml';\r\n\r\ninterface GpuModeOption {\r\n value: GpuMode;\r\n label: string;\r\n description: string;\r\n icon: React.ReactNode;\r\n recommended?: boolean;\r\n}\r\n\r\ninterface SemanticInstallDialogProps {\r\n open: boolean;\r\n onOpenChange: (open: boolean) => void;\r\n onSuccess?: () => void;\r\n}\r\n\r\nexport function SemanticInstallDialog({ open, onOpenChange, onSuccess }: SemanticInstallDialogProps) {\r\n const { formatMessage } = useIntl();\r\n const { success, error: showError } = useNotifications();\r\n const { installSemantic, isInstallingSemantic } = useCodexLensMutations();\r\n\r\n const [selectedMode, setSelectedMode] = useState<GpuMode>('cpu');\r\n\r\n const gpuModes: GpuModeOption[] = [\r\n {\r\n value: 'cpu',\r\n label: formatMessage({ id: 'codexlens.semantic.gpu.cpu' }),\r\n description: formatMessage({ id: 'codexlens.semantic.gpu.cpuDesc' }),\r\n icon: <Cpu className=\"w-5 h-5\" />,\r\n },\r\n {\r\n value: 'directml',\r\n label: formatMessage({ id: 'codexlens.semantic.gpu.directml' }),\r\n description: formatMessage({ id: 'codexlens.semantic.gpu.directmlDesc' }),\r\n icon: <Monitor className=\"w-5 h-5\" />,\r\n recommended: true,\r\n },\r\n {\r\n value: 'cuda',\r\n label: formatMessage({ id: 'codexlens.semantic.gpu.cuda' }),\r\n description: formatMessage({ id: 'codexlens.semantic.gpu.cudaDesc' }),\r\n icon: <Zap className=\"w-5 h-5\" />,\r\n },\r\n ];\r\n\r\n const handleInstall = async () => {\r\n try {\r\n const result = await installSemantic(selectedMode);\r\n if (result.success) {\r\n success(\r\n formatMessage({ id: 'codexlens.semantic.installSuccess' }),\r\n result.message || formatMessage({ id: 'codexlens.semantic.installSuccessDesc' }, { mode: selectedMode })\r\n );\r\n onSuccess?.();\r\n onOpenChange(false);\r\n } else {\r\n throw new Error(result.message || 'Installation failed');\r\n }\r\n } catch (err) {\r\n showError(\r\n formatMessage({ id: 'codexlens.semantic.installFailed' }),\r\n err instanceof Error ? err.message : formatMessage({ id: 'codexlens.semantic.unknownError' })\r\n );\r\n }\r\n };\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={onOpenChange}>\r\n <DialogContent className=\"max-w-2xl\">\r\n <DialogHeader>\r\n <DialogTitle className=\"flex items-center gap-2\">\r\n <Zap className=\"w-5 h-5 text-primary\" />\r\n {formatMessage({ id: 'codexlens.semantic.installTitle' })}\r\n </DialogTitle>\r\n <DialogDescription>\r\n {formatMessage({ id: 'codexlens.semantic.installDescription' })}\r\n </DialogDescription>\r\n </DialogHeader>\r\n\r\n <div className=\"space-y-4 py-4\">\r\n {/* Info Card */}\r\n <Card className=\"bg-muted/50 border-muted\">\r\n <CardContent className=\"p-4 flex items-start gap-3\">\r\n <AlertCircle className=\"w-5 h-5 text-info mt-0.5 flex-shrink-0\" />\r\n <div className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.semantic.installInfo' })}\r\n </div>\r\n </CardContent>\r\n </Card>\r\n\r\n {/* GPU Mode Selection */}\r\n <RadioGroup value={selectedMode} onValueChange={(v) => setSelectedMode(v as GpuMode)}>\r\n <div className=\"grid grid-cols-1 gap-3\">\r\n {gpuModes.map((mode) => (\r\n <Card\r\n key={mode.value}\r\n className={cn(\r\n \"cursor-pointer transition-colors hover:bg-accent/50\",\r\n selectedMode === mode.value && \"border-primary bg-accent\"\r\n )}\r\n >\r\n <CardContent className=\"p-4\">\r\n <div className=\"flex items-start gap-4\">\r\n <RadioGroupItem\r\n value={mode.value}\r\n id={`gpu-mode-${mode.value}`}\r\n className=\"mt-1\"\r\n />\r\n <div className=\"flex items-start gap-3 flex-1\">\r\n <div className={cn(\r\n \"p-2 rounded-lg\",\r\n selectedMode === mode.value\r\n ? \"bg-primary/20 text-primary\"\r\n : \"bg-muted text-muted-foreground\"\r\n )}>\r\n {mode.icon}\r\n </div>\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <Label\r\n htmlFor={`gpu-mode-${mode.value}`}\r\n className=\"font-medium cursor-pointer\"\r\n >\r\n {mode.label}\r\n </Label>\r\n {mode.recommended && (\r\n <span className=\"text-xs px-2 py-0.5 rounded-full bg-primary/10 text-primary\">\r\n {formatMessage({ id: 'codexlens.semantic.recommended' })}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {mode.description}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n ))}\r\n </div>\r\n </RadioGroup>\r\n </div>\r\n\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => onOpenChange(false)}\r\n disabled={isInstallingSemantic}\r\n >\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n <Button\r\n onClick={handleInstall}\r\n disabled={isInstallingSemantic}\r\n >\r\n {isInstallingSemantic ? (\r\n <>\r\n <Zap className=\"w-4 h-4 mr-2 animate-pulse\" />\r\n {formatMessage({ id: 'codexlens.semantic.installing' })}\r\n </>\r\n ) : (\r\n <>\r\n <CheckCircle2 className=\"w-4 h-4 mr-2\" />\r\n {formatMessage({ id: 'codexlens.semantic.install' })}\r\n </>\r\n )}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default SemanticInstallDialog;\r\n","// ========================================\r\n// CodexLens Install Progress Overlay\r\n// ========================================\r\n// Dialog overlay showing 5-stage simulated progress during CodexLens bootstrap installation\r\n\r\nimport { useState, useEffect, useRef, useCallback } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Check,\r\n Download,\r\n Info,\r\n Loader2,\r\n} from 'lucide-react';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogDescription,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/ui/Dialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Progress } from '@/components/ui/Progress';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\n\r\n// ----------------------------------------\r\n// Types\r\n// ----------------------------------------\r\n\r\ninterface InstallStage {\r\n progress: number;\r\n messageId: string;\r\n}\r\n\r\ninterface InstallProgressOverlayProps {\r\n open: boolean;\r\n onOpenChange: (open: boolean) => void;\r\n onInstall: () => Promise<{ success: boolean }>;\r\n onSuccess?: () => void;\r\n}\r\n\r\n// ----------------------------------------\r\n// Constants\r\n// ----------------------------------------\r\n\r\nconst INSTALL_STAGES: InstallStage[] = [\r\n { progress: 10, messageId: 'codexlens.install.stage.creatingVenv' },\r\n { progress: 30, messageId: 'codexlens.install.stage.installingPip' },\r\n { progress: 50, messageId: 'codexlens.install.stage.installingPackage' },\r\n { progress: 70, messageId: 'codexlens.install.stage.settingUpDeps' },\r\n { progress: 90, messageId: 'codexlens.install.stage.finalizing' },\r\n];\r\n\r\nconst STAGE_INTERVAL_MS = 1500;\r\n\r\n// ----------------------------------------\r\n// Checklist items\r\n// ----------------------------------------\r\n\r\ninterface ChecklistItem {\r\n labelId: string;\r\n descId: string;\r\n}\r\n\r\nconst CHECKLIST_ITEMS: ChecklistItem[] = [\r\n { labelId: 'codexlens.install.pythonVenv', descId: 'codexlens.install.pythonVenvDesc' },\r\n { labelId: 'codexlens.install.codexlensPackage', descId: 'codexlens.install.codexlensPackageDesc' },\r\n { labelId: 'codexlens.install.sqliteFts', descId: 'codexlens.install.sqliteFtsDesc' },\r\n];\r\n\r\n// ----------------------------------------\r\n// Component\r\n// ----------------------------------------\r\n\r\nexport function InstallProgressOverlay({\r\n open,\r\n onOpenChange,\r\n onInstall,\r\n onSuccess,\r\n}: InstallProgressOverlayProps) {\r\n const { formatMessage } = useIntl();\r\n const [isInstalling, setIsInstalling] = useState(false);\r\n const [progress, setProgress] = useState(0);\r\n const [stageText, setStageText] = useState('');\r\n const [isComplete, setIsComplete] = useState(false);\r\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\r\n\r\n const clearStageInterval = useCallback(() => {\r\n if (intervalRef.current) {\r\n clearInterval(intervalRef.current);\r\n intervalRef.current = null;\r\n }\r\n }, []);\r\n\r\n // Reset state when dialog closes\r\n useEffect(() => {\r\n if (!open) {\r\n setIsInstalling(false);\r\n setProgress(0);\r\n setStageText('');\r\n setIsComplete(false);\r\n clearStageInterval();\r\n }\r\n }, [open, clearStageInterval]);\r\n\r\n // Cleanup on unmount\r\n useEffect(() => {\r\n return () => clearStageInterval();\r\n }, [clearStageInterval]);\r\n\r\n const handleInstall = async () => {\r\n setIsInstalling(true);\r\n setProgress(0);\r\n setIsComplete(false);\r\n\r\n // Start stage simulation\r\n let currentStage = 0;\r\n setStageText(formatMessage({ id: INSTALL_STAGES[0].messageId }));\r\n setProgress(INSTALL_STAGES[0].progress);\r\n currentStage = 1;\r\n\r\n intervalRef.current = setInterval(() => {\r\n if (currentStage < INSTALL_STAGES.length) {\r\n setStageText(formatMessage({ id: INSTALL_STAGES[currentStage].messageId }));\r\n setProgress(INSTALL_STAGES[currentStage].progress);\r\n currentStage++;\r\n }\r\n }, STAGE_INTERVAL_MS);\r\n\r\n try {\r\n const result = await onInstall();\r\n clearStageInterval();\r\n\r\n if (result.success) {\r\n setProgress(100);\r\n setStageText(formatMessage({ id: 'codexlens.install.stage.complete' }));\r\n setIsComplete(true);\r\n\r\n // Auto-close after showing completion\r\n setTimeout(() => {\r\n onOpenChange(false);\r\n onSuccess?.();\r\n }, 1200);\r\n } else {\r\n setIsInstalling(false);\r\n setProgress(0);\r\n setStageText('');\r\n }\r\n } catch {\r\n clearStageInterval();\r\n setIsInstalling(false);\r\n setProgress(0);\r\n setStageText('');\r\n }\r\n };\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={isInstalling ? undefined : onOpenChange}>\r\n <DialogContent className=\"max-w-lg\" onPointerDownOutside={isInstalling ? (e) => e.preventDefault() : undefined}>\r\n <DialogHeader>\r\n <DialogTitle className=\"flex items-center gap-2\">\r\n <Download className=\"w-5 h-5 text-primary\" />\r\n {formatMessage({ id: 'codexlens.install.title' })}\r\n </DialogTitle>\r\n <DialogDescription>\r\n {formatMessage({ id: 'codexlens.install.description' })}\r\n </DialogDescription>\r\n </DialogHeader>\r\n\r\n <div className=\"space-y-4 py-4\">\r\n {/* Install Checklist */}\r\n <div>\r\n <h4 className=\"text-sm font-medium mb-2\">\r\n {formatMessage({ id: 'codexlens.install.checklist' })}\r\n </h4>\r\n <ul className=\"space-y-2\">\r\n {CHECKLIST_ITEMS.map((item) => (\r\n <li key={item.labelId} className=\"flex items-start gap-2 text-sm\">\r\n <Check className=\"w-4 h-4 text-green-500 mt-0.5 flex-shrink-0\" />\r\n <span>\r\n <strong>{formatMessage({ id: item.labelId })}</strong>\r\n {' - '}\r\n {formatMessage({ id: item.descId })}\r\n </span>\r\n </li>\r\n ))}\r\n </ul>\r\n </div>\r\n\r\n {/* Install Location Info */}\r\n <Card className=\"bg-primary/5 border-primary/20\">\r\n <CardContent className=\"p-3 flex items-start gap-2\">\r\n <Info className=\"w-4 h-4 text-primary mt-0.5 flex-shrink-0\" />\r\n <div className=\"text-sm text-muted-foreground\">\r\n <p className=\"font-medium text-foreground\">\r\n {formatMessage({ id: 'codexlens.install.location' })}\r\n </p>\r\n <p className=\"mt-1\">\r\n <code className=\"bg-muted px-1.5 py-0.5 rounded text-xs\">\r\n {formatMessage({ id: 'codexlens.install.locationPath' })}\r\n </code>\r\n </p>\r\n <p className=\"mt-1\">\r\n {formatMessage({ id: 'codexlens.install.timeEstimate' })}\r\n </p>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n\r\n {/* Progress Section - shown during install */}\r\n {isInstalling && (\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-3\">\r\n {isComplete ? (\r\n <Check className=\"w-5 h-5 text-green-500\" />\r\n ) : (\r\n <Loader2 className=\"w-5 h-5 text-primary animate-spin\" />\r\n )}\r\n <span className=\"text-sm\">{stageText}</span>\r\n </div>\r\n <Progress value={progress} className=\"h-2\" />\r\n </div>\r\n )}\r\n </div>\r\n\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => onOpenChange(false)}\r\n disabled={isInstalling}\r\n >\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n <Button\r\n onClick={handleInstall}\r\n disabled={isInstalling}\r\n >\r\n {isInstalling ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />\r\n {formatMessage({ id: 'codexlens.install.installing' })}\r\n </>\r\n ) : (\r\n <>\r\n <Download className=\"w-4 h-4 mr-2\" />\r\n {formatMessage({ id: 'codexlens.install.installNow' })}\r\n </>\r\n )}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default InstallProgressOverlay;\r\n","// ========================================\r\n// CodexLens Manager Page\r\n// ========================================\r\n// Manage CodexLens semantic code search with tabbed interface\r\n// Supports Overview, Settings, Models, and Advanced tabs\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Sparkles,\r\n RefreshCw,\r\n Download,\r\n Trash2,\r\n Zap,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\r\nimport {\r\n AlertDialog,\r\n AlertDialogTrigger,\r\n AlertDialogContent,\r\n AlertDialogHeader,\r\n AlertDialogFooter,\r\n AlertDialogTitle,\r\n AlertDialogDescription,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n} from '@/components/ui/AlertDialog';\r\nimport { OverviewTab } from '@/components/codexlens/OverviewTab';\r\nimport { SettingsTab } from '@/components/codexlens/SettingsTab';\r\nimport { AdvancedTab } from '@/components/codexlens/AdvancedTab';\r\nimport { ModelsTab } from '@/components/codexlens/ModelsTab';\r\nimport { SearchTab } from '@/components/codexlens/SearchTab';\r\nimport { SemanticInstallDialog } from '@/components/codexlens/SemanticInstallDialog';\r\nimport { InstallProgressOverlay } from '@/components/codexlens/InstallProgressOverlay';\r\nimport { useCodexLensDashboard, useCodexLensMutations } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\n\r\nexport function CodexLensManagerPage() {\r\n const { formatMessage } = useIntl();\r\n const [activeTab, setActiveTab] = useState('overview');\r\n const [isUninstallDialogOpen, setIsUninstallDialogOpen] = useState(false);\r\n const [isSemanticInstallOpen, setIsSemanticInstallOpen] = useState(false);\r\n const [isInstallOverlayOpen, setIsInstallOverlayOpen] = useState(false);\r\n\r\n const {\r\n installed,\r\n status,\r\n config,\r\n semantic,\r\n isLoading,\r\n isFetching,\r\n refetch,\r\n } = useCodexLensDashboard();\r\n\r\n const {\r\n bootstrap,\r\n isBootstrapping,\r\n uninstall,\r\n isUninstalling,\r\n } = useCodexLensMutations();\r\n\r\n const handleRefresh = () => {\r\n refetch();\r\n };\r\n\r\n const handleBootstrap = () => {\r\n setIsInstallOverlayOpen(true);\r\n };\r\n\r\n const handleBootstrapInstall = async () => {\r\n const result = await bootstrap();\r\n return result;\r\n };\r\n\r\n const handleUninstall = async () => {\r\n const result = await uninstall();\r\n if (result.success) {\r\n refetch();\r\n }\r\n setIsUninstallDialogOpen(false);\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Page Header */}\r\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4\">\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-foreground flex items-center gap-2\">\r\n <Sparkles className=\"w-6 h-6 text-primary\" />\r\n {formatMessage({ id: 'codexlens.title' })}\r\n </h1>\r\n <p className=\"text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'codexlens.description' })}\r\n </p>\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleRefresh}\r\n disabled={isFetching}\r\n >\r\n <RefreshCw className={cn('w-4 h-4 mr-2', isFetching && 'animate-spin')} />\r\n {formatMessage({ id: 'common.actions.refresh' })}\r\n </Button>\r\n {!installed ? (\r\n <Button\r\n onClick={handleBootstrap}\r\n disabled={isBootstrapping}\r\n >\r\n <Download className={cn('w-4 h-4 mr-2', isBootstrapping && 'animate-spin')} />\r\n {isBootstrapping\r\n ? formatMessage({ id: 'codexlens.bootstrapping' })\r\n : formatMessage({ id: 'codexlens.bootstrap' })\r\n }\r\n </Button>\r\n ) : (\r\n <>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => setIsSemanticInstallOpen(true)}\r\n disabled={!semantic?.available}\r\n >\r\n <Zap className=\"w-4 h-4 mr-2\" />\r\n {formatMessage({ id: 'codexlens.semantic.install' })}\r\n </Button>\r\n <AlertDialog open={isUninstallDialogOpen} onOpenChange={setIsUninstallDialogOpen}>\r\n <AlertDialogTrigger asChild>\r\n <Button\r\n variant=\"destructive\"\r\n disabled={isUninstalling}\r\n >\r\n <Trash2 className={cn('w-4 h-4 mr-2', isUninstalling && 'animate-spin')} />\r\n {isUninstalling\r\n ? formatMessage({ id: 'codexlens.uninstalling' })\r\n : formatMessage({ id: 'codexlens.uninstall' })\r\n }\r\n </Button>\r\n </AlertDialogTrigger>\r\n <AlertDialogContent>\r\n <AlertDialogHeader>\r\n <AlertDialogTitle>\r\n {formatMessage({ id: 'codexlens.confirmUninstallTitle' })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage({ id: 'codexlens.confirmUninstall' })}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel disabled={isUninstalling}>\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n onClick={handleUninstall}\r\n disabled={isUninstalling}\r\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n >\r\n {isUninstalling\r\n ? formatMessage({ id: 'codexlens.uninstalling' })\r\n : formatMessage({ id: 'common.actions.confirm' })\r\n }\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Installation Status Alert */}\r\n {!installed && !isLoading && (\r\n <Card className=\"p-4 bg-warning/10 border-warning/20\">\r\n <p className=\"text-sm text-warning-foreground\">\r\n {formatMessage({ id: 'codexlens.notInstalled' })}\r\n </p>\r\n </Card>\r\n )}\r\n\r\n {/* Tabbed Interface */}\r\n <TabsNavigation\r\n value={activeTab}\r\n onValueChange={setActiveTab}\r\n tabs={[\r\n { value: 'overview', label: formatMessage({ id: 'codexlens.tabs.overview' }) },\r\n { value: 'settings', label: formatMessage({ id: 'codexlens.tabs.settings' }) },\r\n { value: 'models', label: formatMessage({ id: 'codexlens.tabs.models' }) },\r\n { value: 'search', label: formatMessage({ id: 'codexlens.tabs.search' }) },\r\n { value: 'advanced', label: formatMessage({ id: 'codexlens.tabs.advanced' }) },\r\n ]}\r\n />\r\n\r\n {/* Tab Content */}\r\n {activeTab === 'overview' && (\r\n <div className=\"mt-4\">\r\n <OverviewTab\r\n installed={installed}\r\n status={status}\r\n config={config}\r\n isLoading={isLoading}\r\n onRefresh={handleRefresh}\r\n />\r\n </div>\r\n )}\r\n\r\n {activeTab === 'settings' && (\r\n <div className=\"mt-4\">\r\n <SettingsTab enabled={installed} />\r\n </div>\r\n )}\r\n\r\n {activeTab === 'models' && (\r\n <div className=\"mt-4\">\r\n <ModelsTab installed={installed} />\r\n </div>\r\n )}\r\n\r\n {activeTab === 'search' && (\r\n <div className=\"mt-4\">\r\n <SearchTab enabled={installed} />\r\n </div>\r\n )}\r\n\r\n {activeTab === 'advanced' && (\r\n <div className=\"mt-4\">\r\n <AdvancedTab enabled={installed} />\r\n </div>\r\n )}\r\n\r\n {/* Semantic Install Dialog */}\r\n <SemanticInstallDialog\r\n open={isSemanticInstallOpen}\r\n onOpenChange={setIsSemanticInstallOpen}\r\n onSuccess={() => refetch()}\r\n />\r\n\r\n {/* Install Progress Overlay */}\r\n <InstallProgressOverlay\r\n open={isInstallOverlayOpen}\r\n onOpenChange={setIsInstallOverlayOpen}\r\n onInstall={handleBootstrapInstall}\r\n onSuccess={() => refetch()}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\nexport default CodexLensManagerPage;\r\n"],"names":["ArrowUpDown","createLucideIcon","Box","RotateCw","Scissors","codexLensKeys","path","profile","params","STALE_TIME_SHORT","STALE_TIME_MEDIUM","STALE_TIME_LONG","useCodexLensDashboard","options","enabled","staleTime","query","useQuery","fetchCodexLensDashboardInit","refetch","_a","_b","_c","_d","useCodexLensConfig","fetchCodexLensConfig","useCodexLensModels","fetchCodexLensModels","models","embeddingModels","m","rerankerModels","useCodexLensEnv","fetchCodexLensEnv","useCodexLensIgnorePatterns","fetchCodexLensIgnorePatterns","useUpdateCodexLensConfig","queryClient","useQueryClient","formatMessage","useFormatMessage","success","info","errorToast","useNotifications","mutation","useMutation","updateCodexLensConfig","err","sanitized","sanitizeErrorMessage","message","title","useBootstrapCodexLens","bootstrapCodexLens","useInstallSemantic","installCodexLensSemantic","useUninstallCodexLens","uninstallCodexLens","useDownloadModel","modelName","modelType","downloadCodexLensModel","downloadCodexLensCustomModel","useDeleteModel","cachePath","deleteCodexLensModel","deleteCodexLensModelByPath","useUpdateCodexLensEnv","request","updateCodexLensEnv","useSelectGpu","selectMutation","deviceId","selectCodexLensGpu","resetMutation","resetCodexLensGpu","useUpdateIgnorePatterns","updateCodexLensIgnorePatterns","useCodexLensIndexingStatus","checkCodexLensIndexingStatus","useRebuildIndex","projectPath","rebuildCodexLensIndex","useUpdateIndex","updateCodexLensIndex","useCancelIndexing","cancelCodexLensIndexing","useCodexLensMutations","updateConfig","bootstrap","installSemantic","uninstall","download","deleteModel","updateEnv","gpu","updatePatterns","rebuildIndex","updateIndex","cancelIndexing","useCodexLensSearch","searchCodexLens","useCodexLensFilesSearch","searchFilesCodexLens","useCodexLensSymbolSearch","searchSymbolCodexLens","useCodexLensLspStatus","fetchCodexLensLspStatus","data","_e","_f","_g","useCodexLensLspMutations","startMutation","startCodexLensLsp","stopMutation","stopCodexLensLsp","restartMutation","restartCodexLensLsp","useCodexLensSemanticSearch","semanticSearchCodexLens","useCodexLensWatcher","fetchCodexLensWatcherStatus","useCodexLensWatcherMutations","debounceMs","startCodexLensWatcher","stopCodexLensWatcher","useCcwToolsList","fetchCcwTools","IndexOperations","disabled","onRefresh","useIntl","showError","wsLastMessage","useWorkflowStore","selectProjectPath","inProgress","isRebuilding","isUpdating","isCancelling","useWebSocket","indexProgress","setIndexProgress","useState","activeOperation","setActiveOperation","useEffect","progress","isOperating","handleOperation","operation","isVector","result","handleCancel","operations","jsx","Zap","op","isComplete","isError","isCancelled","Card","CardHeader","jsxs","CardTitle","Button","X","CardContent","CheckCircle2","AlertCircle","Progress","cn","formatUptime","seconds","s","h","FileWatcherCard","running","rootPath","eventsProcessed","uptimeSeconds","isLoading","startWatcher","stopWatcher","isStarting","isStopping","isMutating","handleToggle","Activity","Badge","Clock","FolderOpen","Fragment","EyeOff","Eye","LspServerCard","available","semanticAvailable","projectCount","modes","startLsp","stopLsp","restartLsp","isRestarting","handleRestart","Server","Cpu","Layers","PowerOff","Power","OverviewTab","installed","status","config","i","Database","isReady","version","indexDir","indexCount","XCircle","FileText","envVarGroupsSchema","env","evaluateShowWhen","field","values","getSchemaDefaults","defaults","group","key","ModelSelectField","value","onChange","localModels","backendType","open","setOpen","search","setSearch","containerRef","useRef","inputRef","handleClickOutside","e","useMemo","apiGroups","item","model","modelId","displayText","localGroups","filtered","q","opt","grouped","groups","handleSelect","handleInputChange","val","ChevronDown","items","iconMap","GitBranch","SchemaFormRenderer","localEmbeddingModels","localRerankerModels","groupEntries","groupKey","IconComponent","Collapsible","CollapsibleTrigger","CollapsibleContent","varKey","FieldRenderer","allValues","label","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","Checkbox","checked","backendKey","backendValue","SettingsTab","apiMaxWorkers","apiBatchSize","isLoadingConfig","refetchConfig","serverEnv","serverSettings","isLoadingEnv","refetchEnv","setIndexDir","indexDirError","setIndexDirError","envValues","setEnvValues","hasChanges","setHasChanges","initialEnvValues","setInitialEnvValues","initialIndexDir","setInitialIndexDir","merged","detectChanges","useCallback","currentEnv","currentIndexDir","handleEnvChange","prev","next","handleIndexDirChange","installedEmbeddingModels","installedRerankerModels","handleSave","handleReset","Save","RefreshCw","CODEX_LENS_PREFIX","isCodexLensTool","tool","CcwToolsCard","tools","error","codexLensTools","otherTools","t","Wrench","Loader2","ToolRow","variant","FILTER_ENTRY_PATTERN","parseListEntries","text","entry","normalizeListEntries","entries","normalizeListText","AdvancedTab","raw","settings","envError","patterns","extensionFilters","isLoadingPatterns","patternsError","refetchPatterns","isUpdatingPatterns","envInput","setEnvInput","ignorePatternsInput","setIgnorePatternsInput","extensionFiltersInput","setExtensionFiltersInput","errors","setErrors","hasFilterChanges","setHasFilterChanges","showWarning","setShowWarning","currentIgnorePatterns","currentExtensionFilters","defaultIgnorePatterns","defaultExtensionFilters","nextIgnorePatterns","nextExtensionFilters","updateFilterChangeState","nextIgnorePatternsInput","nextExtensionFiltersInput","normalizedCurrentIgnorePatterns","normalizedCurrentExtensionFilters","currentRaw","handleIgnorePatternsChange","handleExtensionFiltersChange","parseEnvVariables","envObj","lines","line","trimmed","valParts","validateForm","newErrors","parsed","invalidKeys","validateFilterForm","nextErrors","parsedIgnorePatterns","parsedExtensionFilters","invalidIgnorePatterns","invalidExtensionFilters","handleSaveFilters","handleResetFilters","handleRestoreDefaultFilters","defaultIgnoreText","defaultExtensionText","isLoadingFilters","currentEnvVars","settingsVars","AlertTriangle","Filter","Textarea","event","pattern","FileCode","getModelTypeVariant","type","formatSize","size","ModelCard","isDownloading","downloadProgress","isDeleting","onDownload","onDelete","onCancelDownload","handleDownload","handleDelete","HardDrive","Package","Trash2","Download","CustomModelInput","setModelName","setModelType","handleSubmit","filterModels","filter","ModelsTab","searchQuery","setSearchQuery","filterType","setFilterType","downloadingProfile","setDownloadingProfile","setDownloadProgress","downloadModel","downloadCustomModel","filteredModels","stats","progressInterval","handleCustomDownload","filterButtons","Search","count","SearchTab","searchType","setSearchType","searchMode","setSearchMode","semanticMode","setSemanticMode","fusionStrategy","setFusionStrategy","stagedStage2Mode","setStagedStage2Mode","setQuery","hasSearched","setHasSearched","lspStatus","searchParams","contentSearch","fileSearch","symbolSearch","semanticSearch","handleSearch","handleKeyPress","handleSearchTypeChange","handleSearchModeChange","handleSemanticModeChange","handleFusionStrategyChange","handleStagedStage2ModeChange","handleQueryChange","getResultCount","CheckCircle","Code","Sparkles","SemanticInstallDialog","onOpenChange","onSuccess","isInstallingSemantic","selectedMode","setSelectedMode","gpuModes","Monitor","handleInstall","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","RadioGroup","v","mode","RadioGroupItem","DialogFooter","INSTALL_STAGES","STAGE_INTERVAL_MS","CHECKLIST_ITEMS","InstallProgressOverlay","onInstall","isInstalling","setIsInstalling","setProgress","stageText","setStageText","setIsComplete","intervalRef","clearStageInterval","currentStage","Check","Info","CodexLensManagerPage","activeTab","setActiveTab","isUninstallDialogOpen","setIsUninstallDialogOpen","isSemanticInstallOpen","setIsSemanticInstallOpen","isInstallOverlayOpen","setIsInstallOverlayOpen","semantic","isFetching","isBootstrapping","isUninstalling","handleRefresh","handleBootstrap","handleBootstrapInstall","handleUninstall","AlertDialog","AlertDialogTrigger","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","TabsNavigation"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|