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,469 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
2
+ import { join } from 'path';
3
+
4
+ interface TaskMeta {
5
+ type: string;
6
+ agent: string | null;
7
+ scope: string | null;
8
+ module: string | null;
9
+ }
10
+
11
+ interface TaskContext {
12
+ requirements: string[];
13
+ focus_paths: string[];
14
+ acceptance: string[];
15
+ depends_on: string[];
16
+ }
17
+
18
+ interface TaskFlowControl {
19
+ implementation_approach: Array<{
20
+ step: string;
21
+ action: string;
22
+ }>;
23
+ }
24
+
25
+ interface NormalizedTask {
26
+ id: string;
27
+ title: string;
28
+ status: string;
29
+ meta: TaskMeta;
30
+ context: TaskContext;
31
+ flow_control: TaskFlowControl;
32
+ _raw: unknown;
33
+ }
34
+
35
+ interface Progress {
36
+ total: number;
37
+ completed: number;
38
+ percentage: number;
39
+ }
40
+
41
+ interface DiagnosisItem {
42
+ id: string;
43
+ filename: string;
44
+ [key: string]: unknown;
45
+ }
46
+
47
+ interface Diagnoses {
48
+ manifest: unknown | null;
49
+ items: DiagnosisItem[];
50
+ }
51
+
52
+ interface LiteSession {
53
+ id: string;
54
+ type: string;
55
+ path: string;
56
+ createdAt: string;
57
+ plan: unknown | null;
58
+ tasks: NormalizedTask[];
59
+ diagnoses?: Diagnoses;
60
+ progress: Progress;
61
+ }
62
+
63
+ interface LiteTasks {
64
+ litePlan: LiteSession[];
65
+ liteFix: LiteSession[];
66
+ }
67
+
68
+ interface LiteTaskDetail {
69
+ id: string;
70
+ type: string;
71
+ path: string;
72
+ plan: unknown | null;
73
+ tasks: NormalizedTask[];
74
+ explorations: unknown[];
75
+ clarifications: unknown | null;
76
+ diagnoses?: Diagnoses;
77
+ }
78
+
79
+ /**
80
+ * Scan lite-plan and lite-fix directories for task sessions
81
+ * @param workflowDir - Path to .workflow directory
82
+ * @returns Lite tasks data
83
+ */
84
+ export async function scanLiteTasks(workflowDir: string): Promise<LiteTasks> {
85
+ const litePlanDir = join(workflowDir, '.lite-plan');
86
+ const liteFixDir = join(workflowDir, '.lite-fix');
87
+
88
+ return {
89
+ litePlan: scanLiteDir(litePlanDir, 'lite-plan'),
90
+ liteFix: scanLiteDir(liteFixDir, 'lite-fix')
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Scan a lite task directory
96
+ * @param dir - Directory path
97
+ * @param type - Task type ('lite-plan' or 'lite-fix')
98
+ * @returns Array of lite task sessions
99
+ */
100
+ function scanLiteDir(dir: string, type: string): LiteSession[] {
101
+ if (!existsSync(dir)) return [];
102
+
103
+ try {
104
+ const sessions = readdirSync(dir, { withFileTypes: true })
105
+ .filter(d => d.isDirectory())
106
+ .map(d => {
107
+ const sessionPath = join(dir, d.name);
108
+ const session: LiteSession = {
109
+ id: d.name,
110
+ type,
111
+ path: sessionPath,
112
+ createdAt: getCreatedTime(sessionPath),
113
+ plan: loadPlanJson(sessionPath),
114
+ tasks: loadTaskJsons(sessionPath),
115
+ progress: { total: 0, completed: 0, percentage: 0 }
116
+ };
117
+
118
+ // For lite-fix sessions, also load diagnoses separately
119
+ if (type === 'lite-fix') {
120
+ session.diagnoses = loadDiagnoses(sessionPath);
121
+ }
122
+
123
+ // Calculate progress
124
+ session.progress = calculateProgress(session.tasks);
125
+
126
+ return session;
127
+ })
128
+ .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
129
+
130
+ return sessions;
131
+ } catch (err) {
132
+ console.error(`Error scanning ${dir}:`, (err as Error).message);
133
+ return [];
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Load plan.json or fix-plan.json from session directory
139
+ * @param sessionPath - Session directory path
140
+ * @returns Plan data or null
141
+ */
142
+ function loadPlanJson(sessionPath: string): unknown | null {
143
+ // Try fix-plan.json first (for lite-fix), then plan.json (for lite-plan)
144
+ const fixPlanPath = join(sessionPath, 'fix-plan.json');
145
+ const planPath = join(sessionPath, 'plan.json');
146
+
147
+ // Try fix-plan.json first
148
+ if (existsSync(fixPlanPath)) {
149
+ try {
150
+ const content = readFileSync(fixPlanPath, 'utf8');
151
+ return JSON.parse(content);
152
+ } catch {
153
+ // Continue to try plan.json
154
+ }
155
+ }
156
+
157
+ // Fallback to plan.json
158
+ if (existsSync(planPath)) {
159
+ try {
160
+ const content = readFileSync(planPath, 'utf8');
161
+ return JSON.parse(content);
162
+ } catch {
163
+ return null;
164
+ }
165
+ }
166
+
167
+ return null;
168
+ }
169
+
170
+ /**
171
+ * Load all task JSON files from session directory
172
+ * Supports multiple task formats:
173
+ * 1. .task/IMPL-*.json files
174
+ * 2. tasks array in plan.json
175
+ * 3. task-*.json files in session root
176
+ * @param sessionPath - Session directory path
177
+ * @returns Array of task objects
178
+ */
179
+ function loadTaskJsons(sessionPath: string): NormalizedTask[] {
180
+ let tasks: NormalizedTask[] = [];
181
+
182
+ // Method 1: Check .task/IMPL-*.json files
183
+ const taskDir = join(sessionPath, '.task');
184
+ if (existsSync(taskDir)) {
185
+ try {
186
+ const implTasks = readdirSync(taskDir)
187
+ .filter(f => f.endsWith('.json') && (
188
+ f.startsWith('IMPL-') ||
189
+ f.startsWith('TASK-') ||
190
+ f.startsWith('task-') ||
191
+ f.startsWith('diagnosis-') ||
192
+ /^T\d+\.json$/i.test(f)
193
+ ))
194
+ .map(f => {
195
+ const taskPath = join(taskDir, f);
196
+ try {
197
+ const content = readFileSync(taskPath, 'utf8');
198
+ return normalizeTask(JSON.parse(content));
199
+ } catch {
200
+ return null;
201
+ }
202
+ })
203
+ .filter((t): t is NormalizedTask => t !== null);
204
+ tasks = tasks.concat(implTasks);
205
+ } catch {
206
+ // Continue to other methods
207
+ }
208
+ }
209
+
210
+ // Method 2: Check plan.json or fix-plan.json for embedded tasks array
211
+ if (tasks.length === 0) {
212
+ // Try fix-plan.json first (for lite-fix), then plan.json (for lite-plan)
213
+ const fixPlanPath = join(sessionPath, 'fix-plan.json');
214
+ const planPath = join(sessionPath, 'plan.json');
215
+
216
+ const planFile = existsSync(fixPlanPath) ? fixPlanPath :
217
+ existsSync(planPath) ? planPath : null;
218
+
219
+ if (planFile) {
220
+ try {
221
+ const plan = JSON.parse(readFileSync(planFile, 'utf8')) as { tasks?: unknown[] };
222
+ if (Array.isArray(plan.tasks)) {
223
+ tasks = plan.tasks.map(t => normalizeTask(t)).filter((t): t is NormalizedTask => t !== null);
224
+ }
225
+ } catch {
226
+ // Continue to other methods
227
+ }
228
+ }
229
+ }
230
+
231
+ // Method 3: Check for task-*.json and diagnosis-*.json files in session root
232
+ if (tasks.length === 0) {
233
+ try {
234
+ const rootTasks = readdirSync(sessionPath)
235
+ .filter(f => f.endsWith('.json') && (
236
+ f.startsWith('task-') ||
237
+ f.startsWith('TASK-') ||
238
+ f.startsWith('diagnosis-') ||
239
+ /^T\d+\.json$/i.test(f)
240
+ ))
241
+ .map(f => {
242
+ const taskPath = join(sessionPath, f);
243
+ try {
244
+ const content = readFileSync(taskPath, 'utf8');
245
+ return normalizeTask(JSON.parse(content));
246
+ } catch {
247
+ return null;
248
+ }
249
+ })
250
+ .filter((t): t is NormalizedTask => t !== null);
251
+ tasks = tasks.concat(rootTasks);
252
+ } catch {
253
+ // No tasks found
254
+ }
255
+ }
256
+
257
+ // Sort tasks by ID
258
+ return tasks.sort((a, b) => {
259
+ const aNum = parseInt(a.id?.replace(/\D/g, '') || '0');
260
+ const bNum = parseInt(b.id?.replace(/\D/g, '') || '0');
261
+ return aNum - bNum;
262
+ });
263
+ }
264
+
265
+ /**
266
+ * Normalize task object to consistent structure
267
+ * @param task - Raw task object
268
+ * @returns Normalized task
269
+ */
270
+ function normalizeTask(task: unknown): NormalizedTask | null {
271
+ if (!task || typeof task !== 'object') return null;
272
+
273
+ const taskObj = task as Record<string, unknown>;
274
+
275
+ // Determine status - support various status formats
276
+ let status = (taskObj.status as string | { state?: string; value?: string }) || 'pending';
277
+ if (typeof status === 'object') {
278
+ status = status.state || status.value || 'pending';
279
+ }
280
+
281
+ const meta = taskObj.meta as Record<string, unknown> | undefined;
282
+ const context = taskObj.context as Record<string, unknown> | undefined;
283
+ const flowControl = taskObj.flow_control as Record<string, unknown> | undefined;
284
+ const implementation = taskObj.implementation as unknown[] | undefined;
285
+ const modificationPoints = taskObj.modification_points as Array<{ file?: string }> | undefined;
286
+
287
+ return {
288
+ id: (taskObj.id as string) || (taskObj.task_id as string) || 'unknown',
289
+ title: (taskObj.title as string) || (taskObj.name as string) || (taskObj.summary as string) || 'Untitled Task',
290
+ status: (status as string).toLowerCase(),
291
+ // Preserve original fields for flexible rendering
292
+ meta: meta ? {
293
+ type: (meta.type as string) || (taskObj.type as string) || (taskObj.action as string) || 'task',
294
+ agent: (meta.agent as string) || (taskObj.agent as string) || null,
295
+ scope: (meta.scope as string) || (taskObj.scope as string) || null,
296
+ module: (meta.module as string) || (taskObj.module as string) || null
297
+ } : {
298
+ type: (taskObj.type as string) || (taskObj.action as string) || 'task',
299
+ agent: (taskObj.agent as string) || null,
300
+ scope: (taskObj.scope as string) || null,
301
+ module: (taskObj.module as string) || null
302
+ },
303
+ context: context ? {
304
+ requirements: (context.requirements as string[]) || [],
305
+ focus_paths: (context.focus_paths as string[]) || [],
306
+ acceptance: (context.acceptance as string[]) || [],
307
+ depends_on: (context.depends_on as string[]) || []
308
+ } : {
309
+ requirements: (taskObj.requirements as string[]) || (taskObj.description ? [taskObj.description as string] : []),
310
+ focus_paths: (taskObj.focus_paths as string[]) || modificationPoints?.map(m => m.file).filter((f): f is string => !!f) || [],
311
+ acceptance: (taskObj.acceptance as string[]) || [],
312
+ depends_on: (taskObj.depends_on as string[]) || []
313
+ },
314
+ flow_control: flowControl ? {
315
+ implementation_approach: (flowControl.implementation_approach as Array<{ step: string; action: string }>) || []
316
+ } : {
317
+ implementation_approach: implementation?.map((step, i) => ({
318
+ step: `Step ${i + 1}`,
319
+ action: step as string
320
+ })) || []
321
+ },
322
+ // Keep all original fields for raw JSON view
323
+ _raw: task
324
+ };
325
+ }
326
+
327
+ /**
328
+ * Get directory creation time
329
+ * @param dirPath - Directory path
330
+ * @returns ISO date string
331
+ */
332
+ function getCreatedTime(dirPath: string): string {
333
+ try {
334
+ const stat = statSync(dirPath);
335
+ return stat.birthtime.toISOString();
336
+ } catch {
337
+ return new Date().toISOString();
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Calculate progress from tasks
343
+ * @param tasks - Array of task objects
344
+ * @returns Progress info
345
+ */
346
+ function calculateProgress(tasks: NormalizedTask[]): Progress {
347
+ if (!tasks || tasks.length === 0) {
348
+ return { total: 0, completed: 0, percentage: 0 };
349
+ }
350
+
351
+ const total = tasks.length;
352
+ const completed = tasks.filter(t => t.status === 'completed').length;
353
+ const percentage = Math.round((completed / total) * 100);
354
+
355
+ return { total, completed, percentage };
356
+ }
357
+
358
+ /**
359
+ * Get detailed lite task info
360
+ * @param workflowDir - Workflow directory
361
+ * @param type - 'lite-plan' or 'lite-fix'
362
+ * @param sessionId - Session ID
363
+ * @returns Detailed task info
364
+ */
365
+ export function getLiteTaskDetail(workflowDir: string, type: string, sessionId: string): LiteTaskDetail | null {
366
+ const dir = type === 'lite-plan'
367
+ ? join(workflowDir, '.lite-plan', sessionId)
368
+ : join(workflowDir, '.lite-fix', sessionId);
369
+
370
+ if (!existsSync(dir)) return null;
371
+
372
+ const detail: LiteTaskDetail = {
373
+ id: sessionId,
374
+ type,
375
+ path: dir,
376
+ plan: loadPlanJson(dir),
377
+ tasks: loadTaskJsons(dir),
378
+ explorations: loadExplorations(dir),
379
+ clarifications: loadClarifications(dir)
380
+ };
381
+
382
+ // For lite-fix sessions, also load diagnoses
383
+ if (type === 'lite-fix') {
384
+ detail.diagnoses = loadDiagnoses(dir);
385
+ }
386
+
387
+ return detail;
388
+ }
389
+
390
+ /**
391
+ * Load exploration results
392
+ * @param sessionPath - Session directory path
393
+ * @returns Exploration results
394
+ */
395
+ function loadExplorations(sessionPath: string): unknown[] {
396
+ const explorePath = join(sessionPath, 'explorations.json');
397
+ if (!existsSync(explorePath)) return [];
398
+
399
+ try {
400
+ const content = readFileSync(explorePath, 'utf8');
401
+ return JSON.parse(content);
402
+ } catch {
403
+ return [];
404
+ }
405
+ }
406
+
407
+ /**
408
+ * Load clarification data
409
+ * @param sessionPath - Session directory path
410
+ * @returns Clarification data
411
+ */
412
+ function loadClarifications(sessionPath: string): unknown | null {
413
+ const clarifyPath = join(sessionPath, 'clarifications.json');
414
+ if (!existsSync(clarifyPath)) return null;
415
+
416
+ try {
417
+ const content = readFileSync(clarifyPath, 'utf8');
418
+ return JSON.parse(content);
419
+ } catch {
420
+ return null;
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Load diagnosis files for lite-fix sessions
426
+ * Loads diagnosis-*.json files from session root directory
427
+ * @param sessionPath - Session directory path
428
+ * @returns Diagnoses data with manifest and items
429
+ */
430
+ function loadDiagnoses(sessionPath: string): Diagnoses {
431
+ const result: Diagnoses = {
432
+ manifest: null,
433
+ items: []
434
+ };
435
+
436
+ // Try to load diagnoses-manifest.json first
437
+ const manifestPath = join(sessionPath, 'diagnoses-manifest.json');
438
+ if (existsSync(manifestPath)) {
439
+ try {
440
+ result.manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
441
+ } catch {
442
+ // Continue without manifest
443
+ }
444
+ }
445
+
446
+ // Load all diagnosis-*.json files from session root
447
+ try {
448
+ const diagnosisFiles = readdirSync(sessionPath)
449
+ .filter(f => f.startsWith('diagnosis-') && f.endsWith('.json'));
450
+
451
+ for (const file of diagnosisFiles) {
452
+ const filePath = join(sessionPath, file);
453
+ try {
454
+ const content = JSON.parse(readFileSync(filePath, 'utf8')) as Record<string, unknown>;
455
+ result.items.push({
456
+ id: file.replace('diagnosis-', '').replace('.json', ''),
457
+ filename: file,
458
+ ...content
459
+ });
460
+ } catch {
461
+ // Skip invalid files
462
+ }
463
+ }
464
+ } catch {
465
+ // Return empty items if directory read fails
466
+ }
467
+
468
+ return result;
469
+ }
@@ -1,14 +1,44 @@
1
- import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, unlinkSync, statSync } from 'fs';
2
- import { join, dirname } from 'path';
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, unlinkSync } from 'fs';
2
+ import { join } from 'path';
3
3
  import { homedir } from 'os';
4
4
 
5
5
  // Manifest directory location
6
6
  const MANIFEST_DIR = join(homedir(), '.claude-manifests');
7
7
 
8
+ export interface ManifestFileEntry {
9
+ path: string;
10
+ type: 'File';
11
+ timestamp: string;
12
+ }
13
+
14
+ export interface ManifestDirectoryEntry {
15
+ path: string;
16
+ type: 'Directory';
17
+ timestamp: string;
18
+ }
19
+
20
+ export interface Manifest {
21
+ manifest_id: string;
22
+ version: string;
23
+ installation_mode: string;
24
+ installation_path: string;
25
+ installation_date: string;
26
+ installer_version: string;
27
+ files: ManifestFileEntry[];
28
+ directories: ManifestDirectoryEntry[];
29
+ }
30
+
31
+ export interface ManifestWithMetadata extends Manifest {
32
+ manifest_file: string;
33
+ application_version: string;
34
+ files_count: number;
35
+ directories_count: number;
36
+ }
37
+
8
38
  /**
9
39
  * Ensure manifest directory exists
10
40
  */
11
- function ensureManifestDir() {
41
+ function ensureManifestDir(): void {
12
42
  if (!existsSync(MANIFEST_DIR)) {
13
43
  mkdirSync(MANIFEST_DIR, { recursive: true });
14
44
  }
@@ -16,11 +46,11 @@ function ensureManifestDir() {
16
46
 
17
47
  /**
18
48
  * Create a new installation manifest
19
- * @param {string} mode - Installation mode (Global/Path)
20
- * @param {string} installPath - Installation path
21
- * @returns {Object} - New manifest object
49
+ * @param mode - Installation mode (Global/Path)
50
+ * @param installPath - Installation path
51
+ * @returns New manifest object
22
52
  */
23
- export function createManifest(mode, installPath) {
53
+ export function createManifest(mode: string, installPath: string): Manifest {
24
54
  ensureManifestDir();
25
55
 
26
56
  const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace('T', '-').split('.')[0];
@@ -41,10 +71,10 @@ export function createManifest(mode, installPath) {
41
71
 
42
72
  /**
43
73
  * Add file entry to manifest
44
- * @param {Object} manifest - Manifest object
45
- * @param {string} filePath - File path
74
+ * @param manifest - Manifest object
75
+ * @param filePath - File path
46
76
  */
47
- export function addFileEntry(manifest, filePath) {
77
+ export function addFileEntry(manifest: Manifest, filePath: string): void {
48
78
  manifest.files.push({
49
79
  path: filePath,
50
80
  type: 'File',
@@ -54,10 +84,10 @@ export function addFileEntry(manifest, filePath) {
54
84
 
55
85
  /**
56
86
  * Add directory entry to manifest
57
- * @param {Object} manifest - Manifest object
58
- * @param {string} dirPath - Directory path
87
+ * @param manifest - Manifest object
88
+ * @param dirPath - Directory path
59
89
  */
60
- export function addDirectoryEntry(manifest, dirPath) {
90
+ export function addDirectoryEntry(manifest: Manifest, dirPath: string): void {
61
91
  manifest.directories.push({
62
92
  path: dirPath,
63
93
  type: 'Directory',
@@ -67,10 +97,10 @@ export function addDirectoryEntry(manifest, dirPath) {
67
97
 
68
98
  /**
69
99
  * Save manifest to disk
70
- * @param {Object} manifest - Manifest object
71
- * @returns {string} - Path to saved manifest
100
+ * @param manifest - Manifest object
101
+ * @returns Path to saved manifest
72
102
  */
73
- export function saveManifest(manifest) {
103
+ export function saveManifest(manifest: Manifest): string {
74
104
  ensureManifestDir();
75
105
 
76
106
  // Remove old manifests for same path and mode
@@ -84,10 +114,10 @@ export function saveManifest(manifest) {
84
114
 
85
115
  /**
86
116
  * Remove old manifests for the same installation path and mode
87
- * @param {string} installPath - Installation path
88
- * @param {string} mode - Installation mode
117
+ * @param installPath - Installation path
118
+ * @param mode - Installation mode
89
119
  */
90
- function removeOldManifests(installPath, mode) {
120
+ function removeOldManifests(installPath: string, mode: string): void {
91
121
  if (!existsSync(MANIFEST_DIR)) return;
92
122
 
93
123
  const normalizedPath = installPath.toLowerCase().replace(/[\\/]+$/, '');
@@ -98,7 +128,7 @@ function removeOldManifests(installPath, mode) {
98
128
  for (const file of files) {
99
129
  try {
100
130
  const filePath = join(MANIFEST_DIR, file);
101
- const content = JSON.parse(readFileSync(filePath, 'utf8'));
131
+ const content = JSON.parse(readFileSync(filePath, 'utf8')) as Partial<Manifest>;
102
132
 
103
133
  const manifestPath = (content.installation_path || '').toLowerCase().replace(/[\\/]+$/, '');
104
134
  const manifestMode = content.installation_mode || 'Global';
@@ -117,12 +147,12 @@ function removeOldManifests(installPath, mode) {
117
147
 
118
148
  /**
119
149
  * Get all installation manifests
120
- * @returns {Array} - Array of manifest objects
150
+ * @returns Array of manifest objects
121
151
  */
122
- export function getAllManifests() {
152
+ export function getAllManifests(): ManifestWithMetadata[] {
123
153
  if (!existsSync(MANIFEST_DIR)) return [];
124
154
 
125
- const manifests = [];
155
+ const manifests: ManifestWithMetadata[] = [];
126
156
 
127
157
  try {
128
158
  const files = readdirSync(MANIFEST_DIR).filter(f => f.endsWith('.json'));
@@ -130,14 +160,14 @@ export function getAllManifests() {
130
160
  for (const file of files) {
131
161
  try {
132
162
  const filePath = join(MANIFEST_DIR, file);
133
- const content = JSON.parse(readFileSync(filePath, 'utf8'));
163
+ const content = JSON.parse(readFileSync(filePath, 'utf8')) as Manifest;
134
164
 
135
165
  // Try to read version.json for application version
136
166
  let appVersion = 'unknown';
137
167
  try {
138
168
  const versionPath = join(content.installation_path, '.claude', 'version.json');
139
169
  if (existsSync(versionPath)) {
140
- const versionInfo = JSON.parse(readFileSync(versionPath, 'utf8'));
170
+ const versionInfo = JSON.parse(readFileSync(versionPath, 'utf8')) as { version?: string };
141
171
  appVersion = versionInfo.version || 'unknown';
142
172
  }
143
173
  } catch {
@@ -157,7 +187,7 @@ export function getAllManifests() {
157
187
  }
158
188
 
159
189
  // Sort by installation date (newest first)
160
- manifests.sort((a, b) => new Date(b.installation_date) - new Date(a.installation_date));
190
+ manifests.sort((a, b) => new Date(b.installation_date).getTime() - new Date(a.installation_date).getTime());
161
191
 
162
192
  } catch {
163
193
  // Ignore errors
@@ -168,11 +198,11 @@ export function getAllManifests() {
168
198
 
169
199
  /**
170
200
  * Find manifest for a specific path and mode
171
- * @param {string} installPath - Installation path
172
- * @param {string} mode - Installation mode
173
- * @returns {Object|null} - Manifest or null
201
+ * @param installPath - Installation path
202
+ * @param mode - Installation mode
203
+ * @returns Manifest or null
174
204
  */
175
- export function findManifest(installPath, mode) {
205
+ export function findManifest(installPath: string, mode: string): ManifestWithMetadata | null {
176
206
  const manifests = getAllManifests();
177
207
  const normalizedPath = installPath.toLowerCase().replace(/[\\/]+$/, '');
178
208
 
@@ -184,9 +214,9 @@ export function findManifest(installPath, mode) {
184
214
 
185
215
  /**
186
216
  * Delete a manifest file
187
- * @param {string} manifestFile - Path to manifest file
217
+ * @param manifestFile - Path to manifest file
188
218
  */
189
- export function deleteManifest(manifestFile) {
219
+ export function deleteManifest(manifestFile: string): void {
190
220
  if (existsSync(manifestFile)) {
191
221
  unlinkSync(manifestFile);
192
222
  }
@@ -194,8 +224,48 @@ export function deleteManifest(manifestFile) {
194
224
 
195
225
  /**
196
226
  * Get manifest directory path
197
- * @returns {string}
227
+ * @returns Manifest directory path
198
228
  */
199
- export function getManifestDir() {
229
+ export function getManifestDir(): string {
200
230
  return MANIFEST_DIR;
201
231
  }
232
+
233
+ /**
234
+ * Get file reference counts across all manifests
235
+ * Returns a map of file path -> array of manifest IDs that reference it
236
+ * @param excludeManifestId - Optional manifest ID to exclude from counting
237
+ * @returns Map of file paths to referencing manifest IDs
238
+ */
239
+ export function getFileReferenceCounts(excludeManifestId?: string): Map<string, string[]> {
240
+ const fileRefs = new Map<string, string[]>();
241
+ const manifests = getAllManifests();
242
+
243
+ for (const manifest of manifests) {
244
+ // Skip the excluded manifest (usually the one being replaced)
245
+ if (excludeManifestId && manifest.manifest_id === excludeManifestId) {
246
+ continue;
247
+ }
248
+
249
+ for (const fileEntry of manifest.files || []) {
250
+ const normalizedPath = fileEntry.path.toLowerCase().replace(/\\/g, '/');
251
+ const refs = fileRefs.get(normalizedPath) || [];
252
+ refs.push(manifest.manifest_id);
253
+ fileRefs.set(normalizedPath, refs);
254
+ }
255
+ }
256
+
257
+ return fileRefs;
258
+ }
259
+
260
+ /**
261
+ * Check if a file is referenced by other installations
262
+ * @param filePath - File path to check
263
+ * @param excludeManifestId - Manifest ID to exclude from checking
264
+ * @returns True if file is referenced by other installations
265
+ */
266
+ export function isFileReferencedByOthers(filePath: string, excludeManifestId: string): boolean {
267
+ const fileRefs = getFileReferenceCounts(excludeManifestId);
268
+ const normalizedPath = filePath.toLowerCase().replace(/\\/g, '/');
269
+ const refs = fileRefs.get(normalizedPath) || [];
270
+ return refs.length > 0;
271
+ }