claude-code-workflow 6.1.4 → 6.2.2

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 (437) hide show
  1. package/.claude/CLAUDE.md +10 -0
  2. package/.claude/agents/action-planning-agent.md +857 -778
  3. package/.claude/agents/cli-execution-agent.md +266 -269
  4. package/.claude/agents/cli-explore-agent.md +2 -2
  5. package/.claude/agents/cli-lite-planning-agent.md +142 -92
  6. package/.claude/agents/cli-planning-agent.md +4 -4
  7. package/.claude/agents/code-developer.md +7 -6
  8. package/.claude/agents/conceptual-planning-agent.md +2 -2
  9. package/.claude/agents/context-search-agent.md +31 -32
  10. package/.claude/agents/doc-generator.md +4 -4
  11. package/.claude/agents/memory-bridge.md +93 -93
  12. package/.claude/agents/test-context-search-agent.md +8 -7
  13. package/.claude/agents/test-fix-agent.md +7 -6
  14. package/.claude/commands/clean.md +516 -0
  15. package/.claude/commands/memory/compact.md +383 -0
  16. package/.claude/commands/memory/docs-full-cli.md +471 -471
  17. package/.claude/commands/memory/docs-related-cli.md +386 -386
  18. package/.claude/commands/memory/docs.md +615 -615
  19. package/.claude/commands/memory/load.md +5 -5
  20. package/.claude/commands/memory/tech-research-rules.md +310 -0
  21. package/.claude/commands/memory/update-full.md +332 -332
  22. package/.claude/commands/memory/workflow-skill-memory.md +4 -4
  23. package/.claude/commands/task/create.md +151 -151
  24. package/.claude/commands/version.md +254 -254
  25. package/.claude/commands/workflow/brainstorm/api-designer.md +587 -585
  26. package/.claude/commands/workflow/brainstorm/artifacts.md +1 -0
  27. package/.claude/commands/workflow/brainstorm/auto-parallel.md +443 -443
  28. package/.claude/commands/workflow/brainstorm/data-architect.md +220 -220
  29. package/.claude/commands/workflow/brainstorm/product-manager.md +200 -200
  30. package/.claude/commands/workflow/brainstorm/product-owner.md +200 -200
  31. package/.claude/commands/workflow/brainstorm/scrum-master.md +200 -200
  32. package/.claude/commands/workflow/brainstorm/subject-matter-expert.md +200 -200
  33. package/.claude/commands/workflow/brainstorm/system-architect.md +389 -387
  34. package/.claude/commands/workflow/brainstorm/ui-designer.md +221 -221
  35. package/.claude/commands/workflow/brainstorm/ux-expert.md +221 -221
  36. package/.claude/commands/workflow/debug.md +321 -0
  37. package/.claude/commands/workflow/execute.md +13 -0
  38. package/.claude/commands/workflow/init.md +165 -164
  39. package/.claude/commands/workflow/lite-execute.md +119 -13
  40. package/.claude/commands/workflow/lite-fix.md +623 -621
  41. package/.claude/commands/workflow/lite-plan.md +610 -592
  42. package/.claude/commands/workflow/plan.md +5 -5
  43. package/.claude/commands/workflow/review-module-cycle.md +2 -0
  44. package/.claude/commands/workflow/review-session-cycle.md +2 -0
  45. package/.claude/commands/workflow/review.md +297 -291
  46. package/.claude/commands/workflow/session/complete.md +153 -500
  47. package/.claude/commands/workflow/session/list.md +95 -95
  48. package/.claude/commands/workflow/session/resume.md +60 -60
  49. package/.claude/commands/workflow/session/start.md +199 -199
  50. package/.claude/commands/workflow/tdd-plan.md +3 -3
  51. package/.claude/commands/workflow/tdd-verify.md +23 -9
  52. package/.claude/commands/workflow/test-cycle-execute.md +2 -0
  53. package/.claude/commands/workflow/test-fix-gen.md +699 -699
  54. package/.claude/commands/workflow/tools/conflict-resolution.md +104 -18
  55. package/.claude/commands/workflow/tools/context-gather.md +436 -434
  56. package/.claude/commands/workflow/tools/task-generate-agent.md +490 -291
  57. package/.claude/commands/workflow/tools/task-generate-tdd.md +18 -10
  58. package/.claude/commands/workflow/tools/test-concept-enhanced.md +2 -1
  59. package/.claude/commands/workflow/tools/test-context-gather.md +1 -0
  60. package/.claude/commands/workflow/tools/test-task-generate.md +1 -0
  61. package/.claude/commands/workflow/ui-design/import-from-code.md +9 -6
  62. package/.claude/skills/command-guide/SKILL.md +5 -5
  63. package/.claude/skills/command-guide/index/all-commands.json +1 -1
  64. package/.claude/skills/command-guide/index/by-category.json +1 -1
  65. package/.claude/skills/command-guide/index/by-use-case.json +1 -1
  66. package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +857 -778
  67. package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +266 -269
  68. package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +2 -2
  69. package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +142 -92
  70. package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +4 -4
  71. package/.claude/skills/command-guide/reference/agents/code-developer.md +7 -6
  72. package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +2 -2
  73. package/.claude/skills/command-guide/reference/agents/context-search-agent.md +31 -32
  74. package/.claude/skills/command-guide/reference/agents/doc-generator.md +4 -4
  75. package/.claude/skills/command-guide/reference/agents/memory-bridge.md +93 -93
  76. package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +8 -7
  77. package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +7 -6
  78. package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -471
  79. package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -386
  80. package/.claude/skills/command-guide/reference/commands/memory/docs.md +17 -16
  81. package/.claude/skills/command-guide/reference/commands/memory/load.md +5 -5
  82. package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +194 -357
  83. package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -332
  84. package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +4 -4
  85. package/.claude/skills/command-guide/reference/commands/task/create.md +151 -151
  86. package/.claude/skills/command-guide/reference/commands/version.md +254 -254
  87. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +585 -585
  88. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +443 -443
  89. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +220 -220
  90. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +200 -200
  91. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +200 -200
  92. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +200 -200
  93. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +200 -200
  94. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +387 -387
  95. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +221 -221
  96. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +221 -221
  97. package/.claude/skills/command-guide/reference/commands/workflow/execute.md +25 -20
  98. package/.claude/skills/command-guide/reference/commands/workflow/init.md +164 -164
  99. package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +748 -686
  100. package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +664 -621
  101. package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +645 -592
  102. package/.claude/skills/command-guide/reference/commands/workflow/plan.md +5 -5
  103. package/.claude/skills/command-guide/reference/commands/workflow/review.md +25 -18
  104. package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +547 -500
  105. package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +45 -27
  106. package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +35 -19
  107. package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +90 -33
  108. package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +3 -3
  109. package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +23 -9
  110. package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +699 -699
  111. package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +103 -17
  112. package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -434
  113. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +487 -291
  114. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +17 -10
  115. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +1 -1
  116. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +6 -6
  117. package/.claude/workflows/chinese-response.md +38 -0
  118. package/.claude/workflows/cli-templates/prompts/rules/rule-api.txt +122 -0
  119. package/.claude/workflows/cli-templates/prompts/rules/rule-components.txt +122 -0
  120. package/.claude/workflows/cli-templates/prompts/rules/rule-config.txt +89 -0
  121. package/.claude/workflows/cli-templates/prompts/rules/rule-core.txt +60 -0
  122. package/.claude/workflows/cli-templates/prompts/rules/rule-patterns.txt +70 -0
  123. package/.claude/workflows/cli-templates/prompts/rules/rule-testing.txt +81 -0
  124. package/.claude/workflows/cli-templates/prompts/rules/tech-rules-agent-prompt.txt +89 -0
  125. package/.claude/workflows/cli-templates/prompts/workflow/gemini-solution-design.txt +131 -131
  126. package/.claude/workflows/cli-templates/prompts/workflow/skill-conflict-patterns.txt +5 -9
  127. package/.claude/workflows/cli-templates/prompts/workflow/skill-lessons-learned.txt +5 -9
  128. package/.claude/workflows/cli-templates/protocols/analysis-protocol.md +112 -0
  129. package/.claude/workflows/cli-templates/protocols/write-protocol.md +201 -0
  130. package/.claude/workflows/cli-templates/schemas/conflict-resolution-schema.json +137 -0
  131. package/.claude/workflows/cli-templates/schemas/debug-log-json-schema.json +127 -0
  132. package/.claude/workflows/cli-templates/schemas/fix-plan-json-schema.json +25 -0
  133. package/.claude/workflows/cli-templates/schemas/plan-json-schema.json +25 -0
  134. package/.claude/workflows/cli-tools-usage.md +526 -0
  135. package/{CLAUDE.md → .claude/workflows/coding-philosophy.md} +24 -45
  136. package/.claude/workflows/context-tools.md +84 -0
  137. package/.claude/workflows/file-modification.md +64 -0
  138. package/.claude/workflows/tool-strategy.md +216 -79
  139. package/.claude/workflows/windows-platform.md +16 -0
  140. package/.claude/workflows/workflow-architecture.md +942 -942
  141. package/.codex/AGENTS.md +63 -330
  142. package/.codex/prompts/debug.md +318 -0
  143. package/.codex/prompts/execute.md +273 -0
  144. package/.codex/prompts/lite-execute.md +164 -0
  145. package/.codex/prompts/lite-plan.md +469 -0
  146. package/.codex/prompts.zip +0 -0
  147. package/.gemini/GEMINI.md +25 -164
  148. package/.qwen/QWEN.md +0 -139
  149. package/README.md +29 -9
  150. package/ccw/README.md +30 -6
  151. package/ccw/bin/ccw-mcp.js +7 -0
  152. package/ccw/bin/ccw.js +9 -9
  153. package/ccw/package.json +65 -47
  154. package/ccw/src/.workflow/.cli-history/history.db +0 -0
  155. package/ccw/src/.workflow/.cli-history/history.db-shm +0 -0
  156. package/ccw/src/.workflow/.cli-history/history.db-wal +0 -0
  157. package/ccw/src/cli.ts +244 -0
  158. package/ccw/src/commands/cli.ts +740 -0
  159. package/ccw/src/commands/core-memory.ts +770 -0
  160. package/ccw/src/commands/hook.ts +315 -0
  161. package/ccw/src/commands/install.ts +519 -0
  162. package/ccw/src/commands/{list.js → list.ts} +1 -1
  163. package/ccw/src/commands/memory.ts +1090 -0
  164. package/ccw/src/commands/{serve.js → serve.ts} +14 -5
  165. package/ccw/src/commands/session-path-resolver.ts +372 -0
  166. package/ccw/src/commands/session.ts +1141 -0
  167. package/ccw/src/commands/{stop.js → stop.ts} +16 -6
  168. package/ccw/src/commands/tool.ts +201 -0
  169. package/ccw/src/commands/{uninstall.js → uninstall.ts} +89 -40
  170. package/ccw/src/commands/{upgrade.js → upgrade.ts} +68 -23
  171. package/ccw/src/commands/{view.js → view.ts} +22 -8
  172. package/ccw/src/config/storage-paths.ts +670 -0
  173. package/ccw/src/core/cache-manager.ts +294 -0
  174. package/ccw/src/core/claude-freshness.ts +319 -0
  175. package/ccw/src/core/core-memory-store.ts +1528 -0
  176. package/ccw/src/core/{dashboard-generator-patch.js → dashboard-generator-patch.ts} +18 -0
  177. package/ccw/src/core/{dashboard-generator.js → dashboard-generator.ts} +69 -12
  178. package/ccw/src/core/data-aggregator.ts +584 -0
  179. package/ccw/src/core/history-importer.ts +625 -0
  180. package/ccw/src/core/{lite-scanner.js → lite-scanner-complete.ts} +162 -66
  181. package/ccw/src/core/lite-scanner.ts +469 -0
  182. package/ccw/src/core/{manifest.js → manifest.ts} +104 -34
  183. package/ccw/src/core/memory-embedder-bridge.ts +262 -0
  184. package/ccw/src/core/memory-store.ts +978 -0
  185. package/ccw/src/core/routes/ccw-routes.ts +96 -0
  186. package/ccw/src/core/routes/claude-routes.ts +1183 -0
  187. package/ccw/src/core/routes/cli-routes.ts +561 -0
  188. package/ccw/src/core/routes/codexlens-routes.ts +806 -0
  189. package/ccw/src/core/routes/core-memory-routes.ts +605 -0
  190. package/ccw/src/core/routes/files-routes.ts +428 -0
  191. package/ccw/src/core/routes/graph-routes.md +164 -0
  192. package/ccw/src/core/routes/graph-routes.ts +626 -0
  193. package/ccw/src/core/routes/help-routes.ts +308 -0
  194. package/ccw/src/core/routes/hooks-routes.ts +405 -0
  195. package/ccw/src/core/routes/mcp-routes.ts +1271 -0
  196. package/ccw/src/core/routes/mcp-routes.ts.backup +550 -0
  197. package/ccw/src/core/routes/mcp-templates-db.ts +268 -0
  198. package/ccw/src/core/routes/memory-routes.ts +1206 -0
  199. package/ccw/src/core/routes/rules-routes.ts +526 -0
  200. package/ccw/src/core/routes/session-routes.ts +467 -0
  201. package/ccw/src/core/routes/skills-routes.ts +599 -0
  202. package/ccw/src/core/routes/status-routes.ts +57 -0
  203. package/ccw/src/core/routes/system-routes.ts +427 -0
  204. package/ccw/src/core/server.ts +431 -0
  205. package/ccw/src/core/session-clustering-service.ts +1258 -0
  206. package/ccw/src/core/session-scanner.ts +283 -0
  207. package/ccw/src/core/websocket.ts +190 -0
  208. package/ccw/src/{index.js → index.ts} +1 -0
  209. package/ccw/src/mcp-server/index.ts +186 -0
  210. package/ccw/src/templates/assets/css/github-dark.min.css +10 -0
  211. package/ccw/src/templates/assets/css/github.min.css +10 -0
  212. package/ccw/src/templates/assets/js/cytoscape.min.js +32 -0
  213. package/ccw/src/templates/assets/js/d3.min.js +2 -0
  214. package/ccw/src/templates/assets/js/highlight.min.js +1244 -0
  215. package/ccw/src/templates/assets/js/lucide.min.js +12 -0
  216. package/ccw/src/templates/assets/js/marked.min.js +69 -0
  217. package/ccw/src/templates/assets/js/tailwind.js +83 -0
  218. package/ccw/src/templates/dashboard-css/01-base.css +11 -0
  219. package/ccw/src/templates/dashboard-css/02-session.css +22 -0
  220. package/ccw/src/templates/dashboard-css/04-lite-tasks.css +10 -0
  221. package/ccw/src/templates/dashboard-css/06-cards.css +10 -4
  222. package/ccw/src/templates/dashboard-css/07-managers.css +1178 -7
  223. package/ccw/src/templates/dashboard-css/09-explorer.css +23 -12
  224. package/ccw/src/templates/dashboard-css/10-cli-status.css +337 -0
  225. package/ccw/src/templates/dashboard-css/11-cli-history.css +271 -0
  226. package/ccw/src/templates/dashboard-css/12-cli-legacy.css +796 -0
  227. package/ccw/src/templates/dashboard-css/13-cli-ccw.css +199 -0
  228. package/ccw/src/templates/dashboard-css/14-cli-modals.css +258 -0
  229. package/ccw/src/templates/dashboard-css/15-cli-endpoints.css +305 -0
  230. package/ccw/src/templates/dashboard-css/16-cli-session.css +241 -0
  231. package/ccw/src/templates/dashboard-css/17-cli-conversation.css +283 -0
  232. package/ccw/src/templates/dashboard-css/18-cli-settings.css +160 -0
  233. package/ccw/src/templates/dashboard-css/19-cli-native-session.css +496 -0
  234. package/ccw/src/templates/dashboard-css/20-cli-taskqueue.css +188 -0
  235. package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +310 -0
  236. package/ccw/src/templates/dashboard-css/22-cli-semantic.css +240 -0
  237. package/ccw/src/templates/dashboard-css/23-memory.css +2390 -0
  238. package/ccw/src/templates/dashboard-css/24-prompt-history.css +1089 -0
  239. package/ccw/src/templates/dashboard-css/25-skills-rules.css +326 -0
  240. package/ccw/src/templates/dashboard-css/26-claude-manager.css +908 -0
  241. package/ccw/src/templates/dashboard-css/27-graph-explorer.css +1678 -0
  242. package/ccw/src/templates/dashboard-css/28-mcp-manager.css +748 -0
  243. package/ccw/src/templates/dashboard-css/29-help.css +264 -0
  244. package/ccw/src/templates/dashboard-css/30-core-memory.css +1700 -0
  245. package/ccw/src/templates/dashboard-js/api.js +162 -142
  246. package/ccw/src/templates/dashboard-js/components/carousel.js +4 -4
  247. package/ccw/src/templates/dashboard-js/components/cli-history.js +876 -0
  248. package/ccw/src/templates/dashboard-js/components/cli-status.js +978 -0
  249. package/ccw/src/templates/dashboard-js/components/global-notifications.js +508 -219
  250. package/ccw/src/templates/dashboard-js/components/hook-manager.js +1277 -282
  251. package/ccw/src/templates/dashboard-js/components/index-manager.js +302 -0
  252. package/ccw/src/templates/dashboard-js/components/mcp-manager.js +718 -27
  253. package/ccw/src/templates/dashboard-js/components/modals.js +66 -0
  254. package/ccw/src/templates/dashboard-js/components/navigation.js +80 -12
  255. package/ccw/src/templates/dashboard-js/components/notifications.js +758 -194
  256. package/ccw/src/templates/dashboard-js/components/storage-manager.js +478 -0
  257. package/ccw/src/templates/dashboard-js/components/tabs-other.js +157 -6
  258. package/ccw/src/templates/dashboard-js/components/task-queue-sidebar.js +716 -0
  259. package/ccw/src/templates/dashboard-js/help-i18n.js +272 -0
  260. package/ccw/src/templates/dashboard-js/i18n.js +2807 -0
  261. package/ccw/src/templates/dashboard-js/main.js +15 -0
  262. package/ccw/src/templates/dashboard-js/state.js +243 -42
  263. package/ccw/src/templates/dashboard-js/utils.js +47 -1
  264. package/ccw/src/templates/dashboard-js/views/claude-manager.js +912 -0
  265. package/ccw/src/templates/dashboard-js/views/cli-manager.js +2272 -0
  266. package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +964 -0
  267. package/ccw/src/templates/dashboard-js/views/core-memory-clusters.js +503 -0
  268. package/ccw/src/templates/dashboard-js/views/core-memory.js +782 -0
  269. package/ccw/src/templates/dashboard-js/views/explorer.js +888 -852
  270. package/ccw/src/templates/dashboard-js/views/graph-explorer.js +1157 -0
  271. package/ccw/src/templates/dashboard-js/views/help.js +856 -0
  272. package/ccw/src/templates/dashboard-js/views/history.js +337 -0
  273. package/ccw/src/templates/dashboard-js/views/home.js +61 -15
  274. package/ccw/src/templates/dashboard-js/views/hook-manager.js +311 -43
  275. package/ccw/src/templates/dashboard-js/views/lite-tasks.js +204 -28
  276. package/ccw/src/templates/dashboard-js/views/mcp-manager.js +2187 -411
  277. package/ccw/src/templates/dashboard-js/views/mcp-manager.js.backup +1729 -0
  278. package/ccw/src/templates/dashboard-js/views/mcp-manager.js.new +928 -0
  279. package/ccw/src/templates/dashboard-js/views/memory.js +1221 -0
  280. package/ccw/src/templates/dashboard-js/views/prompt-history.js +713 -0
  281. package/ccw/src/templates/dashboard-js/views/rules-manager.js +828 -0
  282. package/ccw/src/templates/dashboard-js/views/session-detail.js +54 -53
  283. package/ccw/src/templates/dashboard-js/views/skills-manager.js +819 -0
  284. package/ccw/src/templates/dashboard.html +185 -85
  285. package/ccw/src/templates/hooks-config-example.json +60 -0
  286. package/ccw/src/tools/classify-folders.ts +245 -0
  287. package/ccw/src/tools/cli-config-manager.ts +268 -0
  288. package/ccw/src/tools/cli-executor.ts +2014 -0
  289. package/ccw/src/tools/cli-history-store.ts +1195 -0
  290. package/ccw/src/tools/codex-lens.ts +1141 -0
  291. package/ccw/src/tools/{convert-tokens-to-css.js → convert-tokens-to-css.ts} +73 -23
  292. package/ccw/src/tools/core-memory.ts +444 -0
  293. package/ccw/src/tools/detect-changed-modules.ts +325 -0
  294. package/ccw/src/tools/{discover-design-files.js → discover-design-files.ts} +74 -24
  295. package/ccw/src/tools/edit-file.ts +568 -0
  296. package/ccw/src/tools/{generate-module-docs.js → generate-module-docs.ts} +207 -185
  297. package/ccw/src/tools/{get-modules-by-depth.js → get-modules-by-depth.ts} +120 -79
  298. package/ccw/src/tools/index.ts +370 -0
  299. package/ccw/src/tools/native-session-discovery.ts +795 -0
  300. package/ccw/src/tools/notifier.ts +129 -0
  301. package/ccw/src/tools/read-file.ts +410 -0
  302. package/ccw/src/tools/resume-strategy.ts +345 -0
  303. package/ccw/src/tools/session-content-parser.ts +619 -0
  304. package/ccw/src/tools/session-manager.ts +1026 -0
  305. package/ccw/src/tools/smart-context.ts +228 -0
  306. package/ccw/src/tools/smart-search.ts +2065 -0
  307. package/ccw/src/tools/smart-search.ts.backup +1233 -0
  308. package/ccw/src/tools/storage-manager.ts +455 -0
  309. package/ccw/src/tools/write-file.ts +222 -0
  310. package/ccw/src/types/config.ts +11 -0
  311. package/ccw/src/types/index.ts +3 -0
  312. package/ccw/src/types/session.ts +25 -0
  313. package/ccw/src/types/tool.ts +41 -0
  314. package/ccw/src/utils/{browser-launcher.js → browser-launcher.ts} +10 -8
  315. package/ccw/src/utils/file-utils.ts +48 -0
  316. package/ccw/src/utils/{path-resolver.js → path-resolver.ts} +114 -78
  317. package/ccw/src/utils/path-validator.ts +153 -0
  318. package/ccw/src/utils/{ui.js → ui.ts} +32 -25
  319. package/codex-lens/pyproject.toml +48 -0
  320. package/codex-lens/src/codexlens/.workflow/.cli-history/history.db +0 -0
  321. package/codex-lens/src/codexlens/__init__.py +28 -0
  322. package/codex-lens/src/codexlens/__main__.py +14 -0
  323. package/codex-lens/src/codexlens/__pycache__/__init__.cpython-313.pyc +0 -0
  324. package/codex-lens/src/codexlens/__pycache__/__main__.cpython-313.pyc +0 -0
  325. package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
  326. package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
  327. package/codex-lens/src/codexlens/__pycache__/errors.cpython-313.pyc +0 -0
  328. package/codex-lens/src/codexlens/cli/__init__.py +27 -0
  329. package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-313.pyc +0 -0
  330. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
  331. package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
  332. package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
  333. package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-313.pyc +0 -0
  334. package/codex-lens/src/codexlens/cli/commands.py +1931 -0
  335. package/codex-lens/src/codexlens/cli/embedding_manager.py +620 -0
  336. package/codex-lens/src/codexlens/cli/model_manager.py +289 -0
  337. package/codex-lens/src/codexlens/cli/output.py +124 -0
  338. package/codex-lens/src/codexlens/config.py +201 -0
  339. package/codex-lens/src/codexlens/entities.py +121 -0
  340. package/codex-lens/src/codexlens/errors.py +55 -0
  341. package/codex-lens/src/codexlens/indexing/README.md +77 -0
  342. package/codex-lens/src/codexlens/indexing/__init__.py +4 -0
  343. package/codex-lens/src/codexlens/indexing/__pycache__/__init__.cpython-313.pyc +0 -0
  344. package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
  345. package/codex-lens/src/codexlens/indexing/symbol_extractor.py +243 -0
  346. package/codex-lens/src/codexlens/parsers/__init__.py +8 -0
  347. package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-313.pyc +0 -0
  348. package/codex-lens/src/codexlens/parsers/__pycache__/encoding.cpython-313.pyc +0 -0
  349. package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
  350. package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-313.pyc +0 -0
  351. package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
  352. package/codex-lens/src/codexlens/parsers/encoding.py +202 -0
  353. package/codex-lens/src/codexlens/parsers/factory.py +256 -0
  354. package/codex-lens/src/codexlens/parsers/tokenizer.py +98 -0
  355. package/codex-lens/src/codexlens/parsers/treesitter_parser.py +335 -0
  356. package/codex-lens/src/codexlens/search/__init__.py +15 -0
  357. package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-313.pyc +0 -0
  358. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
  359. package/codex-lens/src/codexlens/search/__pycache__/enrichment.cpython-313.pyc +0 -0
  360. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
  361. package/codex-lens/src/codexlens/search/__pycache__/query_parser.cpython-313.pyc +0 -0
  362. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
  363. package/codex-lens/src/codexlens/search/chain_search.py +647 -0
  364. package/codex-lens/src/codexlens/search/enrichment.py +150 -0
  365. package/codex-lens/src/codexlens/search/hybrid_search.py +313 -0
  366. package/codex-lens/src/codexlens/search/query_parser.py +242 -0
  367. package/codex-lens/src/codexlens/search/ranking.py +274 -0
  368. package/codex-lens/src/codexlens/semantic/__init__.py +39 -0
  369. package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
  370. package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-313.pyc +0 -0
  371. package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
  372. package/codex-lens/src/codexlens/semantic/__pycache__/code_extractor.cpython-313.pyc +0 -0
  373. package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
  374. package/codex-lens/src/codexlens/semantic/__pycache__/graph_analyzer.cpython-313.pyc +0 -0
  375. package/codex-lens/src/codexlens/semantic/__pycache__/llm_enhancer.cpython-313.pyc +0 -0
  376. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
  377. package/codex-lens/src/codexlens/semantic/ann_index.py +414 -0
  378. package/codex-lens/src/codexlens/semantic/chunker.py +448 -0
  379. package/codex-lens/src/codexlens/semantic/code_extractor.py +274 -0
  380. package/codex-lens/src/codexlens/semantic/embedder.py +185 -0
  381. package/codex-lens/src/codexlens/semantic/vector_store.py +955 -0
  382. package/codex-lens/src/codexlens/storage/__init__.py +29 -0
  383. package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-313.pyc +0 -0
  384. package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
  385. package/codex-lens/src/codexlens/storage/__pycache__/file_cache.cpython-313.pyc +0 -0
  386. package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
  387. package/codex-lens/src/codexlens/storage/__pycache__/migration_manager.cpython-313.pyc +0 -0
  388. package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-313.pyc +0 -0
  389. package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-313.pyc +0 -0
  390. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
  391. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-313.pyc +0 -0
  392. package/codex-lens/src/codexlens/storage/dir_index.py +1850 -0
  393. package/codex-lens/src/codexlens/storage/file_cache.py +32 -0
  394. package/codex-lens/src/codexlens/storage/index_tree.py +776 -0
  395. package/codex-lens/src/codexlens/storage/migration_manager.py +154 -0
  396. package/codex-lens/src/codexlens/storage/migrations/__init__.py +1 -0
  397. package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
  398. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_001_normalize_keywords.cpython-313.pyc +0 -0
  399. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_002_add_token_metadata.cpython-313.pyc +0 -0
  400. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_003_code_relationships.cpython-313.pyc +0 -0
  401. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_004_dual_fts.cpython-313.pyc +0 -0
  402. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_005_cleanup_unused_fields.cpython-313.pyc +0 -0
  403. package/codex-lens/src/codexlens/storage/migrations/migration_001_normalize_keywords.py +123 -0
  404. package/codex-lens/src/codexlens/storage/migrations/migration_002_add_token_metadata.py +48 -0
  405. package/codex-lens/src/codexlens/storage/migrations/migration_004_dual_fts.py +232 -0
  406. package/codex-lens/src/codexlens/storage/migrations/migration_005_cleanup_unused_fields.py +196 -0
  407. package/codex-lens/src/codexlens/storage/path_mapper.py +274 -0
  408. package/codex-lens/src/codexlens/storage/registry.py +670 -0
  409. package/codex-lens/src/codexlens/storage/sqlite_store.py +576 -0
  410. package/codex-lens/src/codexlens/storage/sqlite_utils.py +64 -0
  411. package/package.json +4 -1
  412. package/.claude/commands/memory/tech-research.md +0 -477
  413. package/.claude/scripts/classify-folders.sh +0 -39
  414. package/.claude/scripts/convert_tokens_to_css.sh +0 -229
  415. package/.claude/scripts/detect_changed_modules.sh +0 -161
  416. package/.claude/scripts/discover-design-files.sh +0 -87
  417. package/.claude/scripts/extract-animations.js +0 -243
  418. package/.claude/scripts/extract-computed-styles.js +0 -118
  419. package/.claude/scripts/extract-layout-structure.js +0 -411
  420. package/.claude/scripts/generate_module_docs.sh +0 -717
  421. package/.claude/scripts/get_modules_by_depth.sh +0 -170
  422. package/.claude/scripts/ui-generate-preview.sh +0 -395
  423. package/.claude/scripts/ui-instantiate-prototypes.sh +0 -815
  424. package/.claude/scripts/update_module_claude.sh +0 -337
  425. package/.claude/workflows/context-search-strategy.md +0 -77
  426. package/.claude/workflows/intelligent-tools-strategy.md +0 -662
  427. package/ccw/src/cli.js +0 -119
  428. package/ccw/src/commands/install.js +0 -324
  429. package/ccw/src/commands/tool.js +0 -138
  430. package/ccw/src/core/data-aggregator.js +0 -409
  431. package/ccw/src/core/server.js +0 -2063
  432. package/ccw/src/core/session-scanner.js +0 -235
  433. package/ccw/src/tools/classify-folders.js +0 -204
  434. package/ccw/src/tools/detect-changed-modules.js +0 -288
  435. package/ccw/src/tools/edit-file.js +0 -266
  436. package/ccw/src/tools/index.js +0 -176
  437. package/ccw/src/utils/file-utils.js +0 -48
@@ -0,0 +1,289 @@
1
+ """Model Manager - Manage fastembed models for semantic search."""
2
+
3
+ import json
4
+ import os
5
+ import shutil
6
+ from pathlib import Path
7
+ from typing import Dict, List, Optional
8
+
9
+ try:
10
+ from fastembed import TextEmbedding
11
+ FASTEMBED_AVAILABLE = True
12
+ except ImportError:
13
+ FASTEMBED_AVAILABLE = False
14
+
15
+
16
+ # Model profiles with metadata
17
+ MODEL_PROFILES = {
18
+ "fast": {
19
+ "model_name": "BAAI/bge-small-en-v1.5",
20
+ "dimensions": 384,
21
+ "size_mb": 80,
22
+ "description": "Fast, lightweight, English-optimized",
23
+ "use_case": "Quick prototyping, resource-constrained environments",
24
+ },
25
+ "code": {
26
+ "model_name": "jinaai/jina-embeddings-v2-base-code",
27
+ "dimensions": 768,
28
+ "size_mb": 150,
29
+ "description": "Code-optimized, best for programming languages",
30
+ "use_case": "Open source projects, code semantic search",
31
+ },
32
+ "multilingual": {
33
+ "model_name": "intfloat/multilingual-e5-large",
34
+ "dimensions": 1024,
35
+ "size_mb": 1000,
36
+ "description": "Multilingual + code support",
37
+ "use_case": "Enterprise multilingual projects",
38
+ },
39
+ "balanced": {
40
+ "model_name": "mixedbread-ai/mxbai-embed-large-v1",
41
+ "dimensions": 1024,
42
+ "size_mb": 600,
43
+ "description": "High accuracy, general purpose",
44
+ "use_case": "High-quality semantic search, balanced performance",
45
+ },
46
+ }
47
+
48
+
49
+ def get_cache_dir() -> Path:
50
+ """Get fastembed cache directory.
51
+
52
+ Returns:
53
+ Path to cache directory (usually ~/.cache/fastembed or %LOCALAPPDATA%\\Temp\\fastembed_cache)
54
+ """
55
+ # Check HF_HOME environment variable first
56
+ if "HF_HOME" in os.environ:
57
+ return Path(os.environ["HF_HOME"])
58
+
59
+ # Default cache locations
60
+ if os.name == "nt": # Windows
61
+ cache_dir = Path(os.environ.get("LOCALAPPDATA", Path.home() / "AppData" / "Local")) / "Temp" / "fastembed_cache"
62
+ else: # Unix-like
63
+ cache_dir = Path.home() / ".cache" / "fastembed"
64
+
65
+ return cache_dir
66
+
67
+
68
+ def list_models() -> Dict[str, any]:
69
+ """List available model profiles and their installation status.
70
+
71
+ Returns:
72
+ Dictionary with model profiles, installed status, and cache info
73
+ """
74
+ if not FASTEMBED_AVAILABLE:
75
+ return {
76
+ "success": False,
77
+ "error": "fastembed not installed. Install with: pip install codexlens[semantic]",
78
+ }
79
+
80
+ cache_dir = get_cache_dir()
81
+ cache_exists = cache_dir.exists()
82
+
83
+ models = []
84
+ for profile, info in MODEL_PROFILES.items():
85
+ model_name = info["model_name"]
86
+
87
+ # Check if model is cached
88
+ installed = False
89
+ cache_size_mb = 0
90
+
91
+ if cache_exists:
92
+ # Check for model directory in cache
93
+ model_cache_path = cache_dir / f"models--{model_name.replace('/', '--')}"
94
+ if model_cache_path.exists():
95
+ installed = True
96
+ # Calculate cache size
97
+ total_size = sum(
98
+ f.stat().st_size
99
+ for f in model_cache_path.rglob("*")
100
+ if f.is_file()
101
+ )
102
+ cache_size_mb = round(total_size / (1024 * 1024), 1)
103
+
104
+ models.append({
105
+ "profile": profile,
106
+ "model_name": model_name,
107
+ "dimensions": info["dimensions"],
108
+ "estimated_size_mb": info["size_mb"],
109
+ "actual_size_mb": cache_size_mb if installed else None,
110
+ "description": info["description"],
111
+ "use_case": info["use_case"],
112
+ "installed": installed,
113
+ })
114
+
115
+ return {
116
+ "success": True,
117
+ "result": {
118
+ "models": models,
119
+ "cache_dir": str(cache_dir),
120
+ "cache_exists": cache_exists,
121
+ },
122
+ }
123
+
124
+
125
+ def download_model(profile: str, progress_callback: Optional[callable] = None) -> Dict[str, any]:
126
+ """Download a model by profile name.
127
+
128
+ Args:
129
+ profile: Model profile name (fast, code, multilingual, balanced)
130
+ progress_callback: Optional callback function to report progress
131
+
132
+ Returns:
133
+ Result dictionary with success status
134
+ """
135
+ if not FASTEMBED_AVAILABLE:
136
+ return {
137
+ "success": False,
138
+ "error": "fastembed not installed. Install with: pip install codexlens[semantic]",
139
+ }
140
+
141
+ if profile not in MODEL_PROFILES:
142
+ return {
143
+ "success": False,
144
+ "error": f"Unknown profile: {profile}. Available: {', '.join(MODEL_PROFILES.keys())}",
145
+ }
146
+
147
+ model_name = MODEL_PROFILES[profile]["model_name"]
148
+
149
+ try:
150
+ # Download model by instantiating TextEmbedding
151
+ # This will automatically download to cache if not present
152
+ if progress_callback:
153
+ progress_callback(f"Downloading {model_name}...")
154
+
155
+ embedder = TextEmbedding(model_name=model_name)
156
+
157
+ if progress_callback:
158
+ progress_callback(f"Model {model_name} downloaded successfully")
159
+
160
+ # Get cache info
161
+ cache_dir = get_cache_dir()
162
+ model_cache_path = cache_dir / f"models--{model_name.replace('/', '--')}"
163
+
164
+ cache_size = 0
165
+ if model_cache_path.exists():
166
+ total_size = sum(
167
+ f.stat().st_size
168
+ for f in model_cache_path.rglob("*")
169
+ if f.is_file()
170
+ )
171
+ cache_size = round(total_size / (1024 * 1024), 1)
172
+
173
+ return {
174
+ "success": True,
175
+ "result": {
176
+ "profile": profile,
177
+ "model_name": model_name,
178
+ "cache_size_mb": cache_size,
179
+ "cache_path": str(model_cache_path),
180
+ },
181
+ }
182
+
183
+ except Exception as e:
184
+ return {
185
+ "success": False,
186
+ "error": f"Failed to download model: {str(e)}",
187
+ }
188
+
189
+
190
+ def delete_model(profile: str) -> Dict[str, any]:
191
+ """Delete a downloaded model from cache.
192
+
193
+ Args:
194
+ profile: Model profile name to delete
195
+
196
+ Returns:
197
+ Result dictionary with success status
198
+ """
199
+ if profile not in MODEL_PROFILES:
200
+ return {
201
+ "success": False,
202
+ "error": f"Unknown profile: {profile}. Available: {', '.join(MODEL_PROFILES.keys())}",
203
+ }
204
+
205
+ model_name = MODEL_PROFILES[profile]["model_name"]
206
+ cache_dir = get_cache_dir()
207
+ model_cache_path = cache_dir / f"models--{model_name.replace('/', '--')}"
208
+
209
+ if not model_cache_path.exists():
210
+ return {
211
+ "success": False,
212
+ "error": f"Model {profile} ({model_name}) is not installed",
213
+ }
214
+
215
+ try:
216
+ # Calculate size before deletion
217
+ total_size = sum(
218
+ f.stat().st_size
219
+ for f in model_cache_path.rglob("*")
220
+ if f.is_file()
221
+ )
222
+ size_mb = round(total_size / (1024 * 1024), 1)
223
+
224
+ # Delete model directory
225
+ shutil.rmtree(model_cache_path)
226
+
227
+ return {
228
+ "success": True,
229
+ "result": {
230
+ "profile": profile,
231
+ "model_name": model_name,
232
+ "deleted_size_mb": size_mb,
233
+ "cache_path": str(model_cache_path),
234
+ },
235
+ }
236
+
237
+ except Exception as e:
238
+ return {
239
+ "success": False,
240
+ "error": f"Failed to delete model: {str(e)}",
241
+ }
242
+
243
+
244
+ def get_model_info(profile: str) -> Dict[str, any]:
245
+ """Get detailed information about a model profile.
246
+
247
+ Args:
248
+ profile: Model profile name
249
+
250
+ Returns:
251
+ Result dictionary with model information
252
+ """
253
+ if profile not in MODEL_PROFILES:
254
+ return {
255
+ "success": False,
256
+ "error": f"Unknown profile: {profile}. Available: {', '.join(MODEL_PROFILES.keys())}",
257
+ }
258
+
259
+ info = MODEL_PROFILES[profile]
260
+ model_name = info["model_name"]
261
+
262
+ # Check installation status
263
+ cache_dir = get_cache_dir()
264
+ model_cache_path = cache_dir / f"models--{model_name.replace('/', '--')}"
265
+ installed = model_cache_path.exists()
266
+
267
+ cache_size_mb = None
268
+ if installed:
269
+ total_size = sum(
270
+ f.stat().st_size
271
+ for f in model_cache_path.rglob("*")
272
+ if f.is_file()
273
+ )
274
+ cache_size_mb = round(total_size / (1024 * 1024), 1)
275
+
276
+ return {
277
+ "success": True,
278
+ "result": {
279
+ "profile": profile,
280
+ "model_name": model_name,
281
+ "dimensions": info["dimensions"],
282
+ "estimated_size_mb": info["size_mb"],
283
+ "actual_size_mb": cache_size_mb,
284
+ "description": info["description"],
285
+ "use_case": info["use_case"],
286
+ "installed": installed,
287
+ "cache_path": str(model_cache_path) if installed else None,
288
+ },
289
+ }
@@ -0,0 +1,124 @@
1
+ """Rich and JSON output helpers for CodexLens CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+ from dataclasses import asdict, is_dataclass
8
+ from pathlib import Path
9
+ from typing import Any, Iterable, Mapping, Sequence
10
+
11
+ from rich.console import Console
12
+ from rich.table import Table
13
+ from rich.text import Text
14
+
15
+ from codexlens.entities import SearchResult, Symbol
16
+
17
+ # Force UTF-8 encoding for Windows console to properly display Chinese text
18
+ # Use force_terminal=True and legacy_windows=False to avoid GBK encoding issues
19
+ console = Console(force_terminal=True, legacy_windows=False)
20
+
21
+
22
+ def _to_jsonable(value: Any) -> Any:
23
+ if value is None:
24
+ return None
25
+ if hasattr(value, "model_dump"):
26
+ return value.model_dump()
27
+ if is_dataclass(value):
28
+ return asdict(value)
29
+ if isinstance(value, Path):
30
+ return str(value)
31
+ if isinstance(value, Mapping):
32
+ return {k: _to_jsonable(v) for k, v in value.items()}
33
+ if isinstance(value, (list, tuple, set)):
34
+ return [_to_jsonable(v) for v in value]
35
+ return value
36
+
37
+
38
+ def print_json(*, success: bool, result: Any = None, error: str | None = None) -> None:
39
+ payload: dict[str, Any] = {"success": success}
40
+ if success:
41
+ payload["result"] = _to_jsonable(result)
42
+ else:
43
+ payload["error"] = error or "Unknown error"
44
+ console.print_json(json.dumps(payload, ensure_ascii=False))
45
+
46
+
47
+ def render_search_results(
48
+ results: Sequence[SearchResult], *, title: str = "Search Results", verbose: bool = False
49
+ ) -> None:
50
+ """Render search results with optional source tags in verbose mode.
51
+
52
+ Args:
53
+ results: Search results to display
54
+ title: Table title
55
+ verbose: If True, show search source tags ([E], [F], [V]) and fusion scores
56
+ """
57
+ table = Table(title=title, show_lines=False)
58
+
59
+ if verbose:
60
+ # Verbose mode: show source tags
61
+ table.add_column("Source", style="dim", width=6, justify="center")
62
+
63
+ table.add_column("Path", style="cyan", no_wrap=True)
64
+ table.add_column("Score", style="magenta", justify="right")
65
+ table.add_column("Excerpt", style="white")
66
+
67
+ for res in results:
68
+ excerpt = res.excerpt or ""
69
+ score_str = f"{res.score:.3f}"
70
+
71
+ if verbose:
72
+ # Extract search source tag if available
73
+ source = getattr(res, "search_source", None)
74
+ source_tag = ""
75
+ if source == "exact":
76
+ source_tag = "[E]"
77
+ elif source == "fuzzy":
78
+ source_tag = "[F]"
79
+ elif source == "vector":
80
+ source_tag = "[V]"
81
+ elif source == "fusion":
82
+ source_tag = "[RRF]"
83
+ table.add_row(source_tag, res.path, score_str, excerpt)
84
+ else:
85
+ table.add_row(res.path, score_str, excerpt)
86
+
87
+ console.print(table)
88
+
89
+
90
+ def render_symbols(symbols: Sequence[Symbol], *, title: str = "Symbols") -> None:
91
+ table = Table(title=title)
92
+ table.add_column("Name", style="green")
93
+ table.add_column("Kind", style="yellow")
94
+ table.add_column("Range", style="white", justify="right")
95
+
96
+ for sym in symbols:
97
+ start, end = sym.range
98
+ table.add_row(sym.name, sym.kind, f"{start}-{end}")
99
+
100
+ console.print(table)
101
+
102
+
103
+ def render_status(stats: Mapping[str, Any]) -> None:
104
+ table = Table(title="Index Status")
105
+ table.add_column("Metric", style="cyan")
106
+ table.add_column("Value", style="white")
107
+
108
+ for key, value in stats.items():
109
+ if isinstance(value, Mapping):
110
+ value_text = ", ".join(f"{k}:{v}" for k, v in value.items())
111
+ elif isinstance(value, (list, tuple)):
112
+ value_text = ", ".join(str(v) for v in value)
113
+ else:
114
+ value_text = str(value)
115
+ table.add_row(str(key), value_text)
116
+
117
+ console.print(table)
118
+
119
+
120
+ def render_file_inspect(path: str, language: str, symbols: Iterable[Symbol]) -> None:
121
+ header = Text.assemble(("File: ", "bold"), (path, "cyan"), (" Language: ", "bold"), (language, "green"))
122
+ console.print(header)
123
+ render_symbols(list(symbols), title="Discovered Symbols")
124
+
@@ -0,0 +1,201 @@
1
+ """Configuration system for CodexLens."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from dataclasses import dataclass, field
7
+ from functools import cached_property
8
+ from pathlib import Path
9
+ from typing import Any, Dict, List, Optional
10
+
11
+ from .errors import ConfigError
12
+
13
+
14
+ # Workspace-local directory name
15
+ WORKSPACE_DIR_NAME = ".codexlens"
16
+
17
+
18
+ def _default_global_dir() -> Path:
19
+ """Get global CodexLens data directory."""
20
+ env_override = os.getenv("CODEXLENS_DATA_DIR")
21
+ if env_override:
22
+ return Path(env_override).expanduser().resolve()
23
+ return (Path.home() / ".codexlens").resolve()
24
+
25
+
26
+ def find_workspace_root(start_path: Path) -> Optional[Path]:
27
+ """Find the workspace root by looking for .codexlens directory.
28
+
29
+ Searches from start_path upward to find an existing .codexlens directory.
30
+ Returns None if not found.
31
+ """
32
+ current = start_path.resolve()
33
+
34
+ # Search up to filesystem root
35
+ while current != current.parent:
36
+ workspace_dir = current / WORKSPACE_DIR_NAME
37
+ if workspace_dir.is_dir():
38
+ return current
39
+ current = current.parent
40
+
41
+ # Check root as well
42
+ workspace_dir = current / WORKSPACE_DIR_NAME
43
+ if workspace_dir.is_dir():
44
+ return current
45
+
46
+ return None
47
+
48
+
49
+ @dataclass
50
+ class Config:
51
+ """Runtime configuration for CodexLens.
52
+
53
+ - data_dir: Base directory for all persistent CodexLens data.
54
+ - venv_path: Optional virtualenv used for language tooling.
55
+ - supported_languages: Language IDs and their associated file extensions.
56
+ - parsing_rules: Per-language parsing and chunking hints.
57
+ """
58
+
59
+ data_dir: Path = field(default_factory=_default_global_dir)
60
+ venv_path: Path = field(default_factory=lambda: _default_global_dir() / "venv")
61
+ supported_languages: Dict[str, Dict[str, Any]] = field(
62
+ default_factory=lambda: {
63
+ "python": {"extensions": [".py"], "tree_sitter_language": "python"},
64
+ "javascript": {"extensions": [".js", ".jsx"], "tree_sitter_language": "javascript"},
65
+ "typescript": {"extensions": [".ts", ".tsx"], "tree_sitter_language": "typescript"},
66
+ "java": {"extensions": [".java"], "tree_sitter_language": "java"},
67
+ "go": {"extensions": [".go"], "tree_sitter_language": "go"},
68
+ "zig": {"extensions": [".zig"], "tree_sitter_language": "zig"},
69
+ "objective-c": {"extensions": [".m", ".mm"], "tree_sitter_language": "objc"},
70
+ "markdown": {"extensions": [".md", ".mdx"], "tree_sitter_language": None},
71
+ "text": {"extensions": [".txt"], "tree_sitter_language": None},
72
+ }
73
+ )
74
+ parsing_rules: Dict[str, Dict[str, Any]] = field(
75
+ default_factory=lambda: {
76
+ "default": {
77
+ "max_chunk_chars": 4000,
78
+ "max_chunk_lines": 200,
79
+ "overlap_lines": 20,
80
+ }
81
+ }
82
+ )
83
+
84
+ llm_enabled: bool = False
85
+ llm_tool: str = "gemini"
86
+ llm_timeout_ms: int = 300000
87
+ llm_batch_size: int = 5
88
+
89
+ # Hybrid chunker configuration
90
+ hybrid_max_chunk_size: int = 2000 # Max characters per chunk before LLM refinement
91
+ hybrid_llm_refinement: bool = False # Enable LLM-based semantic boundary refinement
92
+ def __post_init__(self) -> None:
93
+ try:
94
+ self.data_dir = self.data_dir.expanduser().resolve()
95
+ self.venv_path = self.venv_path.expanduser().resolve()
96
+ self.data_dir.mkdir(parents=True, exist_ok=True)
97
+ except Exception as exc:
98
+ raise ConfigError(f"Failed to initialize data_dir at {self.data_dir}: {exc}") from exc
99
+
100
+ @cached_property
101
+ def cache_dir(self) -> Path:
102
+ """Directory for transient caches."""
103
+ return self.data_dir / "cache"
104
+
105
+ @cached_property
106
+ def index_dir(self) -> Path:
107
+ """Directory where index artifacts are stored."""
108
+ return self.data_dir / "index"
109
+
110
+ @cached_property
111
+ def db_path(self) -> Path:
112
+ """Default SQLite index path."""
113
+ return self.index_dir / "codexlens.db"
114
+
115
+ def ensure_runtime_dirs(self) -> None:
116
+ """Create standard runtime directories if missing."""
117
+ for directory in (self.cache_dir, self.index_dir):
118
+ try:
119
+ directory.mkdir(parents=True, exist_ok=True)
120
+ except Exception as exc:
121
+ raise ConfigError(f"Failed to create directory {directory}: {exc}") from exc
122
+
123
+ def language_for_path(self, path: str | Path) -> str | None:
124
+ """Infer a supported language ID from a file path."""
125
+ extension = Path(path).suffix.lower()
126
+ for language_id, spec in self.supported_languages.items():
127
+ extensions: List[str] = spec.get("extensions", [])
128
+ if extension in extensions:
129
+ return language_id
130
+ return None
131
+
132
+ def rules_for_language(self, language_id: str) -> Dict[str, Any]:
133
+ """Get parsing rules for a specific language, falling back to defaults."""
134
+ return {**self.parsing_rules.get("default", {}), **self.parsing_rules.get(language_id, {})}
135
+
136
+
137
+ @dataclass
138
+ class WorkspaceConfig:
139
+ """Workspace-local configuration for CodexLens.
140
+
141
+ Stores index data in project/.codexlens/ directory.
142
+ """
143
+
144
+ workspace_root: Path
145
+
146
+ def __post_init__(self) -> None:
147
+ self.workspace_root = Path(self.workspace_root).resolve()
148
+
149
+ @property
150
+ def codexlens_dir(self) -> Path:
151
+ """The .codexlens directory in workspace root."""
152
+ return self.workspace_root / WORKSPACE_DIR_NAME
153
+
154
+ @property
155
+ def db_path(self) -> Path:
156
+ """SQLite index path for this workspace."""
157
+ return self.codexlens_dir / "index.db"
158
+
159
+ @property
160
+ def cache_dir(self) -> Path:
161
+ """Cache directory for this workspace."""
162
+ return self.codexlens_dir / "cache"
163
+
164
+ def initialize(self) -> None:
165
+ """Create the .codexlens directory structure."""
166
+ try:
167
+ self.codexlens_dir.mkdir(parents=True, exist_ok=True)
168
+ self.cache_dir.mkdir(parents=True, exist_ok=True)
169
+
170
+ # Create .gitignore to exclude cache but keep index
171
+ gitignore_path = self.codexlens_dir / ".gitignore"
172
+ if not gitignore_path.exists():
173
+ gitignore_path.write_text(
174
+ "# CodexLens workspace data\n"
175
+ "cache/\n"
176
+ "*.log\n"
177
+ )
178
+ except Exception as exc:
179
+ raise ConfigError(f"Failed to initialize workspace at {self.codexlens_dir}: {exc}") from exc
180
+
181
+ def exists(self) -> bool:
182
+ """Check if workspace is already initialized."""
183
+ return self.codexlens_dir.is_dir() and self.db_path.exists()
184
+
185
+ @classmethod
186
+ def from_path(cls, path: Path) -> Optional["WorkspaceConfig"]:
187
+ """Create WorkspaceConfig from a path by finding workspace root.
188
+
189
+ Returns None if no workspace found.
190
+ """
191
+ root = find_workspace_root(path)
192
+ if root is None:
193
+ return None
194
+ return cls(workspace_root=root)
195
+
196
+ @classmethod
197
+ def create_at(cls, path: Path) -> "WorkspaceConfig":
198
+ """Create a new workspace at the given path."""
199
+ config = cls(workspace_root=path)
200
+ config.initialize()
201
+ return config