claude-code-workflow 7.2.10 → 7.2.12

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.
Files changed (331) hide show
  1. package/.claude/agents/cli-planning-agent.md +3 -0
  2. package/.claude/agents/debug-explore-agent.md +1 -0
  3. package/.claude/agents/tdd-developer.md +1 -0
  4. package/.claude/agents/team-worker.md +1 -1
  5. package/.claude/agents/test-action-planning-agent.md +3 -0
  6. package/.claude/agents/test-context-search-agent.md +1 -0
  7. package/.claude/agents/test-fix-agent.md +3 -0
  8. package/.claude/commands/workflow/analyze-with-file.md +108 -54
  9. package/.claude/commands/workflow-tune.md +811 -0
  10. package/.claude/skills/review-code/SKILL.md +2 -0
  11. package/.claude/skills/review-cycle/SKILL.md +4 -0
  12. package/.claude/skills/skill-simplify/phases/02-optimize.md +4 -0
  13. package/.claude/skills/spec-generator/phases/05-epics-stories.md +4 -0
  14. package/.claude/skills/team-arch-opt/specs/team-config.json +5 -5
  15. package/.claude/skills/team-frontend-debug/roles/analyzer/role.md +3 -2
  16. package/.claude/skills/team-perf-opt/roles/coordinator/commands/monitor.md +1 -1
  17. package/.claude/skills/team-perf-opt/specs/team-config.json +5 -5
  18. package/.claude/skills/team-quality-assurance/roles/executor/role.md +2 -1
  19. package/.claude/skills/team-review/roles/reviewer/role.md +2 -1
  20. package/.claude/skills/team-tech-debt/roles/scanner/role.md +2 -1
  21. package/.claude/skills/team-testing/roles/executor/role.md +2 -1
  22. package/.claude/skills/team-testing/roles/generator/role.md +2 -1
  23. package/.claude/skills/team-ultra-analyze/roles/explorer/role.md +2 -1
  24. package/.claude/skills/team-ux-improve/specs/team-config.json +6 -6
  25. package/.claude/skills/workflow-execute/phases/06-review.md +4 -4
  26. package/.claude/skills/workflow-lite-execute/SKILL.md +106 -14
  27. package/.claude/skills/workflow-lite-plan/SKILL.md +34 -72
  28. package/.claude/skills/workflow-lite-test-review/SKILL.md +41 -26
  29. package/.claude/skills/workflow-plan/phases/05-plan-verify.md +4 -0
  30. package/.claude/skills/workflow-tdd-plan/phases/02-context-gathering.md +1 -0
  31. package/.claude/skills/workflow-tdd-plan/phases/05-tdd-task-generation.md +2 -1
  32. package/.claude/skills/workflow-test-fix/phases/02-test-context-gather.md +1 -0
  33. package/.claude/skills/workflow-test-fix/phases/05-test-cycle-execute.md +2 -1
  34. package/.codex/skills/analyze-with-file/SKILL.md +2 -0
  35. package/.codex/skills/debug-with-file/SKILL.md +4 -0
  36. package/.codex/skills/issue-discover/SKILL.md +1 -0
  37. package/.codex/skills/review-cycle/phases/02-parallel-review.md +3 -0
  38. package/.codex/skills/team-designer/agents/validation-reporter.md +186 -0
  39. package/.codex/skills/team-iterdev/agents/gc-controller.md +193 -0
  40. package/.codex/skills/team-iterdev/agents/task-analyzer.md +206 -0
  41. package/.codex/skills/team-lifecycle-v4/agents/quality-gate.md +165 -0
  42. package/.codex/skills/team-lifecycle-v4/agents/requirement-clarifier.md +163 -0
  43. package/.codex/skills/team-lifecycle-v4/agents/supervisor.md +182 -0
  44. package/.codex/skills/team-uidesign/agents/completion-handler.md +177 -0
  45. package/.codex/skills/team-uidesign/agents/gc-loop-handler.md +162 -0
  46. package/.codex/skills/workflow-test-fix-cycle/phases/01-test-fix-gen.md +4 -0
  47. package/.codex/skills/workflow-test-fix-cycle/phases/02-test-cycle-execute.md +2 -0
  48. package/ccw/dist/commands/spec.d.ts.map +1 -1
  49. package/ccw/dist/commands/spec.js +9 -4
  50. package/ccw/dist/commands/spec.js.map +1 -1
  51. package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
  52. package/ccw/dist/core/routes/codexlens-routes.js +3 -1
  53. package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
  54. package/ccw/dist/tools/spec-index-builder.d.ts +8 -4
  55. package/ccw/dist/tools/spec-index-builder.d.ts.map +1 -1
  56. package/ccw/dist/tools/spec-index-builder.js +8 -4
  57. package/ccw/dist/tools/spec-index-builder.js.map +1 -1
  58. package/ccw/dist/tools/spec-init.d.ts +1 -1
  59. package/ccw/dist/tools/spec-init.d.ts.map +1 -1
  60. package/ccw/dist/tools/spec-init.js +127 -0
  61. package/ccw/dist/tools/spec-init.js.map +1 -1
  62. package/ccw/dist/tools/spec-loader.d.ts.map +1 -1
  63. package/ccw/dist/tools/spec-loader.js +2 -1
  64. package/ccw/dist/tools/spec-loader.js.map +1 -1
  65. package/ccw/frontend/dist/assets/{AlertDialog-gTMl4gSG.js → AlertDialog-BW9jiZ-p.js} +2 -2
  66. package/ccw/frontend/dist/assets/{AlertDialog-gTMl4gSG.js.map → AlertDialog-BW9jiZ-p.js.map} +1 -1
  67. package/ccw/frontend/dist/assets/{AnalysisPage-Bc4p4SvJ.js → AnalysisPage-ds-w_nVO.js} +2 -2
  68. package/ccw/frontend/dist/assets/{AnalysisPage-Bc4p4SvJ.js.map → AnalysisPage-ds-w_nVO.js.map} +1 -1
  69. package/ccw/frontend/dist/assets/{ApiSettingsPage-CVK108u2.js → ApiSettingsPage-DlCbXxTz.js} +2 -2
  70. package/ccw/frontend/dist/assets/{ApiSettingsPage-CVK108u2.js.map → ApiSettingsPage-DlCbXxTz.js.map} +1 -1
  71. package/ccw/frontend/dist/assets/{CliModeToggle-34Sjwl05.js → CliModeToggle-Dq3nL4fF.js} +2 -2
  72. package/ccw/frontend/dist/assets/{CliModeToggle-34Sjwl05.js.map → CliModeToggle-Dq3nL4fF.js.map} +1 -1
  73. package/ccw/frontend/dist/assets/{CliSessionSharePage-bJZAYI38.js → CliSessionSharePage-BNDkEE4u.js} +2 -2
  74. package/ccw/frontend/dist/assets/{CliSessionSharePage-bJZAYI38.js.map → CliSessionSharePage-BNDkEE4u.js.map} +1 -1
  75. package/ccw/frontend/dist/assets/{CliViewerPage-VYnQGjxU.js → CliViewerPage-ChM-uNx_.js} +2 -2
  76. package/ccw/frontend/dist/assets/{CliViewerPage-VYnQGjxU.js.map → CliViewerPage-ChM-uNx_.js.map} +1 -1
  77. package/ccw/frontend/dist/assets/CodexLensPage-DOcsYNQk.js +2 -0
  78. package/ccw/frontend/dist/assets/CodexLensPage-DOcsYNQk.js.map +1 -0
  79. package/ccw/frontend/dist/assets/{Collapsible-B_xd1Qbg.js → Collapsible-CRNbykXN.js} +2 -2
  80. package/ccw/frontend/dist/assets/{Collapsible-B_xd1Qbg.js.map → Collapsible-CRNbykXN.js.map} +1 -1
  81. package/ccw/frontend/dist/assets/{CommandsManagerPage-Bjx1bPbH.js → CommandsManagerPage-C2JWcemF.js} +2 -2
  82. package/ccw/frontend/dist/assets/{CommandsManagerPage-Bjx1bPbH.js.map → CommandsManagerPage-C2JWcemF.js.map} +1 -1
  83. package/ccw/frontend/dist/assets/{DeepWikiPage-EgHsHvAH.js → DeepWikiPage-CvleOtJy.js} +2 -2
  84. package/ccw/frontend/dist/assets/{DeepWikiPage-EgHsHvAH.js.map → DeepWikiPage-CvleOtJy.js.map} +1 -1
  85. package/ccw/frontend/dist/assets/{EndpointsPage-CuwpbCzK.js → EndpointsPage-CMOWQG64.js} +2 -2
  86. package/ccw/frontend/dist/assets/{EndpointsPage-CuwpbCzK.js.map → EndpointsPage-CMOWQG64.js.map} +1 -1
  87. package/ccw/frontend/dist/assets/{ExplorerPage-cvlx0Zw0.js → ExplorerPage-DaFPRlNo.js} +2 -2
  88. package/ccw/frontend/dist/assets/{ExplorerPage-cvlx0Zw0.js.map → ExplorerPage-DaFPRlNo.js.map} +1 -1
  89. package/ccw/frontend/dist/assets/{FixSessionPage-C74-MPza.js → FixSessionPage-CC4p04Az.js} +2 -2
  90. package/ccw/frontend/dist/assets/{FixSessionPage-C74-MPza.js.map → FixSessionPage-CC4p04Az.js.map} +1 -1
  91. package/ccw/frontend/dist/assets/{FloatingFileBrowser-x_-6y_n2.js → FloatingFileBrowser-DROn1xZ5.js} +2 -2
  92. package/ccw/frontend/dist/assets/{FloatingFileBrowser-x_-6y_n2.js.map → FloatingFileBrowser-DROn1xZ5.js.map} +1 -1
  93. package/ccw/frontend/dist/assets/{FloatingPanel-BGwmbJR1.js → FloatingPanel-CmL_yhDv.js} +2 -2
  94. package/ccw/frontend/dist/assets/{FloatingPanel-BGwmbJR1.js.map → FloatingPanel-CmL_yhDv.js.map} +1 -1
  95. package/ccw/frontend/dist/assets/{GraphExplorerPage-Bg5-aQxi.js → GraphExplorerPage-DCV5ybKE.js} +2 -2
  96. package/ccw/frontend/dist/assets/{GraphExplorerPage-Bg5-aQxi.js.map → GraphExplorerPage-DCV5ybKE.js.map} +1 -1
  97. package/ccw/frontend/dist/assets/{HistoryPage-C00fh0HE.js → HistoryPage-D0fYQZgc.js} +2 -2
  98. package/ccw/frontend/dist/assets/{HistoryPage-C00fh0HE.js.map → HistoryPage-D0fYQZgc.js.map} +1 -1
  99. package/ccw/frontend/dist/assets/{HookManagerPage-CtVTB_ae.js → HookManagerPage-D2FuJfsM.js} +2 -2
  100. package/ccw/frontend/dist/assets/{HookManagerPage-CtVTB_ae.js.map → HookManagerPage-D2FuJfsM.js.map} +1 -1
  101. package/ccw/frontend/dist/assets/{InstallationsPage-CYuMQDbC.js → InstallationsPage-tjklillZ.js} +2 -2
  102. package/ccw/frontend/dist/assets/{InstallationsPage-CYuMQDbC.js.map → InstallationsPage-tjklillZ.js.map} +1 -1
  103. package/ccw/frontend/dist/assets/{IssueHubPage-T_VSvUMh.js → IssueHubPage-E4JVrhO1.js} +2 -2
  104. package/ccw/frontend/dist/assets/{IssueHubPage-T_VSvUMh.js.map → IssueHubPage-E4JVrhO1.js.map} +1 -1
  105. package/ccw/frontend/dist/assets/{LiteTasksPage-DmcgvIvi.js → LiteTasksPage-aJuRoyLt.js} +2 -2
  106. package/ccw/frontend/dist/assets/{LiteTasksPage-DmcgvIvi.js.map → LiteTasksPage-aJuRoyLt.js.map} +1 -1
  107. package/ccw/frontend/dist/assets/{McpManagerPage-C_a7QSKz.js → McpManagerPage-BJeuWJv1.js} +2 -2
  108. package/ccw/frontend/dist/assets/{McpManagerPage-C_a7QSKz.js.map → McpManagerPage-BJeuWJv1.js.map} +1 -1
  109. package/ccw/frontend/dist/assets/{MemoryPage-CWKmXY5k.js → MemoryPage-BI4FAXhs.js} +2 -2
  110. package/ccw/frontend/dist/assets/{MemoryPage-CWKmXY5k.js.map → MemoryPage-BI4FAXhs.js.map} +1 -1
  111. package/ccw/frontend/dist/assets/{NotFoundPage-B1duXK6r.js → NotFoundPage-DD2svchp.js} +2 -2
  112. package/ccw/frontend/dist/assets/{NotFoundPage-B1duXK6r.js.map → NotFoundPage-DD2svchp.js.map} +1 -1
  113. package/ccw/frontend/dist/assets/{OrchestratorPage-Ib9TM6HE.js → OrchestratorPage-FC__7yYa.js} +2 -2
  114. package/ccw/frontend/dist/assets/{OrchestratorPage-Ib9TM6HE.js.map → OrchestratorPage-FC__7yYa.js.map} +1 -1
  115. package/ccw/frontend/dist/assets/{ProjectOverviewPage-sXSWMbF8.js → ProjectOverviewPage-DBB_-FzV.js} +2 -2
  116. package/ccw/frontend/dist/assets/{ProjectOverviewPage-sXSWMbF8.js.map → ProjectOverviewPage-DBB_-FzV.js.map} +1 -1
  117. package/ccw/frontend/dist/assets/{PromptHistoryPage-B6jaqG12.js → PromptHistoryPage-BwOAvCH8.js} +2 -2
  118. package/ccw/frontend/dist/assets/{PromptHistoryPage-B6jaqG12.js.map → PromptHistoryPage-BwOAvCH8.js.map} +1 -1
  119. package/ccw/frontend/dist/assets/{ReviewSessionPage-D5qJyr3s.js → ReviewSessionPage-Dd1-g_gp.js} +2 -2
  120. package/ccw/frontend/dist/assets/{ReviewSessionPage-D5qJyr3s.js.map → ReviewSessionPage-Dd1-g_gp.js.map} +1 -1
  121. package/ccw/frontend/dist/assets/{RulesManagerPage-DyawK8QE.js → RulesManagerPage-B3RGdsKD.js} +2 -2
  122. package/ccw/frontend/dist/assets/{RulesManagerPage-DyawK8QE.js.map → RulesManagerPage-B3RGdsKD.js.map} +1 -1
  123. package/ccw/frontend/dist/assets/{SessionDetailPage-Cym_RvC9.js → SessionDetailPage-DM-W5R8K.js} +2 -2
  124. package/ccw/frontend/dist/assets/{SessionDetailPage-Cym_RvC9.js.map → SessionDetailPage-DM-W5R8K.js.map} +1 -1
  125. package/ccw/frontend/dist/assets/{SessionsPage-Dkc1Hv8W.js → SessionsPage-BVz1KCc7.js} +2 -2
  126. package/ccw/frontend/dist/assets/{SessionsPage-Dkc1Hv8W.js.map → SessionsPage-BVz1KCc7.js.map} +1 -1
  127. package/ccw/frontend/dist/assets/{SettingsPage-Rik9cUIj.js → SettingsPage-ComW7EZS.js} +4 -4
  128. package/ccw/frontend/dist/assets/{SettingsPage-Rik9cUIj.js.map → SettingsPage-ComW7EZS.js.map} +1 -1
  129. package/ccw/frontend/dist/assets/{SkillsManagerPage-BGDWYAyI.js → SkillsManagerPage-CKom9XwV.js} +2 -2
  130. package/ccw/frontend/dist/assets/{SkillsManagerPage-BGDWYAyI.js.map → SkillsManagerPage-CKom9XwV.js.map} +1 -1
  131. package/ccw/frontend/dist/assets/{SpecsSettingsPage-CTiA1DMP.js → SpecsSettingsPage-DQz7WP2s.js} +2 -2
  132. package/ccw/frontend/dist/assets/{SpecsSettingsPage-CTiA1DMP.js.map → SpecsSettingsPage-DQz7WP2s.js.map} +1 -1
  133. package/ccw/frontend/dist/assets/{Switch-BgAFC-Wk.js → Switch-BPMdND9H.js} +2 -2
  134. package/ccw/frontend/dist/assets/{Switch-BgAFC-Wk.js.map → Switch-BPMdND9H.js.map} +1 -1
  135. package/ccw/frontend/dist/assets/{TabsNavigation-drSnu5jn.js → TabsNavigation-qqt70VYL.js} +2 -2
  136. package/ccw/frontend/dist/assets/{TabsNavigation-drSnu5jn.js.map → TabsNavigation-qqt70VYL.js.map} +1 -1
  137. package/ccw/frontend/dist/assets/{TaskDrawer-ePC__6-P.js → TaskDrawer-BqK_qiHX.js} +2 -2
  138. package/ccw/frontend/dist/assets/{TaskDrawer-ePC__6-P.js.map → TaskDrawer-BqK_qiHX.js.map} +1 -1
  139. package/ccw/frontend/dist/assets/{TeamPage-C6bdFWn8.js → TeamPage-u5_i0Rgh.js} +2 -2
  140. package/ccw/frontend/dist/assets/{TeamPage-C6bdFWn8.js.map → TeamPage-u5_i0Rgh.js.map} +1 -1
  141. package/ccw/frontend/dist/assets/{TerminalDashboardPage-Zofi_DZM.js → TerminalDashboardPage-rUtC9e40.js} +2 -2
  142. package/ccw/frontend/dist/assets/{TerminalDashboardPage-Zofi_DZM.js.map → TerminalDashboardPage-rUtC9e40.js.map} +1 -1
  143. package/ccw/frontend/dist/assets/{archive-Bza1KlB9.js → archive-C3u8YNQF.js} +2 -2
  144. package/ccw/frontend/dist/assets/{archive-Bza1KlB9.js.map → archive-C3u8YNQF.js.map} +1 -1
  145. package/ccw/frontend/dist/assets/{archive-restore-CpsDm-cG.js → archive-restore-DfQ998g5.js} +2 -2
  146. package/ccw/frontend/dist/assets/{archive-restore-CpsDm-cG.js.map → archive-restore-DfQ998g5.js.map} +1 -1
  147. package/ccw/frontend/dist/assets/{arrow-right-CibG_LVO.js → arrow-right-BshJM9Po.js} +2 -2
  148. package/ccw/frontend/dist/assets/{arrow-right-CibG_LVO.js.map → arrow-right-BshJM9Po.js.map} +1 -1
  149. package/ccw/frontend/dist/assets/{bookmark-plus-BheO8EgG.js → bookmark-plus-D03qJyOZ.js} +2 -2
  150. package/ccw/frontend/dist/assets/{bookmark-plus-BheO8EgG.js.map → bookmark-plus-D03qJyOZ.js.map} +1 -1
  151. package/ccw/frontend/dist/assets/{bot-BlhM0Nl0.js → bot-CyzWuwq0.js} +2 -2
  152. package/ccw/frontend/dist/assets/{bot-BlhM0Nl0.js.map → bot-CyzWuwq0.js.map} +1 -1
  153. package/ccw/frontend/dist/assets/{braces-Dqjg_eCO.js → braces-BPgtyjsG.js} +2 -2
  154. package/ccw/frontend/dist/assets/{braces-Dqjg_eCO.js.map → braces-BPgtyjsG.js.map} +1 -1
  155. package/ccw/frontend/dist/assets/{circle-stop-DYZSLYU0.js → circle-stop-Dix1AOmw.js} +2 -2
  156. package/ccw/frontend/dist/assets/{circle-stop-DYZSLYU0.js.map → circle-stop-Dix1AOmw.js.map} +1 -1
  157. package/ccw/frontend/dist/assets/{cpu-DWCyAOAv.js → cpu-CCQ4Q0Zh.js} +2 -2
  158. package/ccw/frontend/dist/assets/{cpu-DWCyAOAv.js.map → cpu-CCQ4Q0Zh.js.map} +1 -1
  159. package/ccw/frontend/dist/assets/{ellipsis-vertical-DIyoSEHx.js → ellipsis-vertical-BpTysg-Y.js} +2 -2
  160. package/ccw/frontend/dist/assets/{ellipsis-vertical-DIyoSEHx.js.map → ellipsis-vertical-BpTysg-Y.js.map} +1 -1
  161. package/ccw/frontend/dist/assets/{eye-DUy7aLEx.js → eye-DGY1rAZs.js} +2 -2
  162. package/ccw/frontend/dist/assets/{eye-DUy7aLEx.js.map → eye-DGY1rAZs.js.map} +1 -1
  163. package/ccw/frontend/dist/assets/{eye-off-CGRUVRDR.js → eye-off-D8t3JfWG.js} +2 -2
  164. package/ccw/frontend/dist/assets/{eye-off-CGRUVRDR.js.map → eye-off-D8t3JfWG.js.map} +1 -1
  165. package/ccw/frontend/dist/assets/{file-json-BxLBtU9d.js → file-json-BAdJb0n8.js} +2 -2
  166. package/ccw/frontend/dist/assets/{file-json-BxLBtU9d.js.map → file-json-BAdJb0n8.js.map} +1 -1
  167. package/ccw/frontend/dist/assets/{file-text-BoHsW2es.js → file-text-DrJFiOUB.js} +2 -2
  168. package/ccw/frontend/dist/assets/{file-text-BoHsW2es.js.map → file-text-DrJFiOUB.js.map} +1 -1
  169. package/ccw/frontend/dist/assets/{filter-B4vOqP6B.js → filter-CKqzYbz7.js} +2 -2
  170. package/ccw/frontend/dist/assets/{filter-B4vOqP6B.js.map → filter-CKqzYbz7.js.map} +1 -1
  171. package/ccw/frontend/dist/assets/{folder-BKhwCNFG.js → folder-CV8511y9.js} +2 -2
  172. package/ccw/frontend/dist/assets/{folder-BKhwCNFG.js.map → folder-CV8511y9.js.map} +1 -1
  173. package/ccw/frontend/dist/assets/{gauge-Dgf64gkT.js → gauge-XKvmu_uU.js} +2 -2
  174. package/ccw/frontend/dist/assets/{gauge-Dgf64gkT.js.map → gauge-XKvmu_uU.js.map} +1 -1
  175. package/ccw/frontend/dist/assets/{globe-Cus_S6Ux.js → globe-C56cDUzX.js} +2 -2
  176. package/ccw/frontend/dist/assets/{globe-Cus_S6Ux.js.map → globe-C56cDUzX.js.map} +1 -1
  177. package/ccw/frontend/dist/assets/{grid-3x3-DM08hpAN.js → grid-3x3-Bya-suFW.js} +2 -2
  178. package/ccw/frontend/dist/assets/{grid-3x3-DM08hpAN.js.map → grid-3x3-Bya-suFW.js.map} +1 -1
  179. package/ccw/frontend/dist/assets/{hard-drive-eCtll84F.js → hard-drive-CmuTZpsB.js} +2 -2
  180. package/ccw/frontend/dist/assets/{hard-drive-eCtll84F.js.map → hard-drive-CmuTZpsB.js.map} +1 -1
  181. package/ccw/frontend/dist/assets/{hash-Bd1RD285.js → hash-CRPT_tJQ.js} +2 -2
  182. package/ccw/frontend/dist/assets/{hash-Bd1RD285.js.map → hash-CRPT_tJQ.js.map} +1 -1
  183. package/ccw/frontend/dist/assets/{history-eyyCQA6b.js → history-C1pJZQCL.js} +2 -2
  184. package/ccw/frontend/dist/assets/{history-eyyCQA6b.js.map → history-C1pJZQCL.js.map} +1 -1
  185. package/ccw/frontend/dist/assets/{index-ZnmWxcZg.js → index-B6TpijCe.js} +2 -2
  186. package/ccw/frontend/dist/assets/{index-ZnmWxcZg.js.map → index-B6TpijCe.js.map} +1 -1
  187. package/ccw/frontend/dist/assets/{index-b2C0iFd1.js → index-Bcq-7r6F.js} +2 -2
  188. package/ccw/frontend/dist/assets/{index-b2C0iFd1.js.map → index-Bcq-7r6F.js.map} +1 -1
  189. package/ccw/frontend/dist/assets/{index-Cs2ShCCy.js → index-CI8-rBff.js} +2 -2
  190. package/ccw/frontend/dist/assets/{index-Cs2ShCCy.js.map → index-CI8-rBff.js.map} +1 -1
  191. package/ccw/frontend/dist/assets/{index-CY6Lueph.js → index-Dmt9OiEf.js} +2 -2
  192. package/ccw/frontend/dist/assets/{index-CY6Lueph.js.map → index-Dmt9OiEf.js.map} +1 -1
  193. package/ccw/frontend/dist/assets/{index-DfeBbFXo.js → index-anSMmEF8.js} +2 -2
  194. package/ccw/frontend/dist/assets/{index-DfeBbFXo.js.map → index-anSMmEF8.js.map} +1 -1
  195. package/ccw/frontend/dist/assets/{index-B6I7GQC5.js → index-dWT2M6Ef.js} +4 -4
  196. package/ccw/frontend/dist/assets/{index-B6I7GQC5.js.map → index-dWT2M6Ef.js.map} +1 -1
  197. package/ccw/frontend/dist/assets/{layout-grid-ChrTrCby.js → layout-grid-TSO0BFQE.js} +2 -2
  198. package/ccw/frontend/dist/assets/{layout-grid-ChrTrCby.js.map → layout-grid-TSO0BFQE.js.map} +1 -1
  199. package/ccw/frontend/dist/assets/{lightbulb-CvXiTlzN.js → lightbulb-Caj6fIQD.js} +2 -2
  200. package/ccw/frontend/dist/assets/{lightbulb-CvXiTlzN.js.map → lightbulb-Caj6fIQD.js.map} +1 -1
  201. package/ccw/frontend/dist/assets/{link-2-W0Nl17ec.js → link-2-DE9lMxa-.js} +2 -2
  202. package/ccw/frontend/dist/assets/{link-2-W0Nl17ec.js.map → link-2-DE9lMxa-.js.map} +1 -1
  203. package/ccw/frontend/dist/assets/{link-CL4JmoHb.js → link-BZtPgLW0.js} +2 -2
  204. package/ccw/frontend/dist/assets/{link-CL4JmoHb.js.map → link-BZtPgLW0.js.map} +1 -1
  205. package/ccw/frontend/dist/assets/{list-CDmYFcio.js → list-DubWyY-U.js} +2 -2
  206. package/ccw/frontend/dist/assets/{list-CDmYFcio.js.map → list-DubWyY-U.js.map} +1 -1
  207. package/ccw/frontend/dist/assets/{map-pin-0Mfsw_3d.js → map-pin-DwN_48AF.js} +2 -2
  208. package/ccw/frontend/dist/assets/{map-pin-0Mfsw_3d.js.map → map-pin-DwN_48AF.js.map} +1 -1
  209. package/ccw/frontend/dist/assets/{messages-square-C6h08ple.js → messages-square-bjxvaiM9.js} +2 -2
  210. package/ccw/frontend/dist/assets/{messages-square-C6h08ple.js.map → messages-square-bjxvaiM9.js.map} +1 -1
  211. package/ccw/frontend/dist/assets/{minimize-2-Cbu2yRzi.js → minimize-2-CGfBKD_V.js} +2 -2
  212. package/ccw/frontend/dist/assets/{minimize-2-Cbu2yRzi.js.map → minimize-2-CGfBKD_V.js.map} +1 -1
  213. package/ccw/frontend/dist/assets/{package-CoLVUZGJ.js → package-nzWY6ilt.js} +2 -2
  214. package/ccw/frontend/dist/assets/{package-CoLVUZGJ.js.map → package-nzWY6ilt.js.map} +1 -1
  215. package/ccw/frontend/dist/assets/{plug-BYTYqsw1.js → plug-CiLce49C.js} +2 -2
  216. package/ccw/frontend/dist/assets/{plug-BYTYqsw1.js.map → plug-CiLce49C.js.map} +1 -1
  217. package/ccw/frontend/dist/assets/{power-DmIojFl-.js → power-CFLmB-U9.js} +2 -2
  218. package/ccw/frontend/dist/assets/{power-DmIojFl-.js.map → power-CFLmB-U9.js.map} +1 -1
  219. package/ccw/frontend/dist/assets/{save-BFa03OnG.js → save-DuO6OF0C.js} +2 -2
  220. package/ccw/frontend/dist/assets/{save-BFa03OnG.js.map → save-DuO6OF0C.js.map} +1 -1
  221. package/ccw/frontend/dist/assets/{send-Vet3sN4J.js → send-CZk9p0mM.js} +2 -2
  222. package/ccw/frontend/dist/assets/{send-Vet3sN4J.js.map → send-CZk9p0mM.js.map} +1 -1
  223. package/ccw/frontend/dist/assets/{square-check-big-B9nzZRfE.js → square-check-big-BY_1YQQg.js} +2 -2
  224. package/ccw/frontend/dist/assets/{square-check-big-B9nzZRfE.js.map → square-check-big-BY_1YQQg.js.map} +1 -1
  225. package/ccw/frontend/dist/assets/{square-pen-C7K13x4Z.js → square-pen-CnZgm6g-.js} +2 -2
  226. package/ccw/frontend/dist/assets/{square-pen-C7K13x4Z.js.map → square-pen-CnZgm6g-.js.map} +1 -1
  227. package/ccw/frontend/dist/assets/{star-BCQHcnSe.js → star-Cn1F0qy7.js} +2 -2
  228. package/ccw/frontend/dist/assets/{star-BCQHcnSe.js.map → star-Cn1F0qy7.js.map} +1 -1
  229. package/ccw/frontend/dist/assets/{style-CJsrp48L.js → style-Dxs1iXCV.js} +2 -2
  230. package/ccw/frontend/dist/assets/{style-CJsrp48L.js.map → style-Dxs1iXCV.js.map} +1 -1
  231. package/ccw/frontend/dist/assets/{target-CBzCJCB1.js → target-Bz1fLRKH.js} +2 -2
  232. package/ccw/frontend/dist/assets/{target-CBzCJCB1.js.map → target-Bz1fLRKH.js.map} +1 -1
  233. package/ccw/frontend/dist/assets/{test-tube-BYTc5mvQ.js → test-tube-C6qCYlDr.js} +2 -2
  234. package/ccw/frontend/dist/assets/{test-tube-BYTc5mvQ.js.map → test-tube-C6qCYlDr.js.map} +1 -1
  235. package/ccw/frontend/dist/assets/{upload-DzyQj7ib.js → upload-C71kd4Qs.js} +2 -2
  236. package/ccw/frontend/dist/assets/{upload-DzyQj7ib.js.map → upload-C71kd4Qs.js.map} +1 -1
  237. package/ccw/frontend/dist/assets/{useApiSettings-CFPww7gU.js → useApiSettings-CqP2BAJ7.js} +2 -2
  238. package/ccw/frontend/dist/assets/{useApiSettings-CFPww7gU.js.map → useApiSettings-CqP2BAJ7.js.map} +1 -1
  239. package/ccw/frontend/dist/assets/{useCli-ByL_a5CD.js → useCli-PCoPoVeM.js} +2 -2
  240. package/ccw/frontend/dist/assets/{useCli-ByL_a5CD.js.map → useCli-PCoPoVeM.js.map} +1 -1
  241. package/ccw/frontend/dist/assets/{useCommands-BvKIoOzB.js → useCommands-3OfPQPw4.js} +2 -2
  242. package/ccw/frontend/dist/assets/{useCommands-BvKIoOzB.js.map → useCommands-3OfPQPw4.js.map} +1 -1
  243. package/ccw/frontend/dist/assets/{useDebounce-CmKmoP7n.js → useDebounce-bXiFhQx9.js} +2 -2
  244. package/ccw/frontend/dist/assets/{useDebounce-CmKmoP7n.js.map → useDebounce-bXiFhQx9.js.map} +1 -1
  245. package/ccw/frontend/dist/assets/{useFileExplorer-G5UoArCU.js → useFileExplorer-DEyUm46_.js} +2 -2
  246. package/ccw/frontend/dist/assets/{useFileExplorer-G5UoArCU.js.map → useFileExplorer-DEyUm46_.js.map} +1 -1
  247. package/ccw/frontend/dist/assets/{useLocale-D2iHK44M.js → useLocale-sXTrdxcJ.js} +2 -2
  248. package/ccw/frontend/dist/assets/{useLocale-D2iHK44M.js.map → useLocale-sXTrdxcJ.js.map} +1 -1
  249. package/ccw/frontend/dist/assets/{useSkills-CYU4zqhm.js → useSkills-D0W0kXYm.js} +3 -3
  250. package/ccw/frontend/dist/assets/{useSkills-CYU4zqhm.js.map → useSkills-D0W0kXYm.js.map} +1 -1
  251. package/ccw/frontend/dist/assets/{useSystemSettings-JznNpij7.js → useSystemSettings-DZ-8lZsG.js} +2 -2
  252. package/ccw/frontend/dist/assets/{useSystemSettings-JznNpij7.js.map → useSystemSettings-DZ-8lZsG.js.map} +1 -1
  253. package/ccw/frontend/dist/assets/{wand-sparkles-DqS0VCeN.js → wand-sparkles-83GmAYuw.js} +2 -2
  254. package/ccw/frontend/dist/assets/{wand-sparkles-DqS0VCeN.js.map → wand-sparkles-83GmAYuw.js.map} +1 -1
  255. package/ccw/frontend/dist/index.html +1 -1
  256. package/package.json +1 -1
  257. package/.claude/commands/ddd/auto.md +0 -359
  258. package/.claude/commands/ddd/doc-generate.md +0 -222
  259. package/.claude/commands/ddd/doc-refresh.md +0 -218
  260. package/.claude/commands/ddd/execute.md +0 -416
  261. package/.claude/commands/ddd/index-build.md +0 -212
  262. package/.claude/commands/ddd/plan.md +0 -611
  263. package/.claude/commands/ddd/scan.md +0 -365
  264. package/.claude/commands/ddd/sync.md +0 -353
  265. package/.claude/commands/ddd/update.md +0 -160
  266. package/.claude/commands/idaw/add.md +0 -287
  267. package/.claude/commands/idaw/resume.md +0 -442
  268. package/.claude/commands/idaw/run-coordinate.md +0 -648
  269. package/.claude/commands/idaw/run.md +0 -539
  270. package/.claude/commands/idaw/status.md +0 -182
  271. package/.claude/skills/team-arch-opt/role-specs/analyzer.md +0 -80
  272. package/.claude/skills/team-arch-opt/role-specs/designer.md +0 -118
  273. package/.claude/skills/team-arch-opt/role-specs/refactorer.md +0 -106
  274. package/.claude/skills/team-arch-opt/role-specs/reviewer.md +0 -116
  275. package/.claude/skills/team-arch-opt/role-specs/validator.md +0 -117
  276. package/.claude/skills/team-brainstorm/role-specs/challenger.md +0 -63
  277. package/.claude/skills/team-brainstorm/role-specs/evaluator.md +0 -58
  278. package/.claude/skills/team-brainstorm/role-specs/ideator.md +0 -71
  279. package/.claude/skills/team-brainstorm/role-specs/synthesizer.md +0 -59
  280. package/.claude/skills/team-frontend/role-specs/analyst.md +0 -91
  281. package/.claude/skills/team-frontend/role-specs/architect.md +0 -85
  282. package/.claude/skills/team-frontend/role-specs/developer.md +0 -92
  283. package/.claude/skills/team-frontend/role-specs/qa.md +0 -78
  284. package/.claude/skills/team-issue/role-specs/explorer.md +0 -95
  285. package/.claude/skills/team-issue/role-specs/implementer.md +0 -89
  286. package/.claude/skills/team-issue/role-specs/integrator.md +0 -86
  287. package/.claude/skills/team-issue/role-specs/planner.md +0 -83
  288. package/.claude/skills/team-issue/role-specs/reviewer.md +0 -89
  289. package/.claude/skills/team-iterdev/role-specs/architect.md +0 -64
  290. package/.claude/skills/team-iterdev/role-specs/developer.md +0 -73
  291. package/.claude/skills/team-iterdev/role-specs/reviewer.md +0 -65
  292. package/.claude/skills/team-iterdev/role-specs/tester.md +0 -87
  293. package/.claude/skills/team-perf-opt/role-specs/benchmarker.md +0 -110
  294. package/.claude/skills/team-perf-opt/role-specs/optimizer.md +0 -102
  295. package/.claude/skills/team-perf-opt/role-specs/profiler.md +0 -73
  296. package/.claude/skills/team-perf-opt/role-specs/reviewer.md +0 -91
  297. package/.claude/skills/team-perf-opt/role-specs/strategist.md +0 -114
  298. package/.claude/skills/team-planex/role-specs/executor.md +0 -90
  299. package/.claude/skills/team-planex/role-specs/planner.md +0 -110
  300. package/.claude/skills/team-quality-assurance/role-specs/analyst.md +0 -79
  301. package/.claude/skills/team-quality-assurance/role-specs/executor.md +0 -64
  302. package/.claude/skills/team-quality-assurance/role-specs/generator.md +0 -67
  303. package/.claude/skills/team-quality-assurance/role-specs/scout.md +0 -66
  304. package/.claude/skills/team-quality-assurance/role-specs/strategist.md +0 -70
  305. package/.claude/skills/team-review/role-specs/fixer.md +0 -75
  306. package/.claude/skills/team-review/role-specs/reviewer.md +0 -66
  307. package/.claude/skills/team-review/role-specs/scanner.md +0 -70
  308. package/.claude/skills/team-roadmap-dev/role-specs/executor.md +0 -71
  309. package/.claude/skills/team-roadmap-dev/role-specs/planner.md +0 -77
  310. package/.claude/skills/team-roadmap-dev/role-specs/verifier.md +0 -73
  311. package/.claude/skills/team-tech-debt/role-specs/assessor.md +0 -70
  312. package/.claude/skills/team-tech-debt/role-specs/executor.md +0 -80
  313. package/.claude/skills/team-tech-debt/role-specs/planner.md +0 -71
  314. package/.claude/skills/team-tech-debt/role-specs/scanner.md +0 -85
  315. package/.claude/skills/team-tech-debt/role-specs/validator.md +0 -83
  316. package/.claude/skills/team-testing/role-specs/analyst.md +0 -94
  317. package/.claude/skills/team-testing/role-specs/executor.md +0 -97
  318. package/.claude/skills/team-testing/role-specs/generator.md +0 -96
  319. package/.claude/skills/team-testing/role-specs/strategist.md +0 -82
  320. package/.claude/skills/team-uidesign/role-specs/designer.md +0 -72
  321. package/.claude/skills/team-uidesign/role-specs/implementer.md +0 -74
  322. package/.claude/skills/team-uidesign/role-specs/researcher.md +0 -84
  323. package/.claude/skills/team-uidesign/role-specs/reviewer.md +0 -70
  324. package/.claude/skills/team-ux-improve/role-specs/designer.md +0 -191
  325. package/.claude/skills/team-ux-improve/role-specs/diagnoser.md +0 -110
  326. package/.claude/skills/team-ux-improve/role-specs/explorer.md +0 -109
  327. package/.claude/skills/team-ux-improve/role-specs/implementer.md +0 -164
  328. package/.claude/skills/team-ux-improve/role-specs/scanner.md +0 -117
  329. package/.claude/skills/team-ux-improve/role-specs/tester.md +0 -163
  330. package/ccw/frontend/dist/assets/CodexLensPage-My6DnfN6.js +0 -2
  331. package/ccw/frontend/dist/assets/CodexLensPage-My6DnfN6.js.map +0 -1
@@ -1,117 +0,0 @@
1
- ---
2
- prefix: SCAN
3
- inner_loop: false
4
- message_types:
5
- success: scan_complete
6
- error: error
7
- ---
8
-
9
- # UI Scanner
10
-
11
- Scan UI components to identify interaction issues: unresponsive buttons, missing feedback mechanisms, state not refreshing.
12
-
13
- ## Phase 2: Context Loading
14
-
15
- | Input | Source | Required |
16
- |-------|--------|----------|
17
- | Project path | Task description CONTEXT | Yes |
18
- | Framework | Task description CONTEXT | Yes |
19
- | Scan scope | Task description CONSTRAINTS | Yes |
20
-
21
- 1. Extract session path and project path from task description
22
- 2. Detect framework from project structure:
23
-
24
- | Signal | Framework |
25
- |--------|-----------|
26
- | package.json has "react" | React |
27
- | package.json has "vue" | Vue |
28
- | *.tsx files present | React |
29
- | *.vue files present | Vue |
30
-
31
- 3. Build file pattern list for scanning:
32
- - React: `**/*.tsx`, `**/*.jsx`, `**/use*.ts`
33
- - Vue: `**/*.vue`, `**/composables/*.ts`
34
-
35
- ### Wisdom Input
36
-
37
- 1. Read `<session>/wisdom/anti-patterns/common-ux-pitfalls.md` if available
38
- 2. Use anti-patterns to identify known UX issues during scanning
39
- 3. Check `<session>/wisdom/patterns/ui-feedback.md` for expected feedback patterns
40
-
41
- ### Complex Analysis (use CLI)
42
-
43
- For large projects with many components:
44
-
45
- ```
46
- Bash(`ccw cli -p "PURPOSE: Discover all UI components with user interactions
47
- CONTEXT: @<project-path>/**/*.tsx @<project-path>/**/*.vue
48
- EXPECTED: Component list with interaction types (click, submit, input, select)
49
- CONSTRAINTS: Focus on interactive components only" --tool gemini --mode analysis`)
50
- ```
51
-
52
- ## Phase 3: Component Scanning
53
-
54
- Scan strategy:
55
-
56
- | Category | Detection Pattern | Severity |
57
- |----------|-------------------|----------|
58
- | Unresponsive actions | onClick/\@click without async handling or error catching | High |
59
- | Missing loading state | Form submit without isLoading/loading ref | High |
60
- | State not refreshing | Array.splice/push without reactive reassignment | High |
61
- | Missing error feedback | try/catch without error state or user notification | Medium |
62
- | Missing success feedback | API call without success confirmation | Medium |
63
- | No empty state | Data list without empty state placeholder | Low |
64
- | Input without validation | Form input without validation rules | Low |
65
- | Missing file selector | Text input for file/folder path without picker | Medium |
66
-
67
- For each component file:
68
- 1. Read file content
69
- 2. Scan for interaction patterns using Grep
70
- 3. Check for feedback mechanisms (loading, error, success states)
71
- 4. Check state update patterns (mutation vs reactive)
72
- 5. Record issues with file:line references
73
-
74
- ## Phase 4: Issue Report Generation
75
-
76
- 1. Classify issues by severity (High/Medium/Low)
77
- 2. Group by category (unresponsive, missing feedback, state issues, input UX)
78
- 3. Generate structured report:
79
-
80
- ```markdown
81
- # UI Scan Report
82
-
83
- ## Summary
84
- - Total issues: <count>
85
- - High: <count> | Medium: <count> | Low: <count>
86
-
87
- ## Issues
88
-
89
- ### High Severity
90
- | # | File:Line | Component | Issue | Category |
91
- |---|-----------|-----------|-------|----------|
92
- | 1 | src/components/Upload.tsx:45 | UploadForm | No loading state on submit | Missing feedback |
93
-
94
- ### Medium Severity
95
- ...
96
-
97
- ### Low Severity
98
- ...
99
- ```
100
-
101
- 4. Write report to `<session>/artifacts/scan-report.md`
102
- 5. Share state via team_msg:
103
- ```
104
- team_msg(operation="log", session_id=<session-id>, from="scanner",
105
- type="state_update", data={
106
- total_issues: <count>,
107
- high: <count>, medium: <count>, low: <count>,
108
- categories: [<category-list>],
109
- scanned_files: <count>
110
- })
111
- ```
112
-
113
- ### Wisdom Contribution
114
-
115
- If novel UX issues discovered that aren't in anti-patterns:
116
- 1. Write findings to `<session>/wisdom/contributions/scanner-issues-<timestamp>.md`
117
- 2. Format: Issue description, detection criteria, affected components
@@ -1,163 +0,0 @@
1
- ---
2
- prefix: TEST
3
- inner_loop: false
4
- message_types:
5
- success: test_complete
6
- error: error
7
- fix: fix_required
8
- ---
9
-
10
- # Test Engineer
11
-
12
- Generate and run tests to verify fixes (loading states, error handling, state updates).
13
-
14
- ## Phase 2: Environment Detection
15
-
16
- 1. Detect test framework from project files:
17
-
18
- | Signal | Framework |
19
- |--------|-----------|
20
- | package.json has "jest" | Jest |
21
- | package.json has "vitest" | Vitest |
22
- | package.json has "@testing-library/react" | React Testing Library |
23
- | package.json has "@vue/test-utils" | Vue Test Utils |
24
-
25
- 2. Get changed files from implementer state:
26
- ```
27
- team_msg(operation="get_state", session_id=<session-id>, role="implementer")
28
- ```
29
-
30
- 3. Load test strategy from design guide
31
-
32
- ### Wisdom Input
33
-
34
- 1. Read `<session>/wisdom/anti-patterns/common-ux-pitfalls.md` for common issues to test
35
- 2. Read `<session>/wisdom/patterns/ui-feedback.md` for expected feedback behaviors to verify
36
- 3. Use wisdom to design comprehensive test cases covering known edge cases
37
-
38
- ## Phase 3: Test Generation & Execution
39
-
40
- ### Test Generation
41
-
42
- For each modified file, generate test cases:
43
-
44
- **React Example**:
45
- ```typescript
46
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
47
- import Upload from '../Upload';
48
-
49
- describe('Upload Component', () => {
50
- it('shows loading state during upload', async () => {
51
- global.fetch = vi.fn(() => Promise.resolve({ ok: true }));
52
-
53
- render(<Upload />);
54
- const uploadButton = screen.getByRole('button', { name: /upload/i });
55
-
56
- fireEvent.click(uploadButton);
57
-
58
- // Check loading state
59
- await waitFor(() => {
60
- expect(screen.getByText(/uploading.../i)).toBeInTheDocument();
61
- expect(uploadButton).toBeDisabled();
62
- });
63
-
64
- // Check normal state restored
65
- await waitFor(() => {
66
- expect(uploadButton).not.toBeDisabled();
67
- });
68
- });
69
-
70
- it('displays error message on failure', async () => {
71
- global.fetch = vi.fn(() => Promise.reject(new Error('Upload failed')));
72
-
73
- render(<Upload />);
74
- fireEvent.click(screen.getByRole('button', { name: /upload/i }));
75
-
76
- await waitFor(() => {
77
- expect(screen.getByText(/upload failed/i)).toBeInTheDocument();
78
- });
79
- });
80
- });
81
- ```
82
-
83
- ### Test Execution
84
-
85
- Iterative test-fix cycle (max 5 iterations):
86
-
87
- 1. Run tests: `npm test` or `npm run test:unit`
88
- 2. Parse results -> calculate pass rate
89
- 3. If pass rate >= 95% -> exit (success)
90
- 4. If pass rate < 95% and iterations < 5:
91
- - Analyze failures
92
- - Use CLI to generate fixes:
93
- ```
94
- Bash(`ccw cli -p "PURPOSE: Fix test failures
95
- CONTEXT: @<test-file> @<source-file>
96
- EXPECTED: Fixed code that passes tests
97
- CONSTRAINTS: Maintain existing functionality" --tool gemini --mode write`)
98
- ```
99
- - Increment iteration counter
100
- - Loop to step 1
101
- 5. If iterations >= 5 -> send fix_required message
102
-
103
- ## Phase 4: Test Report
104
-
105
- ### Wisdom Contribution
106
-
107
- If new edge cases or test patterns discovered:
108
- 1. Write test findings to `<session>/wisdom/contributions/tester-edge-cases-<timestamp>.md`
109
- 2. Format: Edge case description, test scenario, expected behavior, actual behavior
110
-
111
- Generate test report:
112
-
113
- ```markdown
114
- # Test Report
115
-
116
- ## Summary
117
- - Total tests: <count>
118
- - Passed: <count>
119
- - Failed: <count>
120
- - Pass rate: <percentage>%
121
- - Fix iterations: <count>
122
-
123
- ## Test Results
124
-
125
- ### Passed Tests
126
- - ✅ Upload Component > shows loading state during upload
127
- - ✅ Upload Component > displays error message on failure
128
-
129
- ### Failed Tests
130
- - ❌ Form Component > validates input before submit
131
- - Error: Expected validation message not found
132
-
133
- ## Coverage
134
- - Statements: 85%
135
- - Branches: 78%
136
- - Functions: 90%
137
- - Lines: 84%
138
-
139
- ## Remaining Issues
140
- - Form validation test failing (needs manual review)
141
- ```
142
-
143
- Write report to `<session>/artifacts/test-report.md`
144
-
145
- Share state via team_msg:
146
- ```
147
- team_msg(operation="log", session_id=<session-id>, from="tester",
148
- type="state_update", data={
149
- total_tests: <count>,
150
- passed: <count>,
151
- failed: <count>,
152
- pass_rate: <percentage>,
153
- fix_iterations: <count>
154
- })
155
- ```
156
-
157
- If pass rate < 95%, send fix_required message:
158
- ```
159
- SendMessage({
160
- to: "coordinator",
161
- message: "[tester] Test validation incomplete. Pass rate: <percentage>%. Manual review needed."
162
- })
163
- ```
@@ -1,2 +0,0 @@
1
- import{ab as M,aF as A,aH as I,ga as b,u as C,r as j,a9 as z,aa as W,j as e,B as w,C as _,ai as O,aj as L,e as h,bq as V,am as Z,R as Y,a as S,N as y,an as T,dh as $,dg as G,T as J,I as X,a7 as ee,cJ as se,b as ne}from"./index-B6I7GQC5.js";import{T as te}from"./TabsNavigation-drSnu5jn.js";import{S as ae}from"./save-BFa03OnG.js";import{E as le}from"./eye-off-CGRUVRDR.js";import{E as ie}from"./eye-DUy7aLEx.js";const N={all:["codexLens"],models:()=>[...N.all,"models"],indexStatus:s=>[...N.all,"indexStatus",s],env:()=>[...N.all,"env"],mcpConfig:()=>[...N.all,"mcpConfig"]};function de(){return M({queryKey:N.models(),queryFn:()=>b("/api/codexlens/models").then(s=>s.models),staleTime:3e4})}function ce(){const s=A(),n=I({mutationFn:t=>b("/api/codexlens/models/download",{method:"POST",body:JSON.stringify({name:t})}),onSuccess:()=>{s.invalidateQueries({queryKey:N.models()})}});return{downloadModel:n.mutateAsync,isDownloading:n.isPending,error:n.error}}function oe(){const s=A(),n=I({mutationFn:t=>b("/api/codexlens/models/delete",{method:"POST",body:JSON.stringify({name:t})}),onSuccess:()=>{s.invalidateQueries({queryKey:N.models()})}});return{deleteModel:n.mutateAsync,isDeleting:n.isPending,error:n.error}}function re(s){return M({queryKey:N.indexStatus(s),queryFn:()=>b(`/api/codexlens/index/status?projectPath=${encodeURIComponent(s)}`).then(n=>n.status),enabled:!!s,staleTime:1e4})}function me(){const s=I({mutationFn:n=>b("/api/codexlens/index/sync",{method:"POST",body:JSON.stringify({projectPath:n})})});return{syncIndex:s.mutateAsync,isSyncing:s.isPending,error:s.error}}function xe(){const s=I({mutationFn:n=>b("/api/codexlens/index/rebuild",{method:"POST",body:JSON.stringify({projectPath:n})})});return{rebuildIndex:s.mutateAsync,isRebuilding:s.isPending,error:s.error}}function K(){return M({queryKey:N.env(),queryFn:()=>b("/api/codexlens/env").then(s=>({values:s.env??{},defaults:s.defaults??{}})),staleTime:6e4})}function ue(){const s=A(),n=I({mutationFn:t=>b("/api/codexlens/env",{method:"POST",body:JSON.stringify({env:t})}),onSuccess:()=>{s.invalidateQueries({queryKey:N.env()}),s.invalidateQueries({queryKey:N.mcpConfig()})}});return{saveEnv:n.mutateAsync,isSaving:n.isPending,error:n.error}}function Ee(){return M({queryKey:N.mcpConfig(),queryFn:()=>b("/api/codexlens/mcp-config").then(s=>s.config),staleTime:3e4})}function pe(){const{formatMessage:s}=C(),{data:n,isLoading:t,isError:i,refetch:o}=Ee(),{data:l}=K(),[x,u]=j.useState(!1),[r,a]=j.useState(!1),[c,E]=j.useState(null),p=z(W),D=async g=>{a(!0),E(null);try{const v=n==null?void 0:n.mcpServers,P=v&&typeof v=="object"?v.codexlens:void 0;if(!P||typeof P!="object")throw new Error(s({id:"codexlens.mcp.noConfig"}));const F=P;if(g==="project"){if(!p)throw new Error(s({id:"codexlens.mcp.installError"}));await $("codexlens",F,p)}else await G("codexlens",F);E({ok:!0,msg:s({id:"codexlens.mcp.installSuccess"})})}catch(v){E({ok:!1,msg:v.message})}finally{a(!1)}},k=!!(l!=null&&l.values.CODEXLENS_EMBED_API_URL),R=k?"API":"Local fastembed",m=n?JSON.stringify(n,null,2):"",f=()=>{navigator.clipboard.writeText(m).then(()=>{u(!0),setTimeout(()=>u(!1),2e3)})},d=()=>{o()};return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[s({id:"codexlens.mcp.embedMode"}),":"]}),e.jsx(w,{variant:k?"success":"secondary",children:R})]}),e.jsxs(_,{children:[e.jsx(O,{className:"pb-3",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(L,{className:"text-base",children:s({id:"codexlens.mcp.configTitle"})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(h,{variant:"outline",size:"sm",onClick:f,disabled:!m||t,children:[x?e.jsx(V,{className:"w-4 h-4 mr-1"}):e.jsx(Z,{className:"w-4 h-4 mr-1"}),s(x?{id:"codexlens.mcp.copied"}:{id:"codexlens.mcp.copy"})]}),e.jsxs(h,{variant:"outline",size:"sm",onClick:d,disabled:t,children:[e.jsx(Y,{className:`w-4 h-4 mr-1 ${t?"animate-spin":""}`}),s({id:"codexlens.mcp.regenerate"})]})]})]})}),e.jsxs(S,{children:[t&&e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"codexlens.mcp.loading"})}),i&&e.jsx("p",{className:"text-sm text-destructive",children:s({id:"codexlens.mcp.error"})}),!t&&!i&&e.jsx("pre",{className:"bg-muted rounded-md p-4 text-xs overflow-auto max-h-96 font-mono",children:m||s({id:"codexlens.mcp.noConfig"})})]})]}),e.jsxs(_,{children:[e.jsxs(O,{className:"pb-3",children:[e.jsx(L,{className:"text-base",children:s({id:"codexlens.mcp.quickInstallTitle"})}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:s({id:"codexlens.mcp.quickInstallDesc"})})]}),e.jsxs(S,{className:"space-y-3",children:[e.jsxs("div",{className:"flex gap-2 flex-wrap",children:[e.jsxs(h,{variant:"outline",size:"sm",onClick:()=>D("project"),disabled:r||!p,children:[r?e.jsx(y,{className:"w-4 h-4 mr-1 animate-spin"}):e.jsx(T,{className:"w-4 h-4 mr-1"}),s(r?{id:"codexlens.mcp.installing"}:{id:"codexlens.mcp.installProject"})]}),e.jsxs(h,{variant:"outline",size:"sm",onClick:()=>D("global"),disabled:r,children:[r?e.jsx(y,{className:"w-4 h-4 mr-1 animate-spin"}):e.jsx(T,{className:"w-4 h-4 mr-1"}),s(r?{id:"codexlens.mcp.installing"}:{id:"codexlens.mcp.installGlobal"})]})]}),c&&e.jsx("p",{className:`text-sm ${c.ok?"text-success":"text-destructive"}`,children:c.msg})]})]}),e.jsxs(_,{children:[e.jsx(O,{className:"pb-3",children:e.jsx(L,{className:"text-base",children:s({id:"codexlens.mcp.installTitle"})})}),e.jsx(S,{children:e.jsxs("ol",{className:"list-decimal list-inside space-y-2 text-sm text-muted-foreground",children:[e.jsx("li",{children:s({id:"codexlens.mcp.installSteps.step1"})}),e.jsx("li",{children:s({id:"codexlens.mcp.installSteps.step2"})}),e.jsx("li",{children:s({id:"codexlens.mcp.installSteps.step3"})}),e.jsx("li",{children:s({id:"codexlens.mcp.installSteps.step4"})}),e.jsx("li",{children:s({id:"codexlens.mcp.installSteps.step5"})})]})})]})]})}function he(){const{formatMessage:s}=C(),{data:n,isLoading:t,isError:i}=de(),{data:o}=K(),{downloadModel:l,isDownloading:x}=ce(),{deleteModel:u,isDeleting:r}=oe(),a=!!(o!=null&&o.values.CODEXLENS_EMBED_API_URL),c=a?"API":"Local fastembed",E=n??[];return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 p-3 rounded-md bg-muted text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:[s({id:"codexlens.models.embedMode"}),":"]}),e.jsx(w,{variant:a?"success":"secondary",children:c})]}),t&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground p-4",children:[e.jsx(y,{className:"w-4 h-4 animate-spin"}),s({id:"codexlens.models.loading"})]}),i&&e.jsx("p",{className:"text-sm text-destructive p-4",children:s({id:"codexlens.models.error"})}),!t&&!i&&E.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:s({id:"codexlens.models.noModels"})}),!t&&!i&&E.length>0&&e.jsx(_,{children:e.jsx(S,{className:"p-0",children:e.jsx("div",{className:"divide-y divide-border",children:E.map(p=>e.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-sm font-medium",children:p.name}),e.jsx(w,{variant:p.installed?"success":"secondary",children:p.installed?s({id:"codexlens.models.installed"}):s({id:"codexlens.models.notInstalled"})})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(h,{variant:"outline",size:"sm",onClick:()=>l(p.name),disabled:x,children:[x?e.jsx(y,{className:"w-4 h-4 animate-spin"}):e.jsx(T,{className:"w-4 h-4"}),e.jsx("span",{className:"ml-1",children:s({id:"codexlens.models.download"})})]}),e.jsxs(h,{variant:"outline",size:"sm",onClick:()=>u(p.name),disabled:!p.installed||r,children:[r?e.jsx(y,{className:"w-4 h-4 animate-spin"}):e.jsx(J,{className:"w-4 h-4"}),e.jsx("span",{className:"ml-1",children:s({id:"codexlens.models.delete"})})]})]})]},p.name))})})})]})}function Ne({projectPath:s}){const{formatMessage:n}=C(),t=A(),{data:i,isLoading:o,isError:l}=re(s),{syncIndex:x,isSyncing:u}=me(),{rebuildIndex:r,isRebuilding:a}=xe(),c=i,E=()=>{t.invalidateQueries({queryKey:N.indexStatus(s)})};return e.jsxs(_,{children:[e.jsx(O,{className:"pb-3",children:e.jsx(L,{className:"text-sm font-medium truncate",children:s})}),e.jsxs(S,{className:"space-y-4",children:[o&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(y,{className:"w-4 h-4 animate-spin"}),n({id:"codexlens.index.loading"})]}),l&&e.jsx("p",{className:"text-sm text-destructive",children:n({id:"codexlens.index.error"})}),!o&&!l&&c&&e.jsxs("div",{className:"grid grid-cols-3 gap-3",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"text-lg font-semibold",children:c.files_tracked??0}),e.jsx("p",{className:"text-xs text-muted-foreground",children:n({id:"codexlens.index.filesTracked"})})]}),e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"text-lg font-semibold",children:c.total_chunks??0}),e.jsx("p",{className:"text-xs text-muted-foreground",children:n({id:"codexlens.index.totalChunks"})})]}),e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"text-lg font-semibold",children:c.deleted_chunks??0}),e.jsx("p",{className:"text-xs text-muted-foreground",children:n({id:"codexlens.index.deletedChunks"})})]})]}),e.jsxs("div",{className:"flex gap-2 flex-wrap",children:[e.jsxs(h,{variant:"outline",size:"sm",onClick:()=>x(s),disabled:u,children:[u?e.jsx(y,{className:"w-4 h-4 animate-spin mr-1"}):null,n({id:"codexlens.index.sync"})]}),e.jsxs(h,{variant:"outline",size:"sm",onClick:()=>r(s),disabled:a,children:[a?e.jsx(y,{className:"w-4 h-4 animate-spin mr-1"}):null,n({id:"codexlens.index.rebuild"})]}),e.jsxs(h,{variant:"outline",size:"sm",onClick:E,children:[e.jsx(Y,{className:"w-4 h-4 mr-1"}),n({id:"codexlens.index.refresh"})]})]})]})]})}function fe(){const{formatMessage:s}=C(),n=z(W),[t,i]=j.useState([]),[o,l]=j.useState("");j.useEffect(()=>{n&&i(a=>a.includes(n)?a:[n,...a])},[n]);const x=()=>{const a=o.trim();a&&!t.includes(a)&&i(c=>[...c,a]),l("")},u=a=>{i(c=>c.filter(E=>E!==a))},r=a=>{a.key==="Enter"&&x()};return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(X,{placeholder:s({id:"codexlens.index.pathPlaceholder"}),value:o,onChange:a=>l(a.target.value),onKeyDown:r,className:"flex-1"}),e.jsxs(h,{onClick:x,disabled:!o.trim(),children:[e.jsx(ee,{className:"w-4 h-4 mr-1"}),s({id:"codexlens.index.add"})]})]}),t.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:s({id:"codexlens.index.empty"})}),t.map(a=>e.jsxs("div",{className:"relative",children:[e.jsx(h,{variant:"ghost",size:"sm",className:"absolute top-2 right-2 z-10 h-7 w-7 p-0",onClick:()=>u(a),title:s({id:"codexlens.index.removeProject"}),children:e.jsx(J,{className:"w-4 h-4 text-muted-foreground"})}),e.jsx(Ne,{projectPath:a})]},a))]})}const Q=[{title:"embed",fields:[{key:"CODEXLENS_EMBED_API_URL",label:"Embed API URL"},{key:"CODEXLENS_EMBED_API_KEY",label:"Embed API Key",sensitive:!0},{key:"CODEXLENS_EMBED_API_MODEL",label:"Embed API Model"},{key:"CODEXLENS_EMBED_DIM",label:"Embed Dimension"},{key:"CODEXLENS_EMBED_API_ENDPOINTS",label:"Embed API Endpoints",sensitive:!0},{key:"CODEXLENS_EMBED_BATCH_SIZE",label:"Embed Batch Size"},{key:"CODEXLENS_EMBED_API_CONCURRENCY",label:"Embed API Concurrency"}]},{title:"reranker",fields:[{key:"CODEXLENS_RERANKER_API_URL",label:"Reranker API URL"},{key:"CODEXLENS_RERANKER_API_KEY",label:"Reranker API Key",sensitive:!0},{key:"CODEXLENS_RERANKER_API_MODEL",label:"Reranker API Model"}]},{title:"performance",fields:[{key:"CODEXLENS_BINARY_TOP_K",label:"Binary Top K"},{key:"CODEXLENS_ANN_TOP_K",label:"ANN Top K"},{key:"CODEXLENS_FTS_TOP_K",label:"FTS Top K"},{key:"CODEXLENS_FUSION_K",label:"Fusion K"},{key:"CODEXLENS_RERANKER_TOP_K",label:"Reranker Top K"},{key:"CODEXLENS_RERANKER_BATCH_SIZE",label:"Reranker Batch Size"}]},{title:"index",fields:[{key:"CODEXLENS_DB_PATH",label:"DB Path"},{key:"CODEXLENS_INDEX_WORKERS",label:"Index Workers"},{key:"CODEXLENS_CODE_AWARE_CHUNKING",label:"Code Aware Chunking"},{key:"CODEXLENS_MAX_FILE_SIZE",label:"Max File Size"},{key:"CODEXLENS_HNSW_EF",label:"HNSW EF"},{key:"CODEXLENS_HNSW_M",label:"HNSW M"}]}],je=new Set(["CODEXLENS_EMBED_API_URL","CODEXLENS_EMBED_API_KEY","CODEXLENS_EMBED_API_ENDPOINTS","CODEXLENS_EMBED_API_CONCURRENCY"]),q={CODEXLENS_EMBED_API_MODEL:"text-embedding-3-small",CODEXLENS_EMBED_DIM:"1536",CODEXLENS_EMBED_BATCH_SIZE:"64",CODEXLENS_EMBED_API_CONCURRENCY:"4",CODEXLENS_BINARY_TOP_K:"200",CODEXLENS_ANN_TOP_K:"50",CODEXLENS_FTS_TOP_K:"50",CODEXLENS_FUSION_K:"60",CODEXLENS_RERANKER_TOP_K:"20",CODEXLENS_RERANKER_BATCH_SIZE:"32",CODEXLENS_INDEX_WORKERS:"2",CODEXLENS_CODE_AWARE_CHUNKING:"true",CODEXLENS_MAX_FILE_SIZE:"1000000",CODEXLENS_HNSW_EF:"150",CODEXLENS_HNSW_M:"32"},B=Q.flatMap(s=>s.fields.map(n=>n.key));function U(){return Object.fromEntries(B.map(s=>[s,""]))}function H(s,n){return Object.fromEntries(B.map(t=>[t,s[t]??n[t]??""]))}function ge({value:s,onChange:n,id:t}){const[i,o]=j.useState(!1);return e.jsxs("div",{className:"relative",children:[e.jsx(X,{id:t,type:i?"text":"password",value:s,onChange:l=>n(l.target.value),className:"pr-10"}),e.jsx("button",{type:"button",className:"absolute inset-y-0 right-2 flex items-center text-muted-foreground hover:text-foreground",onClick:()=>o(l=>!l),tabIndex:-1,children:i?e.jsx(le,{className:"w-4 h-4"}):e.jsx(ie,{className:"w-4 h-4"})})]})}function be(){const{formatMessage:s}=C(),{data:n,isLoading:t}=K(),{saveEnv:i,isSaving:o}=ue(),[l,x]=j.useState("local"),[u,r]=j.useState(U),a=(n==null?void 0:n.values)??{},c={...q,...(n==null?void 0:n.defaults)??{}},E=H(a,c);j.useEffect(()=>{if(n){const m={...q,...n.defaults??{}},f=n.values??{};r(H(f,m)),f.CODEXLENS_EMBED_API_URL&&x("api")}},[n]);const p=B.some(m=>u[m]!==(E[m]??"")),D=(m,f)=>{r(d=>({...d,[m]:f}))},k=async()=>{const m=Object.fromEntries(Object.entries(u).flatMap(([f,d])=>{const g=d.trim(),v=c[f]??"";return!g||g===v?[]:[[f,g]]}));await i(m)},R=()=>{r(U())};return t?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:s({id:"codexlens.env.loading"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"text-sm font-medium",children:[s({id:"codexlens.env.mode"}),":"]}),e.jsxs("div",{className:"flex rounded-md border border-border overflow-hidden",children:[e.jsx("button",{type:"button",onClick:()=>x("local"),className:`px-3 py-1.5 text-sm transition-colors ${l==="local"?"bg-primary text-primary-foreground":"bg-background text-muted-foreground hover:bg-muted"}`,children:s({id:"codexlens.env.localMode"})}),e.jsx("button",{type:"button",onClick:()=>x("api"),className:`px-3 py-1.5 text-sm transition-colors ${l==="api"?"bg-primary text-primary-foreground":"bg-background text-muted-foreground hover:bg-muted"}`,children:s({id:"codexlens.env.apiMode"})})]}),e.jsx("span",{className:"text-xs text-muted-foreground",children:s(l==="local"?{id:"codexlens.env.localModeDesc"}:{id:"codexlens.env.apiModeDesc"})})]}),Q.map(m=>{const f=l==="local"?m.fields.filter(d=>!je.has(d.key)):m.fields;return f.length===0?null:e.jsxs(_,{children:[e.jsx(O,{className:"pb-3",children:e.jsx(L,{className:"text-base",children:s({id:`codexlens.env.sections.${m.title}`})})}),e.jsx(S,{className:"space-y-3",children:f.map(d=>e.jsxs("div",{className:"grid grid-cols-3 gap-3 items-center",children:[e.jsx("label",{htmlFor:d.key,className:"text-sm text-muted-foreground col-span-1",children:d.label}),e.jsx("div",{className:"col-span-2",children:d.sensitive?e.jsx(ge,{id:d.key,value:u[d.key]??"",onChange:g=>D(d.key,g)}):e.jsx(X,{id:d.key,value:u[d.key]??"",placeholder:c[d.key]??"",onChange:g=>D(d.key,g.target.value)})})]},d.key))})]},m.title)}),e.jsxs("div",{className:"flex justify-between pt-2",children:[e.jsxs(h,{variant:"outline",onClick:R,children:[e.jsx(se,{className:"w-4 h-4 mr-2"}),s({id:"codexlens.env.clearForm"})]}),e.jsxs(h,{onClick:k,disabled:!p||o,children:[e.jsx(ae,{className:"w-4 h-4 mr-2"}),s(o?{id:"codexlens.env.saving"}:{id:"codexlens.env.save"})]})]})]})}function De(){const{formatMessage:s}=C(),[n,t]=j.useState("mcp");return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold text-foreground flex items-center gap-2",children:[e.jsx(ne,{className:"w-6 h-6 text-primary"}),s({id:"codexlens.page.title"})]}),e.jsx("p",{className:"text-muted-foreground mt-1",children:s({id:"codexlens.page.description"})})]}),e.jsx(te,{value:n,onValueChange:i=>t(i),tabs:[{value:"mcp",label:s({id:"codexlens.tabs.mcp"})},{value:"models",label:s({id:"codexlens.tabs.models"})},{value:"index",label:s({id:"codexlens.tabs.index"})},{value:"env",label:s({id:"codexlens.tabs.env"})}]}),e.jsxs("div",{className:"mt-4",children:[n==="mcp"&&e.jsx(pe,{}),n==="models"&&e.jsx(he,{}),n==="index"&&e.jsx(fe,{}),n==="env"&&e.jsx(be,{})]})]})}export{De as CodexLensPage,De as default};
2
- //# sourceMappingURL=CodexLensPage-My6DnfN6.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CodexLensPage-My6DnfN6.js","sources":["../../src/hooks/useCodexLens.ts","../../src/components/codexlens/McpConfigTab.tsx","../../src/components/codexlens/ModelManagerTab.tsx","../../src/components/codexlens/IndexManagerTab.tsx","../../src/components/codexlens/EnvSettingsTab.tsx","../../src/pages/CodexLensPage.tsx"],"sourcesContent":["// ========================================\n// useCodexLens Hook\n// ========================================\n// TanStack Query hooks for CodexLens v2 API management\n\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { fetchApi } from '@/lib/api';\n\n// ========================================\n// Domain types (exported for component use)\n// ========================================\n\nexport interface ModelEntry {\n name: string;\n installed: boolean;\n type?: string;\n cache_path?: string;\n}\n\nexport interface IndexStatusData {\n status?: string;\n files_tracked?: number;\n total_chunks?: number;\n deleted_chunks?: number;\n db_path?: string;\n}\n\nexport type McpConfigData = Record<string, unknown>;\nexport interface CodexLensEnvData {\n values: Record<string, string>;\n defaults: Record<string, string>;\n}\n\n// Internal API response wrappers\ninterface ModelsResponse { success: boolean; models: ModelEntry[] }\ninterface IndexStatusResponse { success: boolean; status: IndexStatusData }\ninterface EnvResponse {\n success: boolean;\n env: Record<string, string>;\n defaults?: Record<string, string>;\n}\ninterface McpConfigResponse { success: boolean; config: McpConfigData }\n\n// ========================================\n// Query Key Factory\n// ========================================\n\nexport const codexLensKeys = {\n all: ['codexLens'] as const,\n models: () => [...codexLensKeys.all, 'models'] as const,\n indexStatus: (path: string) => [...codexLensKeys.all, 'indexStatus', path] as const,\n env: () => [...codexLensKeys.all, 'env'] as const,\n mcpConfig: () => [...codexLensKeys.all, 'mcpConfig'] as const,\n};\n\n// ========================================\n// Models Hooks\n// ========================================\n\nexport function useCodexLensModels() {\n return useQuery({\n queryKey: codexLensKeys.models(),\n queryFn: () => fetchApi<ModelsResponse>('/api/codexlens/models').then(r => r.models),\n staleTime: 30_000,\n });\n}\n\nexport function useDownloadModel() {\n const queryClient = useQueryClient();\n\n const mutation = useMutation({\n mutationFn: (modelName: string) =>\n fetchApi<{ success: boolean }>('/api/codexlens/models/download', {\n method: 'POST',\n body: JSON.stringify({ name: modelName }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: codexLensKeys.models() });\n },\n });\n\n return {\n downloadModel: mutation.mutateAsync,\n isDownloading: mutation.isPending,\n error: mutation.error,\n };\n}\n\nexport function useDeleteModel() {\n const queryClient = useQueryClient();\n\n const mutation = useMutation({\n mutationFn: (modelName: string) =>\n fetchApi<{ success: boolean }>('/api/codexlens/models/delete', {\n method: 'POST',\n body: JSON.stringify({ name: modelName }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: codexLensKeys.models() });\n },\n });\n\n return {\n deleteModel: mutation.mutateAsync,\n isDeleting: mutation.isPending,\n error: mutation.error,\n };\n}\n\n// ========================================\n// Index Hooks\n// ========================================\n\nexport function useIndexStatus(projectPath: string) {\n return useQuery({\n queryKey: codexLensKeys.indexStatus(projectPath),\n queryFn: () =>\n fetchApi<IndexStatusResponse>(\n `/api/codexlens/index/status?projectPath=${encodeURIComponent(projectPath)}`\n ).then(r => r.status),\n enabled: !!projectPath,\n staleTime: 10_000,\n });\n}\n\nexport function useSyncIndex() {\n const mutation = useMutation({\n mutationFn: (projectPath: string) =>\n fetchApi<{ success: boolean }>('/api/codexlens/index/sync', {\n method: 'POST',\n body: JSON.stringify({ projectPath }),\n }),\n });\n\n return {\n syncIndex: mutation.mutateAsync,\n isSyncing: mutation.isPending,\n error: mutation.error,\n };\n}\n\nexport function useRebuildIndex() {\n const mutation = useMutation({\n mutationFn: (projectPath: string) =>\n fetchApi<{ success: boolean }>('/api/codexlens/index/rebuild', {\n method: 'POST',\n body: JSON.stringify({ projectPath }),\n }),\n });\n\n return {\n rebuildIndex: mutation.mutateAsync,\n isRebuilding: mutation.isPending,\n error: mutation.error,\n };\n}\n\n// ========================================\n// Env Hooks\n// ========================================\n\nexport function useCodexLensEnv() {\n return useQuery({\n queryKey: codexLensKeys.env(),\n queryFn: () =>\n fetchApi<EnvResponse>('/api/codexlens/env').then((r): CodexLensEnvData => ({\n values: r.env ?? {},\n defaults: r.defaults ?? {},\n })),\n staleTime: 60_000,\n });\n}\n\nexport function useSaveCodexLensEnv() {\n const queryClient = useQueryClient();\n\n const mutation = useMutation({\n mutationFn: (env: Record<string, string>) =>\n fetchApi<{ success: boolean }>('/api/codexlens/env', {\n method: 'POST',\n body: JSON.stringify({ env }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: codexLensKeys.env() });\n queryClient.invalidateQueries({ queryKey: codexLensKeys.mcpConfig() });\n },\n });\n\n return {\n saveEnv: mutation.mutateAsync,\n isSaving: mutation.isPending,\n error: mutation.error,\n };\n}\n\n// ========================================\n// MCP Config Hooks\n// ========================================\n\nexport function useCodexLensMcpConfig() {\n return useQuery({\n queryKey: codexLensKeys.mcpConfig(),\n queryFn: () => fetchApi<McpConfigResponse>('/api/codexlens/mcp-config').then(r => r.config),\n staleTime: 30_000,\n });\n}\n","// ========================================\r\n// McpConfigTab Component\r\n// ========================================\r\n// Read-only MCP config JSON display with copy-to-clipboard and regenerate\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Copy, RefreshCw, Check, Download, Loader2 } from 'lucide-react';\nimport { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';\nimport { Button } from '@/components/ui/Button';\nimport { Badge } from '@/components/ui/Badge';\nimport { useCodexLensMcpConfig, useCodexLensEnv } from '@/hooks/useCodexLens';\nimport { addGlobalMcpServer, copyMcpServerToProject } from '@/lib/api';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\n\r\nexport function McpConfigTab() {\r\n const { formatMessage } = useIntl();\r\n const { data: mcpConfig, isLoading, isError, refetch } = useCodexLensMcpConfig();\r\n const { data: envData } = useCodexLensEnv();\r\n const [copied, setCopied] = useState(false);\r\n const [installing, setInstalling] = useState(false);\r\n const [installResult, setInstallResult] = useState<{ ok: boolean; msg: string } | null>(null);\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const handleInstall = async (scope: 'global' | 'project') => {\n setInstalling(true);\n setInstallResult(null);\n try {\n const mcpServers = mcpConfig?.['mcpServers'];\n const serverConfig = mcpServers && typeof mcpServers === 'object'\n ? (mcpServers as Record<string, unknown>).codexlens\n : undefined;\n\n if (!serverConfig || typeof serverConfig !== 'object') {\n throw new Error(formatMessage({ id: 'codexlens.mcp.noConfig' }));\n }\n\n const typedConfig = serverConfig as {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n type?: string;\n };\n\n if (scope === 'project') {\n if (!projectPath) {\n throw new Error(formatMessage({ id: 'codexlens.mcp.installError' }));\n }\n await copyMcpServerToProject('codexlens', typedConfig, projectPath);\n } else {\n await addGlobalMcpServer('codexlens', typedConfig);\n }\n\n setInstallResult({\n ok: true,\n msg: formatMessage({ id: 'codexlens.mcp.installSuccess' }),\n });\n } catch (err) {\n setInstallResult({ ok: false, msg: (err as Error).message });\n } finally {\n setInstalling(false);\n }\n };\n\n const hasApiUrl = !!(envData?.values.CODEXLENS_EMBED_API_URL);\n const embedMode = hasApiUrl ? 'API' : 'Local fastembed';\r\n\r\n const configJson = mcpConfig ? JSON.stringify(mcpConfig, null, 2) : '';\r\n\r\n const handleCopy = () => {\r\n navigator.clipboard.writeText(configJson).then(() => {\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 2000);\r\n });\r\n };\r\n\r\n const handleRegenerate = () => {\r\n refetch();\r\n };\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Embed mode badge */}\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm text-muted-foreground\">{formatMessage({ id: 'codexlens.mcp.embedMode' })}:</span>\r\n <Badge variant={hasApiUrl ? 'success' : 'secondary'}>\r\n {embedMode}\r\n </Badge>\r\n </div>\r\n\r\n {/* Config JSON block */}\r\n <Card>\r\n <CardHeader className=\"pb-3\">\r\n <div className=\"flex items-center justify-between\">\r\n <CardTitle className=\"text-base\">{formatMessage({ id: 'codexlens.mcp.configTitle' })}</CardTitle>\r\n <div className=\"flex gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleCopy}\r\n disabled={!configJson || isLoading}\r\n >\r\n {copied ? <Check className=\"w-4 h-4 mr-1\" /> : <Copy className=\"w-4 h-4 mr-1\" />}\r\n {copied ? formatMessage({ id: 'codexlens.mcp.copied' }) : formatMessage({ id: 'codexlens.mcp.copy' })}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleRegenerate}\r\n disabled={isLoading}\r\n >\r\n <RefreshCw className={`w-4 h-4 mr-1 ${isLoading ? 'animate-spin' : ''}`} />\r\n {formatMessage({ id: 'codexlens.mcp.regenerate' })}\r\n </Button>\r\n </div>\r\n </div>\r\n </CardHeader>\r\n <CardContent>\r\n {isLoading && (\r\n <p className=\"text-sm text-muted-foreground\">{formatMessage({ id: 'codexlens.mcp.loading' })}</p>\r\n )}\r\n {isError && (\r\n <p className=\"text-sm text-destructive\">{formatMessage({ id: 'codexlens.mcp.error' })}</p>\r\n )}\r\n {!isLoading && !isError && (\r\n <pre className=\"bg-muted rounded-md p-4 text-xs overflow-auto max-h-96 font-mono\">\r\n {configJson || formatMessage({ id: 'codexlens.mcp.noConfig' })}\r\n </pre>\r\n )}\r\n </CardContent>\r\n </Card>\r\n\r\n {/* Quick Install */}\r\n <Card>\r\n <CardHeader className=\"pb-3\">\r\n <CardTitle className=\"text-base\">{formatMessage({ id: 'codexlens.mcp.quickInstallTitle' })}</CardTitle>\r\n <p className=\"text-xs text-muted-foreground mt-1\">{formatMessage({ id: 'codexlens.mcp.quickInstallDesc' })}</p>\r\n </CardHeader>\r\n <CardContent className=\"space-y-3\">\r\n <div className=\"flex gap-2 flex-wrap\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => handleInstall('project')}\r\n disabled={installing || !projectPath}\r\n >\r\n {installing ? <Loader2 className=\"w-4 h-4 mr-1 animate-spin\" /> : <Download className=\"w-4 h-4 mr-1\" />}\r\n {installing ? formatMessage({ id: 'codexlens.mcp.installing' }) : formatMessage({ id: 'codexlens.mcp.installProject' })}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => handleInstall('global')}\r\n disabled={installing}\r\n >\r\n {installing ? <Loader2 className=\"w-4 h-4 mr-1 animate-spin\" /> : <Download className=\"w-4 h-4 mr-1\" />}\r\n {installing ? formatMessage({ id: 'codexlens.mcp.installing' }) : formatMessage({ id: 'codexlens.mcp.installGlobal' })}\r\n </Button>\r\n </div>\r\n {installResult && (\r\n <p className={`text-sm ${installResult.ok ? 'text-success' : 'text-destructive'}`}>\r\n {installResult.msg}\r\n </p>\r\n )}\r\n </CardContent>\r\n </Card>\r\n\r\n {/* Installation instructions */}\r\n <Card>\r\n <CardHeader className=\"pb-3\">\r\n <CardTitle className=\"text-base\">{formatMessage({ id: 'codexlens.mcp.installTitle' })}</CardTitle>\r\n </CardHeader>\r\n <CardContent>\r\n <ol className=\"list-decimal list-inside space-y-2 text-sm text-muted-foreground\">\r\n <li>{formatMessage({ id: 'codexlens.mcp.installSteps.step1' })}</li>\r\n <li>{formatMessage({ id: 'codexlens.mcp.installSteps.step2' })}</li>\r\n <li>{formatMessage({ id: 'codexlens.mcp.installSteps.step3' })}</li>\r\n <li>{formatMessage({ id: 'codexlens.mcp.installSteps.step4' })}</li>\r\n <li>{formatMessage({ id: 'codexlens.mcp.installSteps.step5' })}</li>\r\n </ol>\r\n </CardContent>\r\n </Card>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// ModelManagerTab Component\r\n// ========================================\r\n// Model list with download/delete actions and embed mode banner\r\n\r\nimport { useIntl } from 'react-intl';\r\nimport { Download, Trash2, Loader2 } from 'lucide-react';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n useCodexLensModels,\r\n useDownloadModel,\r\n useDeleteModel,\r\n useCodexLensEnv,\r\n type ModelEntry,\r\n} from '@/hooks/useCodexLens';\r\n\r\nexport function ModelManagerTab() {\r\n const { formatMessage } = useIntl();\r\n const { data: modelsData, isLoading, isError } = useCodexLensModels();\r\n const { data: envData } = useCodexLensEnv();\r\n const { downloadModel, isDownloading } = useDownloadModel();\r\n const { deleteModel, isDeleting } = useDeleteModel();\r\n\r\n const hasApiUrl = !!(envData?.values.CODEXLENS_EMBED_API_URL);\n const embedMode = hasApiUrl ? 'API' : 'Local fastembed';\r\n\r\n const models: ModelEntry[] = modelsData ?? [];\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Embed mode banner */}\r\n <div className=\"flex items-center gap-2 p-3 rounded-md bg-muted text-sm\">\r\n <span className=\"text-muted-foreground\">{formatMessage({ id: 'codexlens.models.embedMode' })}:</span>\r\n <Badge variant={hasApiUrl ? 'success' : 'secondary'}>{embedMode}</Badge>\r\n </div>\r\n\r\n {/* Loading / Error states */}\r\n {isLoading && (\r\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground p-4\">\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n {formatMessage({ id: 'codexlens.models.loading' })}\r\n </div>\r\n )}\r\n\r\n {isError && (\r\n <p className=\"text-sm text-destructive p-4\">{formatMessage({ id: 'codexlens.models.error' })}</p>\r\n )}\r\n\r\n {/* Model list */}\r\n {!isLoading && !isError && models.length === 0 && (\r\n <p className=\"text-sm text-muted-foreground p-4\">{formatMessage({ id: 'codexlens.models.noModels' })}</p>\r\n )}\r\n\r\n {!isLoading && !isError && models.length > 0 && (\r\n <Card>\r\n <CardContent className=\"p-0\">\r\n <div className=\"divide-y divide-border\">\r\n {models.map((model) => (\r\n <div\r\n key={model.name}\r\n className=\"flex items-center justify-between px-4 py-3\"\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <span className=\"text-sm font-medium\">{model.name}</span>\r\n <Badge variant={model.installed ? 'success' : 'secondary'}>\r\n {model.installed\r\n ? formatMessage({ id: 'codexlens.models.installed' })\r\n : formatMessage({ id: 'codexlens.models.notInstalled' })}\r\n </Badge>\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => downloadModel(model.name)}\r\n disabled={isDownloading}\r\n >\r\n {isDownloading ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Download className=\"w-4 h-4\" />\r\n )}\r\n <span className=\"ml-1\">{formatMessage({ id: 'codexlens.models.download' })}</span>\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => deleteModel(model.name)}\r\n disabled={!model.installed || isDeleting}\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 <span className=\"ml-1\">{formatMessage({ id: 'codexlens.models.delete' })}</span>\r\n </Button>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n </CardContent>\r\n </Card>\r\n )}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// IndexManagerTab Component\r\n// ========================================\r\n// Project path input, index status display, and sync/rebuild actions\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Plus, Trash2, RefreshCw, Loader2 } from 'lucide-react';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { useIndexStatus, useSyncIndex, useRebuildIndex, codexLensKeys, type IndexStatusData } from '@/hooks/useCodexLens';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\ninterface ProjectStatusCardProps {\r\n projectPath: string;\r\n}\r\n\r\nfunction ProjectStatusCard({ projectPath }: ProjectStatusCardProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n const { data: statusData, isLoading, isError } = useIndexStatus(projectPath);\r\n const { syncIndex, isSyncing } = useSyncIndex();\r\n const { rebuildIndex, isRebuilding } = useRebuildIndex();\r\n\r\n const status: IndexStatusData | undefined = statusData;\r\n\r\n const handleRefresh = () => {\r\n queryClient.invalidateQueries({ queryKey: codexLensKeys.indexStatus(projectPath) });\r\n };\r\n\r\n return (\r\n <Card>\r\n <CardHeader className=\"pb-3\">\r\n <CardTitle className=\"text-sm font-medium truncate\">{projectPath}</CardTitle>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n {/* Status stats */}\r\n {isLoading && (\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 {formatMessage({ id: 'codexlens.index.loading' })}\r\n </div>\r\n )}\r\n {isError && (\r\n <p className=\"text-sm text-destructive\">{formatMessage({ id: 'codexlens.index.error' })}</p>\r\n )}\r\n {!isLoading && !isError && status && (\r\n <div className=\"grid grid-cols-3 gap-3\">\r\n <div className=\"text-center\">\r\n <p className=\"text-lg font-semibold\">{status.files_tracked ?? 0}</p>\r\n <p className=\"text-xs text-muted-foreground\">{formatMessage({ id: 'codexlens.index.filesTracked' })}</p>\r\n </div>\r\n <div className=\"text-center\">\r\n <p className=\"text-lg font-semibold\">{status.total_chunks ?? 0}</p>\r\n <p className=\"text-xs text-muted-foreground\">{formatMessage({ id: 'codexlens.index.totalChunks' })}</p>\r\n </div>\r\n <div className=\"text-center\">\r\n <p className=\"text-lg font-semibold\">{status.deleted_chunks ?? 0}</p>\r\n <p className=\"text-xs text-muted-foreground\">{formatMessage({ id: 'codexlens.index.deletedChunks' })}</p>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Action buttons */}\r\n <div className=\"flex gap-2 flex-wrap\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => syncIndex(projectPath)}\r\n disabled={isSyncing}\r\n >\r\n {isSyncing ? <Loader2 className=\"w-4 h-4 animate-spin mr-1\" /> : null}\r\n {formatMessage({ id: 'codexlens.index.sync' })}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => rebuildIndex(projectPath)}\r\n disabled={isRebuilding}\r\n >\r\n {isRebuilding ? <Loader2 className=\"w-4 h-4 animate-spin mr-1\" /> : null}\r\n {formatMessage({ id: 'codexlens.index.rebuild' })}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleRefresh}\r\n >\r\n <RefreshCw className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'codexlens.index.refresh' })}\r\n </Button>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\nexport function IndexManagerTab() {\r\n const { formatMessage } = useIntl();\r\n const currentWorkspacePath = useWorkflowStore(selectProjectPath);\r\n const [paths, setPaths] = useState<string[]>([]);\r\n const [inputValue, setInputValue] = useState('');\r\n\r\n // Auto-add current workspace path on mount and when workspace changes\r\n useEffect(() => {\r\n if (currentWorkspacePath) {\r\n setPaths((prev) => {\r\n if (prev.includes(currentWorkspacePath)) return prev;\r\n return [currentWorkspacePath, ...prev];\r\n });\r\n }\r\n }, [currentWorkspacePath]);\r\n\r\n const handleAdd = () => {\r\n const trimmed = inputValue.trim();\r\n if (trimmed && !paths.includes(trimmed)) {\r\n setPaths((prev) => [...prev, trimmed]);\r\n }\r\n setInputValue('');\r\n };\r\n\r\n const handleRemove = (path: string) => {\r\n setPaths((prev) => prev.filter((p) => p !== path));\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (e.key === 'Enter') {\r\n handleAdd();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Add project path */}\r\n <div className=\"flex gap-2\">\r\n <Input\r\n placeholder={formatMessage({ id: 'codexlens.index.pathPlaceholder' })}\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n className=\"flex-1\"\r\n />\r\n <Button onClick={handleAdd} disabled={!inputValue.trim()}>\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'codexlens.index.add' })}\r\n </Button>\r\n </div>\r\n\r\n {paths.length === 0 && (\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'codexlens.index.empty' })}\r\n </p>\r\n )}\r\n\r\n {/* Project status cards */}\r\n {paths.map((path) => (\r\n <div key={path} className=\"relative\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"absolute top-2 right-2 z-10 h-7 w-7 p-0\"\r\n onClick={() => handleRemove(path)}\r\n title={formatMessage({ id: 'codexlens.index.removeProject' })}\r\n >\r\n <Trash2 className=\"w-4 h-4 text-muted-foreground\" />\r\n </Button>\r\n <ProjectStatusCard projectPath={path} />\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// EnvSettingsTab Component\r\n// ========================================\r\n// Grouped env var form with save/reset actions\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Eye, EyeOff, Save, RotateCcw } from 'lucide-react';\r\nimport { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { useCodexLensEnv, useSaveCodexLensEnv } from '@/hooks/useCodexLens';\r\n\r\ntype EmbedMode = 'local' | 'api';\r\n\r\n// ========================================\r\n// ENV group definitions\r\n// ========================================\r\n\r\ninterface EnvField {\r\n key: string;\r\n label: string;\r\n sensitive?: boolean;\r\n}\r\n\r\ninterface EnvGroup {\r\n title: string;\r\n fields: EnvField[];\r\n}\r\n\r\nconst ENV_GROUPS: EnvGroup[] = [\r\n {\r\n title: 'embed',\r\n fields: [\r\n { key: 'CODEXLENS_EMBED_API_URL', label: 'Embed API URL' },\r\n { key: 'CODEXLENS_EMBED_API_KEY', label: 'Embed API Key', sensitive: true },\r\n { key: 'CODEXLENS_EMBED_API_MODEL', label: 'Embed API Model' },\r\n { key: 'CODEXLENS_EMBED_DIM', label: 'Embed Dimension' },\r\n { key: 'CODEXLENS_EMBED_API_ENDPOINTS', label: 'Embed API Endpoints', sensitive: true },\r\n { key: 'CODEXLENS_EMBED_BATCH_SIZE', label: 'Embed Batch Size' },\r\n { key: 'CODEXLENS_EMBED_API_CONCURRENCY', label: 'Embed API Concurrency' },\r\n ],\r\n },\r\n {\r\n title: 'reranker',\r\n fields: [\r\n { key: 'CODEXLENS_RERANKER_API_URL', label: 'Reranker API URL' },\r\n { key: 'CODEXLENS_RERANKER_API_KEY', label: 'Reranker API Key', sensitive: true },\r\n { key: 'CODEXLENS_RERANKER_API_MODEL', label: 'Reranker API Model' },\r\n ],\r\n },\r\n {\r\n title: 'performance',\r\n fields: [\r\n { key: 'CODEXLENS_BINARY_TOP_K', label: 'Binary Top K' },\r\n { key: 'CODEXLENS_ANN_TOP_K', label: 'ANN Top K' },\r\n { key: 'CODEXLENS_FTS_TOP_K', label: 'FTS Top K' },\r\n { key: 'CODEXLENS_FUSION_K', label: 'Fusion K' },\r\n { key: 'CODEXLENS_RERANKER_TOP_K', label: 'Reranker Top K' },\r\n { key: 'CODEXLENS_RERANKER_BATCH_SIZE', label: 'Reranker Batch Size' },\r\n ],\r\n },\r\n {\r\n title: 'index',\r\n fields: [\r\n { key: 'CODEXLENS_DB_PATH', label: 'DB Path' },\r\n { key: 'CODEXLENS_INDEX_WORKERS', label: 'Index Workers' },\r\n { key: 'CODEXLENS_CODE_AWARE_CHUNKING', label: 'Code Aware Chunking' },\r\n { key: 'CODEXLENS_MAX_FILE_SIZE', label: 'Max File Size' },\r\n { key: 'CODEXLENS_HNSW_EF', label: 'HNSW EF' },\r\n { key: 'CODEXLENS_HNSW_M', label: 'HNSW M' },\r\n ],\r\n },\r\n];\r\n\r\n// Fields that are only relevant in API mode\r\nconst API_ONLY_KEYS = new Set([\r\n 'CODEXLENS_EMBED_API_URL',\r\n 'CODEXLENS_EMBED_API_KEY',\r\n 'CODEXLENS_EMBED_API_ENDPOINTS',\r\n 'CODEXLENS_EMBED_API_CONCURRENCY',\r\n]);\r\n\r\n// Default placeholder values\r\nconst FIELD_DEFAULTS: Record<string, string> = {\n CODEXLENS_EMBED_API_MODEL: 'text-embedding-3-small',\n CODEXLENS_EMBED_DIM: '1536',\n CODEXLENS_EMBED_BATCH_SIZE: '64',\n CODEXLENS_EMBED_API_CONCURRENCY: '4',\n CODEXLENS_BINARY_TOP_K: '200',\n CODEXLENS_ANN_TOP_K: '50',\n CODEXLENS_FTS_TOP_K: '50',\n CODEXLENS_FUSION_K: '60',\n CODEXLENS_RERANKER_TOP_K: '20',\n CODEXLENS_RERANKER_BATCH_SIZE: '32',\n CODEXLENS_INDEX_WORKERS: '2',\n CODEXLENS_CODE_AWARE_CHUNKING: 'true',\n CODEXLENS_MAX_FILE_SIZE: '1000000',\n CODEXLENS_HNSW_EF: '150',\n CODEXLENS_HNSW_M: '32',\n};\n\r\n// Collect all keys\r\nconst ALL_KEYS = ENV_GROUPS.flatMap((g) => g.fields.map((f) => f.key));\r\n\r\nfunction buildEmptyEnv(): Record<string, string> {\n return Object.fromEntries(ALL_KEYS.map((k) => [k, '']));\n}\n\nfunction buildEffectiveEnv(\n values: Record<string, string>,\n defaults: Record<string, string>,\n): Record<string, string> {\n return Object.fromEntries(\n ALL_KEYS.map((key) => [key, values[key] ?? defaults[key] ?? '']),\n );\n}\n\r\n// ========================================\r\n// Sensitive field with show/hide toggle\r\n// ========================================\r\n\r\ninterface SensitiveInputProps {\r\n value: string;\r\n onChange: (v: string) => void;\r\n id: string;\r\n}\r\n\r\nfunction SensitiveInput({ value, onChange, id }: SensitiveInputProps) {\r\n const [show, setShow] = useState(false);\r\n return (\r\n <div className=\"relative\">\r\n <Input\r\n id={id}\r\n type={show ? 'text' : 'password'}\r\n value={value}\r\n onChange={(e) => onChange(e.target.value)}\r\n className=\"pr-10\"\r\n />\r\n <button\r\n type=\"button\"\r\n className=\"absolute inset-y-0 right-2 flex items-center text-muted-foreground hover:text-foreground\"\r\n onClick={() => setShow((s) => !s)}\r\n tabIndex={-1}\r\n >\r\n {show ? <EyeOff className=\"w-4 h-4\" /> : <Eye className=\"w-4 h-4\" />}\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\n// ========================================\r\n// Main component\r\n// ========================================\r\n\r\nexport function EnvSettingsTab() {\n const { formatMessage } = useIntl();\n const { data: envData, isLoading } = useCodexLensEnv();\n const { saveEnv, isSaving } = useSaveCodexLensEnv();\n\n const [embedMode, setEmbedMode] = useState<EmbedMode>('local');\n const [localEnv, setLocalEnv] = useState<Record<string, string>>(buildEmptyEnv);\n\n const serverValues = envData?.values ?? {};\n const serverDefaults = { ...FIELD_DEFAULTS, ...(envData?.defaults ?? {}) };\n const serverRecord = buildEffectiveEnv(serverValues, serverDefaults);\n\n // Sync server state into local when loaded and detect embed mode\n useEffect(() => {\n if (envData) {\n const nextDefaults = { ...FIELD_DEFAULTS, ...(envData.defaults ?? {}) };\n const nextValues = envData.values ?? {};\n setLocalEnv(buildEffectiveEnv(nextValues, nextDefaults));\n // Auto-detect mode from saved env\n if (nextValues.CODEXLENS_EMBED_API_URL) {\n setEmbedMode('api');\n }\n }\n }, [envData]);\n\n const isDirty = ALL_KEYS.some((k) => localEnv[k] !== (serverRecord[k] ?? ''));\n\r\n const handleChange = (key: string, value: string) => {\r\n setLocalEnv((prev) => ({ ...prev, [key]: value }));\r\n };\n\n const handleSave = async () => {\n const payload = Object.fromEntries(\n Object.entries(localEnv).flatMap(([key, value]) => {\n const trimmed = value.trim();\n const defaultValue = serverDefaults[key] ?? '';\n if (!trimmed || trimmed === defaultValue) {\n return [];\n }\n return [[key, trimmed]];\n }),\n );\n await saveEnv(payload);\n };\n\r\n const handleReset = () => {\r\n setLocalEnv(buildEmptyEnv());\r\n };\r\n\r\n if (isLoading) {\r\n return <p className=\"text-sm text-muted-foreground p-4\">{formatMessage({ id: 'codexlens.env.loading' })}</p>;\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Mode toggle */}\r\n <div className=\"flex items-center gap-3\">\r\n <span className=\"text-sm font-medium\">{formatMessage({ id: 'codexlens.env.mode' })}:</span>\r\n <div className=\"flex rounded-md border border-border overflow-hidden\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setEmbedMode('local')}\r\n className={`px-3 py-1.5 text-sm transition-colors ${\r\n embedMode === 'local'\r\n ? 'bg-primary text-primary-foreground'\r\n : 'bg-background text-muted-foreground hover:bg-muted'\r\n }`}\r\n >\r\n {formatMessage({ id: 'codexlens.env.localMode' })}\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={() => setEmbedMode('api')}\r\n className={`px-3 py-1.5 text-sm transition-colors ${\r\n embedMode === 'api'\r\n ? 'bg-primary text-primary-foreground'\r\n : 'bg-background text-muted-foreground hover:bg-muted'\r\n }`}\r\n >\r\n {formatMessage({ id: 'codexlens.env.apiMode' })}\r\n </button>\r\n </div>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {embedMode === 'local'\r\n ? formatMessage({ id: 'codexlens.env.localModeDesc' })\r\n : formatMessage({ id: 'codexlens.env.apiModeDesc' })}\r\n </span>\r\n </div>\r\n\r\n {ENV_GROUPS.map((group) => {\r\n // In local mode, filter out API-only fields from embed group\r\n const visibleFields = embedMode === 'local'\r\n ? group.fields.filter((f) => !API_ONLY_KEYS.has(f.key))\r\n : group.fields;\r\n if (visibleFields.length === 0) return null;\r\n return (\r\n <Card key={group.title}>\r\n <CardHeader className=\"pb-3\">\r\n <CardTitle className=\"text-base\">{formatMessage({ id: `codexlens.env.sections.${group.title}` })}</CardTitle>\r\n </CardHeader>\r\n <CardContent className=\"space-y-3\">\r\n {visibleFields.map((field) => (\r\n <div key={field.key} className=\"grid grid-cols-3 gap-3 items-center\">\r\n <label\r\n htmlFor={field.key}\r\n className=\"text-sm text-muted-foreground col-span-1\"\r\n >\r\n {field.label}\r\n </label>\r\n <div className=\"col-span-2\">\r\n {field.sensitive ? (\r\n <SensitiveInput\r\n id={field.key}\r\n value={localEnv[field.key] ?? ''}\r\n onChange={(v) => handleChange(field.key, v)}\r\n />\r\n ) : (\r\n <Input\n id={field.key}\n value={localEnv[field.key] ?? ''}\n placeholder={serverDefaults[field.key] ?? ''}\n onChange={(e) => handleChange(field.key, e.target.value)}\n />\n )}\n </div>\r\n </div>\r\n ))}\r\n </CardContent>\r\n </Card>\r\n );\r\n })}\r\n\r\n {/* Action buttons */}\r\n <div className=\"flex justify-between pt-2\">\r\n <Button variant=\"outline\" onClick={handleReset}>\r\n <RotateCcw className=\"w-4 h-4 mr-2\" />\r\n {formatMessage({ id: 'codexlens.env.clearForm' })}\r\n </Button>\r\n <Button onClick={handleSave} disabled={!isDirty || isSaving}>\r\n <Save className=\"w-4 h-4 mr-2\" />\r\n {isSaving ? formatMessage({ id: 'codexlens.env.saving' }) : formatMessage({ id: 'codexlens.env.save' })}\r\n </Button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// ========================================\r\n// CodexLens Page\r\n// ========================================\r\n// Main page for CodexLens v2 management: MCP config, models, index, env\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Search } from 'lucide-react';\r\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\r\nimport { McpConfigTab } from '@/components/codexlens/McpConfigTab';\r\nimport { ModelManagerTab } from '@/components/codexlens/ModelManagerTab';\r\nimport { IndexManagerTab } from '@/components/codexlens/IndexManagerTab';\r\nimport { EnvSettingsTab } from '@/components/codexlens/EnvSettingsTab';\r\n\r\ntype TabType = 'mcp' | 'models' | 'index' | 'env';\r\n\r\nexport function CodexLensPage() {\r\n const { formatMessage } = useIntl();\r\n const [activeTab, setActiveTab] = useState<TabType>('mcp');\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Page Header */}\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-foreground flex items-center gap-2\">\r\n <Search className=\"w-6 h-6 text-primary\" />\r\n {formatMessage({ id: 'codexlens.page.title' })}\r\n </h1>\r\n <p className=\"text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'codexlens.page.description' })}\r\n </p>\r\n </div>\r\n\r\n {/* Tab Navigation */}\r\n <TabsNavigation\r\n value={activeTab}\r\n onValueChange={(v) => setActiveTab(v as TabType)}\r\n tabs={[\r\n { value: 'mcp', label: formatMessage({ id: 'codexlens.tabs.mcp' }) },\r\n { value: 'models', label: formatMessage({ id: 'codexlens.tabs.models' }) },\r\n { value: 'index', label: formatMessage({ id: 'codexlens.tabs.index' }) },\r\n { value: 'env', label: formatMessage({ id: 'codexlens.tabs.env' }) },\r\n ]}\r\n />\r\n\r\n {/* Tab Content */}\r\n <div className=\"mt-4\">\r\n {activeTab === 'mcp' && <McpConfigTab />}\r\n {activeTab === 'models' && <ModelManagerTab />}\r\n {activeTab === 'index' && <IndexManagerTab />}\r\n {activeTab === 'env' && <EnvSettingsTab />}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default CodexLensPage;\r\n"],"names":["codexLensKeys","path","useCodexLensModels","useQuery","fetchApi","r","useDownloadModel","queryClient","useQueryClient","mutation","useMutation","modelName","useDeleteModel","useIndexStatus","projectPath","useSyncIndex","useRebuildIndex","useCodexLensEnv","useSaveCodexLensEnv","env","useCodexLensMcpConfig","McpConfigTab","formatMessage","useIntl","mcpConfig","isLoading","isError","refetch","envData","copied","setCopied","useState","installing","setInstalling","installResult","setInstallResult","useWorkflowStore","selectProjectPath","handleInstall","scope","mcpServers","serverConfig","typedConfig","copyMcpServerToProject","addGlobalMcpServer","err","hasApiUrl","embedMode","configJson","handleCopy","handleRegenerate","jsxs","Badge","Card","jsx","CardHeader","CardTitle","Button","Check","Copy","RefreshCw","CardContent","Loader2","Download","ModelManagerTab","modelsData","downloadModel","isDownloading","deleteModel","isDeleting","models","model","Trash2","ProjectStatusCard","statusData","syncIndex","isSyncing","rebuildIndex","isRebuilding","status","handleRefresh","IndexManagerTab","currentWorkspacePath","paths","setPaths","inputValue","setInputValue","useEffect","prev","handleAdd","trimmed","handleRemove","p","handleKeyDown","e","Input","Plus","ENV_GROUPS","API_ONLY_KEYS","FIELD_DEFAULTS","ALL_KEYS","g","f","buildEmptyEnv","k","buildEffectiveEnv","values","defaults","key","SensitiveInput","value","onChange","id","show","setShow","s","EyeOff","Eye","EnvSettingsTab","saveEnv","isSaving","setEmbedMode","localEnv","setLocalEnv","serverValues","serverDefaults","serverRecord","nextDefaults","nextValues","isDirty","handleChange","handleSave","payload","defaultValue","handleReset","group","visibleFields","field","v","RotateCcw","Save","CodexLensPage","activeTab","setActiveTab","Search","TabsNavigation"],"mappings":"4ZA+CO,MAAMA,EAAgB,CAC3B,IAAK,CAAC,WAAW,EACjB,OAAQ,IAAM,CAAC,GAAGA,EAAc,IAAK,QAAQ,EAC7C,YAAcC,GAAiB,CAAC,GAAGD,EAAc,IAAK,cAAeC,CAAI,EACzE,IAAK,IAAM,CAAC,GAAGD,EAAc,IAAK,KAAK,EACvC,UAAW,IAAM,CAAC,GAAGA,EAAc,IAAK,WAAW,CACrD,EAMO,SAASE,IAAqB,CACnC,OAAOC,EAAS,CACd,SAAUH,EAAc,OAAA,EACxB,QAAS,IAAMI,EAAyB,uBAAuB,EAAE,KAAKC,GAAKA,EAAE,MAAM,EACnF,UAAW,GAAA,CACZ,CACH,CAEO,SAASC,IAAmB,CACjC,MAAMC,EAAcC,EAAA,EAEdC,EAAWC,EAAY,CAC3B,WAAaC,GACXP,EAA+B,iCAAkC,CAC/D,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,KAAMO,EAAW,CAAA,CACzC,EACH,UAAW,IAAM,CACfJ,EAAY,kBAAkB,CAAE,SAAUP,EAAc,OAAA,EAAU,CACpE,CAAA,CACD,EAED,MAAO,CACL,cAAeS,EAAS,YACxB,cAAeA,EAAS,UACxB,MAAOA,EAAS,KAAA,CAEpB,CAEO,SAASG,IAAiB,CAC/B,MAAML,EAAcC,EAAA,EAEdC,EAAWC,EAAY,CAC3B,WAAaC,GACXP,EAA+B,+BAAgC,CAC7D,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,KAAMO,EAAW,CAAA,CACzC,EACH,UAAW,IAAM,CACfJ,EAAY,kBAAkB,CAAE,SAAUP,EAAc,OAAA,EAAU,CACpE,CAAA,CACD,EAED,MAAO,CACL,YAAaS,EAAS,YACtB,WAAYA,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAMO,SAASI,GAAeC,EAAqB,CAClD,OAAOX,EAAS,CACd,SAAUH,EAAc,YAAYc,CAAW,EAC/C,QAAS,IACPV,EACE,2CAA2C,mBAAmBU,CAAW,CAAC,EAAA,EAC1E,KAAKT,GAAKA,EAAE,MAAM,EACtB,QAAS,CAAC,CAACS,EACX,UAAW,GAAA,CACZ,CACH,CAEO,SAASC,IAAe,CAC7B,MAAMN,EAAWC,EAAY,CAC3B,WAAaI,GACXV,EAA+B,4BAA6B,CAC1D,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,YAAAU,EAAa,CAAA,CACrC,CAAA,CACJ,EAED,MAAO,CACL,UAAWL,EAAS,YACpB,UAAWA,EAAS,UACpB,MAAOA,EAAS,KAAA,CAEpB,CAEO,SAASO,IAAkB,CAChC,MAAMP,EAAWC,EAAY,CAC3B,WAAaI,GACXV,EAA+B,+BAAgC,CAC7D,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,YAAAU,EAAa,CAAA,CACrC,CAAA,CACJ,EAED,MAAO,CACL,aAAcL,EAAS,YACvB,aAAcA,EAAS,UACvB,MAAOA,EAAS,KAAA,CAEpB,CAMO,SAASQ,GAAkB,CAChC,OAAOd,EAAS,CACd,SAAUH,EAAc,IAAA,EACxB,QAAS,IACPI,EAAsB,oBAAoB,EAAE,KAAMC,IAAyB,CACzE,OAAQA,EAAE,KAAO,CAAA,EACjB,SAAUA,EAAE,UAAY,CAAA,CAAC,EACzB,EACJ,UAAW,GAAA,CACZ,CACH,CAEO,SAASa,IAAsB,CACpC,MAAMX,EAAcC,EAAA,EAEdC,EAAWC,EAAY,CAC3B,WAAaS,GACXf,EAA+B,qBAAsB,CACnD,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,IAAAe,EAAK,CAAA,CAC7B,EACH,UAAW,IAAM,CACfZ,EAAY,kBAAkB,CAAE,SAAUP,EAAc,IAAA,EAAO,EAC/DO,EAAY,kBAAkB,CAAE,SAAUP,EAAc,UAAA,EAAa,CACvE,CAAA,CACD,EAED,MAAO,CACL,QAASS,EAAS,YAClB,SAAUA,EAAS,UACnB,MAAOA,EAAS,KAAA,CAEpB,CAMO,SAASW,IAAwB,CACtC,OAAOjB,EAAS,CACd,SAAUH,EAAc,UAAA,EACxB,QAAS,IAAMI,EAA4B,2BAA2B,EAAE,KAAKC,GAAKA,EAAE,MAAM,EAC1F,UAAW,GAAA,CACZ,CACH,CC9LO,SAASgB,IAAe,CAC7B,KAAM,CAAE,cAAAC,CAAA,EAAkBC,EAAA,EACpB,CAAE,KAAMC,EAAW,UAAAC,EAAW,QAAAC,EAAS,QAAAC,CAAA,EAAYP,GAAA,EACnD,CAAE,KAAMQ,CAAA,EAAYX,EAAA,EACpB,CAACY,EAAQC,CAAS,EAAIC,EAAAA,SAAS,EAAK,EACpC,CAACC,EAAYC,CAAa,EAAIF,EAAAA,SAAS,EAAK,EAC5C,CAACG,EAAeC,CAAgB,EAAIJ,EAAAA,SAA8C,IAAI,EACtFjB,EAAcsB,EAAiBC,CAAiB,EAEhDC,EAAgB,MAAOC,GAAgC,CAC3DN,EAAc,EAAI,EAClBE,EAAiB,IAAI,EACrB,GAAI,CACF,MAAMK,EAAahB,GAAA,YAAAA,EAAY,WACzBiB,EAAeD,GAAc,OAAOA,GAAe,SACpDA,EAAuC,UACxC,OAEJ,GAAI,CAACC,GAAgB,OAAOA,GAAiB,SAC3C,MAAM,IAAI,MAAMnB,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAC,EAGjE,MAAMoB,EAAcD,EAOpB,GAAIF,IAAU,UAAW,CACvB,GAAI,CAACzB,EACH,MAAM,IAAI,MAAMQ,EAAc,CAAE,GAAI,4BAAA,CAA8B,CAAC,EAErE,MAAMqB,EAAuB,YAAaD,EAAa5B,CAAW,CACpE,MACE,MAAM8B,EAAmB,YAAaF,CAAW,EAGnDP,EAAiB,CACf,GAAI,GACJ,IAAKb,EAAc,CAAE,GAAI,+BAAgC,CAAA,CAC1D,CACH,OAASuB,EAAK,CACZV,EAAiB,CAAE,GAAI,GAAO,IAAMU,EAAc,QAAS,CAC7D,QAAA,CACEZ,EAAc,EAAK,CACrB,CACF,EAEMa,EAAY,CAAC,EAAElB,GAAA,MAAAA,EAAS,OAAO,yBAC/BmB,EAAYD,EAAY,MAAQ,kBAEhCE,EAAaxB,EAAY,KAAK,UAAUA,EAAW,KAAM,CAAC,EAAI,GAE9DyB,EAAa,IAAM,CACvB,UAAU,UAAU,UAAUD,CAAU,EAAE,KAAK,IAAM,CACnDlB,EAAU,EAAI,EACd,WAAW,IAAMA,EAAU,EAAK,EAAG,GAAI,CACzC,CAAC,CACH,EAEMoB,EAAmB,IAAM,CAC7BvB,EAAA,CACF,EAEA,OACEwB,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,gCAAiC,SAAA,CAAA7B,EAAc,CAAE,GAAI,0BAA2B,EAAE,GAAA,EAAC,QAClG8B,EAAA,CAAM,QAASN,EAAY,UAAY,YACrC,SAAAC,CAAA,CACH,CAAA,EACF,SAGCM,EAAA,CACC,SAAA,CAAAC,EAAAA,IAACC,GAAW,UAAU,OACpB,SAAAJ,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAG,EAAAA,IAACE,EAAA,CAAU,UAAU,YAAa,SAAAlC,EAAc,CAAE,GAAI,2BAAA,CAA6B,EAAE,EACrF6B,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASR,EACT,SAAU,CAACD,GAAcvB,EAExB,SAAA,CAAAI,EAASyB,EAAAA,IAACI,GAAM,UAAU,cAAA,CAAe,EAAKJ,EAAAA,IAACK,EAAA,CAAK,UAAU,cAAA,CAAe,EACpErC,EAATO,EAAuB,CAAE,GAAI,sBAAA,EAA0C,CAAE,GAAI,oBAAA,CAAxB,CAA8C,CAAA,CAAA,EAEtGsB,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASP,EACT,SAAUzB,EAEV,SAAA,CAAA6B,MAACM,GAAU,UAAW,gBAAgBnC,EAAY,eAAiB,EAAE,GAAI,EACxEH,EAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CAAA,CAAA,CACnD,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,SACCuC,EAAA,CACE,SAAA,CAAApC,GACC6B,EAAAA,IAAC,KAAE,UAAU,gCAAiC,WAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAE,EAE9F5B,GACC4B,EAAAA,IAAC,IAAA,CAAE,UAAU,2BAA4B,WAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAAE,EAEvF,CAAC7B,GAAa,CAACC,SACb,MAAA,CAAI,UAAU,mEACZ,SAAAsB,GAAc1B,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CAC/D,CAAA,CAAA,CAEJ,CAAA,EACF,SAGC+B,EAAA,CACC,SAAA,CAAAF,EAAAA,KAACI,EAAA,CAAW,UAAU,OACpB,SAAA,CAAAD,EAAAA,IAACE,EAAA,CAAU,UAAU,YAAa,SAAAlC,EAAc,CAAE,GAAI,iCAAA,CAAmC,EAAE,EAC3FgC,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,gCAAA,CAAkC,CAAA,CAAE,CAAA,EAC7G,EACAH,EAAAA,KAACU,EAAA,CAAY,UAAU,YACrB,SAAA,CAAAV,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACb,SAAA,CAAAA,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMnB,EAAc,SAAS,EACtC,SAAUN,GAAc,CAAClB,EAExB,SAAA,CAAAkB,EAAasB,EAAAA,IAACQ,GAAQ,UAAU,2BAAA,CAA4B,EAAKR,EAAAA,IAACS,EAAA,CAAS,UAAU,cAAA,CAAe,EACvFzC,EAAbU,EAA2B,CAAE,GAAI,0BAAA,EAA8C,CAAE,GAAI,8BAAA,CAAxB,CAAwD,CAAA,CAAA,EAExHmB,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMnB,EAAc,QAAQ,EACrC,SAAUN,EAET,SAAA,CAAAA,EAAasB,EAAAA,IAACQ,GAAQ,UAAU,2BAAA,CAA4B,EAAKR,EAAAA,IAACS,EAAA,CAAS,UAAU,cAAA,CAAe,EACvFzC,EAAbU,EAA2B,CAAE,GAAI,0BAAA,EAA8C,CAAE,GAAI,6BAAA,CAAxB,CAAuD,CAAA,CAAA,CACvH,EACF,EACCE,GACCoB,EAAAA,IAAC,IAAA,CAAE,UAAW,WAAWpB,EAAc,GAAK,eAAiB,kBAAkB,GAC5E,SAAAA,EAAc,GAAA,CACjB,CAAA,CAAA,CAEJ,CAAA,EACF,SAGCmB,EAAA,CACC,SAAA,CAAAC,EAAAA,IAACC,EAAA,CAAW,UAAU,OACpB,SAAAD,EAAAA,IAACE,EAAA,CAAU,UAAU,YAAa,SAAAlC,EAAc,CAAE,GAAI,4BAAA,CAA8B,EAAE,EACxF,EACAgC,MAACO,EAAA,CACC,SAAAV,EAAAA,KAAC,KAAA,CAAG,UAAU,mEACZ,SAAA,CAAAG,MAAC,MAAI,SAAAhC,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAAE,QAC9D,KAAA,CAAI,SAAAA,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAAE,QAC9D,KAAA,CAAI,SAAAA,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAAE,QAC9D,KAAA,CAAI,SAAAA,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAAE,QAC9D,KAAA,CAAI,SAAAA,EAAc,CAAE,GAAI,kCAAA,CAAoC,CAAA,CAAE,CAAA,CAAA,CACjE,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,CAEJ,CCtKO,SAAS0C,IAAkB,CAChC,KAAM,CAAE,cAAA1C,CAAA,EAAkBC,EAAA,EACpB,CAAE,KAAM0C,EAAY,UAAAxC,EAAW,QAAAC,CAAA,EAAYxB,GAAA,EAC3C,CAAE,KAAM0B,CAAA,EAAYX,EAAA,EACpB,CAAE,cAAAiD,EAAe,cAAAC,CAAA,EAAkB7D,GAAA,EACnC,CAAE,YAAA8D,EAAa,WAAAC,CAAA,EAAezD,GAAA,EAE9BkC,EAAY,CAAC,EAAElB,GAAA,MAAAA,EAAS,OAAO,yBAC/BmB,EAAYD,EAAY,MAAQ,kBAEhCwB,EAAuBL,GAAc,CAAA,EAE3C,OACEd,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,wBAAyB,SAAA,CAAA7B,EAAc,CAAE,GAAI,6BAA8B,EAAE,GAAA,EAAC,QAC7F8B,EAAA,CAAM,QAASN,EAAY,UAAY,YAAc,SAAAC,CAAA,CAAU,CAAA,EAClE,EAGCtB,GACC0B,EAAAA,KAAC,MAAA,CAAI,UAAU,4DACb,SAAA,CAAAG,EAAAA,IAACQ,EAAA,CAAQ,UAAU,sBAAA,CAAuB,EACzCxC,EAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,EACnD,EAGDI,GACC4B,EAAAA,IAAC,IAAA,CAAE,UAAU,+BAAgC,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CAAE,EAI9F,CAAC7B,GAAa,CAACC,GAAW4C,EAAO,SAAW,GAC3ChB,EAAAA,IAAC,IAAA,CAAE,UAAU,oCAAqC,SAAAhC,EAAc,CAAE,GAAI,2BAAA,CAA6B,EAAE,EAGtG,CAACG,GAAa,CAACC,GAAW4C,EAAO,OAAS,SACxCjB,EAAA,CACC,SAAAC,EAAAA,IAACO,GAAY,UAAU,MACrB,eAAC,MAAA,CAAI,UAAU,yBACZ,SAAAS,EAAO,IAAKC,GACXpB,EAAAA,KAAC,MAAA,CAEC,UAAU,8CAEV,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAG,EAAAA,IAAC,OAAA,CAAK,UAAU,sBAAuB,SAAAiB,EAAM,KAAK,EAClDjB,MAACF,GAAM,QAASmB,EAAM,UAAY,UAAY,YAC3C,WAAM,UACHjD,EAAc,CAAE,GAAI,4BAAA,CAA8B,EAClDA,EAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CAC3D,CAAA,EACF,EACA6B,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMS,EAAcK,EAAM,IAAI,EACvC,SAAUJ,EAET,SAAA,CAAAA,EACCb,EAAAA,IAACQ,GAAQ,UAAU,sBAAA,CAAuB,EAE1CR,EAAAA,IAACS,EAAA,CAAS,UAAU,SAAA,CAAU,EAEhCT,MAAC,QAAK,UAAU,OAAQ,WAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAE,CAAA,CAAA,CAAA,EAE7EH,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMW,EAAYG,EAAM,IAAI,EACrC,SAAU,CAACA,EAAM,WAAaF,EAE7B,SAAA,CAAAA,EACCf,EAAAA,IAACQ,GAAQ,UAAU,sBAAA,CAAuB,EAE1CR,EAAAA,IAACkB,EAAA,CAAO,UAAU,SAAA,CAAU,EAE9BlB,MAAC,QAAK,UAAU,OAAQ,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAE,CAAA,CAAA,CAAA,CAC3E,CAAA,CACF,CAAA,CAAA,EAtCKiB,EAAM,IAAA,CAwCd,CAAA,CACH,CAAA,CACF,CAAA,CACF,CAAA,EAEJ,CAEJ,CCzFA,SAASE,GAAkB,CAAE,YAAA3D,GAAuC,CAClE,KAAM,CAAE,cAAAQ,CAAA,EAAkBC,EAAA,EACpBhB,EAAcC,EAAA,EACd,CAAE,KAAMkE,EAAY,UAAAjD,EAAW,QAAAC,CAAA,EAAYb,GAAeC,CAAW,EACrE,CAAE,UAAA6D,EAAW,UAAAC,CAAA,EAAc7D,GAAA,EAC3B,CAAE,aAAA8D,EAAc,aAAAC,CAAA,EAAiB9D,GAAA,EAEjC+D,EAAsCL,EAEtCM,EAAgB,IAAM,CAC1BzE,EAAY,kBAAkB,CAAE,SAAUP,EAAc,YAAYc,CAAW,EAAG,CACpF,EAEA,cACGuC,EAAA,CACC,SAAA,CAAAC,EAAAA,IAACC,EAAA,CAAW,UAAU,OACpB,SAAAD,EAAAA,IAACE,GAAU,UAAU,+BAAgC,WAAY,CAAA,CACnE,EACAL,EAAAA,KAACU,EAAA,CAAY,UAAU,YAEpB,SAAA,CAAApC,GACC0B,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAAG,EAAAA,IAACQ,EAAA,CAAQ,UAAU,sBAAA,CAAuB,EACzCxC,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,EAClD,EAEDI,GACC4B,EAAAA,IAAC,IAAA,CAAE,UAAU,2BAA4B,WAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAE,EAEzF,CAAC7B,GAAa,CAACC,GAAWqD,GACzB5B,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,cACb,SAAA,CAAAG,MAAC,IAAA,CAAE,UAAU,wBAAyB,SAAAyB,EAAO,eAAiB,EAAE,EAChEzB,MAAC,KAAE,UAAU,gCAAiC,WAAc,CAAE,GAAI,8BAAA,CAAgC,CAAA,CAAE,CAAA,EACtG,EACAH,EAAAA,KAAC,MAAA,CAAI,UAAU,cACb,SAAA,CAAAG,MAAC,IAAA,CAAE,UAAU,wBAAyB,SAAAyB,EAAO,cAAgB,EAAE,EAC/DzB,MAAC,KAAE,UAAU,gCAAiC,WAAc,CAAE,GAAI,6BAAA,CAA+B,CAAA,CAAE,CAAA,EACrG,EACAH,EAAAA,KAAC,MAAA,CAAI,UAAU,cACb,SAAA,CAAAG,MAAC,IAAA,CAAE,UAAU,wBAAyB,SAAAyB,EAAO,gBAAkB,EAAE,EACjEzB,MAAC,KAAE,UAAU,gCAAiC,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CAAE,CAAA,CAAA,CACvG,CAAA,EACF,EAIFH,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACb,SAAA,CAAAA,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMkB,EAAU7D,CAAW,EACpC,SAAU8D,EAET,SAAA,CAAAA,EAAYtB,EAAAA,IAACQ,EAAA,CAAQ,UAAU,2BAAA,CAA4B,EAAK,KAChExC,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAAA,CAAA,EAE/C6B,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMoB,EAAa/D,CAAW,EACvC,SAAUgE,EAET,SAAA,CAAAA,EAAexB,EAAAA,IAACQ,EAAA,CAAQ,UAAU,2BAAA,CAA4B,EAAK,KACnExC,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,CAAA,EAElD6B,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASuB,EAET,SAAA,CAAA1B,EAAAA,IAACM,EAAA,CAAU,UAAU,cAAA,CAAe,EACnCtC,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,CAAA,CAClD,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,CAEJ,CAEO,SAAS2D,IAAkB,CAChC,KAAM,CAAE,cAAA3D,CAAA,EAAkBC,EAAA,EACpB2D,EAAuB9C,EAAiBC,CAAiB,EACzD,CAAC8C,EAAOC,CAAQ,EAAIrD,EAAAA,SAAmB,CAAA,CAAE,EACzC,CAACsD,EAAYC,CAAa,EAAIvD,EAAAA,SAAS,EAAE,EAG/CwD,EAAAA,UAAU,IAAM,CACVL,GACFE,EAAUI,GACJA,EAAK,SAASN,CAAoB,EAAUM,EACzC,CAACN,EAAsB,GAAGM,CAAI,CACtC,CAEL,EAAG,CAACN,CAAoB,CAAC,EAEzB,MAAMO,EAAY,IAAM,CACtB,MAAMC,EAAUL,EAAW,KAAA,EACvBK,GAAW,CAACP,EAAM,SAASO,CAAO,GACpCN,EAAUI,GAAS,CAAC,GAAGA,EAAME,CAAO,CAAC,EAEvCJ,EAAc,EAAE,CAClB,EAEMK,EAAgB1F,GAAiB,CACrCmF,EAAUI,GAASA,EAAK,OAAQI,GAAMA,IAAM3F,CAAI,CAAC,CACnD,EAEM4F,EAAiBC,GAA6C,CAC9DA,EAAE,MAAQ,SACZL,EAAA,CAEJ,EAEA,OACEtC,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAG,EAAAA,IAACyC,EAAA,CACC,YAAazE,EAAc,CAAE,GAAI,kCAAmC,EACpE,MAAO+D,EACP,SAAWS,GAAMR,EAAcQ,EAAE,OAAO,KAAK,EAC7C,UAAWD,EACX,UAAU,QAAA,CAAA,EAEZ1C,OAACM,GAAO,QAASgC,EAAW,SAAU,CAACJ,EAAW,OAChD,SAAA,CAAA/B,EAAAA,IAAC0C,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B1E,EAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAAA,CAC9C,CAAA,EACF,EAEC6D,EAAM,SAAW,GAChB7B,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAhC,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAChD,EAID6D,EAAM,IAAKlF,GACVkD,EAAAA,KAAC,MAAA,CAAe,UAAU,WACxB,SAAA,CAAAG,EAAAA,IAACG,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,0CACV,QAAS,IAAMkC,EAAa1F,CAAI,EAChC,MAAOqB,EAAc,CAAE,GAAI,gCAAiC,EAE5D,SAAAgC,EAAAA,IAACkB,EAAA,CAAO,UAAU,+BAAA,CAAgC,CAAA,CAAA,EAEpDlB,EAAAA,IAACmB,GAAA,CAAkB,YAAaxE,CAAA,CAAM,CAAA,CAAA,EAV9BA,CAWV,CACD,CAAA,EACH,CAEJ,CC/IA,MAAMgG,EAAyB,CAC7B,CACE,MAAO,QACP,OAAQ,CACN,CAAE,IAAK,0BAA2B,MAAO,eAAA,EACzC,CAAE,IAAK,0BAA2B,MAAO,gBAAiB,UAAW,EAAA,EACrE,CAAE,IAAK,4BAA6B,MAAO,iBAAA,EAC3C,CAAE,IAAK,sBAAuB,MAAO,iBAAA,EACrC,CAAE,IAAK,gCAAiC,MAAO,sBAAuB,UAAW,EAAA,EACjF,CAAE,IAAK,6BAA8B,MAAO,kBAAA,EAC5C,CAAE,IAAK,kCAAmC,MAAO,uBAAA,CAAwB,CAC3E,EAEF,CACE,MAAO,WACP,OAAQ,CACN,CAAE,IAAK,6BAA8B,MAAO,kBAAA,EAC5C,CAAE,IAAK,6BAA8B,MAAO,mBAAoB,UAAW,EAAA,EAC3E,CAAE,IAAK,+BAAgC,MAAO,oBAAA,CAAqB,CACrE,EAEF,CACE,MAAO,cACP,OAAQ,CACN,CAAE,IAAK,yBAA0B,MAAO,cAAA,EACxC,CAAE,IAAK,sBAAuB,MAAO,WAAA,EACrC,CAAE,IAAK,sBAAuB,MAAO,WAAA,EACrC,CAAE,IAAK,qBAAsB,MAAO,UAAA,EACpC,CAAE,IAAK,2BAA4B,MAAO,gBAAA,EAC1C,CAAE,IAAK,gCAAiC,MAAO,qBAAA,CAAsB,CACvE,EAEF,CACE,MAAO,QACP,OAAQ,CACN,CAAE,IAAK,oBAAqB,MAAO,SAAA,EACnC,CAAE,IAAK,0BAA2B,MAAO,eAAA,EACzC,CAAE,IAAK,gCAAiC,MAAO,qBAAA,EAC/C,CAAE,IAAK,0BAA2B,MAAO,eAAA,EACzC,CAAE,IAAK,oBAAqB,MAAO,SAAA,EACnC,CAAE,IAAK,mBAAoB,MAAO,QAAA,CAAS,CAC7C,CAEJ,EAGMC,OAAoB,IAAI,CAC5B,0BACA,0BACA,gCACA,iCACF,CAAC,EAGKC,EAAyC,CAC7C,0BAA2B,yBAC3B,oBAAqB,OACrB,2BAA4B,KAC5B,gCAAiC,IACjC,uBAAwB,MACxB,oBAAqB,KACrB,oBAAqB,KACrB,mBAAoB,KACpB,yBAA0B,KAC1B,8BAA+B,KAC/B,wBAAyB,IACzB,8BAA+B,OAC/B,wBAAyB,UACzB,kBAAmB,MACnB,iBAAkB,IACpB,EAGMC,EAAWH,EAAW,QAASI,GAAMA,EAAE,OAAO,IAAKC,GAAMA,EAAE,GAAG,CAAC,EAErE,SAASC,GAAwC,CAC/C,OAAO,OAAO,YAAYH,EAAS,IAAKI,GAAM,CAACA,EAAG,EAAE,CAAC,CAAC,CACxD,CAEA,SAASC,EACPC,EACAC,EACwB,CACxB,OAAO,OAAO,YACZP,EAAS,IAAKQ,GAAQ,CAACA,EAAKF,EAAOE,CAAG,GAAKD,EAASC,CAAG,GAAK,EAAE,CAAC,CAAA,CAEnE,CAYA,SAASC,GAAe,CAAE,MAAAC,EAAO,SAAAC,EAAU,GAAAC,GAA2B,CACpE,KAAM,CAACC,EAAMC,CAAO,EAAInF,EAAAA,SAAS,EAAK,EACtC,OACEoB,EAAAA,KAAC,MAAA,CAAI,UAAU,WACb,SAAA,CAAAG,EAAAA,IAACyC,EAAA,CACC,GAAAiB,EACA,KAAMC,EAAO,OAAS,WACtB,MAAAH,EACA,SAAWhB,GAAMiB,EAASjB,EAAE,OAAO,KAAK,EACxC,UAAU,OAAA,CAAA,EAEZxC,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,UAAU,2FACV,QAAS,IAAM4D,EAASC,GAAM,CAACA,CAAC,EAChC,SAAU,GAET,SAAAF,QAAQG,GAAA,CAAO,UAAU,UAAU,EAAK9D,EAAAA,IAAC+D,GAAA,CAAI,UAAU,SAAA,CAAU,CAAA,CAAA,CACpE,EACF,CAEJ,CAMO,SAASC,IAAiB,CAC/B,KAAM,CAAE,cAAAhG,CAAA,EAAkBC,EAAA,EACpB,CAAE,KAAMK,EAAS,UAAAH,CAAA,EAAcR,EAAA,EAC/B,CAAE,QAAAsG,EAAS,SAAAC,CAAA,EAAatG,GAAA,EAExB,CAAC6B,EAAW0E,CAAY,EAAI1F,EAAAA,SAAoB,OAAO,EACvD,CAAC2F,EAAUC,CAAW,EAAI5F,EAAAA,SAAiCwE,CAAa,EAExEqB,GAAehG,GAAA,YAAAA,EAAS,SAAU,CAAA,EAClCiG,EAAiB,CAAE,GAAG1B,EAAgB,IAAIvE,GAAA,YAAAA,EAAS,WAAY,EAAC,EAChEkG,EAAerB,EAAkBmB,EAAcC,CAAc,EAGnEtC,EAAAA,UAAU,IAAM,CACd,GAAI3D,EAAS,CACX,MAAMmG,EAAe,CAAE,GAAG5B,EAAgB,GAAIvE,EAAQ,UAAY,EAAC,EAC7DoG,EAAapG,EAAQ,QAAU,CAAA,EACrC+F,EAAYlB,EAAkBuB,EAAYD,CAAY,CAAC,EAEnDC,EAAW,yBACbP,EAAa,KAAK,CAEtB,CACF,EAAG,CAAC7F,CAAO,CAAC,EAEZ,MAAMqG,EAAU7B,EAAS,KAAMI,GAAMkB,EAASlB,CAAC,KAAOsB,EAAatB,CAAC,GAAK,GAAG,EAEtE0B,EAAe,CAACtB,EAAaE,IAAkB,CACnDa,EAAanC,IAAU,CAAE,GAAGA,EAAM,CAACoB,CAAG,EAAGE,CAAA,EAAQ,CACnD,EAEMqB,EAAa,SAAY,CAC7B,MAAMC,EAAU,OAAO,YACrB,OAAO,QAAQV,CAAQ,EAAE,QAAQ,CAAC,CAACd,EAAKE,CAAK,IAAM,CACjD,MAAMpB,EAAUoB,EAAM,KAAA,EAChBuB,EAAeR,EAAejB,CAAG,GAAK,GAC5C,MAAI,CAAClB,GAAWA,IAAY2C,EACnB,CAAA,EAEF,CAAC,CAACzB,EAAKlB,CAAO,CAAC,CACxB,CAAC,CAAA,EAEH,MAAM6B,EAAQa,CAAO,CACvB,EAEME,EAAc,IAAM,CACxBX,EAAYpB,GAAe,CAC7B,EAEA,OAAI9E,EACK6B,MAAC,KAAE,UAAU,oCAAqC,WAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAE,EAIxGH,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,sBAAuB,SAAA,CAAA7B,EAAc,CAAE,GAAI,qBAAsB,EAAE,GAAA,EAAC,EACpF6B,EAAAA,KAAC,MAAA,CAAI,UAAU,uDACb,SAAA,CAAAG,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMmE,EAAa,OAAO,EACnC,UAAW,yCACT1E,IAAc,QACV,qCACA,oDACN,GAEC,SAAAzB,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,EAElDgC,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMmE,EAAa,KAAK,EACjC,UAAW,yCACT1E,IAAc,MACV,qCACA,oDACN,GAEC,SAAAzB,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAA,CAChD,EACF,QACC,OAAA,CAAK,UAAU,gCACb,SACGA,EADHyB,IAAc,QACG,CAAE,GAAI,6BAAA,EACN,CAAE,GAAI,2BAAA,CAD+B,CACF,CACvD,CAAA,EACF,EAECkD,EAAW,IAAKsC,GAAU,CAEzB,MAAMC,EAAgBzF,IAAc,QAChCwF,EAAM,OAAO,OAAQjC,GAAM,CAACJ,GAAc,IAAII,EAAE,GAAG,CAAC,EACpDiC,EAAM,OACV,OAAIC,EAAc,SAAW,EAAU,YAEtCnF,EAAA,CACC,SAAA,CAAAC,MAACC,GAAW,UAAU,OACpB,SAAAD,MAACE,EAAA,CAAU,UAAU,YAAa,SAAAlC,EAAc,CAAE,GAAI,0BAA0BiH,EAAM,KAAK,EAAA,CAAI,EAAE,EACnG,EACAjF,EAAAA,IAACO,EAAA,CAAY,UAAU,YACpB,SAAA2E,EAAc,IAAKC,GAClBtF,EAAAA,KAAC,MAAA,CAAoB,UAAU,sCAC7B,SAAA,CAAAG,EAAAA,IAAC,QAAA,CACC,QAASmF,EAAM,IACf,UAAU,2CAET,SAAAA,EAAM,KAAA,CAAA,EAETnF,EAAAA,IAAC,MAAA,CAAI,UAAU,aACZ,WAAM,UACLA,EAAAA,IAACuD,GAAA,CACC,GAAI4B,EAAM,IACV,MAAOf,EAASe,EAAM,GAAG,GAAK,GAC9B,SAAWC,GAAMR,EAAaO,EAAM,IAAKC,CAAC,CAAA,CAAA,EAG5CpF,EAAAA,IAACyC,EAAA,CACC,GAAI0C,EAAM,IACV,MAAOf,EAASe,EAAM,GAAG,GAAK,GAC9B,YAAaZ,EAAeY,EAAM,GAAG,GAAK,GAC1C,SAAW3C,GAAMoC,EAAaO,EAAM,IAAK3C,EAAE,OAAO,KAAK,CAAA,CAAA,CACzD,CAEJ,CAAA,GAtBQ2C,EAAM,GAuBhB,CACD,CAAA,CACH,CAAA,CAAA,EA/BSF,EAAM,KAgCjB,CAEF,CAAC,EAGDpF,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACb,SAAA,CAAAA,EAAAA,KAACM,EAAA,CAAO,QAAQ,UAAU,QAAS6E,EACjC,SAAA,CAAAhF,EAAAA,IAACqF,GAAA,CAAU,UAAU,cAAA,CAAe,EACnCrH,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,EAClD,SACCmC,EAAA,CAAO,QAAS0E,EAAY,SAAU,CAACF,GAAWT,EACjD,SAAA,CAAAlE,EAAAA,IAACsF,GAAA,CAAK,UAAU,cAAA,CAAe,EACnBtH,EAAXkG,EAAyB,CAAE,GAAI,sBAAA,EAA0C,CAAE,GAAI,oBAAA,CAAxB,CAA8C,CAAA,CACxG,CAAA,CAAA,CACF,CAAA,EACF,CAEJ,CC5RO,SAASqB,IAAgB,CAC9B,KAAM,CAAE,cAAAvH,CAAA,EAAkBC,EAAA,EACpB,CAACuH,EAAWC,CAAY,EAAIhH,EAAAA,SAAkB,KAAK,EAEzD,OACEoB,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,6DACZ,SAAA,CAAAG,EAAAA,IAAC0F,GAAA,CAAO,UAAU,sBAAA,CAAuB,EACxC1H,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,EAC/C,EACAgC,MAAC,KAAE,UAAU,6BACV,WAAc,CAAE,GAAI,4BAAA,CAA8B,CAAA,CACrD,CAAA,EACF,EAGAA,EAAAA,IAAC2F,GAAA,CACC,MAAOH,EACP,cAAgBJ,GAAMK,EAAaL,CAAY,EAC/C,KAAM,CACJ,CAAE,MAAO,MAAO,MAAOpH,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EACjE,CAAE,MAAO,SAAU,MAAOA,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,EACvE,CAAE,MAAO,QAAS,MAAOA,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,EACrE,CAAE,MAAO,MAAO,MAAOA,EAAc,CAAE,GAAI,qBAAsB,CAAA,CAAE,CACrE,CAAA,EAIF6B,EAAAA,KAAC,MAAA,CAAI,UAAU,OACZ,SAAA,CAAA2F,IAAc,aAAUzH,GAAA,CAAA,CAAa,EACrCyH,IAAc,UAAYxF,MAACU,GAAA,CAAA,CAAgB,EAC3C8E,IAAc,SAAWxF,MAAC2B,GAAA,CAAA,CAAgB,EAC1C6D,IAAc,OAASxF,MAACgE,GAAA,CAAA,CAAe,CAAA,CAAA,CAC1C,CAAA,EACF,CAEJ"}