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,196 @@
1
+ """
2
+ Migration 005: Remove unused and redundant database fields.
3
+
4
+ This migration removes four problematic fields identified by Gemini analysis:
5
+
6
+ 1. **semantic_metadata.keywords** (deprecated - replaced by file_keywords table)
7
+ - Data: Migrated to normalized file_keywords table in migration 001
8
+ - Impact: Column now redundant, remove to prevent sync issues
9
+
10
+ 2. **symbols.token_count** (unused - always NULL)
11
+ - Data: Never populated, always NULL
12
+ - Impact: No data loss, just removes unused column
13
+
14
+ 3. **symbols.symbol_type** (redundant - duplicates kind)
15
+ - Data: Redundant with symbols.kind field
16
+ - Impact: No data loss, kind field contains same information
17
+
18
+ 4. **subdirs.direct_files** (unused - never displayed)
19
+ - Data: Never used in queries or display logic
20
+ - Impact: No data loss, just removes unused column
21
+
22
+ Schema changes use table recreation pattern (SQLite best practice):
23
+ - Create new table without deprecated columns
24
+ - Copy data from old table
25
+ - Drop old table
26
+ - Rename new table
27
+ - Recreate indexes
28
+ """
29
+
30
+ import logging
31
+ from sqlite3 import Connection
32
+
33
+ log = logging.getLogger(__name__)
34
+
35
+
36
+ def upgrade(db_conn: Connection):
37
+ """Remove unused and redundant fields from schema.
38
+
39
+ Note: Transaction management is handled by MigrationManager.
40
+ This migration should NOT start its own transaction.
41
+
42
+ Args:
43
+ db_conn: The SQLite database connection.
44
+ """
45
+ cursor = db_conn.cursor()
46
+
47
+ # Step 1: Remove semantic_metadata.keywords (if column exists)
48
+ log.info("Checking semantic_metadata.keywords column...")
49
+
50
+ cursor.execute(
51
+ "SELECT name FROM sqlite_master WHERE type='table' AND name='semantic_metadata'"
52
+ )
53
+ if cursor.fetchone():
54
+ # Check if keywords column exists
55
+ cursor.execute("PRAGMA table_info(semantic_metadata)")
56
+ columns = {row[1] for row in cursor.fetchall()}
57
+
58
+ if "keywords" in columns:
59
+ log.info("Removing semantic_metadata.keywords column...")
60
+ cursor.execute("""
61
+ CREATE TABLE semantic_metadata_new (
62
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
63
+ file_id INTEGER NOT NULL UNIQUE,
64
+ summary TEXT,
65
+ purpose TEXT,
66
+ llm_tool TEXT,
67
+ generated_at REAL,
68
+ FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE
69
+ )
70
+ """)
71
+
72
+ cursor.execute("""
73
+ INSERT INTO semantic_metadata_new (id, file_id, summary, purpose, llm_tool, generated_at)
74
+ SELECT id, file_id, summary, purpose, llm_tool, generated_at
75
+ FROM semantic_metadata
76
+ """)
77
+
78
+ cursor.execute("DROP TABLE semantic_metadata")
79
+ cursor.execute("ALTER TABLE semantic_metadata_new RENAME TO semantic_metadata")
80
+
81
+ # Recreate index
82
+ cursor.execute(
83
+ "CREATE INDEX IF NOT EXISTS idx_semantic_file ON semantic_metadata(file_id)"
84
+ )
85
+ log.info("Removed semantic_metadata.keywords column")
86
+ else:
87
+ log.info("semantic_metadata.keywords column does not exist, skipping")
88
+ else:
89
+ log.info("semantic_metadata table does not exist, skipping")
90
+
91
+ # Step 2: Remove symbols.token_count and symbols.symbol_type (if columns exist)
92
+ log.info("Checking symbols.token_count and symbols.symbol_type columns...")
93
+
94
+ cursor.execute(
95
+ "SELECT name FROM sqlite_master WHERE type='table' AND name='symbols'"
96
+ )
97
+ if cursor.fetchone():
98
+ # Check if token_count or symbol_type columns exist
99
+ cursor.execute("PRAGMA table_info(symbols)")
100
+ columns = {row[1] for row in cursor.fetchall()}
101
+
102
+ if "token_count" in columns or "symbol_type" in columns:
103
+ log.info("Removing symbols.token_count and symbols.symbol_type columns...")
104
+ cursor.execute("""
105
+ CREATE TABLE symbols_new (
106
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
107
+ file_id INTEGER NOT NULL,
108
+ name TEXT NOT NULL,
109
+ kind TEXT,
110
+ start_line INTEGER,
111
+ end_line INTEGER,
112
+ FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE
113
+ )
114
+ """)
115
+
116
+ cursor.execute("""
117
+ INSERT INTO symbols_new (id, file_id, name, kind, start_line, end_line)
118
+ SELECT id, file_id, name, kind, start_line, end_line
119
+ FROM symbols
120
+ """)
121
+
122
+ cursor.execute("DROP TABLE symbols")
123
+ cursor.execute("ALTER TABLE symbols_new RENAME TO symbols")
124
+
125
+ # Recreate indexes
126
+ cursor.execute("CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id)")
127
+ cursor.execute("CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name)")
128
+ log.info("Removed symbols.token_count and symbols.symbol_type columns")
129
+ else:
130
+ log.info("symbols.token_count/symbol_type columns do not exist, skipping")
131
+ else:
132
+ log.info("symbols table does not exist, skipping")
133
+
134
+ # Step 3: Remove subdirs.direct_files (if column exists)
135
+ log.info("Checking subdirs.direct_files column...")
136
+
137
+ cursor.execute(
138
+ "SELECT name FROM sqlite_master WHERE type='table' AND name='subdirs'"
139
+ )
140
+ if cursor.fetchone():
141
+ # Check if direct_files column exists
142
+ cursor.execute("PRAGMA table_info(subdirs)")
143
+ columns = {row[1] for row in cursor.fetchall()}
144
+
145
+ if "direct_files" in columns:
146
+ log.info("Removing subdirs.direct_files column...")
147
+ cursor.execute("""
148
+ CREATE TABLE subdirs_new (
149
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
150
+ name TEXT NOT NULL UNIQUE,
151
+ index_path TEXT NOT NULL,
152
+ files_count INTEGER DEFAULT 0,
153
+ last_updated REAL
154
+ )
155
+ """)
156
+
157
+ cursor.execute("""
158
+ INSERT INTO subdirs_new (id, name, index_path, files_count, last_updated)
159
+ SELECT id, name, index_path, files_count, last_updated
160
+ FROM subdirs
161
+ """)
162
+
163
+ cursor.execute("DROP TABLE subdirs")
164
+ cursor.execute("ALTER TABLE subdirs_new RENAME TO subdirs")
165
+
166
+ # Recreate index
167
+ cursor.execute("CREATE INDEX IF NOT EXISTS idx_subdirs_name ON subdirs(name)")
168
+ log.info("Removed subdirs.direct_files column")
169
+ else:
170
+ log.info("subdirs.direct_files column does not exist, skipping")
171
+ else:
172
+ log.info("subdirs table does not exist, skipping")
173
+
174
+ log.info("Migration 005 completed successfully")
175
+
176
+ # Vacuum to reclaim space (outside transaction, optional)
177
+ # Note: VACUUM cannot run inside a transaction, so we skip it here
178
+ # The caller can run VACUUM separately if desired
179
+
180
+
181
+ def downgrade(db_conn: Connection):
182
+ """Restore removed fields (data will be lost for keywords, token_count, symbol_type, direct_files).
183
+
184
+ This is a placeholder - true downgrade is not feasible as data is lost.
185
+ The migration is designed to be one-way since removed fields are unused/redundant.
186
+
187
+ Args:
188
+ db_conn: The SQLite database connection.
189
+ """
190
+ log.warning(
191
+ "Migration 005 downgrade not supported - removed fields are unused/redundant. "
192
+ "Data cannot be restored."
193
+ )
194
+ raise NotImplementedError(
195
+ "Migration 005 downgrade not supported - this is a one-way migration"
196
+ )
@@ -0,0 +1,274 @@
1
+ """Path mapping utilities for source paths and index paths.
2
+
3
+ This module provides bidirectional mapping between source code directories
4
+ and their corresponding index storage locations.
5
+
6
+ Storage Structure:
7
+ ~/.codexlens/
8
+ ├── registry.db # Global mapping table
9
+ └── indexes/
10
+ └── D/
11
+ └── Claude_dms3/
12
+ ├── _index.db # Root directory index
13
+ └── src/
14
+ └── _index.db # src/ directory index
15
+ """
16
+
17
+ import platform
18
+ from pathlib import Path
19
+ from typing import Optional
20
+
21
+
22
+ class PathMapper:
23
+ """Bidirectional mapping tool for source paths ↔ index paths.
24
+
25
+ Handles cross-platform path normalization and conversion between
26
+ source code directories and their index storage locations.
27
+
28
+ Attributes:
29
+ DEFAULT_INDEX_ROOT: Default root directory for all indexes
30
+ INDEX_DB_NAME: Standard name for index database files
31
+ index_root: Configured index root directory
32
+ """
33
+
34
+ DEFAULT_INDEX_ROOT = Path.home() / ".codexlens" / "indexes"
35
+ INDEX_DB_NAME = "_index.db"
36
+
37
+ def __init__(self, index_root: Optional[Path] = None):
38
+ """Initialize PathMapper with optional custom index root.
39
+
40
+ Args:
41
+ index_root: Custom index root directory. If None, uses DEFAULT_INDEX_ROOT.
42
+ """
43
+ self.index_root = (index_root or self.DEFAULT_INDEX_ROOT).resolve()
44
+
45
+ def source_to_index_dir(self, source_path: Path) -> Path:
46
+ """Convert source directory to its index directory path.
47
+
48
+ Maps a source code directory to where its index data should be stored.
49
+ The mapping preserves the directory structure but normalizes paths
50
+ for cross-platform compatibility.
51
+
52
+ Args:
53
+ source_path: Source directory path to map
54
+
55
+ Returns:
56
+ Index directory path under index_root
57
+
58
+ Examples:
59
+ >>> mapper = PathMapper()
60
+ >>> mapper.source_to_index_dir(Path("D:/Claude_dms3/src"))
61
+ PosixPath('/home/user/.codexlens/indexes/D/Claude_dms3/src')
62
+
63
+ >>> mapper.source_to_index_dir(Path("/home/user/project"))
64
+ PosixPath('/home/user/.codexlens/indexes/home/user/project')
65
+ """
66
+ source_path = source_path.resolve()
67
+ normalized = self.normalize_path(source_path)
68
+ return self.index_root / normalized
69
+
70
+ def source_to_index_db(self, source_path: Path) -> Path:
71
+ """Convert source directory to its index database file path.
72
+
73
+ Maps a source directory to the full path of its index database file,
74
+ including the standard INDEX_DB_NAME.
75
+
76
+ Args:
77
+ source_path: Source directory path to map
78
+
79
+ Returns:
80
+ Full path to the index database file
81
+
82
+ Examples:
83
+ >>> mapper = PathMapper()
84
+ >>> mapper.source_to_index_db(Path("D:/Claude_dms3/src"))
85
+ PosixPath('/home/user/.codexlens/indexes/D/Claude_dms3/src/_index.db')
86
+ """
87
+ index_dir = self.source_to_index_dir(source_path)
88
+ return index_dir / self.INDEX_DB_NAME
89
+
90
+ def index_to_source(self, index_path: Path) -> Path:
91
+ """Convert index path back to original source path.
92
+
93
+ Performs reverse mapping from an index storage location to the
94
+ original source directory. Handles both directory paths and
95
+ database file paths.
96
+
97
+ Args:
98
+ index_path: Index directory or database file path
99
+
100
+ Returns:
101
+ Original source directory path
102
+
103
+ Raises:
104
+ ValueError: If index_path is not under index_root
105
+
106
+ Examples:
107
+ >>> mapper = PathMapper()
108
+ >>> mapper.index_to_source(
109
+ ... Path("~/.codexlens/indexes/D/Claude_dms3/src/_index.db")
110
+ ... )
111
+ WindowsPath('D:/Claude_dms3/src')
112
+
113
+ >>> mapper.index_to_source(
114
+ ... Path("~/.codexlens/indexes/D/Claude_dms3/src")
115
+ ... )
116
+ WindowsPath('D:/Claude_dms3/src')
117
+ """
118
+ index_path = index_path.resolve()
119
+
120
+ # Remove _index.db if present
121
+ if index_path.name == self.INDEX_DB_NAME:
122
+ index_path = index_path.parent
123
+
124
+ # Verify path is under index_root
125
+ try:
126
+ relative = index_path.relative_to(self.index_root)
127
+ except ValueError:
128
+ raise ValueError(
129
+ f"Index path {index_path} is not under index root {self.index_root}"
130
+ )
131
+
132
+ # Convert normalized path back to source path
133
+ normalized_str = str(relative).replace("\\", "/")
134
+ return self.denormalize_path(normalized_str)
135
+
136
+ def get_project_root(self, source_path: Path) -> Path:
137
+ """Find the project root directory (topmost indexed directory).
138
+
139
+ Walks up the directory tree to find the highest-level directory
140
+ that has an index database.
141
+
142
+ Args:
143
+ source_path: Source directory to start from
144
+
145
+ Returns:
146
+ Project root directory path. Returns source_path itself if
147
+ no parent index is found.
148
+
149
+ Examples:
150
+ >>> mapper = PathMapper()
151
+ >>> mapper.get_project_root(Path("D:/Claude_dms3/src/codexlens"))
152
+ WindowsPath('D:/Claude_dms3')
153
+ """
154
+ source_path = source_path.resolve()
155
+ current = source_path
156
+ project_root = source_path
157
+
158
+ # Walk up the tree
159
+ while current.parent != current: # Stop at filesystem root
160
+ parent_index_db = self.source_to_index_db(current.parent)
161
+ if parent_index_db.exists():
162
+ project_root = current.parent
163
+ current = current.parent
164
+ else:
165
+ break
166
+
167
+ return project_root
168
+
169
+ def get_relative_depth(self, source_path: Path, project_root: Path) -> int:
170
+ """Calculate directory depth relative to project root.
171
+
172
+ Args:
173
+ source_path: Target directory path
174
+ project_root: Project root directory path
175
+
176
+ Returns:
177
+ Number of directory levels from project_root to source_path
178
+
179
+ Raises:
180
+ ValueError: If source_path is not under project_root
181
+
182
+ Examples:
183
+ >>> mapper = PathMapper()
184
+ >>> mapper.get_relative_depth(
185
+ ... Path("D:/Claude_dms3/src/codexlens"),
186
+ ... Path("D:/Claude_dms3")
187
+ ... )
188
+ 2
189
+ """
190
+ source_path = source_path.resolve()
191
+ project_root = project_root.resolve()
192
+
193
+ try:
194
+ relative = source_path.relative_to(project_root)
195
+ # Count path components
196
+ return len(relative.parts)
197
+ except ValueError:
198
+ raise ValueError(
199
+ f"Source path {source_path} is not under project root {project_root}"
200
+ )
201
+
202
+ def normalize_path(self, path: Path) -> str:
203
+ """Normalize path to cross-platform storage format.
204
+
205
+ Converts OS-specific paths to a standardized format for storage:
206
+ - Windows: Removes drive colons (D: → D)
207
+ - Unix: Removes leading slash
208
+ - Uses forward slashes throughout
209
+
210
+ Args:
211
+ path: Path to normalize
212
+
213
+ Returns:
214
+ Normalized path string
215
+
216
+ Examples:
217
+ >>> mapper = PathMapper()
218
+ >>> mapper.normalize_path(Path("D:/path/to/dir"))
219
+ 'D/path/to/dir'
220
+
221
+ >>> mapper.normalize_path(Path("/home/user/path"))
222
+ 'home/user/path'
223
+ """
224
+ path = path.resolve()
225
+ path_str = str(path)
226
+
227
+ # Handle Windows paths with drive letters
228
+ if platform.system() == "Windows" and len(path.parts) > 0:
229
+ # Convert D:\path\to\dir → D/path/to/dir
230
+ drive = path.parts[0].replace(":", "") # D: → D
231
+ rest = Path(*path.parts[1:]) if len(path.parts) > 1 else Path()
232
+ normalized = f"{drive}/{rest}".replace("\\", "/")
233
+ return normalized.rstrip("/")
234
+
235
+ # Handle Unix paths
236
+ # /home/user/path → home/user/path
237
+ return path_str.lstrip("/").replace("\\", "/")
238
+
239
+ def denormalize_path(self, normalized: str) -> Path:
240
+ """Convert normalized path back to OS-specific path.
241
+
242
+ Reverses the normalization process to restore OS-native path format:
243
+ - Windows: Adds drive colons (D → D:)
244
+ - Unix: Adds leading slash
245
+
246
+ Args:
247
+ normalized: Normalized path string
248
+
249
+ Returns:
250
+ OS-specific Path object
251
+
252
+ Examples:
253
+ >>> mapper = PathMapper()
254
+ >>> mapper.denormalize_path("D/path/to/dir") # On Windows
255
+ WindowsPath('D:/path/to/dir')
256
+
257
+ >>> mapper.denormalize_path("home/user/path") # On Unix
258
+ PosixPath('/home/user/path')
259
+ """
260
+ parts = normalized.split("/")
261
+
262
+ # Handle Windows paths
263
+ if platform.system() == "Windows" and len(parts) > 0:
264
+ # Check if first part is a drive letter
265
+ if len(parts[0]) == 1 and parts[0].isalpha():
266
+ # D/path/to/dir → D:/path/to/dir
267
+ drive = f"{parts[0]}:"
268
+ if len(parts) > 1:
269
+ return Path(drive) / Path(*parts[1:])
270
+ return Path(drive)
271
+
272
+ # Handle Unix paths or relative paths
273
+ # home/user/path → /home/user/path
274
+ return Path("/") / Path(*parts)