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,1090 @@
1
+ /**
2
+ * Memory Command - Context tracking and prompt optimization
3
+ * Provides CLI interface for Memory module operations
4
+ */
5
+
6
+ import chalk from 'chalk';
7
+ import { getMemoryStore, type Entity, type HotEntity, type PromptHistory } from '../core/memory-store.js';
8
+ import { HistoryImporter } from '../core/history-importer.js';
9
+ import { notifyMemoryUpdate, notifyRefreshRequired } from '../tools/notifier.js';
10
+ import { join } from 'path';
11
+ import { existsSync, readdirSync } from 'fs';
12
+ import { StoragePaths } from '../config/storage-paths.js';
13
+ import {
14
+ generateEmbeddings,
15
+ searchMemories,
16
+ getEmbeddingStatus,
17
+ isEmbedderAvailable,
18
+ type EmbedOptions,
19
+ type SearchOptions as EmbedSearchOptions
20
+ } from '../core/memory-embedder-bridge.js';
21
+ import { getCoreMemoryStore } from '../core/core-memory-store.js';
22
+ import { CliHistoryStore } from '../tools/cli-history-store.js';
23
+
24
+ interface TrackOptions {
25
+ type?: string;
26
+ action?: string;
27
+ value?: string;
28
+ session?: string;
29
+ stdin?: boolean;
30
+ }
31
+
32
+ interface ImportOptions {
33
+ source?: string;
34
+ project?: string;
35
+ }
36
+
37
+ interface StatsOptions {
38
+ type?: string;
39
+ limit?: string;
40
+ sort?: string;
41
+ json?: boolean;
42
+ }
43
+
44
+ interface SearchOptions {
45
+ limit?: string;
46
+ json?: boolean;
47
+ }
48
+
49
+ interface SuggestOptions {
50
+ context?: string;
51
+ limit?: string;
52
+ json?: boolean;
53
+ }
54
+
55
+ interface PruneOptions {
56
+ olderThan?: string;
57
+ dryRun?: boolean;
58
+ }
59
+
60
+ interface EmbedCommandOptions {
61
+ id?: string;
62
+ force?: boolean;
63
+ batchSize?: string;
64
+ }
65
+
66
+ interface SearchCommandOptions {
67
+ topK?: string;
68
+ type?: 'core_memory' | 'workflow' | 'cli_history';
69
+ minScore?: string;
70
+ json?: boolean;
71
+ }
72
+
73
+ interface EmbedStatusOptions {
74
+ json?: boolean;
75
+ }
76
+
77
+ /**
78
+ * Read JSON data from stdin (for Claude Code hooks)
79
+ */
80
+ async function readStdin(): Promise<string> {
81
+ return new Promise((resolve) => {
82
+ let data = '';
83
+ process.stdin.setEncoding('utf8');
84
+ process.stdin.on('readable', () => {
85
+ let chunk;
86
+ while ((chunk = process.stdin.read()) !== null) {
87
+ data += chunk;
88
+ }
89
+ });
90
+ process.stdin.on('end', () => {
91
+ resolve(data);
92
+ });
93
+ // Handle case where stdin is empty or not piped
94
+ if (process.stdin.isTTY) {
95
+ resolve('');
96
+ }
97
+ });
98
+ }
99
+
100
+ /**
101
+ * Normalize file path for consistent storage
102
+ */
103
+ function normalizePath(filePath: string): string {
104
+ // Convert Windows paths to forward slashes and remove drive letter variations
105
+ return filePath
106
+ .replace(/\\/g, '/')
107
+ .replace(/^[A-Za-z]:/, (match) => match.toLowerCase());
108
+ }
109
+
110
+ /**
111
+ * Get project path from hook data or current working directory
112
+ */
113
+ function getProjectPath(hookCwd?: string): string {
114
+ // Prefer hook's cwd (actual project workspace) over process.cwd()
115
+ return hookCwd || process.cwd();
116
+ }
117
+
118
+ /**
119
+ * Track entity access (used by hooks)
120
+ */
121
+ async function trackAction(options: TrackOptions): Promise<void> {
122
+ let { type, action, value, session, stdin } = options;
123
+ let hookCwd: string | undefined;
124
+
125
+ // If --stdin flag is set, read from stdin (Claude Code hook format)
126
+ if (stdin) {
127
+ try {
128
+ const stdinData = await readStdin();
129
+ if (stdinData) {
130
+ const hookData = JSON.parse(stdinData);
131
+ session = hookData.session_id || session;
132
+ hookCwd = hookData.cwd; // Extract workspace path from hook
133
+
134
+ // Extract value based on hook event
135
+ if (hookData.tool_input) {
136
+ // PostToolUse event
137
+ value = hookData.tool_input.file_path ||
138
+ hookData.tool_input.paths ||
139
+ hookData.tool_input.path ||
140
+ JSON.stringify(hookData.tool_input);
141
+ } else if (hookData.prompt) {
142
+ // UserPromptSubmit event
143
+ value = hookData.prompt;
144
+ }
145
+ }
146
+ } catch {
147
+ // Silently continue if stdin parsing fails
148
+ }
149
+ }
150
+
151
+ if (!type || !action) {
152
+ console.error(chalk.red('Error: --type and --action are required'));
153
+ console.error(chalk.gray('Usage: ccw memory track --type file --action read --value "path" --session "id"'));
154
+ console.error(chalk.gray(' ccw memory track --type file --action read --stdin'));
155
+ process.exit(1);
156
+ }
157
+
158
+ // Validate type and action
159
+ const validTypes = ['file', 'module', 'topic', 'url'];
160
+ const validActions = ['read', 'write', 'mention'];
161
+
162
+ if (!validTypes.includes(type)) {
163
+ if (!stdin) {
164
+ console.error(chalk.red(`Error: Invalid type "${type}". Must be one of: ${validTypes.join(', ')}`));
165
+ }
166
+ process.exit(stdin ? 0 : 1);
167
+ }
168
+
169
+ if (!validActions.includes(action)) {
170
+ if (!stdin) {
171
+ console.error(chalk.red(`Error: Invalid action "${action}". Must be one of: ${validActions.join(', ')}`));
172
+ }
173
+ process.exit(stdin ? 0 : 1);
174
+ }
175
+
176
+ // Skip if no value provided
177
+ if (!value) {
178
+ if (stdin) {
179
+ process.exit(0);
180
+ }
181
+ console.error(chalk.red('Error: --value is required'));
182
+ process.exit(1);
183
+ }
184
+
185
+ try {
186
+ const projectPath = getProjectPath(hookCwd);
187
+ const store = getMemoryStore(projectPath);
188
+ const now = new Date().toISOString();
189
+
190
+ // Normalize value for file types
191
+ const normalizedValue = type === 'file' ? normalizePath(value) : value.toLowerCase();
192
+
193
+ // Upsert entity
194
+ const entityId = store.upsertEntity({
195
+ type: type as Entity['type'],
196
+ value: value,
197
+ normalized_value: normalizedValue,
198
+ first_seen_at: now,
199
+ last_seen_at: now
200
+ });
201
+
202
+ // Log access
203
+ store.logAccess({
204
+ entity_id: entityId,
205
+ action: action as 'read' | 'write' | 'mention',
206
+ session_id: session,
207
+ timestamp: now
208
+ });
209
+
210
+ // Update statistics
211
+ store.updateStats(entityId, action as 'read' | 'write' | 'mention');
212
+
213
+ // Calculate heat score periodically (every 10th access)
214
+ const stats = store.getStats(entityId);
215
+ if (stats) {
216
+ const totalAccess = stats.read_count + stats.write_count + stats.mention_count;
217
+ if (totalAccess % 10 === 0) {
218
+ store.calculateHeatScore(entityId);
219
+ }
220
+ }
221
+
222
+ // Notify server of memory update (best-effort, non-blocking)
223
+ notifyMemoryUpdate({
224
+ entityType: type,
225
+ entityId: String(entityId),
226
+ action: action
227
+ }).catch(() => { /* ignore errors - server may not be running */ });
228
+
229
+ if (stdin) {
230
+ // Silent mode for hooks - just exit successfully
231
+ process.exit(0);
232
+ }
233
+
234
+ console.log(chalk.green('✓ Tracked:'), chalk.cyan(`${type}:${action}`), chalk.gray(value));
235
+ } catch (error) {
236
+ if (stdin) {
237
+ // Silent failure for hooks
238
+ process.exit(0);
239
+ }
240
+ console.error(chalk.red(`Error tracking: ${(error as Error).message}`));
241
+ process.exit(1);
242
+ }
243
+ }
244
+
245
+ /**
246
+ * Import Claude Code history
247
+ */
248
+ async function importAction(options: ImportOptions): Promise<void> {
249
+ const { source = 'all', project } = options;
250
+
251
+ console.log(chalk.bold.cyan('\n Importing Claude Code History\n'));
252
+ console.log(chalk.gray(` Source: ${source}`));
253
+ if (project) {
254
+ console.log(chalk.gray(` Project: ${project}`));
255
+ }
256
+
257
+ try {
258
+ const projectPath = getProjectPath();
259
+ const paths = StoragePaths.project(projectPath);
260
+ const dbPath = join(paths.memory, 'history.db');
261
+
262
+ // Ensure memory directory exists
263
+ const { mkdirSync } = await import('fs');
264
+ if (!existsSync(paths.memory)) {
265
+ mkdirSync(paths.memory, { recursive: true });
266
+ }
267
+
268
+ const importer = new HistoryImporter(dbPath);
269
+ let totalImported = 0;
270
+ let totalSkipped = 0;
271
+ let totalErrors = 0;
272
+
273
+ // Import global history
274
+ if (source === 'all' || source === 'history') {
275
+ console.log(chalk.gray('\n Importing global history...'));
276
+ const globalResult = await importer.importGlobalHistory();
277
+ totalImported += globalResult.imported;
278
+ totalSkipped += globalResult.skipped;
279
+ totalErrors += globalResult.errors;
280
+ console.log(chalk.gray(` Imported: ${globalResult.imported}, Skipped: ${globalResult.skipped}, Errors: ${globalResult.errors}`));
281
+ }
282
+
283
+ // Import project sessions
284
+ if (source === 'all' || source === 'sessions') {
285
+ const claudeHome = process.env.USERPROFILE || process.env.HOME || '';
286
+ const projectsDir = join(claudeHome, '.claude', 'projects');
287
+
288
+ if (existsSync(projectsDir)) {
289
+ const projects = project
290
+ ? [project]
291
+ : readdirSync(projectsDir).filter(f => {
292
+ const fullPath = join(projectsDir, f);
293
+ return existsSync(fullPath) && require('fs').statSync(fullPath).isDirectory();
294
+ });
295
+
296
+ for (const proj of projects) {
297
+ console.log(chalk.gray(`\n Importing sessions for: ${proj}...`));
298
+ const sessionResult = await importer.importProjectSessions(proj);
299
+ totalImported += sessionResult.imported;
300
+ totalSkipped += sessionResult.skipped;
301
+ totalErrors += sessionResult.errors;
302
+ console.log(chalk.gray(` Imported: ${sessionResult.imported}, Skipped: ${sessionResult.skipped}, Errors: ${sessionResult.errors}`));
303
+ }
304
+ }
305
+ }
306
+
307
+ importer.close();
308
+
309
+ console.log(chalk.bold.green('\n Import Complete\n'));
310
+ console.log(chalk.gray(` Total Imported: ${totalImported}`));
311
+ console.log(chalk.gray(` Total Skipped: ${totalSkipped}`));
312
+ console.log(chalk.gray(` Total Errors: ${totalErrors}`));
313
+ console.log(chalk.gray(` Database: ${dbPath}\n`));
314
+
315
+ // Notify server to refresh memory data
316
+ if (totalImported > 0) {
317
+ notifyRefreshRequired('memory').catch(() => { /* ignore */ });
318
+ }
319
+ } catch (error) {
320
+ console.error(chalk.red(`\n Error importing: ${(error as Error).message}\n`));
321
+ process.exit(1);
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Show hotspot statistics
327
+ */
328
+ async function statsAction(options: StatsOptions): Promise<void> {
329
+ const { type, limit = '20', sort = 'heat', json } = options;
330
+ const limitNum = parseInt(limit, 10);
331
+
332
+ try {
333
+ const projectPath = getProjectPath();
334
+ const store = getMemoryStore(projectPath);
335
+
336
+ // Get hot entities
337
+ const hotEntities = store.getHotEntities(limitNum * 2); // Get more to filter
338
+
339
+ // Filter by type if specified
340
+ let filtered: HotEntity[] = type
341
+ ? hotEntities.filter((e: HotEntity) => e.type === type)
342
+ : hotEntities;
343
+
344
+ // Sort by specified field
345
+ if (sort === 'reads') {
346
+ filtered.sort((a: HotEntity, b: HotEntity) => b.stats.read_count - a.stats.read_count);
347
+ } else if (sort === 'writes') {
348
+ filtered.sort((a: HotEntity, b: HotEntity) => b.stats.write_count - a.stats.write_count);
349
+ }
350
+ // Default is already sorted by heat_score
351
+
352
+ // Limit results
353
+ filtered = filtered.slice(0, limitNum);
354
+
355
+ if (json) {
356
+ const output = filtered.map((e: HotEntity) => ({
357
+ type: e.type,
358
+ value: e.value,
359
+ reads: e.stats.read_count,
360
+ writes: e.stats.write_count,
361
+ mentions: e.stats.mention_count,
362
+ heat: Math.round(e.stats.heat_score * 100) / 100,
363
+ lastSeen: e.last_seen_at
364
+ }));
365
+ console.log(JSON.stringify(output, null, 2));
366
+ return;
367
+ }
368
+
369
+ console.log(chalk.bold.cyan('\n Memory Hotspot Statistics\n'));
370
+
371
+ if (type) {
372
+ console.log(chalk.gray(` Type: ${type}`));
373
+ }
374
+ console.log(chalk.gray(` Sort: ${sort} | Limit: ${limit}\n`));
375
+
376
+ if (filtered.length === 0) {
377
+ console.log(chalk.yellow(' No data yet. Use hooks to track file access or run:'));
378
+ console.log(chalk.gray(' ccw memory track --type file --action read --value "path/to/file"'));
379
+ console.log(chalk.gray(' ccw memory import --source all\n'));
380
+ return;
381
+ }
382
+
383
+ // Display table header
384
+ console.log(chalk.gray(' ─────────────────────────────────────────────────────────────────'));
385
+ console.log(
386
+ chalk.bold(' Type ') +
387
+ chalk.bold('Heat ') +
388
+ chalk.bold('R ') +
389
+ chalk.bold('W ') +
390
+ chalk.bold('M ') +
391
+ chalk.bold('Value')
392
+ );
393
+ console.log(chalk.gray(' ─────────────────────────────────────────────────────────────────'));
394
+
395
+ for (const entity of filtered) {
396
+ const typeStr = entity.type.padEnd(8);
397
+ const heatStr = entity.stats.heat_score.toFixed(1).padStart(6);
398
+ const readStr = String(entity.stats.read_count).padStart(3);
399
+ const writeStr = String(entity.stats.write_count).padStart(3);
400
+ const mentionStr = String(entity.stats.mention_count).padStart(3);
401
+
402
+ // Truncate value if too long
403
+ const maxValueLen = 40;
404
+ let valueStr = entity.value;
405
+ if (valueStr.length > maxValueLen) {
406
+ valueStr = '...' + valueStr.slice(-maxValueLen + 3);
407
+ }
408
+
409
+ // Color based on type
410
+ const typeColor = entity.type === 'file' ? chalk.blue :
411
+ entity.type === 'module' ? chalk.magenta :
412
+ entity.type === 'topic' ? chalk.yellow : chalk.gray;
413
+
414
+ console.log(
415
+ ' ' +
416
+ typeColor(typeStr) +
417
+ chalk.cyan(heatStr) + ' ' +
418
+ chalk.green(readStr) + ' ' +
419
+ chalk.red(writeStr) + ' ' +
420
+ chalk.yellow(mentionStr) + ' ' +
421
+ chalk.gray(valueStr)
422
+ );
423
+ }
424
+
425
+ console.log(chalk.gray(' ─────────────────────────────────────────────────────────────────'));
426
+ console.log(chalk.gray(`\n R=Reads, W=Writes, M=Mentions, Heat=Composite score\n`));
427
+
428
+ } catch (error) {
429
+ if (json) {
430
+ console.log(JSON.stringify({ error: (error as Error).message }, null, 2));
431
+ } else {
432
+ console.error(chalk.red(`\n Error: ${(error as Error).message}\n`));
433
+ }
434
+ process.exit(1);
435
+ }
436
+ }
437
+
438
+ /**
439
+ * Search through prompt history
440
+ */
441
+ async function searchAction(query: string | undefined, options: SearchOptions): Promise<void> {
442
+ if (!query) {
443
+ console.error(chalk.red('Error: Search query is required'));
444
+ console.error(chalk.gray('Usage: ccw memory search "<query>"'));
445
+ process.exit(1);
446
+ }
447
+
448
+ const { limit = '20', json } = options;
449
+ const limitNum = parseInt(limit, 10);
450
+
451
+ try {
452
+ const projectPath = getProjectPath();
453
+ const store = getMemoryStore(projectPath);
454
+
455
+ // Search prompts using FTS
456
+ const results = store.searchPrompts(query, limitNum);
457
+
458
+ if (json) {
459
+ const output = results.map((p: PromptHistory) => ({
460
+ id: p.id,
461
+ sessionId: p.session_id,
462
+ prompt: p.prompt_text?.substring(0, 200) + (p.prompt_text && p.prompt_text.length > 200 ? '...' : ''),
463
+ timestamp: p.timestamp,
464
+ intentLabel: p.intent_label
465
+ }));
466
+ console.log(JSON.stringify(output, null, 2));
467
+ return;
468
+ }
469
+
470
+ console.log(chalk.bold.cyan('\n Searching Prompt History\n'));
471
+ console.log(chalk.gray(` Query: ${query}`));
472
+ console.log(chalk.gray(` Limit: ${limit}\n`));
473
+
474
+ if (results.length === 0) {
475
+ console.log(chalk.yellow(' No results found.'));
476
+ console.log(chalk.gray(' Try importing history first: ccw memory import --source all\n'));
477
+ return;
478
+ }
479
+
480
+ console.log(chalk.gray(' ─────────────────────────────────────────────────────────────────'));
481
+
482
+ for (const prompt of results) {
483
+ const timestamp = new Date(prompt.timestamp).toLocaleString();
484
+ const preview = prompt.prompt_text?.substring(0, 80).replace(/\n/g, ' ') || '(no content)';
485
+
486
+ console.log(chalk.gray(` ${timestamp}`));
487
+ console.log(chalk.white(` ${preview}${preview.length >= 80 ? '...' : ''}`));
488
+ if (prompt.intent_label) {
489
+ console.log(chalk.cyan(` Intent: ${prompt.intent_label}`));
490
+ }
491
+ console.log(chalk.gray(' ─────────────────────────────────────────────────────────────────'));
492
+ }
493
+
494
+ console.log(chalk.gray(`\n Found ${results.length} result(s)\n`));
495
+
496
+ } catch (error) {
497
+ if (json) {
498
+ console.log(JSON.stringify({ error: (error as Error).message }, null, 2));
499
+ } else {
500
+ console.error(chalk.red(`\n Error: ${(error as Error).message}\n`));
501
+ }
502
+ process.exit(1);
503
+ }
504
+ }
505
+
506
+ /**
507
+ * Get optimization suggestions based on similar successful prompts
508
+ */
509
+ async function suggestAction(options: SuggestOptions): Promise<void> {
510
+ const { context, limit = '5', json } = options;
511
+ const limitNum = parseInt(limit, 10);
512
+
513
+ try {
514
+ const projectPath = getProjectPath();
515
+ const store = getMemoryStore(projectPath);
516
+
517
+ // Get hot entities for suggestions
518
+ const hotEntities = store.getHotEntities(limitNum);
519
+
520
+ const suggestions = hotEntities.map((e: HotEntity) => ({
521
+ type: e.type,
522
+ value: e.value,
523
+ reason: `Frequently accessed (${e.stats.read_count} reads, ${e.stats.write_count} writes)`,
524
+ heat: e.stats.heat_score
525
+ }));
526
+
527
+ if (json) {
528
+ console.log(JSON.stringify({ suggestions, context }, null, 2));
529
+ return;
530
+ }
531
+
532
+ console.log(chalk.bold.cyan('\n Memory Optimization Suggestions\n'));
533
+
534
+ if (context) {
535
+ console.log(chalk.gray(` Context: ${context}\n`));
536
+ }
537
+
538
+ if (suggestions.length === 0) {
539
+ console.log(chalk.yellow(' No suggestions available yet.'));
540
+ console.log(chalk.gray(' Track more file access to get suggestions.\n'));
541
+ return;
542
+ }
543
+
544
+ console.log(chalk.gray(' Based on your access patterns:\n'));
545
+
546
+ for (let i = 0; i < suggestions.length; i++) {
547
+ const s = suggestions[i];
548
+ console.log(chalk.cyan(` ${i + 1}. ${s.type}: `) + chalk.white(s.value));
549
+ console.log(chalk.gray(` ${s.reason}`));
550
+ }
551
+
552
+ console.log(chalk.gray('\n Tip: Include frequently accessed files in your context for better results.\n'));
553
+
554
+ } catch (error) {
555
+ if (json) {
556
+ console.log(JSON.stringify({ error: (error as Error).message }, null, 2));
557
+ } else {
558
+ console.error(chalk.red(`\n Error: ${(error as Error).message}\n`));
559
+ }
560
+ process.exit(1);
561
+ }
562
+ }
563
+
564
+ /**
565
+ * Parse age string to milliseconds
566
+ */
567
+ function parseAge(ageStr: string): number {
568
+ const match = ageStr.match(/^(\d+)([dhm])$/);
569
+ if (!match) {
570
+ throw new Error(`Invalid age format: ${ageStr}. Use format like 30d, 24h, or 60m`);
571
+ }
572
+
573
+ const value = parseInt(match[1], 10);
574
+ const unit = match[2];
575
+
576
+ switch (unit) {
577
+ case 'd': return value * 24 * 60 * 60 * 1000;
578
+ case 'h': return value * 60 * 60 * 1000;
579
+ case 'm': return value * 60 * 1000;
580
+ default: throw new Error(`Unknown unit: ${unit}`);
581
+ }
582
+ }
583
+
584
+ /**
585
+ * Clean up old data
586
+ */
587
+ async function pruneAction(options: PruneOptions): Promise<void> {
588
+ const { olderThan = '30d', dryRun } = options;
589
+
590
+ console.log(chalk.bold.cyan('\n Pruning Memory Data\n'));
591
+ console.log(chalk.gray(` Older than: ${olderThan}`));
592
+ console.log(chalk.gray(` Mode: ${dryRun ? 'Dry run (preview)' : 'Delete'}\n`));
593
+
594
+ try {
595
+ const ageMs = parseAge(olderThan);
596
+ const cutoffDate = new Date(Date.now() - ageMs);
597
+ const cutoffStr = cutoffDate.toISOString();
598
+
599
+ const projectPath = getProjectPath();
600
+ const paths = StoragePaths.project(projectPath);
601
+
602
+ if (!existsSync(paths.memoryDb)) {
603
+ console.log(chalk.yellow(' No memory database found. Nothing to prune.\n'));
604
+ return;
605
+ }
606
+
607
+ // Use direct database access for pruning
608
+ const Database = require('better-sqlite3');
609
+ const db = new Database(paths.memoryDb);
610
+
611
+ // Count records to prune
612
+ const accessLogsCount = db.prepare(`
613
+ SELECT COUNT(*) as count FROM access_logs WHERE timestamp < ?
614
+ `).get(cutoffStr) as { count: number };
615
+
616
+ const entitiesCount = db.prepare(`
617
+ SELECT COUNT(*) as count FROM entities WHERE last_seen_at < ?
618
+ `).get(cutoffStr) as { count: number };
619
+
620
+ console.log(chalk.gray(` Access logs to prune: ${accessLogsCount.count}`));
621
+ console.log(chalk.gray(` Entities to prune: ${entitiesCount.count}`));
622
+
623
+ if (dryRun) {
624
+ console.log(chalk.yellow('\n Dry run - no changes made.\n'));
625
+ db.close();
626
+ return;
627
+ }
628
+
629
+ if (accessLogsCount.count === 0 && entitiesCount.count === 0) {
630
+ console.log(chalk.green('\n Nothing to prune.\n'));
631
+ db.close();
632
+ return;
633
+ }
634
+
635
+ // Delete old access logs
636
+ const deleteAccessLogs = db.prepare(`DELETE FROM access_logs WHERE timestamp < ?`);
637
+ const accessResult = deleteAccessLogs.run(cutoffStr);
638
+
639
+ // Delete entities not seen recently (and their stats)
640
+ const deleteStats = db.prepare(`
641
+ DELETE FROM entity_stats WHERE entity_id IN (
642
+ SELECT id FROM entities WHERE last_seen_at < ?
643
+ )
644
+ `);
645
+ deleteStats.run(cutoffStr);
646
+
647
+ const deleteEntities = db.prepare(`DELETE FROM entities WHERE last_seen_at < ?`);
648
+ const entitiesResult = deleteEntities.run(cutoffStr);
649
+
650
+ db.close();
651
+
652
+ console.log(chalk.green(`\n Pruned ${accessResult.changes} access logs`));
653
+ console.log(chalk.green(` Pruned ${entitiesResult.changes} entities\n`));
654
+
655
+ // Notify server to refresh memory data
656
+ if (accessResult.changes > 0 || entitiesResult.changes > 0) {
657
+ notifyRefreshRequired('memory').catch(() => { /* ignore */ });
658
+ }
659
+
660
+ } catch (error) {
661
+ console.error(chalk.red(`\n Error: ${(error as Error).message}\n`));
662
+ process.exit(1);
663
+ }
664
+ }
665
+
666
+ /**
667
+ * Chunk and prepare memories for embedding
668
+ */
669
+ async function chunkMemoriesForEmbedding(projectPath: string, sourceId?: string, force?: boolean): Promise<number> {
670
+ const coreMemoryStore = getCoreMemoryStore(projectPath);
671
+ let chunksCreated = 0;
672
+
673
+ // 1. Chunk core memories
674
+ const memories = coreMemoryStore.getMemories({ archived: false, limit: 1000 });
675
+ for (const memory of memories) {
676
+ if (sourceId && memory.id !== sourceId) continue;
677
+
678
+ // Check if already chunked (skip unless force)
679
+ const existingChunks = coreMemoryStore.getChunks(memory.id);
680
+ if (existingChunks.length > 0 && !force) continue;
681
+
682
+ // Delete old chunks if force
683
+ if (force && existingChunks.length > 0) {
684
+ coreMemoryStore.deleteChunks(memory.id);
685
+ }
686
+
687
+ // Chunk the memory content
688
+ const chunks = coreMemoryStore.chunkContent(memory.content, memory.id, 'core_memory');
689
+
690
+ // Insert chunks
691
+ for (let i = 0; i < chunks.length; i++) {
692
+ coreMemoryStore.insertChunk({
693
+ source_id: memory.id,
694
+ source_type: 'core_memory',
695
+ chunk_index: i,
696
+ content: chunks[i],
697
+ created_at: new Date().toISOString()
698
+ });
699
+ chunksCreated++;
700
+ }
701
+ }
702
+
703
+ // 2. Chunk CLI history
704
+ try {
705
+ const cliHistoryStore = new CliHistoryStore(projectPath);
706
+ const history = cliHistoryStore.getHistory({ limit: 500 });
707
+
708
+ for (const exec of history.executions) {
709
+ if (sourceId && exec.id !== sourceId) continue;
710
+
711
+ // Check if already chunked
712
+ const existingChunks = coreMemoryStore.getChunks(exec.id);
713
+ if (existingChunks.length > 0 && !force) continue;
714
+
715
+ // Delete old chunks if force
716
+ if (force && existingChunks.length > 0) {
717
+ coreMemoryStore.deleteChunks(exec.id);
718
+ }
719
+
720
+ // Get conversation content
721
+ const conversation = cliHistoryStore.getConversation(exec.id);
722
+ if (!conversation || !conversation.turns || conversation.turns.length === 0) continue;
723
+
724
+ // Create content from turns
725
+ const content = conversation.turns
726
+ .map((t: any) => `Prompt: ${t.prompt}\nOutput: ${(t.stdout || '').substring(0, 500)}`)
727
+ .join('\n---\n');
728
+
729
+ // Chunk the content
730
+ const chunks = coreMemoryStore.chunkContent(content, exec.id, 'cli_history');
731
+
732
+ // Insert chunks
733
+ for (let i = 0; i < chunks.length; i++) {
734
+ coreMemoryStore.insertChunk({
735
+ source_id: exec.id,
736
+ source_type: 'cli_history',
737
+ chunk_index: i,
738
+ content: chunks[i],
739
+ created_at: new Date().toISOString()
740
+ });
741
+ chunksCreated++;
742
+ }
743
+ }
744
+ } catch {
745
+ // CLI history might not exist, continue
746
+ }
747
+
748
+ return chunksCreated;
749
+ }
750
+
751
+ /**
752
+ * Generate embeddings for memory chunks
753
+ */
754
+ async function embedAction(options: EmbedCommandOptions): Promise<void> {
755
+ const { id, force, batchSize } = options;
756
+
757
+ try {
758
+ // Check embedder availability
759
+ if (!isEmbedderAvailable()) {
760
+ console.error(chalk.red('\nError: Memory embedder not available'));
761
+ console.error(chalk.gray('Ensure CodexLens venv exists at ~/.codexlens/venv\n'));
762
+ process.exit(1);
763
+ }
764
+
765
+ const projectPath = getProjectPath();
766
+ const paths = StoragePaths.project(projectPath);
767
+ const dbPath = join(paths.root, 'core-memory', 'core_memory.db');
768
+
769
+ if (!existsSync(dbPath)) {
770
+ console.error(chalk.red('\nError: Core memory database not found'));
771
+ console.error(chalk.gray('Create memories first using "ccw core-memory import"\n'));
772
+ process.exit(1);
773
+ }
774
+
775
+ // Step 1: Chunk memories first
776
+ console.log(chalk.cyan('Chunking memories...'));
777
+ const chunksCreated = await chunkMemoriesForEmbedding(projectPath, id, force);
778
+ if (chunksCreated > 0) {
779
+ console.log(chalk.green(` Created ${chunksCreated} new chunks`));
780
+ }
781
+
782
+ // Step 2: Generate embeddings
783
+ console.log(chalk.cyan('Generating embeddings...'));
784
+
785
+ const embedOptions: EmbedOptions = {
786
+ sourceId: id,
787
+ force: force || false,
788
+ batchSize: batchSize ? parseInt(batchSize, 10) : 8
789
+ };
790
+
791
+ const result = await generateEmbeddings(dbPath, embedOptions);
792
+
793
+ if (!result.success) {
794
+ console.error(chalk.red(`\nError: ${result.error}\n`));
795
+ process.exit(1);
796
+ }
797
+
798
+ console.log(chalk.green(`\n✓ Processed ${result.chunks_processed} chunks in ${result.elapsed_time.toFixed(1)}s`));
799
+
800
+ // Get status to show breakdown by type
801
+ const status = await getEmbeddingStatus(dbPath);
802
+ if (status.success && Object.keys(status.by_type).length > 0) {
803
+ for (const [type, stats] of Object.entries(status.by_type)) {
804
+ if (stats.total > 0) {
805
+ console.log(chalk.white(` - ${type}: ${stats.embedded} chunks`));
806
+ }
807
+ }
808
+ }
809
+ console.log();
810
+
811
+ } catch (error) {
812
+ console.error(chalk.red(`\nError: ${(error as Error).message}\n`));
813
+ process.exit(1);
814
+ }
815
+ }
816
+
817
+ /**
818
+ * Search memories using semantic search
819
+ */
820
+ async function searchEmbedAction(query: string | undefined, options: SearchCommandOptions): Promise<void> {
821
+ if (!query) {
822
+ console.error(chalk.red('Error: Search query is required'));
823
+ console.error(chalk.gray('Usage: ccw memory search "<query>"'));
824
+ process.exit(1);
825
+ }
826
+
827
+ const { topK = '10', type, minScore = '0.5', json } = options;
828
+
829
+ try {
830
+ // Check embedder availability
831
+ if (!isEmbedderAvailable()) {
832
+ console.error(chalk.red('\nError: Memory embedder not available'));
833
+ console.error(chalk.gray('Ensure CodexLens venv exists at ~/.codexlens/venv\n'));
834
+ process.exit(1);
835
+ }
836
+
837
+ const projectPath = getProjectPath();
838
+ const paths = StoragePaths.project(projectPath);
839
+ const dbPath = join(paths.root, 'core-memory', 'core_memory.db');
840
+
841
+ if (!existsSync(dbPath)) {
842
+ console.error(chalk.red('\nError: Core memory database not found'));
843
+ console.error(chalk.gray('Create memories first using "ccw core-memory import"\n'));
844
+ process.exit(1);
845
+ }
846
+
847
+ const searchOptions: EmbedSearchOptions = {
848
+ topK: parseInt(topK, 10),
849
+ minScore: parseFloat(minScore),
850
+ sourceType: type
851
+ };
852
+
853
+ const result = await searchMemories(dbPath, query, searchOptions);
854
+
855
+ if (!result.success) {
856
+ console.error(chalk.red(`\nError: ${result.error}\n`));
857
+ process.exit(1);
858
+ }
859
+
860
+ if (json) {
861
+ const output = result.matches.map(m => ({
862
+ sourceId: m.source_id,
863
+ sourceType: m.source_type,
864
+ score: m.score,
865
+ content: m.content,
866
+ restoreCommand: m.restore_command
867
+ }));
868
+ console.log(JSON.stringify(output, null, 2));
869
+ return;
870
+ }
871
+
872
+ console.log(chalk.bold.cyan(`\nFound ${result.matches.length} matches for "${query}":\n`));
873
+
874
+ if (result.matches.length === 0) {
875
+ console.log(chalk.yellow('No results found. Try:'));
876
+ console.log(chalk.gray(' - Using different keywords'));
877
+ console.log(chalk.gray(' - Lowering --min-score threshold'));
878
+ console.log(chalk.gray(' - Running "ccw memory embed" to generate embeddings\n'));
879
+ return;
880
+ }
881
+
882
+ for (let i = 0; i < result.matches.length; i++) {
883
+ const match = result.matches[i];
884
+ const preview = match.content.length > 80
885
+ ? match.content.substring(0, 80) + '...'
886
+ : match.content;
887
+
888
+ console.log(chalk.bold.white(`${i + 1}. [${match.score.toFixed(2)}] ${match.source_id}`) + chalk.gray(` (${match.source_type})`));
889
+ console.log(chalk.white(` "${preview}"`));
890
+ console.log(chalk.cyan(` → ${match.restore_command}`));
891
+ console.log();
892
+ }
893
+
894
+ } catch (error) {
895
+ if (json) {
896
+ console.log(JSON.stringify({ error: (error as Error).message }, null, 2));
897
+ } else {
898
+ console.error(chalk.red(`\nError: ${(error as Error).message}\n`));
899
+ }
900
+ process.exit(1);
901
+ }
902
+ }
903
+
904
+ /**
905
+ * Show embedding status
906
+ */
907
+ async function embedStatusAction(options: EmbedStatusOptions): Promise<void> {
908
+ const { json } = options;
909
+
910
+ try {
911
+ // Check embedder availability
912
+ if (!isEmbedderAvailable()) {
913
+ console.error(chalk.red('\nError: Memory embedder not available'));
914
+ console.error(chalk.gray('Ensure CodexLens venv exists at ~/.codexlens/venv\n'));
915
+ process.exit(1);
916
+ }
917
+
918
+ const projectPath = getProjectPath();
919
+ const paths = StoragePaths.project(projectPath);
920
+ const dbPath = join(paths.root, 'core-memory', 'core_memory.db');
921
+
922
+ if (!existsSync(dbPath)) {
923
+ console.error(chalk.red('\nError: Core memory database not found'));
924
+ console.error(chalk.gray('Create memories first using "ccw core-memory import"\n'));
925
+ process.exit(1);
926
+ }
927
+
928
+ const status = await getEmbeddingStatus(dbPath);
929
+
930
+ if (!status.success) {
931
+ console.error(chalk.red(`\nError: ${status.error}\n`));
932
+ process.exit(1);
933
+ }
934
+
935
+ if (json) {
936
+ console.log(JSON.stringify(status, null, 2));
937
+ return;
938
+ }
939
+
940
+ const embeddedPercent = status.total_chunks > 0
941
+ ? Math.round((status.embedded_chunks / status.total_chunks) * 100)
942
+ : 0;
943
+
944
+ console.log(chalk.bold.cyan('\nEmbedding Status:'));
945
+ console.log(chalk.white(` Total chunks: ${status.total_chunks}`));
946
+ console.log(chalk.white(` Embedded: ${status.embedded_chunks} (${embeddedPercent}%)`));
947
+ console.log(chalk.white(` Pending: ${status.pending_chunks}`));
948
+
949
+ if (Object.keys(status.by_type).length > 0) {
950
+ console.log(chalk.bold.white('\nBy Type:'));
951
+ for (const [type, stats] of Object.entries(status.by_type)) {
952
+ const typePercent = stats.total > 0
953
+ ? Math.round((stats.embedded / stats.total) * 100)
954
+ : 0;
955
+ console.log(chalk.cyan(` ${type}: `) + chalk.white(`${stats.embedded}/${stats.total} (${typePercent}%)`));
956
+ }
957
+ }
958
+ console.log();
959
+
960
+ } catch (error) {
961
+ if (json) {
962
+ console.log(JSON.stringify({ error: (error as Error).message }, null, 2));
963
+ } else {
964
+ console.error(chalk.red(`\nError: ${(error as Error).message}\n`));
965
+ }
966
+ process.exit(1);
967
+ }
968
+ }
969
+
970
+ /**
971
+ * Memory command entry point
972
+ * @param {string} subcommand - Subcommand (track, import, stats, search, suggest, prune, embed, embed-status)
973
+ * @param {string|string[]} args - Arguments array
974
+ * @param {Object} options - CLI options
975
+ */
976
+ export async function memoryCommand(
977
+ subcommand: string,
978
+ args: string | string[],
979
+ options: TrackOptions | ImportOptions | StatsOptions | SearchOptions | SuggestOptions | PruneOptions | EmbedCommandOptions | SearchCommandOptions | EmbedStatusOptions
980
+ ): Promise<void> {
981
+ const argsArray = Array.isArray(args) ? args : (args ? [args] : []);
982
+
983
+ switch (subcommand) {
984
+ case 'track':
985
+ await trackAction(options as TrackOptions);
986
+ break;
987
+
988
+ case 'import':
989
+ await importAction(options as ImportOptions);
990
+ break;
991
+
992
+ case 'stats':
993
+ await statsAction(options as StatsOptions);
994
+ break;
995
+
996
+ case 'search':
997
+ // Check if this is semantic search (has --top-k or --min-score) or prompt history search
998
+ if ('topK' in options || 'minScore' in options) {
999
+ await searchEmbedAction(argsArray[0], options as SearchCommandOptions);
1000
+ } else {
1001
+ await searchAction(argsArray[0], options as SearchOptions);
1002
+ }
1003
+ break;
1004
+
1005
+ case 'suggest':
1006
+ await suggestAction(options as SuggestOptions);
1007
+ break;
1008
+
1009
+ case 'prune':
1010
+ await pruneAction(options as PruneOptions);
1011
+ break;
1012
+
1013
+ case 'embed':
1014
+ await embedAction(options as EmbedCommandOptions);
1015
+ break;
1016
+
1017
+ case 'embed-status':
1018
+ await embedStatusAction(options as EmbedStatusOptions);
1019
+ break;
1020
+
1021
+ default:
1022
+ console.log(chalk.bold.cyan('\n CCW Memory Module\n'));
1023
+ console.log(' Context tracking and prompt optimization.\n');
1024
+ console.log(' Subcommands:');
1025
+ console.log(chalk.gray(' track Track entity access (used by hooks)'));
1026
+ console.log(chalk.gray(' import Import Claude Code history'));
1027
+ console.log(chalk.gray(' stats Show hotspot statistics'));
1028
+ console.log(chalk.gray(' search <query> Search through prompt history (semantic or FTS)'));
1029
+ console.log(chalk.gray(' suggest Get optimization suggestions'));
1030
+ console.log(chalk.gray(' prune Clean up old data'));
1031
+ console.log(chalk.gray(' embed Generate embeddings for semantic search'));
1032
+ console.log(chalk.gray(' embed-status Show embedding generation status'));
1033
+ console.log();
1034
+ console.log(' Track Options:');
1035
+ console.log(chalk.gray(' --type <type> Entity type: file, module, topic'));
1036
+ console.log(chalk.gray(' --action <action> Action: read, write, mention'));
1037
+ console.log(chalk.gray(' --value <value> Entity value (file path, etc.)'));
1038
+ console.log(chalk.gray(' --session <id> Session ID (optional)'));
1039
+ console.log();
1040
+ console.log(' Import Options:');
1041
+ console.log(chalk.gray(' --source <source> Source: history, sessions, all (default: all)'));
1042
+ console.log(chalk.gray(' --project <name> Project name filter (optional)'));
1043
+ console.log();
1044
+ console.log(' Stats Options:');
1045
+ console.log(chalk.gray(' --type <type> Filter: file, module, topic (optional)'));
1046
+ console.log(chalk.gray(' --limit <n> Number of results (default: 20)'));
1047
+ console.log(chalk.gray(' --sort <field> Sort by: heat, reads, writes (default: heat)'));
1048
+ console.log(chalk.gray(' --json Output as JSON'));
1049
+ console.log();
1050
+ console.log(' Search Options (Prompt History):');
1051
+ console.log(chalk.gray(' --limit <n> Number of results (default: 20)'));
1052
+ console.log(chalk.gray(' --json Output as JSON'));
1053
+ console.log();
1054
+ console.log(' Search Options (Semantic - requires embeddings):');
1055
+ console.log(chalk.gray(' --top-k <n> Number of results (default: 10)'));
1056
+ console.log(chalk.gray(' --min-score <f> Minimum similarity score (default: 0.5)'));
1057
+ console.log(chalk.gray(' --type <type> Filter: core_memory, workflow, cli_history'));
1058
+ console.log(chalk.gray(' --json Output as JSON'));
1059
+ console.log();
1060
+ console.log(' Embed Options:');
1061
+ console.log(chalk.gray(' --id <id> Specific memory/session ID to embed'));
1062
+ console.log(chalk.gray(' --force Force re-embed all chunks'));
1063
+ console.log(chalk.gray(' --batch-size <n> Batch size for embedding (default: 8)'));
1064
+ console.log();
1065
+ console.log(' Embed Status Options:');
1066
+ console.log(chalk.gray(' --json Output as JSON'));
1067
+ console.log();
1068
+ console.log(' Suggest Options:');
1069
+ console.log(chalk.gray(' --context <text> Current task context (optional)'));
1070
+ console.log(chalk.gray(' --limit <n> Number of suggestions (default: 5)'));
1071
+ console.log(chalk.gray(' --json Output as JSON'));
1072
+ console.log();
1073
+ console.log(' Prune Options:');
1074
+ console.log(chalk.gray(' --older-than <age> Age threshold (default: 30d)'));
1075
+ console.log(chalk.gray(' --dry-run Preview without deleting'));
1076
+ console.log();
1077
+ console.log(' Examples:');
1078
+ console.log(chalk.gray(' ccw memory track --type file --action read --value "src/auth.ts"'));
1079
+ console.log(chalk.gray(' ccw memory import --source history --project "my-app"'));
1080
+ console.log(chalk.gray(' ccw memory stats --type file --sort heat --limit 10'));
1081
+ console.log(chalk.gray(' ccw memory search "authentication patterns" # FTS search'));
1082
+ console.log(chalk.gray(' ccw memory embed # Generate all embeddings'));
1083
+ console.log(chalk.gray(' ccw memory embed --id CMEM-xxx # Embed specific memory'));
1084
+ console.log(chalk.gray(' ccw memory embed-status # Check embedding status'));
1085
+ console.log(chalk.gray(' ccw memory search "auth patterns" --top-k 5 # Semantic search'));
1086
+ console.log(chalk.gray(' ccw memory suggest --context "implementing JWT auth"'));
1087
+ console.log(chalk.gray(' ccw memory prune --older-than 60d --dry-run'));
1088
+ console.log();
1089
+ }
1090
+ }