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,308 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Help Routes Module
4
+ * Handles all Help-related API endpoints for command guide and CodexLens docs
5
+ */
6
+ import type { IncomingMessage, ServerResponse } from 'http';
7
+ import { readFileSync, existsSync, watch } from 'fs';
8
+ import { join } from 'path';
9
+ import { homedir } from 'os';
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
+ // ========== In-Memory Cache ==========
22
+ interface CacheEntry {
23
+ data: any;
24
+ timestamp: number;
25
+ }
26
+
27
+ const cache = new Map<string, CacheEntry>();
28
+ const CACHE_TTL = 300000; // 5 minutes
29
+
30
+ /**
31
+ * Get cached data or load from file
32
+ */
33
+ function getCachedData(key: string, filePath: string): any {
34
+ const now = Date.now();
35
+ const cached = cache.get(key);
36
+
37
+ // Return cached data if valid
38
+ if (cached && (now - cached.timestamp) < CACHE_TTL) {
39
+ return cached.data;
40
+ }
41
+
42
+ // Load fresh data
43
+ try {
44
+ if (!existsSync(filePath)) {
45
+ console.error(`Help data file not found: ${filePath}`);
46
+ return null;
47
+ }
48
+
49
+ const content = readFileSync(filePath, 'utf8');
50
+ const data = JSON.parse(content);
51
+
52
+ // Update cache
53
+ cache.set(key, { data, timestamp: now });
54
+
55
+ return data;
56
+ } catch (error) {
57
+ console.error(`Failed to load help data from ${filePath}:`, error);
58
+ return null;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Invalidate cache for a specific key
64
+ */
65
+ function invalidateCache(key: string): void {
66
+ cache.delete(key);
67
+ console.log(`Cache invalidated: ${key}`);
68
+ }
69
+
70
+ // ========== File Watchers ==========
71
+ let watchersInitialized = false;
72
+
73
+ /**
74
+ * Initialize file watchers for JSON indexes
75
+ */
76
+ function initializeFileWatchers(): void {
77
+ if (watchersInitialized) return;
78
+
79
+ const indexDir = join(homedir(), '.claude', 'skills', 'command-guide', 'index');
80
+
81
+ if (!existsSync(indexDir)) {
82
+ console.warn(`Command guide index directory not found: ${indexDir}`);
83
+ return;
84
+ }
85
+
86
+ try {
87
+ // Watch all JSON files in index directory
88
+ const watcher = watch(indexDir, { recursive: false }, (eventType, filename) => {
89
+ if (!filename || !filename.endsWith('.json')) return;
90
+
91
+ console.log(`File change detected: ${filename} (${eventType})`);
92
+
93
+ // Invalidate relevant cache entries
94
+ if (filename === 'all-commands.json') {
95
+ invalidateCache('all-commands');
96
+ } else if (filename === 'command-relationships.json') {
97
+ invalidateCache('command-relationships');
98
+ } else if (filename === 'by-category.json') {
99
+ invalidateCache('by-category');
100
+ }
101
+ });
102
+
103
+ watchersInitialized = true;
104
+ console.log(`File watchers initialized for: ${indexDir}`);
105
+ } catch (error) {
106
+ console.error('Failed to initialize file watchers:', error);
107
+ }
108
+ }
109
+
110
+ // ========== Helper Functions ==========
111
+
112
+ /**
113
+ * Filter commands by search query
114
+ */
115
+ function filterCommands(commands: any[], query: string): any[] {
116
+ if (!query) return commands;
117
+
118
+ const lowerQuery = query.toLowerCase();
119
+ return commands.filter(cmd =>
120
+ cmd.name?.toLowerCase().includes(lowerQuery) ||
121
+ cmd.command?.toLowerCase().includes(lowerQuery) ||
122
+ cmd.description?.toLowerCase().includes(lowerQuery) ||
123
+ cmd.category?.toLowerCase().includes(lowerQuery)
124
+ );
125
+ }
126
+
127
+ /**
128
+ * Group commands by category with subcategories
129
+ */
130
+ function groupCommandsByCategory(commands: any[]): any {
131
+ const grouped: any = {};
132
+
133
+ for (const cmd of commands) {
134
+ const category = cmd.category || 'general';
135
+ const subcategory = cmd.subcategory || null;
136
+
137
+ if (!grouped[category]) {
138
+ grouped[category] = {
139
+ name: category,
140
+ commands: [],
141
+ subcategories: {}
142
+ };
143
+ }
144
+
145
+ if (subcategory) {
146
+ if (!grouped[category].subcategories[subcategory]) {
147
+ grouped[category].subcategories[subcategory] = [];
148
+ }
149
+ grouped[category].subcategories[subcategory].push(cmd);
150
+ } else {
151
+ grouped[category].commands.push(cmd);
152
+ }
153
+ }
154
+
155
+ return grouped;
156
+ }
157
+
158
+ // ========== API Routes ==========
159
+
160
+ /**
161
+ * Handle Help routes
162
+ * @returns true if route was handled, false otherwise
163
+ */
164
+ export async function handleHelpRoutes(ctx: RouteContext): Promise<boolean> {
165
+ const { pathname, url, req, res } = ctx;
166
+
167
+ // Initialize file watchers on first request
168
+ initializeFileWatchers();
169
+
170
+ const indexDir = join(homedir(), '.claude', 'skills', 'command-guide', 'index');
171
+
172
+ // API: Get all commands with optional search
173
+ if (pathname === '/api/help/commands') {
174
+ const searchQuery = url.searchParams.get('q') || '';
175
+ const filePath = join(indexDir, 'all-commands.json');
176
+
177
+ let commands = getCachedData('all-commands', filePath);
178
+
179
+ if (!commands) {
180
+ res.writeHead(404, { 'Content-Type': 'application/json' });
181
+ res.end(JSON.stringify({ error: 'Commands data not found' }));
182
+ return true;
183
+ }
184
+
185
+ // Filter by search query if provided
186
+ if (searchQuery) {
187
+ commands = filterCommands(commands, searchQuery);
188
+ }
189
+
190
+ // Group by category
191
+ const grouped = groupCommandsByCategory(commands);
192
+
193
+ res.writeHead(200, { 'Content-Type': 'application/json' });
194
+ res.end(JSON.stringify({
195
+ commands: commands,
196
+ grouped: grouped,
197
+ total: commands.length
198
+ }));
199
+ return true;
200
+ }
201
+
202
+ // API: Get workflow command relationships
203
+ if (pathname === '/api/help/workflows') {
204
+ const filePath = join(indexDir, 'command-relationships.json');
205
+ const relationships = getCachedData('command-relationships', filePath);
206
+
207
+ if (!relationships) {
208
+ res.writeHead(404, { 'Content-Type': 'application/json' });
209
+ res.end(JSON.stringify({ error: 'Workflow relationships not found' }));
210
+ return true;
211
+ }
212
+
213
+ res.writeHead(200, { 'Content-Type': 'application/json' });
214
+ res.end(JSON.stringify(relationships));
215
+ return true;
216
+ }
217
+
218
+ // API: Get commands by category
219
+ if (pathname === '/api/help/commands/by-category') {
220
+ const filePath = join(indexDir, 'by-category.json');
221
+ const byCategory = getCachedData('by-category', filePath);
222
+
223
+ if (!byCategory) {
224
+ res.writeHead(404, { 'Content-Type': 'application/json' });
225
+ res.end(JSON.stringify({ error: 'Category data not found' }));
226
+ return true;
227
+ }
228
+
229
+ res.writeHead(200, { 'Content-Type': 'application/json' });
230
+ res.end(JSON.stringify(byCategory));
231
+ return true;
232
+ }
233
+
234
+ // API: Get CodexLens documentation metadata
235
+ if (pathname === '/api/help/codexlens') {
236
+ // Return CodexLens quick-start guide data
237
+ const codexLensData = {
238
+ title: 'CodexLens Quick Start',
239
+ description: 'Fast code indexing and semantic search for large codebases',
240
+ sections: [
241
+ {
242
+ title: 'Key Concepts',
243
+ items: [
244
+ {
245
+ name: 'Indexing',
246
+ description: 'CodexLens builds a semantic index of your codebase for fast retrieval',
247
+ command: 'codex_lens(action="init", path=".")'
248
+ },
249
+ {
250
+ name: 'Search Modes',
251
+ description: 'Text search for exact matches, semantic search for concept-based queries',
252
+ command: 'codex_lens(action="search", query="authentication logic", mode="semantic")'
253
+ },
254
+ {
255
+ name: 'Symbol Navigation',
256
+ description: 'Extract and navigate code symbols (functions, classes, interfaces)',
257
+ command: 'codex_lens(action="symbol", file="path/to/file.py")'
258
+ }
259
+ ]
260
+ },
261
+ {
262
+ title: 'Common Commands',
263
+ items: [
264
+ {
265
+ name: 'Initialize Index',
266
+ command: 'codex_lens(action="init", path=".")',
267
+ description: 'Index the current directory'
268
+ },
269
+ {
270
+ name: 'Text Search',
271
+ command: 'codex_lens(action="search", query="function name", path=".")',
272
+ description: 'Search for exact text matches'
273
+ },
274
+ {
275
+ name: 'Semantic Search',
276
+ command: 'codex_lens(action="search", query="user authentication", mode="semantic")',
277
+ description: 'Search by concept or meaning'
278
+ },
279
+ {
280
+ name: 'Check Status',
281
+ command: 'codex_lens(action="status")',
282
+ description: 'View indexing status for all projects'
283
+ }
284
+ ]
285
+ },
286
+ {
287
+ title: 'Best Practices',
288
+ items: [
289
+ { description: 'Index large codebases (>500 files) for optimal performance' },
290
+ { description: 'Use semantic search for exploratory tasks' },
291
+ { description: 'Combine with smart_search for medium-sized projects' },
292
+ { description: 'Re-index after major code changes' }
293
+ ]
294
+ }
295
+ ],
296
+ links: [
297
+ { text: 'Full Documentation', url: 'https://github.com/yourusername/codex-lens' },
298
+ { text: 'Tool Selection Guide', url: '/.claude/rules/tool-selection.md' }
299
+ ]
300
+ };
301
+
302
+ res.writeHead(200, { 'Content-Type': 'application/json' });
303
+ res.end(JSON.stringify(codexLensData));
304
+ return true;
305
+ }
306
+
307
+ return false;
308
+ }
@@ -0,0 +1,405 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Hooks Routes Module
4
+ * Handles all hooks-related API endpoints
5
+ */
6
+ import type { IncomingMessage, ServerResponse } from 'http';
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
8
+ import { join, dirname } from 'path';
9
+ import { homedir } from 'os';
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
+ extractSessionIdFromPath: (filePath: string) => string | null;
20
+ }
21
+
22
+ // ========================================
23
+ // Helper Functions
24
+ // ========================================
25
+
26
+ const GLOBAL_SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
27
+
28
+ /**
29
+ * Get project settings path
30
+ * @param {string} projectPath
31
+ * @returns {string}
32
+ */
33
+ function getProjectSettingsPath(projectPath) {
34
+ const normalizedPath = projectPath.replace(/\//g, '\\').replace(/^\\([a-zA-Z])\\/, '$1:\\');
35
+ return join(normalizedPath, '.claude', 'settings.json');
36
+ }
37
+
38
+ /**
39
+ * Read settings file safely
40
+ * @param {string} filePath
41
+ * @returns {Object}
42
+ */
43
+ function readSettingsFile(filePath) {
44
+ try {
45
+ if (!existsSync(filePath)) {
46
+ return {};
47
+ }
48
+ const content = readFileSync(filePath, 'utf8');
49
+ return JSON.parse(content);
50
+ } catch (error: unknown) {
51
+ console.error(`Error reading settings file ${filePath}:`, error);
52
+ return {};
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Get hooks configuration from global and project settings
58
+ * @param {string} projectPath
59
+ * @returns {Object}
60
+ */
61
+ function getHooksConfig(projectPath) {
62
+ const globalSettings = readSettingsFile(GLOBAL_SETTINGS_PATH);
63
+ const projectSettingsPath = projectPath ? getProjectSettingsPath(projectPath) : null;
64
+ const projectSettings = projectSettingsPath ? readSettingsFile(projectSettingsPath) : {};
65
+
66
+ return {
67
+ global: {
68
+ path: GLOBAL_SETTINGS_PATH,
69
+ hooks: globalSettings.hooks || {}
70
+ },
71
+ project: {
72
+ path: projectSettingsPath,
73
+ hooks: projectSettings.hooks || {}
74
+ }
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Save a hook to settings file
80
+ * @param {string} projectPath
81
+ * @param {string} scope - 'global' or 'project'
82
+ * @param {string} event - Hook event type
83
+ * @param {Object} hookData - Hook configuration
84
+ * @returns {Object}
85
+ */
86
+ function saveHookToSettings(projectPath, scope, event, hookData) {
87
+ try {
88
+ const filePath = scope === 'global' ? GLOBAL_SETTINGS_PATH : getProjectSettingsPath(projectPath);
89
+ const settings = readSettingsFile(filePath);
90
+
91
+ // Ensure hooks object exists
92
+ if (!settings.hooks) {
93
+ settings.hooks = {};
94
+ }
95
+
96
+ // Ensure the event array exists
97
+ if (!settings.hooks[event]) {
98
+ settings.hooks[event] = [];
99
+ }
100
+
101
+ // Ensure it's an array
102
+ if (!Array.isArray(settings.hooks[event])) {
103
+ settings.hooks[event] = [settings.hooks[event]];
104
+ }
105
+
106
+ // Check if we're replacing an existing hook
107
+ if (hookData.replaceIndex !== undefined) {
108
+ const index = hookData.replaceIndex;
109
+ delete hookData.replaceIndex;
110
+ if (index >= 0 && index < settings.hooks[event].length) {
111
+ settings.hooks[event][index] = hookData;
112
+ }
113
+ } else {
114
+ // Add new hook
115
+ settings.hooks[event].push(hookData);
116
+ }
117
+
118
+ // Ensure directory exists and write file
119
+ const dirPath = dirname(filePath);
120
+ if (!existsSync(dirPath)) {
121
+ mkdirSync(dirPath, { recursive: true });
122
+ }
123
+ writeFileSync(filePath, JSON.stringify(settings, null, 2), 'utf8');
124
+
125
+ return {
126
+ success: true,
127
+ event,
128
+ hookData
129
+ };
130
+ } catch (error: unknown) {
131
+ console.error('Error saving hook:', error);
132
+ return { error: (error as Error).message };
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Delete a hook from settings file
138
+ * @param {string} projectPath
139
+ * @param {string} scope - 'global' or 'project'
140
+ * @param {string} event - Hook event type
141
+ * @param {number} hookIndex - Index of hook to delete
142
+ * @returns {Object}
143
+ */
144
+ function deleteHookFromSettings(projectPath, scope, event, hookIndex) {
145
+ try {
146
+ const filePath = scope === 'global' ? GLOBAL_SETTINGS_PATH : getProjectSettingsPath(projectPath);
147
+ const settings = readSettingsFile(filePath);
148
+
149
+ if (!settings.hooks || !settings.hooks[event]) {
150
+ return { error: 'Hook not found' };
151
+ }
152
+
153
+ // Ensure it's an array
154
+ if (!Array.isArray(settings.hooks[event])) {
155
+ settings.hooks[event] = [settings.hooks[event]];
156
+ }
157
+
158
+ if (hookIndex < 0 || hookIndex >= settings.hooks[event].length) {
159
+ return { error: 'Invalid hook index' };
160
+ }
161
+
162
+ // Remove the hook
163
+ settings.hooks[event].splice(hookIndex, 1);
164
+
165
+ // Remove empty event arrays
166
+ if (settings.hooks[event].length === 0) {
167
+ delete settings.hooks[event];
168
+ }
169
+
170
+ writeFileSync(filePath, JSON.stringify(settings, null, 2), 'utf8');
171
+
172
+ return {
173
+ success: true,
174
+ event,
175
+ hookIndex
176
+ };
177
+ } catch (error: unknown) {
178
+ console.error('Error deleting hook:', error);
179
+ return { error: (error as Error).message };
180
+ }
181
+ }
182
+
183
+ // ========================================
184
+ // Session State Tracking (for progressive disclosure)
185
+ // ========================================
186
+
187
+ // Track sessions that have received startup context
188
+ // Key: sessionId, Value: timestamp of first context load
189
+ const sessionContextState = new Map<string, {
190
+ firstLoad: string;
191
+ loadCount: number;
192
+ lastPrompt?: string;
193
+ }>();
194
+
195
+ // Cleanup old sessions (older than 24 hours)
196
+ function cleanupOldSessions() {
197
+ const cutoff = Date.now() - 24 * 60 * 60 * 1000;
198
+ for (const [sessionId, state] of sessionContextState.entries()) {
199
+ if (new Date(state.firstLoad).getTime() < cutoff) {
200
+ sessionContextState.delete(sessionId);
201
+ }
202
+ }
203
+ }
204
+
205
+ // Run cleanup every hour
206
+ setInterval(cleanupOldSessions, 60 * 60 * 1000);
207
+
208
+ // ========================================
209
+ // Route Handler
210
+ // ========================================
211
+
212
+ /**
213
+ * Handle hooks routes
214
+ * @returns true if route was handled, false otherwise
215
+ */
216
+ export async function handleHooksRoutes(ctx: RouteContext): Promise<boolean> {
217
+ const { pathname, url, req, res, initialPath, handlePostRequest, broadcastToClients, extractSessionIdFromPath } = ctx;
218
+
219
+ // API: Hook endpoint for Claude Code notifications
220
+ if (pathname === '/api/hook' && req.method === 'POST') {
221
+ handlePostRequest(req, res, async (body) => {
222
+ const { type, filePath, sessionId, ...extraData } = body;
223
+
224
+ // Determine session ID from file path if not provided
225
+ let resolvedSessionId = sessionId;
226
+ if (!resolvedSessionId && filePath) {
227
+ resolvedSessionId = extractSessionIdFromPath(filePath);
228
+ }
229
+
230
+ // Handle context hooks (session-start, context)
231
+ if (type === 'session-start' || type === 'context') {
232
+ try {
233
+ const projectPath = url.searchParams.get('path') || initialPath;
234
+ const { SessionClusteringService } = await import('../session-clustering-service.js');
235
+ const clusteringService = new SessionClusteringService(projectPath);
236
+
237
+ const format = url.searchParams.get('format') || 'markdown';
238
+
239
+ // Pass type and prompt to getProgressiveIndex
240
+ // session-start: returns recent sessions by time
241
+ // context: returns intent-matched sessions based on prompt
242
+ const index = await clusteringService.getProgressiveIndex({
243
+ type: type as 'session-start' | 'context',
244
+ sessionId: resolvedSessionId,
245
+ prompt: extraData.prompt // Pass user prompt for intent matching
246
+ });
247
+
248
+ // Return context directly
249
+ return {
250
+ success: true,
251
+ type: 'context',
252
+ format,
253
+ content: index,
254
+ sessionId: resolvedSessionId
255
+ };
256
+ } catch (error) {
257
+ console.error('[Hooks] Failed to generate context:', error);
258
+ // Return empty content on failure (fail silently)
259
+ return {
260
+ success: true,
261
+ type: 'context',
262
+ format: 'markdown',
263
+ content: '',
264
+ sessionId: resolvedSessionId,
265
+ error: (error as Error).message
266
+ };
267
+ }
268
+ }
269
+
270
+ // Broadcast to all connected WebSocket clients
271
+ const notification = {
272
+ type: type || 'session_updated',
273
+ payload: {
274
+ sessionId: resolvedSessionId,
275
+ filePath: filePath,
276
+ timestamp: new Date().toISOString(),
277
+ ...extraData // Pass through toolName, status, result, params, error, etc.
278
+ }
279
+ };
280
+
281
+ broadcastToClients(notification);
282
+
283
+ return { success: true, notification };
284
+ });
285
+ return true;
286
+ }
287
+
288
+ // API: Unified Session Context endpoint (Progressive Disclosure)
289
+ // Automatically detects first prompt vs subsequent prompts
290
+ // - First prompt: returns cluster-based session overview
291
+ // - Subsequent prompts: returns intent-matched sessions based on prompt
292
+ if (pathname === '/api/hook/session-context' && req.method === 'POST') {
293
+ handlePostRequest(req, res, async (body) => {
294
+ const { sessionId, prompt } = body as { sessionId?: string; prompt?: string };
295
+
296
+ if (!sessionId) {
297
+ return {
298
+ success: true,
299
+ content: '',
300
+ error: 'sessionId is required'
301
+ };
302
+ }
303
+
304
+ try {
305
+ const projectPath = url.searchParams.get('path') || initialPath;
306
+ const { SessionClusteringService } = await import('../session-clustering-service.js');
307
+ const clusteringService = new SessionClusteringService(projectPath);
308
+
309
+ // Check if this is the first prompt for this session
310
+ const existingState = sessionContextState.get(sessionId);
311
+ const isFirstPrompt = !existingState;
312
+
313
+ // Update session state
314
+ if (isFirstPrompt) {
315
+ sessionContextState.set(sessionId, {
316
+ firstLoad: new Date().toISOString(),
317
+ loadCount: 1,
318
+ lastPrompt: prompt
319
+ });
320
+ } else {
321
+ existingState.loadCount++;
322
+ existingState.lastPrompt = prompt;
323
+ }
324
+
325
+ // Determine which type of context to return
326
+ let contextType: 'session-start' | 'context';
327
+ let content: string;
328
+
329
+ if (isFirstPrompt) {
330
+ // First prompt: return session overview with clusters
331
+ contextType = 'session-start';
332
+ content = await clusteringService.getProgressiveIndex({
333
+ type: 'session-start',
334
+ sessionId
335
+ });
336
+ } else if (prompt && prompt.trim().length > 0) {
337
+ // Subsequent prompts with content: return intent-matched sessions
338
+ contextType = 'context';
339
+ content = await clusteringService.getProgressiveIndex({
340
+ type: 'context',
341
+ sessionId,
342
+ prompt
343
+ });
344
+ } else {
345
+ // Subsequent prompts without content: return minimal context
346
+ contextType = 'context';
347
+ content = ''; // No context needed for empty prompts
348
+ }
349
+
350
+ return {
351
+ success: true,
352
+ type: contextType,
353
+ isFirstPrompt,
354
+ loadCount: sessionContextState.get(sessionId)?.loadCount || 1,
355
+ content,
356
+ sessionId
357
+ };
358
+ } catch (error) {
359
+ console.error('[Hooks] Failed to generate session context:', error);
360
+ return {
361
+ success: true,
362
+ content: '',
363
+ sessionId,
364
+ error: (error as Error).message
365
+ };
366
+ }
367
+ });
368
+ return true;
369
+ }
370
+
371
+ // API: Get hooks configuration
372
+ if (pathname === '/api/hooks' && req.method === 'GET') {
373
+ const projectPathParam = url.searchParams.get('path');
374
+ const hooksData = getHooksConfig(projectPathParam);
375
+ res.writeHead(200, { 'Content-Type': 'application/json' });
376
+ res.end(JSON.stringify(hooksData));
377
+ return true;
378
+ }
379
+
380
+ // API: Save hook
381
+ if (pathname === '/api/hooks' && req.method === 'POST') {
382
+ handlePostRequest(req, res, async (body) => {
383
+ const { projectPath, scope, event, hookData } = body;
384
+ if (!scope || !event || !hookData) {
385
+ return { error: 'scope, event, and hookData are required', status: 400 };
386
+ }
387
+ return saveHookToSettings(projectPath, scope, event, hookData);
388
+ });
389
+ return true;
390
+ }
391
+
392
+ // API: Delete hook
393
+ if (pathname === '/api/hooks' && req.method === 'DELETE') {
394
+ handlePostRequest(req, res, async (body) => {
395
+ const { projectPath, scope, event, hookIndex } = body;
396
+ if (!scope || !event || hookIndex === undefined) {
397
+ return { error: 'scope, event, and hookIndex are required', status: 400 };
398
+ }
399
+ return deleteHookFromSettings(projectPath, scope, event, hookIndex);
400
+ });
401
+ return true;
402
+ }
403
+
404
+ return false;
405
+ }