claude-code-workflow 6.3.18 → 6.3.19

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 (822) hide show
  1. package/.claude/CLAUDE.md +8 -5
  2. package/.claude/agents/action-planning-agent.md +26 -2
  3. package/.claude/agents/code-developer.md +132 -43
  4. package/.claude/agents/debug-explore-agent.md +434 -0
  5. package/.claude/agents/test-fix-agent.md +14 -0
  6. package/.claude/commands/issue/discover.md +41 -0
  7. package/.claude/commands/issue/execute.md +200 -19
  8. package/.claude/commands/issue/new.md +1 -1
  9. package/.claude/commands/issue/plan.md +6 -1
  10. package/.claude/commands/issue/queue.md +94 -39
  11. package/.claude/commands/memory/swagger-docs.md +773 -0
  12. package/.claude/commands/workflow/brainstorm/auto-parallel.md +21 -21
  13. package/.claude/commands/workflow/execute.md +54 -34
  14. package/.claude/commands/workflow/lite-execute.md +48 -164
  15. package/.claude/commands/workflow/lite-fix.md +4 -4
  16. package/.claude/commands/workflow/lite-plan.md +5 -5
  17. package/.claude/commands/workflow/plan.md +27 -27
  18. package/.claude/commands/workflow/review.md +42 -17
  19. package/.claude/commands/workflow/tdd-plan.md +25 -25
  20. package/.claude/commands/workflow/test-fix-gen.md +10 -10
  21. package/.claude/commands/workflow/test-gen.md +14 -14
  22. package/.claude/commands/workflow/ui-design/explore-auto.md +21 -21
  23. package/.claude/commands/workflow/ui-design/imitate-auto.md +24 -24
  24. package/.claude/skills/_shared/SKILL-DESIGN-SPEC.md +693 -0
  25. package/.claude/skills/ccw/SKILL.md +462 -0
  26. package/.claude/skills/ccw/index/command-capabilities.json +127 -0
  27. package/.claude/skills/ccw/index/intent-rules.json +136 -0
  28. package/.claude/skills/ccw/index/workflow-chains.json +451 -0
  29. package/.claude/skills/ccw/phases/actions/bugfix.md +218 -0
  30. package/.claude/skills/ccw/phases/actions/coupled.md +194 -0
  31. package/.claude/skills/ccw/phases/actions/docs.md +93 -0
  32. package/.claude/skills/ccw/phases/actions/full.md +154 -0
  33. package/.claude/skills/ccw/phases/actions/issue.md +201 -0
  34. package/.claude/skills/ccw/phases/actions/rapid.md +104 -0
  35. package/.claude/skills/ccw/phases/actions/review-fix.md +84 -0
  36. package/.claude/skills/ccw/phases/actions/tdd.md +66 -0
  37. package/.claude/skills/ccw/phases/actions/ui.md +79 -0
  38. package/.claude/skills/ccw/phases/orchestrator.md +435 -0
  39. package/.claude/skills/ccw/specs/intent-classification.md +336 -0
  40. package/.claude/skills/ccw-help/SKILL.md +177 -0
  41. package/.claude/skills/ccw-help/index/all-agents.json +82 -0
  42. package/.claude/skills/{command-guide → ccw-help}/index/all-commands.json +183 -73
  43. package/.claude/skills/{command-guide → ccw-help}/index/by-category.json +187 -73
  44. package/.claude/skills/{command-guide → ccw-help}/index/by-use-case.json +295 -185
  45. package/.claude/skills/{command-guide → ccw-help}/index/command-relationships.json +19 -166
  46. package/.claude/skills/{command-guide → ccw-help}/index/essential-commands.json +10 -10
  47. package/.claude/skills/ccw-help/scripts/analyze_commands.py +337 -0
  48. package/.claude/skills/code-reviewer/README.md +340 -0
  49. package/.claude/skills/code-reviewer/SKILL.md +308 -0
  50. package/.claude/skills/code-reviewer/phases/01-code-discovery.md +246 -0
  51. package/.claude/skills/code-reviewer/phases/02-security-analysis.md +442 -0
  52. package/.claude/skills/code-reviewer/phases/03-best-practices-review.md +36 -0
  53. package/.claude/skills/code-reviewer/phases/04-report-generation.md +278 -0
  54. package/.claude/skills/code-reviewer/specs/best-practices-requirements.md +346 -0
  55. package/.claude/skills/code-reviewer/specs/quality-standards.md +252 -0
  56. package/.claude/skills/code-reviewer/specs/security-requirements.md +243 -0
  57. package/.claude/skills/code-reviewer/templates/best-practice-finding.md +234 -0
  58. package/.claude/skills/code-reviewer/templates/report-template.md +316 -0
  59. package/.claude/skills/code-reviewer/templates/security-finding.md +161 -0
  60. package/.claude/skills/skill-generator/SKILL.md +187 -0
  61. package/.claude/skills/skill-generator/phases/01-requirements-discovery.md +239 -0
  62. package/.claude/skills/skill-generator/phases/02-structure-generation.md +207 -0
  63. package/.claude/skills/skill-generator/phases/03-phase-generation.md +802 -0
  64. package/.claude/skills/skill-generator/phases/04-specs-templates.md +328 -0
  65. package/.claude/skills/skill-generator/phases/05-validation.md +334 -0
  66. package/.claude/skills/skill-generator/specs/cli-integration.md +448 -0
  67. package/.claude/skills/skill-generator/specs/execution-modes.md +396 -0
  68. package/.claude/skills/skill-generator/specs/scripting-integration.md +265 -0
  69. package/.claude/skills/skill-generator/specs/skill-requirements.md +466 -0
  70. package/.claude/skills/skill-generator/templates/autonomous-action.md +517 -0
  71. package/.claude/skills/skill-generator/templates/autonomous-orchestrator.md +276 -0
  72. package/.claude/skills/skill-generator/templates/code-analysis-action.md +503 -0
  73. package/.claude/skills/skill-generator/templates/llm-action.md +355 -0
  74. package/.claude/skills/skill-generator/templates/script-bash.md +277 -0
  75. package/.claude/skills/skill-generator/templates/script-python.md +198 -0
  76. package/.claude/skills/skill-generator/templates/sequential-phase.md +441 -0
  77. package/.claude/skills/skill-generator/templates/skill-md.md +156 -0
  78. package/.claude/workflows/chinese-response.md +15 -28
  79. package/.claude/workflows/cli-templates/prompts/documentation/swagger-api.txt +266 -0
  80. package/.claude/workflows/cli-tools-usage.md +221 -177
  81. package/.claude/workflows/windows-platform.md +13 -10
  82. package/.codex/prompts/issue-execute.md +305 -82
  83. package/.codex/prompts/issue-queue.md +22 -0
  84. package/.codex/prompts/lite-execute.md +36 -11
  85. package/README.md +309 -305
  86. package/ccw/README.md +10 -4
  87. package/ccw/dist/cli.d.ts.map +1 -1
  88. package/ccw/dist/cli.js +4 -1
  89. package/ccw/dist/cli.js.map +1 -1
  90. package/ccw/dist/commands/cli.d.ts.map +1 -1
  91. package/ccw/dist/commands/cli.js +131 -34
  92. package/ccw/dist/commands/cli.js.map +1 -1
  93. package/ccw/dist/commands/issue.d.ts +152 -0
  94. package/ccw/dist/commands/issue.d.ts.map +1 -1
  95. package/ccw/dist/commands/issue.js +550 -85
  96. package/ccw/dist/commands/issue.js.map +1 -1
  97. package/ccw/dist/commands/serve.d.ts +1 -0
  98. package/ccw/dist/commands/serve.d.ts.map +1 -1
  99. package/ccw/dist/commands/serve.js +12 -5
  100. package/ccw/dist/commands/serve.js.map +1 -1
  101. package/ccw/dist/commands/stop.d.ts.map +1 -1
  102. package/ccw/dist/commands/stop.js +29 -5
  103. package/ccw/dist/commands/stop.js.map +1 -1
  104. package/ccw/dist/commands/tool.d.ts.map +1 -1
  105. package/ccw/dist/commands/tool.js +19 -2
  106. package/ccw/dist/commands/tool.js.map +1 -1
  107. package/ccw/dist/commands/view.d.ts +1 -0
  108. package/ccw/dist/commands/view.d.ts.map +1 -1
  109. package/ccw/dist/commands/view.js +10 -3
  110. package/ccw/dist/commands/view.js.map +1 -1
  111. package/ccw/dist/config/cli-settings-manager.d.ts +86 -0
  112. package/ccw/dist/config/cli-settings-manager.d.ts.map +1 -0
  113. package/ccw/dist/config/cli-settings-manager.js +392 -0
  114. package/ccw/dist/config/cli-settings-manager.js.map +1 -0
  115. package/ccw/dist/config/litellm-api-config-manager.d.ts +71 -5
  116. package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -1
  117. package/ccw/dist/config/litellm-api-config-manager.js +290 -20
  118. package/ccw/dist/config/litellm-api-config-manager.js.map +1 -1
  119. package/ccw/dist/core/auth/csrf-manager.d.ts +18 -0
  120. package/ccw/dist/core/auth/csrf-manager.d.ts.map +1 -0
  121. package/ccw/dist/core/auth/csrf-manager.js +80 -0
  122. package/ccw/dist/core/auth/csrf-manager.js.map +1 -0
  123. package/ccw/dist/core/auth/csrf-middleware.d.ts +8 -0
  124. package/ccw/dist/core/auth/csrf-middleware.d.ts.map +1 -0
  125. package/ccw/dist/core/auth/csrf-middleware.js +141 -0
  126. package/ccw/dist/core/auth/csrf-middleware.js.map +1 -0
  127. package/ccw/dist/core/auth/middleware.d.ts +15 -0
  128. package/ccw/dist/core/auth/middleware.d.ts.map +1 -0
  129. package/ccw/dist/core/auth/middleware.js +76 -0
  130. package/ccw/dist/core/auth/middleware.js.map +1 -0
  131. package/ccw/dist/core/auth/token-manager.d.ts +41 -0
  132. package/ccw/dist/core/auth/token-manager.d.ts.map +1 -0
  133. package/ccw/dist/core/auth/token-manager.js +171 -0
  134. package/ccw/dist/core/auth/token-manager.js.map +1 -0
  135. package/ccw/dist/core/cache-manager.d.ts +6 -6
  136. package/ccw/dist/core/cache-manager.d.ts.map +1 -1
  137. package/ccw/dist/core/cache-manager.js +70 -48
  138. package/ccw/dist/core/cache-manager.js.map +1 -1
  139. package/ccw/dist/core/claude-freshness.d.ts.map +1 -1
  140. package/ccw/dist/core/claude-freshness.js +23 -3
  141. package/ccw/dist/core/claude-freshness.js.map +1 -1
  142. package/ccw/dist/core/core-memory-store.d.ts.map +1 -1
  143. package/ccw/dist/core/core-memory-store.js +2 -1
  144. package/ccw/dist/core/core-memory-store.js.map +1 -1
  145. package/ccw/dist/core/cors.d.ts +3 -0
  146. package/ccw/dist/core/cors.d.ts.map +1 -0
  147. package/ccw/dist/core/cors.js +10 -0
  148. package/ccw/dist/core/cors.js.map +1 -0
  149. package/ccw/dist/core/dashboard-generator-patch.js +0 -1
  150. package/ccw/dist/core/dashboard-generator-patch.js.map +1 -1
  151. package/ccw/dist/core/dashboard-generator.d.ts.map +1 -1
  152. package/ccw/dist/core/dashboard-generator.js +417 -416
  153. package/ccw/dist/core/dashboard-generator.js.map +1 -1
  154. package/ccw/dist/core/data-aggregator.js +2 -2
  155. package/ccw/dist/core/data-aggregator.js.map +1 -1
  156. package/ccw/dist/core/lite-scanner.d.ts +1 -1
  157. package/ccw/dist/core/lite-scanner.d.ts.map +1 -1
  158. package/ccw/dist/core/lite-scanner.js +130 -127
  159. package/ccw/dist/core/lite-scanner.js.map +1 -1
  160. package/ccw/dist/core/routes/auth-routes.d.ts +12 -0
  161. package/ccw/dist/core/routes/auth-routes.d.ts.map +1 -0
  162. package/ccw/dist/core/routes/auth-routes.js +80 -0
  163. package/ccw/dist/core/routes/auth-routes.js.map +1 -0
  164. package/ccw/dist/core/routes/ccw-routes.d.ts +1 -14
  165. package/ccw/dist/core/routes/ccw-routes.d.ts.map +1 -1
  166. package/ccw/dist/core/routes/ccw-routes.js +9 -4
  167. package/ccw/dist/core/routes/ccw-routes.js.map +1 -1
  168. package/ccw/dist/core/routes/claude-routes.d.ts +1 -14
  169. package/ccw/dist/core/routes/claude-routes.d.ts.map +1 -1
  170. package/ccw/dist/core/routes/claude-routes.js +98 -39
  171. package/ccw/dist/core/routes/claude-routes.js.map +1 -1
  172. package/ccw/dist/core/routes/cli-routes.d.ts +14 -12
  173. package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
  174. package/ccw/dist/core/routes/cli-routes.js +122 -43
  175. package/ccw/dist/core/routes/cli-routes.js.map +1 -1
  176. package/ccw/dist/core/routes/cli-settings-routes.d.ts +11 -0
  177. package/ccw/dist/core/routes/cli-settings-routes.d.ts.map +1 -0
  178. package/ccw/dist/core/routes/cli-settings-routes.js +204 -0
  179. package/ccw/dist/core/routes/cli-settings-routes.js.map +1 -0
  180. package/ccw/dist/core/routes/codexlens/config-handlers.d.ts +6 -0
  181. package/ccw/dist/core/routes/codexlens/config-handlers.d.ts.map +1 -0
  182. package/ccw/dist/core/routes/codexlens/config-handlers.js +1195 -0
  183. package/ccw/dist/core/routes/codexlens/config-handlers.js.map +1 -0
  184. package/ccw/dist/core/routes/codexlens/index-handlers.d.ts +10 -0
  185. package/ccw/dist/core/routes/codexlens/index-handlers.d.ts.map +1 -0
  186. package/ccw/dist/core/routes/codexlens/index-handlers.js +322 -0
  187. package/ccw/dist/core/routes/codexlens/index-handlers.js.map +1 -0
  188. package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts +6 -0
  189. package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts.map +1 -0
  190. package/ccw/dist/core/routes/codexlens/semantic-handlers.js +865 -0
  191. package/ccw/dist/core/routes/codexlens/semantic-handlers.js.map +1 -0
  192. package/ccw/dist/core/routes/codexlens/utils.d.ts +23 -0
  193. package/ccw/dist/core/routes/codexlens/utils.d.ts.map +1 -0
  194. package/ccw/dist/core/routes/codexlens/utils.js +85 -0
  195. package/ccw/dist/core/routes/codexlens/utils.js.map +1 -0
  196. package/ccw/dist/core/routes/codexlens/watcher-handlers.d.ts +13 -0
  197. package/ccw/dist/core/routes/codexlens/watcher-handlers.d.ts.map +1 -0
  198. package/ccw/dist/core/routes/codexlens/watcher-handlers.js +235 -0
  199. package/ccw/dist/core/routes/codexlens/watcher-handlers.js.map +1 -0
  200. package/ccw/dist/core/routes/codexlens-routes.d.ts +2 -11
  201. package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
  202. package/ccw/dist/core/routes/codexlens-routes.js +10 -981
  203. package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
  204. package/ccw/dist/core/routes/discovery-routes.d.ts +1 -35
  205. package/ccw/dist/core/routes/discovery-routes.d.ts.map +1 -1
  206. package/ccw/dist/core/routes/discovery-routes.js +25 -0
  207. package/ccw/dist/core/routes/discovery-routes.js.map +1 -1
  208. package/ccw/dist/core/routes/files-routes.d.ts +1 -14
  209. package/ccw/dist/core/routes/files-routes.d.ts.map +1 -1
  210. package/ccw/dist/core/routes/files-routes.js +57 -14
  211. package/ccw/dist/core/routes/files-routes.js.map +1 -1
  212. package/ccw/dist/core/routes/graph-routes.d.ts +1 -14
  213. package/ccw/dist/core/routes/graph-routes.d.ts.map +1 -1
  214. package/ccw/dist/core/routes/graph-routes.js +36 -37
  215. package/ccw/dist/core/routes/graph-routes.js.map +1 -1
  216. package/ccw/dist/core/routes/help-routes.d.ts +1 -14
  217. package/ccw/dist/core/routes/help-routes.d.ts.map +1 -1
  218. package/ccw/dist/core/routes/help-routes.js +5 -0
  219. package/ccw/dist/core/routes/help-routes.js.map +1 -1
  220. package/ccw/dist/core/routes/hooks-routes.d.ts +4 -14
  221. package/ccw/dist/core/routes/hooks-routes.d.ts.map +1 -1
  222. package/ccw/dist/core/routes/hooks-routes.js +43 -21
  223. package/ccw/dist/core/routes/hooks-routes.js.map +1 -1
  224. package/ccw/dist/core/routes/issue-routes.d.ts +1 -34
  225. package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
  226. package/ccw/dist/core/routes/issue-routes.js +24 -0
  227. package/ccw/dist/core/routes/issue-routes.js.map +1 -1
  228. package/ccw/dist/core/routes/litellm-api-routes.d.ts +1 -14
  229. package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -1
  230. package/ccw/dist/core/routes/litellm-api-routes.js +505 -48
  231. package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -1
  232. package/ccw/dist/core/routes/litellm-routes.d.ts +1 -14
  233. package/ccw/dist/core/routes/litellm-routes.d.ts.map +1 -1
  234. package/ccw/dist/core/routes/litellm-routes.js +28 -11
  235. package/ccw/dist/core/routes/litellm-routes.js.map +1 -1
  236. package/ccw/dist/core/routes/mcp-routes.d.ts +1 -14
  237. package/ccw/dist/core/routes/mcp-routes.d.ts.map +1 -1
  238. package/ccw/dist/core/routes/mcp-routes.js +99 -30
  239. package/ccw/dist/core/routes/mcp-routes.js.map +1 -1
  240. package/ccw/dist/core/routes/mcp-templates-db.d.ts.map +1 -1
  241. package/ccw/dist/core/routes/mcp-templates-db.js +30 -31
  242. package/ccw/dist/core/routes/mcp-templates-db.js.map +1 -1
  243. package/ccw/dist/core/routes/memory-routes.d.ts.map +1 -1
  244. package/ccw/dist/core/routes/memory-routes.js +74 -24
  245. package/ccw/dist/core/routes/memory-routes.js.map +1 -1
  246. package/ccw/dist/core/routes/nav-status-routes.d.ts +3 -0
  247. package/ccw/dist/core/routes/nav-status-routes.d.ts.map +1 -0
  248. package/ccw/dist/core/routes/nav-status-routes.js +217 -0
  249. package/ccw/dist/core/routes/nav-status-routes.js.map +1 -0
  250. package/ccw/dist/core/routes/rules-routes.d.ts +1 -14
  251. package/ccw/dist/core/routes/rules-routes.d.ts.map +1 -1
  252. package/ccw/dist/core/routes/rules-routes.js +481 -58
  253. package/ccw/dist/core/routes/rules-routes.js.map +1 -1
  254. package/ccw/dist/core/routes/session-routes.d.ts +1 -14
  255. package/ccw/dist/core/routes/session-routes.d.ts.map +1 -1
  256. package/ccw/dist/core/routes/session-routes.js +15 -3
  257. package/ccw/dist/core/routes/session-routes.js.map +1 -1
  258. package/ccw/dist/core/routes/skills-routes.d.ts +1 -14
  259. package/ccw/dist/core/routes/skills-routes.d.ts.map +1 -1
  260. package/ccw/dist/core/routes/skills-routes.js +394 -112
  261. package/ccw/dist/core/routes/skills-routes.js.map +1 -1
  262. package/ccw/dist/core/routes/status-routes.d.ts +1 -14
  263. package/ccw/dist/core/routes/status-routes.d.ts.map +1 -1
  264. package/ccw/dist/core/routes/status-routes.js +4 -0
  265. package/ccw/dist/core/routes/status-routes.js.map +1 -1
  266. package/ccw/dist/core/routes/system-routes.d.ts +4 -10
  267. package/ccw/dist/core/routes/system-routes.d.ts.map +1 -1
  268. package/ccw/dist/core/routes/system-routes.js +6 -4
  269. package/ccw/dist/core/routes/system-routes.js.map +1 -1
  270. package/ccw/dist/core/routes/types.d.ts +19 -0
  271. package/ccw/dist/core/routes/types.d.ts.map +1 -0
  272. package/ccw/dist/core/routes/types.js +2 -0
  273. package/ccw/dist/core/routes/types.js.map +1 -0
  274. package/ccw/dist/core/server.d.ts.map +1 -1
  275. package/ccw/dist/core/server.js +201 -29
  276. package/ccw/dist/core/server.js.map +1 -1
  277. package/ccw/dist/core/services/api-key-tester.d.ts +31 -0
  278. package/ccw/dist/core/services/api-key-tester.d.ts.map +1 -0
  279. package/ccw/dist/core/services/api-key-tester.js +106 -0
  280. package/ccw/dist/core/services/api-key-tester.js.map +1 -0
  281. package/ccw/dist/core/services/health-check-service.d.ts +82 -0
  282. package/ccw/dist/core/services/health-check-service.d.ts.map +1 -0
  283. package/ccw/dist/core/services/health-check-service.js +271 -0
  284. package/ccw/dist/core/services/health-check-service.js.map +1 -0
  285. package/ccw/dist/core/websocket.d.ts +9 -7
  286. package/ccw/dist/core/websocket.d.ts.map +1 -1
  287. package/ccw/dist/core/websocket.js +9 -4
  288. package/ccw/dist/core/websocket.js.map +1 -1
  289. package/ccw/dist/tools/claude-cli-tools.d.ts +152 -28
  290. package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
  291. package/ccw/dist/tools/claude-cli-tools.js +490 -100
  292. package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
  293. package/ccw/dist/tools/cli-config-manager.d.ts +24 -8
  294. package/ccw/dist/tools/cli-config-manager.d.ts.map +1 -1
  295. package/ccw/dist/tools/cli-config-manager.js +76 -156
  296. package/ccw/dist/tools/cli-config-manager.js.map +1 -1
  297. package/ccw/dist/tools/cli-executor-core.d.ts +85 -0
  298. package/ccw/dist/tools/cli-executor-core.d.ts.map +1 -0
  299. package/ccw/dist/tools/cli-executor-core.js +1310 -0
  300. package/ccw/dist/tools/cli-executor-core.js.map +1 -0
  301. package/ccw/dist/tools/cli-executor-state.d.ts +241 -0
  302. package/ccw/dist/tools/cli-executor-state.d.ts.map +1 -0
  303. package/ccw/dist/tools/cli-executor-state.js +392 -0
  304. package/ccw/dist/tools/cli-executor-state.js.map +1 -0
  305. package/ccw/dist/tools/cli-executor-utils.d.ts +36 -0
  306. package/ccw/dist/tools/cli-executor-utils.d.ts.map +1 -0
  307. package/ccw/dist/tools/cli-executor-utils.js +298 -0
  308. package/ccw/dist/tools/cli-executor-utils.js.map +1 -0
  309. package/ccw/dist/tools/cli-executor.d.ts +3 -377
  310. package/ccw/dist/tools/cli-executor.d.ts.map +1 -1
  311. package/ccw/dist/tools/cli-executor.js +3 -1884
  312. package/ccw/dist/tools/cli-executor.js.map +1 -1
  313. package/ccw/dist/tools/cli-history-store.d.ts +2 -0
  314. package/ccw/dist/tools/cli-history-store.d.ts.map +1 -1
  315. package/ccw/dist/tools/cli-history-store.js.map +1 -1
  316. package/ccw/dist/tools/cli-output-converter.d.ts +192 -0
  317. package/ccw/dist/tools/cli-output-converter.d.ts.map +1 -0
  318. package/ccw/dist/tools/cli-output-converter.js +1047 -0
  319. package/ccw/dist/tools/cli-output-converter.js.map +1 -0
  320. package/ccw/dist/tools/cli-prompt-builder.d.ts +113 -0
  321. package/ccw/dist/tools/cli-prompt-builder.d.ts.map +1 -0
  322. package/ccw/dist/tools/cli-prompt-builder.js +363 -0
  323. package/ccw/dist/tools/cli-prompt-builder.js.map +1 -0
  324. package/ccw/dist/tools/codex-lens.d.ts +15 -1
  325. package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
  326. package/ccw/dist/tools/codex-lens.js +289 -55
  327. package/ccw/dist/tools/codex-lens.js.map +1 -1
  328. package/ccw/dist/tools/detect-changed-modules.d.ts.map +1 -1
  329. package/ccw/dist/tools/detect-changed-modules.js +22 -4
  330. package/ccw/dist/tools/detect-changed-modules.js.map +1 -1
  331. package/ccw/dist/tools/index.d.ts.map +1 -1
  332. package/ccw/dist/tools/index.js +2 -0
  333. package/ccw/dist/tools/index.js.map +1 -1
  334. package/ccw/dist/tools/litellm-client.d.ts.map +1 -1
  335. package/ccw/dist/tools/litellm-client.js +10 -4
  336. package/ccw/dist/tools/litellm-client.js.map +1 -1
  337. package/ccw/dist/tools/litellm-executor.d.ts +2 -4
  338. package/ccw/dist/tools/litellm-executor.d.ts.map +1 -1
  339. package/ccw/dist/tools/litellm-executor.js +39 -8
  340. package/ccw/dist/tools/litellm-executor.js.map +1 -1
  341. package/ccw/dist/tools/native-session-discovery.d.ts +2 -0
  342. package/ccw/dist/tools/native-session-discovery.d.ts.map +1 -1
  343. package/ccw/dist/tools/native-session-discovery.js +197 -1
  344. package/ccw/dist/tools/native-session-discovery.js.map +1 -1
  345. package/ccw/dist/tools/session-manager.d.ts.map +1 -1
  346. package/ccw/dist/tools/session-manager.js +79 -0
  347. package/ccw/dist/tools/session-manager.js.map +1 -1
  348. package/ccw/dist/tools/skill-context-loader.d.ts +15 -0
  349. package/ccw/dist/tools/skill-context-loader.d.ts.map +1 -0
  350. package/ccw/dist/tools/skill-context-loader.js +198 -0
  351. package/ccw/dist/tools/skill-context-loader.js.map +1 -0
  352. package/ccw/dist/tools/smart-search.d.ts +8 -3
  353. package/ccw/dist/tools/smart-search.d.ts.map +1 -1
  354. package/ccw/dist/tools/smart-search.js +378 -75
  355. package/ccw/dist/tools/smart-search.js.map +1 -1
  356. package/ccw/dist/types/cli-settings.d.ts +86 -0
  357. package/ccw/dist/types/cli-settings.d.ts.map +1 -0
  358. package/ccw/dist/types/cli-settings.js +54 -0
  359. package/ccw/dist/types/cli-settings.js.map +1 -0
  360. package/ccw/dist/types/litellm-api-config.d.ts +40 -1
  361. package/ccw/dist/types/litellm-api-config.d.ts.map +1 -1
  362. package/ccw/dist/utils/exec-constants.d.ts +25 -0
  363. package/ccw/dist/utils/exec-constants.d.ts.map +1 -0
  364. package/ccw/dist/utils/exec-constants.js +25 -0
  365. package/ccw/dist/utils/exec-constants.js.map +1 -0
  366. package/ccw/dist/utils/path-resolver.d.ts +1 -0
  367. package/ccw/dist/utils/path-resolver.d.ts.map +1 -1
  368. package/ccw/dist/utils/path-resolver.js +48 -3
  369. package/ccw/dist/utils/path-resolver.js.map +1 -1
  370. package/ccw/dist/utils/path-validator.d.ts.map +1 -1
  371. package/ccw/dist/utils/path-validator.js +25 -6
  372. package/ccw/dist/utils/path-validator.js.map +1 -1
  373. package/ccw/dist/utils/python-utils.d.ts.map +1 -1
  374. package/ccw/dist/utils/python-utils.js +27 -7
  375. package/ccw/dist/utils/python-utils.js.map +1 -1
  376. package/ccw/dist/utils/shell-escape.d.ts +8 -0
  377. package/ccw/dist/utils/shell-escape.d.ts.map +1 -0
  378. package/ccw/dist/utils/shell-escape.js +24 -0
  379. package/ccw/dist/utils/shell-escape.js.map +1 -0
  380. package/ccw/dist/utils/uv-manager.d.ts +167 -0
  381. package/ccw/dist/utils/uv-manager.d.ts.map +1 -0
  382. package/ccw/dist/utils/uv-manager.js +644 -0
  383. package/ccw/dist/utils/uv-manager.js.map +1 -0
  384. package/ccw/src/cli.ts +4 -1
  385. package/ccw/src/commands/cli.ts +132 -34
  386. package/ccw/src/commands/issue.ts +605 -91
  387. package/ccw/src/commands/serve.ts +15 -5
  388. package/ccw/src/commands/stop.ts +32 -5
  389. package/ccw/src/commands/tool.ts +17 -2
  390. package/ccw/src/commands/view.ts +13 -3
  391. package/ccw/src/config/cli-settings-manager.ts +460 -0
  392. package/ccw/src/config/litellm-api-config-manager.ts +392 -57
  393. package/ccw/src/core/auth/csrf-manager.ts +104 -0
  394. package/ccw/src/core/auth/csrf-middleware.ts +159 -0
  395. package/ccw/src/core/auth/middleware.ts +94 -0
  396. package/ccw/src/core/auth/token-manager.ts +219 -0
  397. package/ccw/src/core/cache-manager.ts +64 -52
  398. package/ccw/src/core/claude-freshness.ts +26 -6
  399. package/ccw/src/core/core-memory-store.ts +2 -1
  400. package/ccw/src/core/cors.ts +10 -0
  401. package/ccw/src/core/dashboard-generator-patch.ts +47 -48
  402. package/ccw/src/core/dashboard-generator.ts +797 -744
  403. package/ccw/src/core/data-aggregator.ts +667 -667
  404. package/ccw/src/core/lite-scanner.ts +156 -140
  405. package/ccw/src/core/routes/auth-routes.ts +98 -0
  406. package/ccw/src/core/routes/ccw-routes.ts +10 -20
  407. package/ccw/src/core/routes/claude-routes.ts +101 -51
  408. package/ccw/src/core/routes/cli-routes.ts +152 -55
  409. package/ccw/src/core/routes/cli-settings-routes.ts +232 -0
  410. package/ccw/src/core/routes/codexlens/README.md +37 -0
  411. package/ccw/src/core/routes/codexlens/config-handlers.ts +1269 -0
  412. package/ccw/src/core/routes/codexlens/index-handlers.ts +354 -0
  413. package/ccw/src/core/routes/codexlens/semantic-handlers.ts +931 -0
  414. package/ccw/src/core/routes/codexlens/utils.ts +96 -0
  415. package/ccw/src/core/routes/codexlens/watcher-handlers.ts +265 -0
  416. package/ccw/src/core/routes/codexlens-routes.ts +11 -1044
  417. package/ccw/src/core/routes/discovery-routes.ts +1 -12
  418. package/ccw/src/core/routes/files-routes.ts +112 -40
  419. package/ccw/src/core/routes/graph-routes.ts +39 -46
  420. package/ccw/src/core/routes/help-routes.ts +2 -12
  421. package/ccw/src/core/routes/hooks-routes.ts +83 -44
  422. package/ccw/src/core/routes/issue-routes.ts +1 -12
  423. package/ccw/src/core/routes/litellm-api-routes.ts +566 -60
  424. package/ccw/src/core/routes/litellm-routes.ts +35 -27
  425. package/ccw/src/core/routes/mcp-routes.ts +157 -60
  426. package/ccw/src/core/routes/mcp-routes.ts.backup +549 -550
  427. package/ccw/src/core/routes/mcp-templates-db.ts +267 -268
  428. package/ccw/src/core/routes/memory-routes.ts +76 -22
  429. package/ccw/src/core/routes/nav-status-routes.ts +231 -0
  430. package/ccw/src/core/routes/rules-routes.ts +600 -81
  431. package/ccw/src/core/routes/session-routes.ts +28 -22
  432. package/ccw/src/core/routes/skills-routes.ts +452 -132
  433. package/ccw/src/core/routes/status-routes.ts +1 -12
  434. package/ccw/src/core/routes/system-routes.ts +15 -22
  435. package/ccw/src/core/routes/types.ts +25 -0
  436. package/ccw/src/core/server.ts +651 -468
  437. package/ccw/src/core/services/api-key-tester.ts +137 -0
  438. package/ccw/src/core/services/health-check-service.ts +340 -0
  439. package/ccw/src/core/websocket.ts +20 -12
  440. package/ccw/src/templates/dashboard-css/01-base.css +109 -0
  441. package/ccw/src/templates/dashboard-css/10-cli-status.css +202 -0
  442. package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +308 -0
  443. package/ccw/src/templates/dashboard-css/30-core-memory.css +20 -0
  444. package/ccw/src/templates/dashboard-css/31-api-settings.css +751 -14
  445. package/ccw/src/templates/dashboard-css/33-cli-stream-viewer.css +230 -2
  446. package/ccw/src/templates/dashboard-js/api.js +5 -0
  447. package/ccw/src/templates/dashboard-js/components/cli-status.js +279 -107
  448. package/ccw/src/templates/dashboard-js/components/cli-stream-viewer.js +262 -20
  449. package/ccw/src/templates/dashboard-js/components/hook-manager.js +105 -5
  450. package/ccw/src/templates/dashboard-js/components/mcp-manager.js +317 -0
  451. package/ccw/src/templates/dashboard-js/components/navigation.js +45 -0
  452. package/ccw/src/templates/dashboard-js/components/notifications.js +128 -0
  453. package/ccw/src/templates/dashboard-js/i18n.js +4438 -3983
  454. package/ccw/src/templates/dashboard-js/main.js +71 -0
  455. package/ccw/src/templates/dashboard-js/services.js +289 -0
  456. package/ccw/src/templates/dashboard-js/views/api-settings.js +5613 -3361
  457. package/ccw/src/templates/dashboard-js/views/claude-manager.js +1 -7
  458. package/ccw/src/templates/dashboard-js/views/cli-manager.js +581 -87
  459. package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +6091 -1965
  460. package/ccw/src/templates/dashboard-js/views/core-memory.js +129 -20
  461. package/ccw/src/templates/dashboard-js/views/hook-manager.js +17 -3
  462. package/ccw/src/templates/dashboard-js/views/mcp-manager.js +63 -0
  463. package/ccw/src/templates/dashboard-js/views/project-overview.js +182 -37
  464. package/ccw/src/templates/dashboard-js/views/rules-manager.js +26 -3
  465. package/ccw/src/templates/dashboard-js/views/skills-manager.js +2 -42
  466. package/ccw/src/templates/dashboard.html +6 -0
  467. package/ccw/src/tools/README.md +29 -0
  468. package/ccw/src/tools/claude-cli-tools.ts +640 -125
  469. package/ccw/src/tools/cli-config-manager.ts +102 -172
  470. package/ccw/src/tools/cli-executor-core.ts +1533 -0
  471. package/ccw/src/tools/cli-executor-state.ts +560 -0
  472. package/ccw/src/tools/cli-executor-utils.ts +349 -0
  473. package/ccw/src/tools/cli-executor.ts +3 -2309
  474. package/ccw/src/tools/cli-history-store.ts +2 -0
  475. package/ccw/src/tools/cli-output-converter.ts +1237 -0
  476. package/ccw/src/tools/cli-prompt-builder.ts +487 -0
  477. package/ccw/src/tools/codex-lens.ts +324 -59
  478. package/ccw/src/tools/detect-changed-modules.ts +24 -6
  479. package/ccw/src/tools/index.ts +2 -0
  480. package/ccw/src/tools/litellm-client.ts +10 -4
  481. package/ccw/src/tools/litellm-executor.ts +146 -114
  482. package/ccw/src/tools/native-session-discovery.ts +209 -1
  483. package/ccw/src/tools/session-manager.ts +88 -0
  484. package/ccw/src/tools/skill-context-loader.ts +213 -0
  485. package/ccw/src/tools/smart-search.ts +427 -76
  486. package/ccw/src/types/cli-settings.ts +137 -0
  487. package/ccw/src/types/litellm-api-config.ts +55 -1
  488. package/ccw/src/utils/exec-constants.ts +24 -0
  489. package/ccw/src/utils/path-resolver.ts +49 -3
  490. package/ccw/src/utils/path-validator.ts +28 -6
  491. package/ccw/src/utils/python-utils.ts +140 -121
  492. package/ccw/src/utils/shell-escape.ts +30 -0
  493. package/ccw/src/utils/uv-manager.ts +796 -0
  494. package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-310.pyc +0 -0
  495. package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-312.pyc +0 -0
  496. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-310.pyc +0 -0
  497. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-312.pyc +0 -0
  498. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-310.pyc +0 -0
  499. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-312.pyc +0 -0
  500. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
  501. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-310.pyc +0 -0
  502. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-312.pyc +0 -0
  503. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-313.pyc +0 -0
  504. package/ccw-litellm/src/ccw_litellm/clients/litellm_embedder.py +270 -251
  505. package/ccw-litellm/src/ccw_litellm/clients/litellm_llm.py +33 -0
  506. package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-310.pyc +0 -0
  507. package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-312.pyc +0 -0
  508. package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-310.pyc +0 -0
  509. package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-312.pyc +0 -0
  510. package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-313.pyc +0 -0
  511. package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-310.pyc +0 -0
  512. package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-312.pyc +0 -0
  513. package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-313.pyc +0 -0
  514. package/ccw-litellm/src/ccw_litellm/config/loader.py +343 -316
  515. package/ccw-litellm/src/ccw_litellm/config/models.py +162 -130
  516. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-310.pyc +0 -0
  517. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-312.pyc +0 -0
  518. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-310.pyc +0 -0
  519. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-312.pyc +0 -0
  520. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-310.pyc +0 -0
  521. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-312.pyc +0 -0
  522. package/codex-lens/pyproject.toml +43 -0
  523. package/codex-lens/src/codexlens/__pycache__/__init__.cpython-310.pyc +0 -0
  524. package/codex-lens/src/codexlens/__pycache__/__init__.cpython-312.pyc +0 -0
  525. package/codex-lens/src/codexlens/__pycache__/__main__.cpython-310.pyc +0 -0
  526. package/codex-lens/src/codexlens/__pycache__/__main__.cpython-312.pyc +0 -0
  527. package/codex-lens/src/codexlens/__pycache__/config.cpython-310.pyc +0 -0
  528. package/codex-lens/src/codexlens/__pycache__/config.cpython-312.pyc +0 -0
  529. package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
  530. package/codex-lens/src/codexlens/__pycache__/entities.cpython-310.pyc +0 -0
  531. package/codex-lens/src/codexlens/__pycache__/entities.cpython-312.pyc +0 -0
  532. package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
  533. package/codex-lens/src/codexlens/__pycache__/env_config.cpython-310.pyc +0 -0
  534. package/codex-lens/src/codexlens/__pycache__/env_config.cpython-312.pyc +0 -0
  535. package/codex-lens/src/codexlens/__pycache__/env_config.cpython-313.pyc +0 -0
  536. package/codex-lens/src/codexlens/__pycache__/errors.cpython-310.pyc +0 -0
  537. package/codex-lens/src/codexlens/__pycache__/errors.cpython-312.pyc +0 -0
  538. package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  539. package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-312.pyc +0 -0
  540. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-310.pyc +0 -0
  541. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-312.pyc +0 -0
  542. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
  543. package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-310.pyc +0 -0
  544. package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-312.pyc +0 -0
  545. package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
  546. package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-310.pyc +0 -0
  547. package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-312.pyc +0 -0
  548. package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
  549. package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-310.pyc +0 -0
  550. package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-312.pyc +0 -0
  551. package/codex-lens/src/codexlens/cli/commands.py +4416 -2295
  552. package/codex-lens/src/codexlens/cli/embedding_manager.py +767 -14
  553. package/codex-lens/src/codexlens/cli/model_manager.py +676 -0
  554. package/codex-lens/src/codexlens/config.py +321 -12
  555. package/codex-lens/src/codexlens/entities.py +4 -1
  556. package/codex-lens/src/codexlens/env_config.py +298 -0
  557. package/codex-lens/src/codexlens/indexing/__init__.py +23 -1
  558. package/codex-lens/src/codexlens/indexing/__pycache__/__init__.cpython-313.pyc +0 -0
  559. package/codex-lens/src/codexlens/indexing/__pycache__/embedding.cpython-313.pyc +0 -0
  560. package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
  561. package/codex-lens/src/codexlens/indexing/embedding.py +582 -0
  562. package/codex-lens/src/codexlens/indexing/symbol_extractor.py +62 -28
  563. package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-310.pyc +0 -0
  564. package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-312.pyc +0 -0
  565. package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-310.pyc +0 -0
  566. package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-312.pyc +0 -0
  567. package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
  568. package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-310.pyc +0 -0
  569. package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-312.pyc +0 -0
  570. package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-310.pyc +0 -0
  571. package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-312.pyc +0 -0
  572. package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
  573. package/codex-lens/src/codexlens/parsers/factory.py +139 -10
  574. package/codex-lens/src/codexlens/parsers/treesitter_parser.py +487 -13
  575. package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-310.pyc +0 -0
  576. package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-312.pyc +0 -0
  577. package/codex-lens/src/codexlens/search/__pycache__/binary_searcher.cpython-313.pyc +0 -0
  578. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-310.pyc +0 -0
  579. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-312.pyc +0 -0
  580. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
  581. package/codex-lens/src/codexlens/search/__pycache__/enrichment.cpython-313.pyc +0 -0
  582. package/codex-lens/src/codexlens/search/__pycache__/graph_expander.cpython-313.pyc +0 -0
  583. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-310.pyc +0 -0
  584. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-312.pyc +0 -0
  585. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
  586. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-310.pyc +0 -0
  587. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-312.pyc +0 -0
  588. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
  589. package/codex-lens/src/codexlens/search/binary_searcher.py +277 -0
  590. package/codex-lens/src/codexlens/search/chain_search.py +1642 -8
  591. package/codex-lens/src/codexlens/search/enrichment.py +21 -0
  592. package/codex-lens/src/codexlens/search/graph_expander.py +264 -0
  593. package/codex-lens/src/codexlens/search/hybrid_search.py +772 -37
  594. package/codex-lens/src/codexlens/search/ranking.py +347 -8
  595. package/codex-lens/src/codexlens/semantic/SPLADE_IMPLEMENTATION.md +225 -0
  596. package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-310.pyc +0 -0
  597. package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-312.pyc +0 -0
  598. package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-310.pyc +0 -0
  599. package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-312.pyc +0 -0
  600. package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-313.pyc +0 -0
  601. package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-310.pyc +0 -0
  602. package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-312.pyc +0 -0
  603. package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-310.pyc +0 -0
  604. package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-312.pyc +0 -0
  605. package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-310.pyc +0 -0
  606. package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-312.pyc +0 -0
  607. package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-310.pyc +0 -0
  608. package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-312.pyc +0 -0
  609. package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-313.pyc +0 -0
  610. package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-310.pyc +0 -0
  611. package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-312.pyc +0 -0
  612. package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-313.pyc +0 -0
  613. package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-310.pyc +0 -0
  614. package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-312.pyc +0 -0
  615. package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
  616. package/codex-lens/src/codexlens/semantic/__pycache__/reranker.cpython-313.pyc +0 -0
  617. package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-310.pyc +0 -0
  618. package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-312.pyc +0 -0
  619. package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-313.pyc +0 -0
  620. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-310.pyc +0 -0
  621. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-312.pyc +0 -0
  622. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
  623. package/codex-lens/src/codexlens/semantic/ann_index.py +654 -0
  624. package/codex-lens/src/codexlens/semantic/factory.py +63 -3
  625. package/codex-lens/src/codexlens/semantic/gpu_support.py +19 -2
  626. package/codex-lens/src/codexlens/semantic/litellm_embedder.py +144 -144
  627. package/codex-lens/src/codexlens/semantic/reranker/__init__.py +25 -0
  628. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/__init__.cpython-310.pyc +0 -0
  629. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/__init__.cpython-313.pyc +0 -0
  630. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/api_reranker.cpython-310.pyc +0 -0
  631. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/api_reranker.cpython-313.pyc +0 -0
  632. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/base.cpython-310.pyc +0 -0
  633. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/base.cpython-313.pyc +0 -0
  634. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/factory.cpython-310.pyc +0 -0
  635. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/factory.cpython-313.pyc +0 -0
  636. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/fastembed_reranker.cpython-310.pyc +0 -0
  637. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/fastembed_reranker.cpython-313.pyc +0 -0
  638. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/legacy.cpython-310.pyc +0 -0
  639. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/legacy.cpython-313.pyc +0 -0
  640. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/litellm_reranker.cpython-313.pyc +0 -0
  641. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/onnx_reranker.cpython-310.pyc +0 -0
  642. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/onnx_reranker.cpython-313.pyc +0 -0
  643. package/codex-lens/src/codexlens/semantic/reranker/api_reranker.py +403 -0
  644. package/codex-lens/src/codexlens/semantic/reranker/base.py +46 -0
  645. package/codex-lens/src/codexlens/semantic/reranker/factory.py +159 -0
  646. package/codex-lens/src/codexlens/semantic/reranker/fastembed_reranker.py +257 -0
  647. package/codex-lens/src/codexlens/semantic/reranker/legacy.py +91 -0
  648. package/codex-lens/src/codexlens/semantic/reranker/litellm_reranker.py +214 -0
  649. package/codex-lens/src/codexlens/semantic/reranker/onnx_reranker.py +268 -0
  650. package/codex-lens/src/codexlens/semantic/splade_encoder.py +567 -0
  651. package/codex-lens/src/codexlens/semantic/vector_store.py +472 -352
  652. package/codex-lens/src/codexlens/storage/__init__.py +3 -0
  653. package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-310.pyc +0 -0
  654. package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-312.pyc +0 -0
  655. package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-313.pyc +0 -0
  656. package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-310.pyc +0 -0
  657. package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-312.pyc +0 -0
  658. package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
  659. package/codex-lens/src/codexlens/storage/__pycache__/global_index.cpython-310.pyc +0 -0
  660. package/codex-lens/src/codexlens/storage/__pycache__/global_index.cpython-312.pyc +0 -0
  661. package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-310.pyc +0 -0
  662. package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-312.pyc +0 -0
  663. package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
  664. package/codex-lens/src/codexlens/storage/__pycache__/merkle_tree.cpython-313.pyc +0 -0
  665. package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-310.pyc +0 -0
  666. package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-312.pyc +0 -0
  667. package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-310.pyc +0 -0
  668. package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-312.pyc +0 -0
  669. package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-310.pyc +0 -0
  670. package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-312.pyc +0 -0
  671. package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-313.pyc +0 -0
  672. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-310.pyc +0 -0
  673. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-312.pyc +0 -0
  674. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
  675. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-310.pyc +0 -0
  676. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-312.pyc +0 -0
  677. package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-310.pyc +0 -0
  678. package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-312.pyc +0 -0
  679. package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-313.pyc +0 -0
  680. package/codex-lens/src/codexlens/storage/dir_index.py +310 -12
  681. package/codex-lens/src/codexlens/storage/index_tree.py +194 -23
  682. package/codex-lens/src/codexlens/storage/merkle_tree.py +136 -0
  683. package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-310.pyc +0 -0
  684. package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-312.pyc +0 -0
  685. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_006_enhance_relationships.cpython-313.pyc +0 -0
  686. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-310.pyc +0 -0
  687. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-312.pyc +0 -0
  688. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-313.pyc +0 -0
  689. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_008_add_merkle_hashes.cpython-313.pyc +0 -0
  690. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_009_add_splade.cpython-313.pyc +0 -0
  691. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_010_add_multi_vector_chunks.cpython-313.pyc +0 -0
  692. package/codex-lens/src/codexlens/storage/migrations/migration_006_enhance_relationships.py +37 -0
  693. package/codex-lens/src/codexlens/storage/migrations/migration_007_add_graph_neighbors.py +47 -0
  694. package/codex-lens/src/codexlens/storage/migrations/migration_008_add_merkle_hashes.py +81 -0
  695. package/codex-lens/src/codexlens/storage/migrations/migration_009_add_splade.py +103 -0
  696. package/codex-lens/src/codexlens/storage/migrations/migration_010_add_multi_vector_chunks.py +162 -0
  697. package/codex-lens/src/codexlens/storage/splade_index.py +578 -0
  698. package/codex-lens/src/codexlens/storage/sqlite_store.py +508 -184
  699. package/codex-lens/src/codexlens/storage/vector_meta_store.py +415 -0
  700. package/codex-lens/src/codexlens/watcher/__init__.py +17 -0
  701. package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-310.pyc +0 -0
  702. package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-312.pyc +0 -0
  703. package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-313.pyc +0 -0
  704. package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-310.pyc +0 -0
  705. package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-312.pyc +0 -0
  706. package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-313.pyc +0 -0
  707. package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-310.pyc +0 -0
  708. package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-312.pyc +0 -0
  709. package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-313.pyc +0 -0
  710. package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-310.pyc +0 -0
  711. package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-312.pyc +0 -0
  712. package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-313.pyc +0 -0
  713. package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-310.pyc +0 -0
  714. package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-312.pyc +0 -0
  715. package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-313.pyc +0 -0
  716. package/codex-lens/src/codexlens/watcher/events.py +82 -0
  717. package/codex-lens/src/codexlens/watcher/file_watcher.py +347 -0
  718. package/codex-lens/src/codexlens/watcher/incremental_indexer.py +369 -0
  719. package/codex-lens/src/codexlens/watcher/manager.py +255 -0
  720. package/package.json +4 -1
  721. package/.claude/commands/workflow/docs/analyze.md +0 -1467
  722. package/.claude/commands/workflow/docs/copyright.md +0 -1265
  723. package/.claude/skills/command-guide/SKILL.md +0 -388
  724. package/.claude/skills/command-guide/UPDATE-GUIDELINE.md +0 -592
  725. package/.claude/skills/command-guide/guides/cli-tools-guide.md +0 -410
  726. package/.claude/skills/command-guide/guides/examples.md +0 -537
  727. package/.claude/skills/command-guide/guides/getting-started.md +0 -242
  728. package/.claude/skills/command-guide/guides/implementation-details.md +0 -1010
  729. package/.claude/skills/command-guide/guides/index-structure.md +0 -326
  730. package/.claude/skills/command-guide/guides/troubleshooting.md +0 -92
  731. package/.claude/skills/command-guide/guides/ui-design-workflow-guide.md +0 -316
  732. package/.claude/skills/command-guide/guides/workflow-patterns.md +0 -662
  733. package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +0 -855
  734. package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +0 -267
  735. package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +0 -182
  736. package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +0 -446
  737. package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +0 -558
  738. package/.claude/skills/command-guide/reference/agents/code-developer.md +0 -311
  739. package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +0 -308
  740. package/.claude/skills/command-guide/reference/agents/context-search-agent.md +0 -581
  741. package/.claude/skills/command-guide/reference/agents/doc-generator.md +0 -330
  742. package/.claude/skills/command-guide/reference/agents/memory-bridge.md +0 -94
  743. package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +0 -400
  744. package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +0 -344
  745. package/.claude/skills/command-guide/reference/agents/ui-design-agent.md +0 -593
  746. package/.claude/skills/command-guide/reference/agents/universal-executor.md +0 -131
  747. package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +0 -440
  748. package/.claude/skills/command-guide/reference/commands/enhance-prompt.md +0 -93
  749. package/.claude/skills/command-guide/reference/commands/memory/code-map-memory.md +0 -687
  750. package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +0 -471
  751. package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +0 -386
  752. package/.claude/skills/command-guide/reference/commands/memory/docs.md +0 -616
  753. package/.claude/skills/command-guide/reference/commands/memory/load-skill-memory.md +0 -182
  754. package/.claude/skills/command-guide/reference/commands/memory/load.md +0 -240
  755. package/.claude/skills/command-guide/reference/commands/memory/skill-memory.md +0 -525
  756. package/.claude/skills/command-guide/reference/commands/memory/style-skill-memory.md +0 -396
  757. package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +0 -314
  758. package/.claude/skills/command-guide/reference/commands/memory/update-full.md +0 -332
  759. package/.claude/skills/command-guide/reference/commands/memory/update-related.md +0 -332
  760. package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +0 -517
  761. package/.claude/skills/command-guide/reference/commands/task/breakdown.md +0 -204
  762. package/.claude/skills/command-guide/reference/commands/task/create.md +0 -152
  763. package/.claude/skills/command-guide/reference/commands/task/execute.md +0 -270
  764. package/.claude/skills/command-guide/reference/commands/task/replan.md +0 -437
  765. package/.claude/skills/command-guide/reference/commands/version.md +0 -254
  766. package/.claude/skills/command-guide/reference/commands/workflow/action-plan-verify.md +0 -447
  767. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +0 -585
  768. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +0 -452
  769. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +0 -443
  770. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +0 -220
  771. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +0 -200
  772. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +0 -200
  773. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +0 -200
  774. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +0 -200
  775. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +0 -398
  776. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +0 -387
  777. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +0 -221
  778. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +0 -221
  779. package/.claude/skills/command-guide/reference/commands/workflow/execute.md +0 -465
  780. package/.claude/skills/command-guide/reference/commands/workflow/init.md +0 -164
  781. package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +0 -748
  782. package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +0 -664
  783. package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +0 -645
  784. package/.claude/skills/command-guide/reference/commands/workflow/plan.md +0 -551
  785. package/.claude/skills/command-guide/reference/commands/workflow/replan.md +0 -515
  786. package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +0 -606
  787. package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +0 -765
  788. package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +0 -776
  789. package/.claude/skills/command-guide/reference/commands/workflow/review.md +0 -298
  790. package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +0 -547
  791. package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +0 -114
  792. package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +0 -77
  793. package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +0 -257
  794. package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +0 -460
  795. package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +0 -400
  796. package/.claude/skills/command-guide/reference/commands/workflow/test-cycle-execute.md +0 -498
  797. package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +0 -699
  798. package/.claude/skills/command-guide/reference/commands/workflow/test-gen.md +0 -529
  799. package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +0 -766
  800. package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +0 -433
  801. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +0 -487
  802. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +0 -518
  803. package/.claude/skills/command-guide/reference/commands/workflow/tools/tdd-coverage-analysis.md +0 -309
  804. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +0 -163
  805. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-context-gather.md +0 -232
  806. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +0 -254
  807. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/animation-extract.md +0 -1150
  808. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/codify-style.md +0 -652
  809. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/design-sync.md +0 -454
  810. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/explore-auto.md +0 -678
  811. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +0 -504
  812. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/imitate-auto.md +0 -745
  813. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +0 -537
  814. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/layout-extract.md +0 -788
  815. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/reference-page-generator.md +0 -356
  816. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/style-extract.md +0 -773
  817. package/.claude/skills/command-guide/scripts/analyze_commands.py +0 -502
  818. package/.claude/skills/command-guide/scripts/update-index.sh +0 -130
  819. package/.claude/skills/command-guide/templates/issue-bug.md +0 -104
  820. package/.claude/skills/command-guide/templates/issue-diagnosis.md +0 -275
  821. package/.claude/skills/command-guide/templates/issue-feature.md +0 -97
  822. package/.claude/skills/command-guide/templates/issue-question.md +0 -141
@@ -0,0 +1,1195 @@
1
+ /**
2
+ * CodexLens configuration + environment handlers.
3
+ */
4
+ import { bootstrapVenv, cancelIndexing, checkSemanticStatus, checkVenvStatus, detectGpuSupport, executeCodexLens, isIndexingInProgress, uninstallCodexLens, } from '../../../tools/codex-lens.js';
5
+ import { EXEC_TIMEOUTS } from '../../../utils/exec-constants.js';
6
+ import { extractJSON } from './utils.js';
7
+ import { stopWatcherForUninstall } from './watcher-handlers.js';
8
+ export async function handleCodexLensConfigRoutes(ctx) {
9
+ const { pathname, url, req, res, initialPath, handlePostRequest, broadcastToClients } = ctx;
10
+ // API: CodexLens Status
11
+ if (pathname === '/api/codexlens/status') {
12
+ const status = await checkVenvStatus();
13
+ res.writeHead(200, { 'Content-Type': 'application/json' });
14
+ res.end(JSON.stringify(status));
15
+ return true;
16
+ }
17
+ // API: CodexLens Dashboard Init - Aggregated endpoint for page initialization
18
+ if (pathname === '/api/codexlens/dashboard-init') {
19
+ try {
20
+ const venvStatus = await checkVenvStatus();
21
+ if (!venvStatus.ready) {
22
+ res.writeHead(200, { 'Content-Type': 'application/json' });
23
+ res.end(JSON.stringify({
24
+ installed: false,
25
+ status: venvStatus,
26
+ config: { index_dir: '~/.codexlens/indexes', index_count: 0 },
27
+ semantic: { available: false }
28
+ }));
29
+ return true;
30
+ }
31
+ // Parallel fetch all initialization data
32
+ const [configResult, statusResult, semanticStatus] = await Promise.all([
33
+ executeCodexLens(['config', '--json']),
34
+ executeCodexLens(['status', '--json']),
35
+ checkSemanticStatus()
36
+ ]);
37
+ // Parse config
38
+ let config = { index_dir: '~/.codexlens/indexes', index_count: 0 };
39
+ if (configResult.success) {
40
+ try {
41
+ const configData = extractJSON(configResult.output ?? '');
42
+ if (configData.success && configData.result) {
43
+ config.index_dir = configData.result.index_dir || configData.result.index_root || config.index_dir;
44
+ }
45
+ }
46
+ catch (e) {
47
+ console.error('[CodexLens] Failed to parse config for dashboard init:', e instanceof Error ? e.message : String(e));
48
+ }
49
+ }
50
+ // Parse status
51
+ let statusData = {};
52
+ if (statusResult.success) {
53
+ try {
54
+ const status = extractJSON(statusResult.output ?? '');
55
+ if (status.success && status.result) {
56
+ config.index_count = status.result.projects_count || 0;
57
+ statusData = status.result;
58
+ }
59
+ }
60
+ catch (e) {
61
+ console.error('[CodexLens] Failed to parse status for dashboard init:', e instanceof Error ? e.message : String(e));
62
+ }
63
+ }
64
+ res.writeHead(200, { 'Content-Type': 'application/json' });
65
+ res.end(JSON.stringify({
66
+ installed: true,
67
+ status: venvStatus,
68
+ config,
69
+ semantic: semanticStatus,
70
+ statusData
71
+ }));
72
+ }
73
+ catch (err) {
74
+ res.writeHead(500, { 'Content-Type': 'application/json' });
75
+ res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }));
76
+ }
77
+ return true;
78
+ }
79
+ // API: CodexLens Workspace Status - Get FTS and Vector index status for current workspace
80
+ if (pathname === '/api/codexlens/workspace-status') {
81
+ try {
82
+ const venvStatus = await checkVenvStatus();
83
+ // Default response when not installed
84
+ if (!venvStatus.ready) {
85
+ res.writeHead(200, { 'Content-Type': 'application/json' });
86
+ res.end(JSON.stringify({
87
+ success: true,
88
+ hasIndex: false,
89
+ fts: { percent: 0, indexedFiles: 0, totalFiles: 0 },
90
+ vector: { percent: 0, filesWithEmbeddings: 0, totalFiles: 0, totalChunks: 0 }
91
+ }));
92
+ return true;
93
+ }
94
+ // Use path from query param, fallback to initialPath
95
+ const projectPath = url.searchParams.get('path') || initialPath;
96
+ // Get project info using 'projects show' command
97
+ const projectResult = await executeCodexLens(['projects', 'show', projectPath, '--json']);
98
+ if (!projectResult.success) {
99
+ // No index for this workspace
100
+ res.writeHead(200, { 'Content-Type': 'application/json' });
101
+ res.end(JSON.stringify({
102
+ success: true,
103
+ hasIndex: false,
104
+ fts: { percent: 0, indexedFiles: 0, totalFiles: 0 },
105
+ vector: { percent: 0, filesWithEmbeddings: 0, totalFiles: 0, totalChunks: 0 }
106
+ }));
107
+ return true;
108
+ }
109
+ // Parse project data
110
+ let projectData = null;
111
+ try {
112
+ const parsed = extractJSON(projectResult.output ?? '');
113
+ if (parsed.success && parsed.result) {
114
+ projectData = parsed.result;
115
+ }
116
+ }
117
+ catch (e) {
118
+ console.error('[CodexLens] Failed to parse project data:', e instanceof Error ? e.message : String(e));
119
+ }
120
+ if (!projectData) {
121
+ res.writeHead(200, { 'Content-Type': 'application/json' });
122
+ res.end(JSON.stringify({
123
+ success: true,
124
+ hasIndex: false,
125
+ fts: { percent: 0, indexedFiles: 0, totalFiles: 0 },
126
+ vector: { percent: 0, filesWithEmbeddings: 0, totalFiles: 0, totalChunks: 0 }
127
+ }));
128
+ return true;
129
+ }
130
+ // Get index status for embeddings coverage using 'index status' command
131
+ const indexStatusResult = await executeCodexLens(['index', 'status', projectPath, '--json']);
132
+ let embeddingsData = null;
133
+ if (indexStatusResult.success && indexStatusResult.output) {
134
+ try {
135
+ const parsed = extractJSON(indexStatusResult.output);
136
+ if (parsed.success && parsed.result?.embeddings) {
137
+ embeddingsData = parsed.result.embeddings;
138
+ }
139
+ }
140
+ catch (e) {
141
+ console.error('[CodexLens] Failed to parse index status:', e instanceof Error ? e.message : String(e));
142
+ }
143
+ }
144
+ // Calculate FTS and Vector percentages
145
+ const totalFiles = projectData.total_files || 0;
146
+ const indexedFiles = projectData.total_files || 0; // All indexed files have FTS
147
+ // Get embeddings data from index status
148
+ // The response structure is: { total_indexes, indexes_with_embeddings, total_chunks, indexes: [{coverage_percent, total_files, ...}] }
149
+ const indexesWithEmbeddings = embeddingsData?.indexes_with_embeddings || 0;
150
+ const totalChunks = embeddingsData?.total_chunks || 0;
151
+ // coverage_percent is in the indexes array - get the first one (for single project query)
152
+ const indexEntry = embeddingsData?.indexes?.[0];
153
+ const vectorPercent = indexEntry?.coverage_percent || 0;
154
+ const filesWithEmbeddings = indexEntry?.total_files || 0;
155
+ // FTS percentage (all indexed files have FTS, so it's always 100% if indexed)
156
+ const ftsPercent = totalFiles > 0 ? 100 : 0;
157
+ res.writeHead(200, { 'Content-Type': 'application/json' });
158
+ res.end(JSON.stringify({
159
+ success: true,
160
+ hasIndex: true,
161
+ path: projectPath,
162
+ fts: {
163
+ percent: ftsPercent,
164
+ indexedFiles,
165
+ totalFiles
166
+ },
167
+ vector: {
168
+ percent: vectorPercent,
169
+ filesWithEmbeddings,
170
+ totalFiles,
171
+ totalChunks
172
+ }
173
+ }));
174
+ }
175
+ catch (err) {
176
+ res.writeHead(500, { 'Content-Type': 'application/json' });
177
+ res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }));
178
+ }
179
+ return true;
180
+ }
181
+ // API: CodexLens Bootstrap (Install)
182
+ if (pathname === '/api/codexlens/bootstrap' && req.method === 'POST') {
183
+ handlePostRequest(req, res, async () => {
184
+ try {
185
+ const result = await bootstrapVenv();
186
+ if (result.success) {
187
+ const status = await checkVenvStatus();
188
+ broadcastToClients({
189
+ type: 'CODEXLENS_INSTALLED',
190
+ payload: { version: status.version, timestamp: new Date().toISOString() }
191
+ });
192
+ return { success: true, message: 'CodexLens installed successfully', version: status.version };
193
+ }
194
+ else {
195
+ return { success: false, error: result.error, status: 500 };
196
+ }
197
+ }
198
+ catch (err) {
199
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
200
+ }
201
+ });
202
+ return true;
203
+ }
204
+ // API: CodexLens Uninstall
205
+ if (pathname === '/api/codexlens/uninstall' && req.method === 'POST') {
206
+ handlePostRequest(req, res, async () => {
207
+ try {
208
+ // Stop watcher if running (to release file handles)
209
+ await stopWatcherForUninstall();
210
+ if (isIndexingInProgress()) {
211
+ console.log('[CodexLens] Cancelling indexing before uninstall...');
212
+ try {
213
+ cancelIndexing();
214
+ }
215
+ catch {
216
+ // Ignore errors
217
+ }
218
+ }
219
+ // Wait a moment for processes to fully exit and release handles
220
+ await new Promise(resolve => setTimeout(resolve, 1000));
221
+ const result = await uninstallCodexLens();
222
+ if (result.success) {
223
+ broadcastToClients({
224
+ type: 'CODEXLENS_UNINSTALLED',
225
+ payload: { timestamp: new Date().toISOString() }
226
+ });
227
+ return { success: true, message: 'CodexLens uninstalled successfully' };
228
+ }
229
+ else {
230
+ return { success: false, error: result.error, status: 500 };
231
+ }
232
+ }
233
+ catch (err) {
234
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
235
+ }
236
+ });
237
+ return true;
238
+ }
239
+ // API: CodexLens Config - GET (Get current configuration with index count)
240
+ if (pathname === '/api/codexlens/config' && req.method === 'GET') {
241
+ try {
242
+ const venvStatus = await checkVenvStatus();
243
+ let responseData = { index_dir: '~/.codexlens/indexes', index_count: 0, api_max_workers: 4, api_batch_size: 8 };
244
+ // If not installed, return default config without executing CodexLens
245
+ if (!venvStatus.ready) {
246
+ res.writeHead(200, { 'Content-Type': 'application/json' });
247
+ res.end(JSON.stringify(responseData));
248
+ return true;
249
+ }
250
+ // Use projects list for accurate index_count (same source as /api/codexlens/indexes)
251
+ const [configResult, projectsResult] = await Promise.all([
252
+ executeCodexLens(['config', '--json']),
253
+ executeCodexLens(['projects', 'list', '--json'])
254
+ ]);
255
+ // Parse config (extract JSON from output that may contain log messages)
256
+ if (configResult.success) {
257
+ try {
258
+ const config = extractJSON(configResult.output ?? '');
259
+ if (config.success && config.result) {
260
+ // CLI returns index_dir (not index_root)
261
+ responseData.index_dir = config.result.index_dir || config.result.index_root || responseData.index_dir;
262
+ // Extract API settings
263
+ if (config.result.api_max_workers !== undefined) {
264
+ responseData.api_max_workers = config.result.api_max_workers;
265
+ }
266
+ if (config.result.api_batch_size !== undefined) {
267
+ responseData.api_batch_size = config.result.api_batch_size;
268
+ }
269
+ }
270
+ }
271
+ catch (e) {
272
+ console.error('[CodexLens] Failed to parse config:', e instanceof Error ? e.message : String(e));
273
+ console.error('[CodexLens] Config output:', (configResult.output ?? '').substring(0, 200));
274
+ }
275
+ }
276
+ // Parse projects list to get index_count (consistent with /api/codexlens/indexes)
277
+ if (projectsResult.success) {
278
+ try {
279
+ const projectsData = extractJSON(projectsResult.output ?? '');
280
+ if (projectsData.success && Array.isArray(projectsData.result)) {
281
+ // Filter out test/temp projects (same logic as /api/codexlens/indexes)
282
+ const validProjects = projectsData.result.filter((project) => {
283
+ if (project.source_root && (project.source_root.includes('\\Temp\\') ||
284
+ project.source_root.includes('/tmp/') ||
285
+ project.total_files === 0)) {
286
+ return false;
287
+ }
288
+ return true;
289
+ });
290
+ responseData.index_count = validProjects.length;
291
+ }
292
+ }
293
+ catch (e) {
294
+ console.error('[CodexLens] Failed to parse projects list:', e instanceof Error ? e.message : String(e));
295
+ console.error('[CodexLens] Projects output:', (projectsResult.output ?? '').substring(0, 200));
296
+ }
297
+ }
298
+ res.writeHead(200, { 'Content-Type': 'application/json' });
299
+ res.end(JSON.stringify(responseData));
300
+ }
301
+ catch (err) {
302
+ res.writeHead(500, { 'Content-Type': 'application/json' });
303
+ res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
304
+ }
305
+ return true;
306
+ }
307
+ // API: CodexLens Config - POST (Set configuration)
308
+ if (pathname === '/api/codexlens/config' && req.method === 'POST') {
309
+ handlePostRequest(req, res, async (body) => {
310
+ const { index_dir, api_max_workers, api_batch_size } = body;
311
+ if (!index_dir) {
312
+ return { success: false, error: 'index_dir is required', status: 400 };
313
+ }
314
+ // Validate index_dir path
315
+ const indexDirStr = String(index_dir).trim();
316
+ // Check for dangerous patterns
317
+ if (indexDirStr.includes('\0')) {
318
+ return { success: false, error: 'Invalid path: contains null bytes', status: 400 };
319
+ }
320
+ // Prevent system root paths and their subdirectories (Windows and Unix)
321
+ const dangerousPaths = ['/', 'C:\\', 'C:/', '/etc', '/usr', '/bin', '/sys', '/proc', '/var',
322
+ 'C:\\Windows', 'C:\\Program Files', 'C:\\Program Files (x86)', 'C:\\System32'];
323
+ const normalizedPath = indexDirStr.replace(/\\/g, '/').toLowerCase();
324
+ for (const dangerous of dangerousPaths) {
325
+ const dangerousLower = dangerous.replace(/\\/g, '/').toLowerCase();
326
+ // Block exact match OR any subdirectory (using startsWith)
327
+ if (normalizedPath === dangerousLower ||
328
+ normalizedPath === dangerousLower + '/' ||
329
+ normalizedPath.startsWith(dangerousLower + '/')) {
330
+ return { success: false, error: 'Invalid path: cannot use system directories or their subdirectories', status: 400 };
331
+ }
332
+ }
333
+ // Additional check: prevent path traversal attempts
334
+ if (normalizedPath.includes('../') || normalizedPath.includes('/..')) {
335
+ return { success: false, error: 'Invalid path: path traversal not allowed', status: 400 };
336
+ }
337
+ // Validate api settings
338
+ if (api_max_workers !== undefined) {
339
+ const workers = Number(api_max_workers);
340
+ if (isNaN(workers) || workers < 1 || workers > 32) {
341
+ return { success: false, error: 'api_max_workers must be between 1 and 32', status: 400 };
342
+ }
343
+ }
344
+ if (api_batch_size !== undefined) {
345
+ const batch = Number(api_batch_size);
346
+ if (isNaN(batch) || batch < 1 || batch > 64) {
347
+ return { success: false, error: 'api_batch_size must be between 1 and 64', status: 400 };
348
+ }
349
+ }
350
+ try {
351
+ // Set index_dir
352
+ const result = await executeCodexLens(['config', 'set', 'index_dir', indexDirStr, '--json']);
353
+ if (!result.success) {
354
+ return { success: false, error: result.error || 'Failed to update index_dir', status: 500 };
355
+ }
356
+ // Set API settings if provided
357
+ if (api_max_workers !== undefined) {
358
+ await executeCodexLens(['config', 'set', 'api_max_workers', String(api_max_workers), '--json']);
359
+ }
360
+ if (api_batch_size !== undefined) {
361
+ await executeCodexLens(['config', 'set', 'api_batch_size', String(api_batch_size), '--json']);
362
+ }
363
+ return { success: true, message: 'Configuration updated successfully' };
364
+ }
365
+ catch (err) {
366
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
367
+ }
368
+ });
369
+ return true;
370
+ }
371
+ // API: Detect GPU support for semantic search
372
+ if (pathname === '/api/codexlens/gpu/detect' && req.method === 'GET') {
373
+ try {
374
+ const gpuInfo = await detectGpuSupport();
375
+ res.writeHead(200, { 'Content-Type': 'application/json' });
376
+ res.end(JSON.stringify({ success: true, ...gpuInfo }));
377
+ }
378
+ catch (err) {
379
+ res.writeHead(500, { 'Content-Type': 'application/json' });
380
+ res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }));
381
+ }
382
+ return true;
383
+ }
384
+ // API: List available GPU devices for selection
385
+ if (pathname === '/api/codexlens/gpu/list' && req.method === 'GET') {
386
+ try {
387
+ // Try CodexLens gpu-list first if available
388
+ const venvStatus = await checkVenvStatus();
389
+ if (venvStatus.ready) {
390
+ const result = await executeCodexLens(['gpu-list', '--json']);
391
+ if (result.success) {
392
+ try {
393
+ const parsed = extractJSON(result.output ?? '');
394
+ if (parsed.devices && parsed.devices.length > 0) {
395
+ res.writeHead(200, { 'Content-Type': 'application/json' });
396
+ res.end(JSON.stringify(parsed));
397
+ return true;
398
+ }
399
+ }
400
+ catch {
401
+ // Fall through to system detection
402
+ }
403
+ }
404
+ }
405
+ // Fallback: Use system commands to detect GPUs
406
+ const devices = [];
407
+ if (process.platform === 'win32') {
408
+ // Windows: Use WMIC to get GPU info
409
+ try {
410
+ const { execSync } = await import('child_process');
411
+ const wmicOutput = execSync('wmic path win32_VideoController get name', {
412
+ encoding: 'utf-8',
413
+ timeout: EXEC_TIMEOUTS.SYSTEM_INFO,
414
+ stdio: ['pipe', 'pipe', 'pipe']
415
+ });
416
+ const lines = wmicOutput.split('\n')
417
+ .map(line => line.trim())
418
+ .filter(line => line && line !== 'Name');
419
+ lines.forEach((name, index) => {
420
+ if (name) {
421
+ const isIntegrated = name.toLowerCase().includes('intel') ||
422
+ name.toLowerCase().includes('integrated');
423
+ devices.push({
424
+ name: name,
425
+ type: isIntegrated ? 'integrated' : 'discrete',
426
+ index: index
427
+ });
428
+ }
429
+ });
430
+ }
431
+ catch (e) {
432
+ console.warn('[CodexLens] WMIC GPU detection failed:', e.message);
433
+ }
434
+ }
435
+ else {
436
+ // Linux/Mac: Try nvidia-smi for NVIDIA GPUs
437
+ try {
438
+ const { execSync } = await import('child_process');
439
+ const nvidiaOutput = execSync('nvidia-smi --query-gpu=name --format=csv,noheader', {
440
+ encoding: 'utf-8',
441
+ timeout: EXEC_TIMEOUTS.SYSTEM_INFO,
442
+ stdio: ['pipe', 'pipe', 'pipe']
443
+ });
444
+ const lines = nvidiaOutput.split('\n').filter(line => line.trim());
445
+ lines.forEach((name, index) => {
446
+ devices.push({
447
+ name: name.trim(),
448
+ type: 'discrete',
449
+ index: index
450
+ });
451
+ });
452
+ }
453
+ catch {
454
+ // NVIDIA not available, that's fine
455
+ }
456
+ }
457
+ res.writeHead(200, { 'Content-Type': 'application/json' });
458
+ res.end(JSON.stringify({ success: true, devices: devices, selected_device_id: null }));
459
+ }
460
+ catch (err) {
461
+ res.writeHead(500, { 'Content-Type': 'application/json' });
462
+ res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }));
463
+ }
464
+ return true;
465
+ }
466
+ // API: Select GPU device for embedding
467
+ if (pathname === '/api/codexlens/gpu/select' && req.method === 'POST') {
468
+ handlePostRequest(req, res, async (body) => {
469
+ const { device_id } = body;
470
+ const resolvedDeviceId = typeof device_id === 'string' || typeof device_id === 'number' ? device_id : undefined;
471
+ if (resolvedDeviceId === undefined) {
472
+ return { success: false, error: 'device_id is required', status: 400 };
473
+ }
474
+ try {
475
+ const result = await executeCodexLens(['gpu-select', String(resolvedDeviceId), '--json']);
476
+ if (result.success) {
477
+ try {
478
+ const parsed = extractJSON(result.output ?? '');
479
+ return parsed;
480
+ }
481
+ catch {
482
+ return { success: true, message: 'GPU selected', output: result.output };
483
+ }
484
+ }
485
+ else {
486
+ return { success: false, error: result.error, status: 500 };
487
+ }
488
+ }
489
+ catch (err) {
490
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
491
+ }
492
+ });
493
+ return true;
494
+ }
495
+ // API: Reset GPU selection to auto-detection
496
+ if (pathname === '/api/codexlens/gpu/reset' && req.method === 'POST') {
497
+ handlePostRequest(req, res, async () => {
498
+ try {
499
+ const result = await executeCodexLens(['gpu-reset', '--json']);
500
+ if (result.success) {
501
+ try {
502
+ const parsed = extractJSON(result.output ?? '');
503
+ return parsed;
504
+ }
505
+ catch {
506
+ return { success: true, message: 'GPU selection reset', output: result.output };
507
+ }
508
+ }
509
+ else {
510
+ return { success: false, error: result.error, status: 500 };
511
+ }
512
+ }
513
+ catch (err) {
514
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
515
+ }
516
+ });
517
+ return true;
518
+ }
519
+ // API: CodexLens Model List (list available embedding models)
520
+ if (pathname === '/api/codexlens/models' && req.method === 'GET') {
521
+ try {
522
+ // Check if CodexLens is installed first (without auto-installing)
523
+ const venvStatus = await checkVenvStatus();
524
+ if (!venvStatus.ready) {
525
+ res.writeHead(200, { 'Content-Type': 'application/json' });
526
+ res.end(JSON.stringify({ success: false, error: 'CodexLens not installed' }));
527
+ return true;
528
+ }
529
+ const result = await executeCodexLens(['model-list', '--json']);
530
+ if (result.success) {
531
+ try {
532
+ const parsed = extractJSON(result.output ?? '');
533
+ res.writeHead(200, { 'Content-Type': 'application/json' });
534
+ res.end(JSON.stringify(parsed));
535
+ }
536
+ catch {
537
+ res.writeHead(200, { 'Content-Type': 'application/json' });
538
+ res.end(JSON.stringify({ success: true, result: { models: [] }, output: result.output }));
539
+ }
540
+ }
541
+ else {
542
+ res.writeHead(500, { 'Content-Type': 'application/json' });
543
+ res.end(JSON.stringify({ success: false, error: result.error }));
544
+ }
545
+ }
546
+ catch (err) {
547
+ res.writeHead(500, { 'Content-Type': 'application/json' });
548
+ res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }));
549
+ }
550
+ return true;
551
+ }
552
+ // API: CodexLens Model Download (download embedding model by profile)
553
+ if (pathname === '/api/codexlens/models/download' && req.method === 'POST') {
554
+ handlePostRequest(req, res, async (body) => {
555
+ const { profile } = body;
556
+ const resolvedProfile = typeof profile === 'string' && profile.trim().length > 0 ? profile.trim() : undefined;
557
+ if (!resolvedProfile) {
558
+ return { success: false, error: 'profile is required', status: 400 };
559
+ }
560
+ try {
561
+ const result = await executeCodexLens(['model-download', resolvedProfile, '--json'], { timeout: 600000 }); // 10 min for download
562
+ if (result.success) {
563
+ try {
564
+ const parsed = extractJSON(result.output ?? '');
565
+ return { success: true, ...parsed };
566
+ }
567
+ catch {
568
+ return { success: true, output: result.output };
569
+ }
570
+ }
571
+ else {
572
+ return { success: false, error: result.error, status: 500 };
573
+ }
574
+ }
575
+ catch (err) {
576
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
577
+ }
578
+ });
579
+ return true;
580
+ }
581
+ // API: CodexLens Model Download Custom (download any HuggingFace model)
582
+ if (pathname === '/api/codexlens/models/download-custom' && req.method === 'POST') {
583
+ handlePostRequest(req, res, async (body) => {
584
+ const { model_name, model_type } = body;
585
+ const resolvedModelName = typeof model_name === 'string' && model_name.trim().length > 0 ? model_name.trim() : undefined;
586
+ const resolvedModelType = typeof model_type === 'string' ? model_type.trim() : 'embedding';
587
+ if (!resolvedModelName) {
588
+ return { success: false, error: 'model_name is required', status: 400 };
589
+ }
590
+ // Validate model name format
591
+ if (!resolvedModelName.includes('/')) {
592
+ return { success: false, error: 'Invalid model_name format. Expected: org/model-name', status: 400 };
593
+ }
594
+ try {
595
+ const result = await executeCodexLens([
596
+ 'model-download-custom', resolvedModelName,
597
+ '--type', resolvedModelType,
598
+ '--json'
599
+ ], { timeout: 600000 }); // 10 min for download
600
+ if (result.success) {
601
+ try {
602
+ const parsed = extractJSON(result.output ?? '');
603
+ return { success: true, ...parsed };
604
+ }
605
+ catch {
606
+ return { success: true, output: result.output };
607
+ }
608
+ }
609
+ else {
610
+ return { success: false, error: result.error, status: 500 };
611
+ }
612
+ }
613
+ catch (err) {
614
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
615
+ }
616
+ });
617
+ return true;
618
+ }
619
+ // API: CodexLens Model Delete (delete embedding model by profile)
620
+ if (pathname === '/api/codexlens/models/delete' && req.method === 'POST') {
621
+ handlePostRequest(req, res, async (body) => {
622
+ const { profile } = body;
623
+ const resolvedProfile = typeof profile === 'string' && profile.trim().length > 0 ? profile.trim() : undefined;
624
+ if (!resolvedProfile) {
625
+ return { success: false, error: 'profile is required', status: 400 };
626
+ }
627
+ try {
628
+ const result = await executeCodexLens(['model-delete', resolvedProfile, '--json']);
629
+ if (result.success) {
630
+ try {
631
+ const parsed = extractJSON(result.output ?? '');
632
+ return { success: true, ...parsed };
633
+ }
634
+ catch {
635
+ return { success: true, output: result.output };
636
+ }
637
+ }
638
+ else {
639
+ return { success: false, error: result.error, status: 500 };
640
+ }
641
+ }
642
+ catch (err) {
643
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
644
+ }
645
+ });
646
+ return true;
647
+ }
648
+ // API: CodexLens Model Delete by Path (delete discovered/manually placed model)
649
+ if (pathname === '/api/codexlens/models/delete-path' && req.method === 'POST') {
650
+ handlePostRequest(req, res, async (body) => {
651
+ const { cache_path } = body;
652
+ const resolvedPath = typeof cache_path === 'string' && cache_path.trim().length > 0 ? cache_path.trim() : undefined;
653
+ if (!resolvedPath) {
654
+ return { success: false, error: 'cache_path is required', status: 400 };
655
+ }
656
+ // Security: Validate that the path is within the HuggingFace cache directory
657
+ const { homedir } = await import('os');
658
+ const { join, resolve, normalize } = await import('path');
659
+ const { rm } = await import('fs/promises');
660
+ const hfCacheDir = process.env.HF_HOME || join(homedir(), '.cache', 'huggingface');
661
+ const normalizedCachePath = normalize(resolve(resolvedPath));
662
+ const normalizedHfCacheDir = normalize(resolve(hfCacheDir));
663
+ // Ensure the path is within the HuggingFace cache directory
664
+ if (!normalizedCachePath.startsWith(normalizedHfCacheDir)) {
665
+ return { success: false, error: 'Path must be within the HuggingFace cache directory', status: 400 };
666
+ }
667
+ // Ensure it's a models-- directory
668
+ const pathParts = normalizedCachePath.split(/[/\\]/);
669
+ const lastPart = pathParts[pathParts.length - 1];
670
+ if (!lastPart.startsWith('models--')) {
671
+ return { success: false, error: 'Path must be a model cache directory (models--*)', status: 400 };
672
+ }
673
+ try {
674
+ await rm(normalizedCachePath, { recursive: true, force: true });
675
+ return { success: true, message: 'Model deleted successfully', cache_path: normalizedCachePath };
676
+ }
677
+ catch (err) {
678
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
679
+ }
680
+ });
681
+ return true;
682
+ }
683
+ // API: CodexLens Model Info (get model info by profile)
684
+ if (pathname === '/api/codexlens/models/info' && req.method === 'GET') {
685
+ const profile = url.searchParams.get('profile');
686
+ if (!profile) {
687
+ res.writeHead(400, { 'Content-Type': 'application/json' });
688
+ res.end(JSON.stringify({ success: false, error: 'profile parameter is required' }));
689
+ return true;
690
+ }
691
+ try {
692
+ const result = await executeCodexLens(['model-info', profile, '--json']);
693
+ if (result.success) {
694
+ try {
695
+ const parsed = extractJSON(result.output ?? '');
696
+ res.writeHead(200, { 'Content-Type': 'application/json' });
697
+ res.end(JSON.stringify(parsed));
698
+ }
699
+ catch {
700
+ res.writeHead(200, { 'Content-Type': 'application/json' });
701
+ res.end(JSON.stringify({ success: false, error: 'Failed to parse response' }));
702
+ }
703
+ }
704
+ else {
705
+ res.writeHead(500, { 'Content-Type': 'application/json' });
706
+ res.end(JSON.stringify({ success: false, error: result.error }));
707
+ }
708
+ }
709
+ catch (err) {
710
+ res.writeHead(500, { 'Content-Type': 'application/json' });
711
+ res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }));
712
+ }
713
+ return true;
714
+ }
715
+ // ============================================================
716
+ // ENV FILE MANAGEMENT ENDPOINTS
717
+ // ============================================================
718
+ // API: Get global env file content
719
+ if (pathname === '/api/codexlens/env' && req.method === 'GET') {
720
+ try {
721
+ const { homedir } = await import('os');
722
+ const { join } = await import('path');
723
+ const { readFile } = await import('fs/promises');
724
+ const envPath = join(homedir(), '.codexlens', '.env');
725
+ let content = '';
726
+ try {
727
+ content = await readFile(envPath, 'utf-8');
728
+ }
729
+ catch {
730
+ // File doesn't exist, return empty
731
+ }
732
+ // Parse env file into key-value pairs (robust parsing)
733
+ const envVars = {};
734
+ const lines = content.split('\n');
735
+ for (const line of lines) {
736
+ const trimmed = line.trim();
737
+ // Skip empty lines and comments
738
+ if (!trimmed || trimmed.startsWith('#'))
739
+ continue;
740
+ // Find first = that's part of key=value (not in a quote)
741
+ const eqIndex = trimmed.indexOf('=');
742
+ if (eqIndex <= 0)
743
+ continue;
744
+ const key = trimmed.substring(0, eqIndex).trim();
745
+ // Validate key format (alphanumeric + underscore)
746
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
747
+ continue;
748
+ let value = trimmed.substring(eqIndex + 1);
749
+ // Handle quoted values (preserves = inside quotes)
750
+ if (value.startsWith('"')) {
751
+ // Find matching closing quote (handle escaped quotes)
752
+ let end = 1;
753
+ while (end < value.length) {
754
+ if (value[end] === '"' && value[end - 1] !== '\\')
755
+ break;
756
+ end++;
757
+ }
758
+ value = value.substring(1, end).replace(/\\"/g, '"');
759
+ }
760
+ else if (value.startsWith("'")) {
761
+ // Single quotes don't support escaping
762
+ const end = value.indexOf("'", 1);
763
+ value = end > 0 ? value.substring(1, end) : value.substring(1);
764
+ }
765
+ else {
766
+ // Unquoted: trim and take until comment or end
767
+ const commentIndex = value.indexOf(' #');
768
+ if (commentIndex > 0) {
769
+ value = value.substring(0, commentIndex);
770
+ }
771
+ value = value.trim();
772
+ }
773
+ envVars[key] = value;
774
+ }
775
+ // Also read settings.json for current configuration
776
+ const settingsPath = join(homedir(), '.codexlens', 'settings.json');
777
+ let settings = {};
778
+ try {
779
+ const settingsContent = await readFile(settingsPath, 'utf-8');
780
+ settings = JSON.parse(settingsContent);
781
+ }
782
+ catch {
783
+ // Settings file doesn't exist or is invalid, use empty
784
+ }
785
+ // Map settings to env var format for defaults
786
+ const settingsDefaults = {};
787
+ // Embedding settings
788
+ if (settings.embedding?.backend) {
789
+ settingsDefaults['CODEXLENS_EMBEDDING_BACKEND'] = settings.embedding.backend;
790
+ }
791
+ if (settings.embedding?.model) {
792
+ settingsDefaults['CODEXLENS_EMBEDDING_MODEL'] = settings.embedding.model;
793
+ settingsDefaults['LITELLM_EMBEDDING_MODEL'] = settings.embedding.model;
794
+ }
795
+ if (settings.embedding?.use_gpu !== undefined) {
796
+ settingsDefaults['CODEXLENS_USE_GPU'] = String(settings.embedding.use_gpu);
797
+ }
798
+ if (settings.embedding?.strategy) {
799
+ settingsDefaults['CODEXLENS_EMBEDDING_STRATEGY'] = settings.embedding.strategy;
800
+ }
801
+ if (settings.embedding?.cooldown !== undefined) {
802
+ settingsDefaults['CODEXLENS_EMBEDDING_COOLDOWN'] = String(settings.embedding.cooldown);
803
+ }
804
+ // Reranker settings
805
+ if (settings.reranker?.backend) {
806
+ settingsDefaults['CODEXLENS_RERANKER_BACKEND'] = settings.reranker.backend;
807
+ }
808
+ if (settings.reranker?.model) {
809
+ settingsDefaults['CODEXLENS_RERANKER_MODEL'] = settings.reranker.model;
810
+ settingsDefaults['LITELLM_RERANKER_MODEL'] = settings.reranker.model;
811
+ }
812
+ if (settings.reranker?.enabled !== undefined) {
813
+ settingsDefaults['CODEXLENS_RERANKER_ENABLED'] = String(settings.reranker.enabled);
814
+ }
815
+ if (settings.reranker?.top_k !== undefined) {
816
+ settingsDefaults['CODEXLENS_RERANKER_TOP_K'] = String(settings.reranker.top_k);
817
+ }
818
+ // API/Concurrency settings
819
+ if (settings.api?.max_workers !== undefined) {
820
+ settingsDefaults['CODEXLENS_API_MAX_WORKERS'] = String(settings.api.max_workers);
821
+ }
822
+ if (settings.api?.batch_size !== undefined) {
823
+ settingsDefaults['CODEXLENS_API_BATCH_SIZE'] = String(settings.api.batch_size);
824
+ }
825
+ // Dynamic batch size settings
826
+ if (settings.api?.batch_size_dynamic !== undefined) {
827
+ settingsDefaults['CODEXLENS_API_BATCH_SIZE_DYNAMIC'] = String(settings.api.batch_size_dynamic);
828
+ }
829
+ if (settings.api?.batch_size_utilization_factor !== undefined) {
830
+ settingsDefaults['CODEXLENS_API_BATCH_SIZE_UTILIZATION'] = String(settings.api.batch_size_utilization_factor);
831
+ }
832
+ if (settings.api?.batch_size_max !== undefined) {
833
+ settingsDefaults['CODEXLENS_API_BATCH_SIZE_MAX'] = String(settings.api.batch_size_max);
834
+ }
835
+ if (settings.api?.chars_per_token_estimate !== undefined) {
836
+ settingsDefaults['CODEXLENS_CHARS_PER_TOKEN'] = String(settings.api.chars_per_token_estimate);
837
+ }
838
+ // Cascade search settings
839
+ if (settings.cascade?.strategy) {
840
+ settingsDefaults['CODEXLENS_CASCADE_STRATEGY'] = settings.cascade.strategy;
841
+ }
842
+ if (settings.cascade?.coarse_k !== undefined) {
843
+ settingsDefaults['CODEXLENS_CASCADE_COARSE_K'] = String(settings.cascade.coarse_k);
844
+ }
845
+ if (settings.cascade?.fine_k !== undefined) {
846
+ settingsDefaults['CODEXLENS_CASCADE_FINE_K'] = String(settings.cascade.fine_k);
847
+ }
848
+ // LLM settings
849
+ if (settings.llm?.enabled !== undefined) {
850
+ settingsDefaults['CODEXLENS_LLM_ENABLED'] = String(settings.llm.enabled);
851
+ }
852
+ if (settings.llm?.batch_size !== undefined) {
853
+ settingsDefaults['CODEXLENS_LLM_BATCH_SIZE'] = String(settings.llm.batch_size);
854
+ }
855
+ res.writeHead(200, { 'Content-Type': 'application/json' });
856
+ res.end(JSON.stringify({
857
+ success: true,
858
+ path: envPath,
859
+ env: envVars,
860
+ raw: content,
861
+ settings: settingsDefaults
862
+ }));
863
+ }
864
+ catch (err) {
865
+ res.writeHead(500, { 'Content-Type': 'application/json' });
866
+ res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }));
867
+ }
868
+ return true;
869
+ }
870
+ // API: Save global env file content (merge mode - preserves existing values)
871
+ if (pathname === '/api/codexlens/env' && req.method === 'POST') {
872
+ handlePostRequest(req, res, async (body) => {
873
+ const { env } = body;
874
+ if (!env || typeof env !== 'object') {
875
+ return { success: false, error: 'env object is required', status: 400 };
876
+ }
877
+ try {
878
+ const { homedir } = await import('os');
879
+ const { join, dirname } = await import('path');
880
+ const { writeFile, mkdir, readFile } = await import('fs/promises');
881
+ const envPath = join(homedir(), '.codexlens', '.env');
882
+ await mkdir(dirname(envPath), { recursive: true });
883
+ // Read existing env file to preserve custom variables
884
+ let existingEnv = {};
885
+ let existingComments = [];
886
+ try {
887
+ const content = await readFile(envPath, 'utf-8');
888
+ const lines = content.split('\n');
889
+ for (const line of lines) {
890
+ const trimmed = line.trim();
891
+ // Preserve comment lines that aren't our headers
892
+ if (trimmed.startsWith('#') && !trimmed.includes('Managed by CCW')) {
893
+ if (!trimmed.includes('Reranker API') && !trimmed.includes('Embedding API') &&
894
+ !trimmed.includes('LiteLLM Config') && !trimmed.includes('CodexLens Settings') &&
895
+ !trimmed.includes('Other Settings') && !trimmed.includes('CodexLens Environment')) {
896
+ existingComments.push(line);
897
+ }
898
+ }
899
+ if (!trimmed || trimmed.startsWith('#'))
900
+ continue;
901
+ // Robust parsing (same as GET handler)
902
+ const eqIndex = trimmed.indexOf('=');
903
+ if (eqIndex <= 0)
904
+ continue;
905
+ const key = trimmed.substring(0, eqIndex).trim();
906
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
907
+ continue;
908
+ let value = trimmed.substring(eqIndex + 1);
909
+ if (value.startsWith('"')) {
910
+ let end = 1;
911
+ while (end < value.length) {
912
+ if (value[end] === '"' && value[end - 1] !== '\\')
913
+ break;
914
+ end++;
915
+ }
916
+ value = value.substring(1, end).replace(/\\"/g, '"');
917
+ }
918
+ else if (value.startsWith("'")) {
919
+ const end = value.indexOf("'", 1);
920
+ value = end > 0 ? value.substring(1, end) : value.substring(1);
921
+ }
922
+ else {
923
+ const commentIndex = value.indexOf(' #');
924
+ if (commentIndex > 0)
925
+ value = value.substring(0, commentIndex);
926
+ value = value.trim();
927
+ }
928
+ existingEnv[key] = value;
929
+ }
930
+ }
931
+ catch {
932
+ // File doesn't exist, start fresh
933
+ }
934
+ // Merge: update known keys from payload, preserve unknown keys
935
+ const knownKeys = new Set([
936
+ 'RERANKER_API_KEY', 'RERANKER_API_BASE', 'RERANKER_MODEL',
937
+ 'EMBEDDING_API_KEY', 'EMBEDDING_API_BASE', 'EMBEDDING_MODEL',
938
+ 'LITELLM_API_KEY', 'LITELLM_API_BASE', 'LITELLM_MODEL'
939
+ ]);
940
+ // Apply updates from payload
941
+ for (const [key, value] of Object.entries(env)) {
942
+ if (value) {
943
+ existingEnv[key] = value;
944
+ }
945
+ else if (knownKeys.has(key)) {
946
+ // Remove known key if value is empty
947
+ delete existingEnv[key];
948
+ }
949
+ }
950
+ // Build env file content
951
+ const lines = [
952
+ '# CodexLens Environment Configuration',
953
+ '# Managed by CCW Dashboard',
954
+ ''
955
+ ];
956
+ // Add preserved custom comments
957
+ if (existingComments.length > 0) {
958
+ lines.push(...existingComments, '');
959
+ }
960
+ // Group by prefix
961
+ const groups = {
962
+ 'RERANKER': [],
963
+ 'EMBEDDING': [],
964
+ 'LITELLM': [],
965
+ 'CODEXLENS': [],
966
+ 'OTHER': []
967
+ };
968
+ for (const [key, value] of Object.entries(existingEnv)) {
969
+ if (!value)
970
+ continue;
971
+ // SECURITY: Escape special characters to prevent .env injection
972
+ const escapedValue = value
973
+ .replace(/\\/g, '\\\\') // Escape backslashes first
974
+ .replace(/"/g, '\\"') // Escape double quotes
975
+ .replace(/\n/g, '\\n') // Escape newlines
976
+ .replace(/\r/g, '\\r'); // Escape carriage returns
977
+ const line = `${key}="${escapedValue}"`;
978
+ if (key.startsWith('RERANKER_'))
979
+ groups['RERANKER'].push(line);
980
+ else if (key.startsWith('EMBEDDING_'))
981
+ groups['EMBEDDING'].push(line);
982
+ else if (key.startsWith('LITELLM_'))
983
+ groups['LITELLM'].push(line);
984
+ else if (key.startsWith('CODEXLENS_'))
985
+ groups['CODEXLENS'].push(line);
986
+ else
987
+ groups['OTHER'].push(line);
988
+ }
989
+ // Add grouped content
990
+ if (groups['RERANKER'].length) {
991
+ lines.push('# Reranker API Configuration');
992
+ lines.push(...groups['RERANKER'], '');
993
+ }
994
+ if (groups['EMBEDDING'].length) {
995
+ lines.push('# Embedding API Configuration');
996
+ lines.push(...groups['EMBEDDING'], '');
997
+ }
998
+ if (groups['LITELLM'].length) {
999
+ lines.push('# LiteLLM Configuration');
1000
+ lines.push(...groups['LITELLM'], '');
1001
+ }
1002
+ if (groups['CODEXLENS'].length) {
1003
+ lines.push('# CodexLens Settings');
1004
+ lines.push(...groups['CODEXLENS'], '');
1005
+ }
1006
+ if (groups['OTHER'].length) {
1007
+ lines.push('# Other Settings');
1008
+ lines.push(...groups['OTHER'], '');
1009
+ }
1010
+ await writeFile(envPath, lines.join('\n'), 'utf-8');
1011
+ // Also update settings.json with mapped values
1012
+ const settingsPath = join(homedir(), '.codexlens', 'settings.json');
1013
+ let settings = {};
1014
+ try {
1015
+ const settingsContent = await readFile(settingsPath, 'utf-8');
1016
+ settings = JSON.parse(settingsContent);
1017
+ }
1018
+ catch {
1019
+ // File doesn't exist, create default structure
1020
+ settings = { embedding: {}, reranker: {}, api: {}, cascade: {}, llm: {} };
1021
+ }
1022
+ // Map env vars to settings.json structure
1023
+ const envToSettings = {
1024
+ 'CODEXLENS_EMBEDDING_BACKEND': { path: ['embedding', 'backend'] },
1025
+ 'CODEXLENS_EMBEDDING_MODEL': { path: ['embedding', 'model'] },
1026
+ 'CODEXLENS_USE_GPU': { path: ['embedding', 'use_gpu'], transform: v => v === 'true' },
1027
+ 'CODEXLENS_EMBEDDING_STRATEGY': { path: ['embedding', 'strategy'] },
1028
+ 'CODEXLENS_EMBEDDING_COOLDOWN': { path: ['embedding', 'cooldown'], transform: v => parseFloat(v) },
1029
+ 'CODEXLENS_RERANKER_BACKEND': { path: ['reranker', 'backend'] },
1030
+ 'CODEXLENS_RERANKER_MODEL': { path: ['reranker', 'model'] },
1031
+ 'CODEXLENS_RERANKER_ENABLED': { path: ['reranker', 'enabled'], transform: v => v === 'true' },
1032
+ 'CODEXLENS_RERANKER_TOP_K': { path: ['reranker', 'top_k'], transform: v => parseInt(v, 10) },
1033
+ 'CODEXLENS_API_MAX_WORKERS': { path: ['api', 'max_workers'], transform: v => parseInt(v, 10) },
1034
+ 'CODEXLENS_API_BATCH_SIZE': { path: ['api', 'batch_size'], transform: v => parseInt(v, 10) },
1035
+ 'CODEXLENS_API_BATCH_SIZE_DYNAMIC': { path: ['api', 'batch_size_dynamic'], transform: v => v === 'true' },
1036
+ 'CODEXLENS_API_BATCH_SIZE_UTILIZATION': { path: ['api', 'batch_size_utilization_factor'], transform: v => parseFloat(v) },
1037
+ 'CODEXLENS_API_BATCH_SIZE_MAX': { path: ['api', 'batch_size_max'], transform: v => parseInt(v, 10) },
1038
+ 'CODEXLENS_CHARS_PER_TOKEN': { path: ['api', 'chars_per_token_estimate'], transform: v => parseInt(v, 10) },
1039
+ 'CODEXLENS_CASCADE_STRATEGY': { path: ['cascade', 'strategy'] },
1040
+ 'CODEXLENS_CASCADE_COARSE_K': { path: ['cascade', 'coarse_k'], transform: v => parseInt(v, 10) },
1041
+ 'CODEXLENS_CASCADE_FINE_K': { path: ['cascade', 'fine_k'], transform: v => parseInt(v, 10) },
1042
+ 'CODEXLENS_LLM_ENABLED': { path: ['llm', 'enabled'], transform: v => v === 'true' },
1043
+ 'CODEXLENS_LLM_BATCH_SIZE': { path: ['llm', 'batch_size'], transform: v => parseInt(v, 10) },
1044
+ 'LITELLM_EMBEDDING_MODEL': { path: ['embedding', 'model'] },
1045
+ 'LITELLM_RERANKER_MODEL': { path: ['reranker', 'model'] }
1046
+ };
1047
+ // Apply env vars to settings
1048
+ for (const [envKey, value] of Object.entries(env)) {
1049
+ const mapping = envToSettings[envKey];
1050
+ if (mapping && value) {
1051
+ const [section, key] = mapping.path;
1052
+ if (!settings[section])
1053
+ settings[section] = {};
1054
+ settings[section][key] = mapping.transform ? mapping.transform(value) : value;
1055
+ }
1056
+ }
1057
+ // Write updated settings
1058
+ await writeFile(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
1059
+ return {
1060
+ success: true,
1061
+ message: 'Environment and settings configuration saved',
1062
+ path: envPath,
1063
+ settingsPath
1064
+ };
1065
+ }
1066
+ catch (err) {
1067
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
1068
+ }
1069
+ });
1070
+ return true;
1071
+ }
1072
+ // ============================================================
1073
+ // IGNORE PATTERNS CONFIGURATION ENDPOINTS
1074
+ // ============================================================
1075
+ // API: Get ignore patterns configuration
1076
+ if (pathname === '/api/codexlens/ignore-patterns' && req.method === 'GET') {
1077
+ try {
1078
+ const { homedir } = await import('os');
1079
+ const { join } = await import('path');
1080
+ const { readFile } = await import('fs/promises');
1081
+ const settingsPath = join(homedir(), '.codexlens', 'settings.json');
1082
+ let settings = {};
1083
+ try {
1084
+ const content = await readFile(settingsPath, 'utf-8');
1085
+ settings = JSON.parse(content);
1086
+ }
1087
+ catch {
1088
+ // File doesn't exist
1089
+ }
1090
+ // Default ignore patterns (matching WatcherConfig defaults in events.py)
1091
+ const defaultPatterns = [
1092
+ // Version control
1093
+ '.git', '.svn', '.hg',
1094
+ // Python environments & cache
1095
+ '.venv', 'venv', 'env', '__pycache__', '.pytest_cache', '.mypy_cache', '.ruff_cache',
1096
+ // Node.js
1097
+ 'node_modules', 'bower_components', '.npm', '.yarn',
1098
+ // Build artifacts
1099
+ 'dist', 'build', 'out', 'target', 'bin', 'obj', '_build', 'coverage', 'htmlcov',
1100
+ // IDE & Editor
1101
+ '.idea', '.vscode', '.vs', '.eclipse',
1102
+ // CodexLens internal
1103
+ '.codexlens',
1104
+ // Package manager caches
1105
+ '.cache', '.parcel-cache', '.turbo', '.next', '.nuxt',
1106
+ // Logs & temp
1107
+ 'logs', 'tmp', 'temp',
1108
+ ];
1109
+ // Default extension filters for embeddings (files skipped for vector index)
1110
+ const defaultExtensionFilters = [
1111
+ // Lock files (large, repetitive)
1112
+ 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'composer.lock', 'Gemfile.lock', 'poetry.lock',
1113
+ // Generated/minified
1114
+ '*.min.js', '*.min.css', '*.bundle.js',
1115
+ // Binary-like text
1116
+ '*.svg', '*.map',
1117
+ ];
1118
+ res.writeHead(200, { 'Content-Type': 'application/json' });
1119
+ res.end(JSON.stringify({
1120
+ success: true,
1121
+ patterns: settings.ignore_patterns || defaultPatterns,
1122
+ extensionFilters: settings.extension_filters || defaultExtensionFilters,
1123
+ defaults: {
1124
+ patterns: defaultPatterns,
1125
+ extensionFilters: defaultExtensionFilters
1126
+ }
1127
+ }));
1128
+ }
1129
+ catch (err) {
1130
+ res.writeHead(500, { 'Content-Type': 'application/json' });
1131
+ res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }));
1132
+ }
1133
+ return true;
1134
+ }
1135
+ // API: Save ignore patterns configuration
1136
+ if (pathname === '/api/codexlens/ignore-patterns' && req.method === 'POST') {
1137
+ handlePostRequest(req, res, async (body) => {
1138
+ const { patterns, extensionFilters } = body;
1139
+ try {
1140
+ const { homedir } = await import('os');
1141
+ const { join, dirname } = await import('path');
1142
+ const { writeFile, mkdir, readFile } = await import('fs/promises');
1143
+ const settingsPath = join(homedir(), '.codexlens', 'settings.json');
1144
+ await mkdir(dirname(settingsPath), { recursive: true });
1145
+ // Read existing settings
1146
+ let settings = {};
1147
+ try {
1148
+ const content = await readFile(settingsPath, 'utf-8');
1149
+ settings = JSON.parse(content);
1150
+ }
1151
+ catch {
1152
+ // File doesn't exist, start fresh
1153
+ }
1154
+ // Validate patterns (alphanumeric, dots, underscores, dashes, asterisks)
1155
+ const validPatternRegex = /^[\w.*\-/]+$/;
1156
+ if (patterns) {
1157
+ const invalidPatterns = patterns.filter(p => !validPatternRegex.test(p));
1158
+ if (invalidPatterns.length > 0) {
1159
+ return {
1160
+ success: false,
1161
+ error: `Invalid patterns: ${invalidPatterns.join(', ')}`,
1162
+ status: 400
1163
+ };
1164
+ }
1165
+ settings.ignore_patterns = patterns;
1166
+ }
1167
+ if (extensionFilters) {
1168
+ const invalidFilters = extensionFilters.filter(p => !validPatternRegex.test(p));
1169
+ if (invalidFilters.length > 0) {
1170
+ return {
1171
+ success: false,
1172
+ error: `Invalid extension filters: ${invalidFilters.join(', ')}`,
1173
+ status: 400
1174
+ };
1175
+ }
1176
+ settings.extension_filters = extensionFilters;
1177
+ }
1178
+ // Write updated settings
1179
+ await writeFile(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
1180
+ return {
1181
+ success: true,
1182
+ message: 'Ignore patterns saved successfully',
1183
+ patterns: settings.ignore_patterns,
1184
+ extensionFilters: settings.extension_filters
1185
+ };
1186
+ }
1187
+ catch (err) {
1188
+ return { success: false, error: err instanceof Error ? err.message : String(err), status: 500 };
1189
+ }
1190
+ });
1191
+ return true;
1192
+ }
1193
+ return false;
1194
+ }
1195
+ //# sourceMappingURL=config-handlers.js.map