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,626 @@
1
+ /**
2
+ * Graph Routes Module
3
+ * Handles graph visualization API endpoints for codex-lens data
4
+ */
5
+ import type { IncomingMessage, ServerResponse } from 'http';
6
+ import { homedir } from 'os';
7
+ import { join, resolve, normalize } from 'path';
8
+ import { existsSync, readdirSync } from 'fs';
9
+ import Database from 'better-sqlite3';
10
+
11
+ export interface RouteContext {
12
+ pathname: string;
13
+ url: URL;
14
+ req: IncomingMessage;
15
+ res: ServerResponse;
16
+ initialPath: string;
17
+ handlePostRequest: (req: IncomingMessage, res: ServerResponse, handler: (body: unknown) => Promise<any>) => void;
18
+ broadcastToClients: (data: unknown) => void;
19
+ }
20
+
21
+ /**
22
+ * PathMapper utility class (simplified from codex-lens Python implementation)
23
+ * Maps source paths to index database paths
24
+ */
25
+ class PathMapper {
26
+ private indexRoot: string;
27
+
28
+ constructor(indexRoot?: string) {
29
+ this.indexRoot = indexRoot || join(homedir(), '.codexlens', 'indexes');
30
+ }
31
+
32
+ /**
33
+ * Normalize path to cross-platform storage format
34
+ * Windows: D:\path\to\dir → D/path/to/dir
35
+ * Unix: /home/user/path → home/user/path
36
+ */
37
+ normalizePath(sourcePath: string): string {
38
+ const resolved = sourcePath.replace(/\\/g, '/');
39
+
40
+ // Handle Windows paths with drive letters
41
+ if (process.platform === 'win32' && /^[A-Za-z]:/.test(resolved)) {
42
+ const drive = resolved[0]; // D
43
+ const rest = resolved.slice(2); // /path/to/dir
44
+ return `${drive}${rest}`.replace(/^\//, '');
45
+ }
46
+
47
+ // Handle Unix paths - remove leading slash
48
+ return resolved.replace(/^\//, '');
49
+ }
50
+
51
+ /**
52
+ * Convert source path to index database path
53
+ */
54
+ sourceToIndexDb(sourcePath: string): string {
55
+ const normalized = this.normalizePath(sourcePath);
56
+ return join(this.indexRoot, normalized, '_index.db');
57
+ }
58
+ }
59
+
60
+ interface GraphNode {
61
+ id: string;
62
+ name: string;
63
+ type: string;
64
+ file: string;
65
+ line: number;
66
+ }
67
+
68
+ interface GraphEdge {
69
+ source: string;
70
+ target: string;
71
+ type: string;
72
+ sourceLine: number;
73
+ sourceFile: string;
74
+ }
75
+
76
+ interface ImpactAnalysis {
77
+ directDependents: string[];
78
+ affectedFiles: string[];
79
+ }
80
+
81
+ /**
82
+ * Validate and sanitize project path to prevent path traversal attacks
83
+ * @returns sanitized absolute path or null if invalid
84
+ */
85
+ function validateProjectPath(projectPath: string, initialPath: string): string | null {
86
+ if (!projectPath) {
87
+ return initialPath;
88
+ }
89
+
90
+ // Resolve to absolute path
91
+ const resolved = resolve(projectPath);
92
+ const normalized = normalize(resolved);
93
+
94
+ // Check for path traversal attempts
95
+ if (normalized.includes('..') || normalized !== resolved) {
96
+ console.error(`[Graph] Path traversal attempt blocked: ${projectPath}`);
97
+ return null;
98
+ }
99
+
100
+ // Ensure path exists and is a directory
101
+ if (!existsSync(normalized)) {
102
+ console.error(`[Graph] Path does not exist: ${normalized}`);
103
+ return null;
104
+ }
105
+
106
+ return normalized;
107
+ }
108
+
109
+ /**
110
+ * Find all _index.db files recursively in a directory
111
+ * @param dir Directory to search
112
+ * @returns Array of absolute paths to _index.db files
113
+ */
114
+ function findAllIndexDbs(dir: string): string[] {
115
+ const dbs: string[] = [];
116
+
117
+ function traverse(currentDir: string): void {
118
+ const dbPath = join(currentDir, '_index.db');
119
+ if (existsSync(dbPath)) {
120
+ dbs.push(dbPath);
121
+ }
122
+
123
+ try {
124
+ const entries = readdirSync(currentDir, { withFileTypes: true });
125
+ for (const entry of entries) {
126
+ if (entry.isDirectory()) {
127
+ traverse(join(currentDir, entry.name));
128
+ }
129
+ }
130
+ } catch {
131
+ // Silently skip directories we can't read
132
+ }
133
+ }
134
+
135
+ traverse(dir);
136
+ return dbs;
137
+ }
138
+
139
+ /**
140
+ * Map codex-lens symbol kinds to graph node types
141
+ * Returns null for non-code symbols (markdown headings, etc.)
142
+ */
143
+ function mapSymbolKind(kind: string): string | null {
144
+ const kindLower = kind.toLowerCase();
145
+
146
+ // Exclude markdown headings
147
+ if (/^h[1-6]$/.test(kindLower)) {
148
+ return null;
149
+ }
150
+
151
+ const kindMap: Record<string, string> = {
152
+ 'function': 'FUNCTION',
153
+ 'class': 'CLASS',
154
+ 'method': 'METHOD',
155
+ 'variable': 'VARIABLE',
156
+ 'module': 'MODULE',
157
+ 'interface': 'CLASS', // TypeScript interfaces as CLASS
158
+ 'type': 'CLASS', // Type aliases as CLASS
159
+ 'constant': 'VARIABLE',
160
+ 'property': 'VARIABLE',
161
+ 'parameter': 'VARIABLE',
162
+ 'import': 'MODULE',
163
+ 'export': 'MODULE',
164
+ };
165
+ return kindMap[kindLower] || 'VARIABLE';
166
+ }
167
+
168
+ /**
169
+ * Map codex-lens relationship types to graph edge types
170
+ */
171
+ function mapRelationType(relType: string): string {
172
+ const typeMap: Record<string, string> = {
173
+ 'call': 'CALLS',
174
+ 'import': 'IMPORTS',
175
+ 'inherits': 'INHERITS',
176
+ 'uses': 'CALLS', // Fallback uses → CALLS
177
+ };
178
+ return typeMap[relType.toLowerCase()] || 'CALLS';
179
+ }
180
+
181
+ /**
182
+ * Query symbols from all codex-lens databases (hierarchical structure)
183
+ * @param projectPath Root project path
184
+ * @param fileFilter Optional file path filter (supports wildcards)
185
+ * @param moduleFilter Optional module/directory filter
186
+ */
187
+ async function querySymbols(projectPath: string, fileFilter?: string, moduleFilter?: string): Promise<GraphNode[]> {
188
+ const mapper = new PathMapper();
189
+ const rootDbPath = mapper.sourceToIndexDb(projectPath);
190
+ const indexRoot = rootDbPath.replace(/[\\/]_index\.db$/, '');
191
+
192
+ if (!existsSync(indexRoot)) {
193
+ return [];
194
+ }
195
+
196
+ // Find all _index.db files recursively
197
+ const dbPaths = findAllIndexDbs(indexRoot);
198
+
199
+ if (dbPaths.length === 0) {
200
+ return [];
201
+ }
202
+
203
+ const allNodes: GraphNode[] = [];
204
+
205
+ for (const dbPath of dbPaths) {
206
+ try {
207
+ const db = Database(dbPath, { readonly: true });
208
+
209
+ // Build WHERE clause for filtering
210
+ let whereClause = '';
211
+ const params: string[] = [];
212
+
213
+ if (fileFilter) {
214
+ const sanitized = sanitizeForLike(fileFilter);
215
+ whereClause = 'WHERE f.full_path LIKE ?';
216
+ params.push(`%${sanitized}%`);
217
+ } else if (moduleFilter) {
218
+ const sanitized = sanitizeForLike(moduleFilter);
219
+ whereClause = 'WHERE f.full_path LIKE ?';
220
+ params.push(`${sanitized}%`);
221
+ }
222
+
223
+ const query = `
224
+ SELECT
225
+ s.id,
226
+ s.name,
227
+ s.kind,
228
+ s.start_line,
229
+ f.full_path as file
230
+ FROM symbols s
231
+ JOIN files f ON s.file_id = f.id
232
+ ${whereClause}
233
+ ORDER BY f.full_path, s.start_line
234
+ `;
235
+
236
+ const rows = params.length > 0 ? db.prepare(query).all(...params) : db.prepare(query).all();
237
+
238
+ db.close();
239
+
240
+ // Filter out non-code symbols (markdown headings, etc.)
241
+ rows.forEach((row: any) => {
242
+ const type = mapSymbolKind(row.kind);
243
+ if (type !== null) {
244
+ allNodes.push({
245
+ id: `${row.file}:${row.name}:${row.start_line}`,
246
+ name: row.name,
247
+ type,
248
+ file: row.file,
249
+ line: row.start_line,
250
+ });
251
+ }
252
+ });
253
+ } catch (err) {
254
+ const message = err instanceof Error ? err.message : String(err);
255
+ console.error(`[Graph] Failed to query symbols from ${dbPath}: ${message}`);
256
+ // Continue with other databases even if one fails
257
+ }
258
+ }
259
+
260
+ return allNodes;
261
+ }
262
+
263
+ /**
264
+ * Query code relationships from all codex-lens databases (hierarchical structure)
265
+ * @param projectPath Root project path
266
+ * @param fileFilter Optional file path filter (supports wildcards)
267
+ * @param moduleFilter Optional module/directory filter
268
+ */
269
+ async function queryRelationships(projectPath: string, fileFilter?: string, moduleFilter?: string): Promise<GraphEdge[]> {
270
+ const mapper = new PathMapper();
271
+ const rootDbPath = mapper.sourceToIndexDb(projectPath);
272
+ const indexRoot = rootDbPath.replace(/[\\/]_index\.db$/, '');
273
+
274
+ if (!existsSync(indexRoot)) {
275
+ return [];
276
+ }
277
+
278
+ // Find all _index.db files recursively
279
+ const dbPaths = findAllIndexDbs(indexRoot);
280
+
281
+ if (dbPaths.length === 0) {
282
+ return [];
283
+ }
284
+
285
+ const allEdges: GraphEdge[] = [];
286
+
287
+ for (const dbPath of dbPaths) {
288
+ try {
289
+ const db = Database(dbPath, { readonly: true });
290
+
291
+ // Build WHERE clause for filtering
292
+ let whereClause = '';
293
+ const params: string[] = [];
294
+
295
+ if (fileFilter) {
296
+ const sanitized = sanitizeForLike(fileFilter);
297
+ whereClause = 'WHERE f.full_path LIKE ?';
298
+ params.push(`%${sanitized}%`);
299
+ } else if (moduleFilter) {
300
+ const sanitized = sanitizeForLike(moduleFilter);
301
+ whereClause = 'WHERE f.full_path LIKE ?';
302
+ params.push(`${sanitized}%`);
303
+ }
304
+
305
+ const query = `
306
+ SELECT
307
+ s.name as source_name,
308
+ s.start_line as source_line,
309
+ f.full_path as source_file,
310
+ r.target_qualified_name,
311
+ r.relationship_type,
312
+ r.target_file
313
+ FROM code_relationships r
314
+ JOIN symbols s ON r.source_symbol_id = s.id
315
+ JOIN files f ON s.file_id = f.id
316
+ ${whereClause}
317
+ ORDER BY f.full_path, s.start_line
318
+ `;
319
+
320
+ const rows = params.length > 0 ? db.prepare(query).all(...params) : db.prepare(query).all();
321
+
322
+ db.close();
323
+
324
+ allEdges.push(...rows.map((row: any) => ({
325
+ source: `${row.source_file}:${row.source_name}:${row.source_line}`,
326
+ target: row.target_qualified_name,
327
+ type: mapRelationType(row.relationship_type),
328
+ sourceLine: row.source_line,
329
+ sourceFile: row.source_file,
330
+ })));
331
+ } catch (err) {
332
+ const message = err instanceof Error ? err.message : String(err);
333
+ console.error(`[Graph] Failed to query relationships from ${dbPath}: ${message}`);
334
+ // Continue with other databases even if one fails
335
+ }
336
+ }
337
+
338
+ return allEdges;
339
+ }
340
+
341
+ /**
342
+ * Sanitize a string for use in SQL LIKE patterns
343
+ * Escapes special characters: %, _, [, ]
344
+ */
345
+ function sanitizeForLike(input: string): string {
346
+ return input
347
+ .replace(/\[/g, '[[]') // Escape [ first
348
+ .replace(/%/g, '[%]') // Escape %
349
+ .replace(/_/g, '[_]'); // Escape _
350
+ }
351
+
352
+ /**
353
+ * Validate and parse symbol ID format
354
+ * Expected format: file:name:line or just symbolName
355
+ * @returns sanitized symbol name or null if invalid
356
+ */
357
+ function parseSymbolId(symbolId: string): string | null {
358
+ if (!symbolId || symbolId.length > 500) {
359
+ return null;
360
+ }
361
+
362
+ // Remove any potentially dangerous characters
363
+ const sanitized = symbolId.replace(/[<>'";&|`$\\]/g, '');
364
+
365
+ // Parse the format: file:name:line
366
+ const parts = sanitized.split(':');
367
+ if (parts.length >= 2) {
368
+ // Return the name part (second element)
369
+ const name = parts[1].trim();
370
+ return name.length > 0 ? name : null;
371
+ }
372
+
373
+ // If no colons, use the whole string as name
374
+ return sanitized.trim() || null;
375
+ }
376
+
377
+ /**
378
+ * Perform impact analysis for a symbol
379
+ * Find all symbols that depend on this symbol (direct and transitive)
380
+ */
381
+ async function analyzeImpact(projectPath: string, symbolId: string): Promise<ImpactAnalysis> {
382
+ const mapper = new PathMapper();
383
+ const dbPath = mapper.sourceToIndexDb(projectPath);
384
+
385
+ if (!existsSync(dbPath)) {
386
+ return { directDependents: [], affectedFiles: [] };
387
+ }
388
+
389
+ // Parse and validate symbol ID
390
+ const symbolName = parseSymbolId(symbolId);
391
+ if (!symbolName) {
392
+ console.error(`[Graph] Invalid symbol ID format: ${symbolId}`);
393
+ return { directDependents: [], affectedFiles: [] };
394
+ }
395
+
396
+ try {
397
+ const db = Database(dbPath, { readonly: true });
398
+
399
+ // Sanitize for LIKE query to prevent injection via special characters
400
+ const sanitizedName = sanitizeForLike(symbolName);
401
+
402
+ // Find all symbols that reference this symbol
403
+ const rows = db.prepare(`
404
+ SELECT DISTINCT
405
+ s.name as dependent_name,
406
+ f.full_path as dependent_file,
407
+ s.start_line as dependent_line
408
+ FROM code_relationships r
409
+ JOIN symbols s ON r.source_symbol_id = s.id
410
+ JOIN files f ON s.file_id = f.id
411
+ WHERE r.target_qualified_name LIKE ?
412
+ `).all(`%${sanitizedName}%`);
413
+
414
+ db.close();
415
+
416
+ const directDependents = rows.map((row: any) =>
417
+ `${row.dependent_file}:${row.dependent_name}:${row.dependent_line}`
418
+ );
419
+
420
+ const affectedFiles = [...new Set(rows.map((row: any) => row.dependent_file))];
421
+
422
+ return {
423
+ directDependents,
424
+ affectedFiles,
425
+ };
426
+ } catch (err) {
427
+ const message = err instanceof Error ? err.message : String(err);
428
+ console.error(`[Graph] Failed to analyze impact: ${message}`);
429
+ return { directDependents: [], affectedFiles: [] };
430
+ }
431
+ }
432
+
433
+ /**
434
+ * Handle Graph routes
435
+ * @returns true if route was handled, false otherwise
436
+ */
437
+ export async function handleGraphRoutes(ctx: RouteContext): Promise<boolean> {
438
+ const { pathname, url, req, res, initialPath } = ctx;
439
+
440
+ // API: Graph Nodes - Get all symbols as graph nodes
441
+ if (pathname === '/api/graph/nodes') {
442
+ const rawPath = url.searchParams.get('path') || initialPath;
443
+ const projectPath = validateProjectPath(rawPath, initialPath);
444
+ const limitStr = url.searchParams.get('limit') || '1000';
445
+ const limit = Math.min(parseInt(limitStr, 10) || 1000, 5000); // Max 5000 nodes
446
+ const fileFilter = url.searchParams.get('file') || undefined;
447
+ const moduleFilter = url.searchParams.get('module') || undefined;
448
+
449
+ if (!projectPath) {
450
+ res.writeHead(400, { 'Content-Type': 'application/json' });
451
+ res.end(JSON.stringify({ error: 'Invalid project path', nodes: [] }));
452
+ return true;
453
+ }
454
+
455
+ try {
456
+ const allNodes = await querySymbols(projectPath, fileFilter, moduleFilter);
457
+ const nodes = allNodes.slice(0, limit);
458
+ res.writeHead(200, { 'Content-Type': 'application/json' });
459
+ res.end(JSON.stringify({
460
+ nodes,
461
+ total: allNodes.length,
462
+ limit,
463
+ hasMore: allNodes.length > limit,
464
+ filters: { file: fileFilter, module: moduleFilter }
465
+ }));
466
+ } catch (err) {
467
+ console.error(`[Graph] Error fetching nodes:`, err);
468
+ res.writeHead(500, { 'Content-Type': 'application/json' });
469
+ res.end(JSON.stringify({ error: 'Failed to fetch graph nodes', nodes: [] }));
470
+ }
471
+ return true;
472
+ }
473
+
474
+ // API: Graph Edges - Get all relationships as graph edges
475
+ if (pathname === '/api/graph/edges') {
476
+ const rawPath = url.searchParams.get('path') || initialPath;
477
+ const projectPath = validateProjectPath(rawPath, initialPath);
478
+ const limitStr = url.searchParams.get('limit') || '2000';
479
+ const limit = Math.min(parseInt(limitStr, 10) || 2000, 10000); // Max 10000 edges
480
+ const fileFilter = url.searchParams.get('file') || undefined;
481
+ const moduleFilter = url.searchParams.get('module') || undefined;
482
+
483
+ if (!projectPath) {
484
+ res.writeHead(400, { 'Content-Type': 'application/json' });
485
+ res.end(JSON.stringify({ error: 'Invalid project path', edges: [] }));
486
+ return true;
487
+ }
488
+
489
+ try {
490
+ const allEdges = await queryRelationships(projectPath, fileFilter, moduleFilter);
491
+ const edges = allEdges.slice(0, limit);
492
+ res.writeHead(200, { 'Content-Type': 'application/json' });
493
+ res.end(JSON.stringify({
494
+ edges,
495
+ total: allEdges.length,
496
+ limit,
497
+ hasMore: allEdges.length > limit,
498
+ filters: { file: fileFilter, module: moduleFilter }
499
+ }));
500
+ } catch (err) {
501
+ console.error(`[Graph] Error fetching edges:`, err);
502
+ res.writeHead(500, { 'Content-Type': 'application/json' });
503
+ res.end(JSON.stringify({ error: 'Failed to fetch graph edges', edges: [] }));
504
+ }
505
+ return true;
506
+ }
507
+
508
+ // API: Get available files and modules for filtering
509
+ if (pathname === '/api/graph/files') {
510
+ const rawPath = url.searchParams.get('path') || initialPath;
511
+ const projectPath = validateProjectPath(rawPath, initialPath);
512
+
513
+ if (!projectPath) {
514
+ res.writeHead(400, { 'Content-Type': 'application/json' });
515
+ res.end(JSON.stringify({ error: 'Invalid project path', files: [], modules: [] }));
516
+ return true;
517
+ }
518
+
519
+ try {
520
+ const mapper = new PathMapper();
521
+ const rootDbPath = mapper.sourceToIndexDb(projectPath);
522
+ const indexRoot = rootDbPath.replace(/[\\/]_index\.db$/, '');
523
+
524
+ if (!existsSync(indexRoot)) {
525
+ res.writeHead(200, { 'Content-Type': 'application/json' });
526
+ res.end(JSON.stringify({ files: [], modules: [] }));
527
+ return true;
528
+ }
529
+
530
+ const dbPaths = findAllIndexDbs(indexRoot);
531
+ const filesSet = new Set<string>();
532
+ const modulesSet = new Set<string>();
533
+
534
+ for (const dbPath of dbPaths) {
535
+ try {
536
+ const db = Database(dbPath, { readonly: true });
537
+ const rows = db.prepare(`SELECT DISTINCT full_path FROM files`).all();
538
+ db.close();
539
+
540
+ rows.forEach((row: any) => {
541
+ const filePath = row.full_path;
542
+ filesSet.add(filePath);
543
+
544
+ // Extract module path (directory)
545
+ const lastSlash = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
546
+ if (lastSlash > 0) {
547
+ const modulePath = filePath.substring(0, lastSlash);
548
+ modulesSet.add(modulePath);
549
+ }
550
+ });
551
+ } catch (err) {
552
+ const message = err instanceof Error ? err.message : String(err);
553
+ console.error(`[Graph] Failed to query files from ${dbPath}: ${message}`);
554
+ }
555
+ }
556
+
557
+ const files = Array.from(filesSet).sort();
558
+ const modules = Array.from(modulesSet).sort();
559
+
560
+ res.writeHead(200, { 'Content-Type': 'application/json' });
561
+ res.end(JSON.stringify({ files, modules }));
562
+ } catch (err) {
563
+ console.error(`[Graph] Error fetching files:`, err);
564
+ res.writeHead(500, { 'Content-Type': 'application/json' });
565
+ res.end(JSON.stringify({ error: 'Failed to fetch files and modules', files: [], modules: [] }));
566
+ }
567
+ return true;
568
+ }
569
+
570
+ // API: Impact Analysis - Get impact analysis for a symbol
571
+ if (pathname === '/api/graph/impact') {
572
+ const rawPath = url.searchParams.get('path') || initialPath;
573
+ const projectPath = validateProjectPath(rawPath, initialPath);
574
+ const symbolId = url.searchParams.get('symbol');
575
+
576
+ if (!projectPath) {
577
+ res.writeHead(400, { 'Content-Type': 'application/json' });
578
+ res.end(JSON.stringify({ error: 'Invalid project path', directDependents: [], affectedFiles: [] }));
579
+ return true;
580
+ }
581
+
582
+ if (!symbolId) {
583
+ res.writeHead(400, { 'Content-Type': 'application/json' });
584
+ res.end(JSON.stringify({ error: 'symbol parameter is required', directDependents: [], affectedFiles: [] }));
585
+ return true;
586
+ }
587
+
588
+ try {
589
+ const impact = await analyzeImpact(projectPath, symbolId);
590
+ res.writeHead(200, { 'Content-Type': 'application/json' });
591
+ res.end(JSON.stringify(impact));
592
+ } catch (err) {
593
+ console.error(`[Graph] Error analyzing impact:`, err);
594
+ res.writeHead(500, { 'Content-Type': 'application/json' });
595
+ res.end(JSON.stringify({
596
+ error: 'Failed to analyze impact',
597
+ directDependents: [],
598
+ affectedFiles: []
599
+ }));
600
+ }
601
+ return true;
602
+ }
603
+
604
+ // API: Search Process - Get search pipeline visualization data (placeholder)
605
+ if (pathname === '/api/graph/search-process') {
606
+ // This endpoint returns mock data for the search process visualization
607
+ // In a real implementation, this would integrate with codex-lens search pipeline
608
+ res.writeHead(200, { 'Content-Type': 'application/json' });
609
+ res.end(JSON.stringify({
610
+ stages: [
611
+ { id: 1, name: 'Query Parsing', duration: 0, status: 'pending' },
612
+ { id: 2, name: 'Vector Search', duration: 0, status: 'pending' },
613
+ { id: 3, name: 'Graph Enrichment', duration: 0, status: 'pending' },
614
+ { id: 4, name: 'Chunk Hierarchy', duration: 0, status: 'pending' },
615
+ { id: 5, name: 'Result Ranking', duration: 0, status: 'pending' }
616
+ ],
617
+ chunks: [],
618
+ callers: [],
619
+ callees: [],
620
+ message: 'Search process visualization requires an active search query'
621
+ }));
622
+ return true;
623
+ }
624
+
625
+ return false;
626
+ }