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,245 @@
1
+ /**
2
+ * Classify Folders Tool
3
+ * Categorize folders by type for documentation generation
4
+ * Types: code (API.md + README.md), navigation (README.md only), skip (empty)
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import type { ToolSchema, ToolResult } from '../types/tool.js';
9
+ import { readdirSync, statSync, existsSync } from 'fs';
10
+ import { join, resolve, extname } from 'path';
11
+
12
+ // Code file extensions
13
+ const CODE_EXTENSIONS = [
14
+ '.ts', '.tsx', '.js', '.jsx',
15
+ '.py', '.go', '.java', '.rs',
16
+ '.c', '.cpp', '.cs', '.rb',
17
+ '.php', '.swift', '.kt'
18
+ ];
19
+
20
+ // Define Zod schema for validation
21
+ const ParamsSchema = z.object({
22
+ input: z.string().optional(),
23
+ path: z.string().optional(),
24
+ }).refine(data => data.input || data.path, {
25
+ message: 'Either "input" or "path" parameter is required'
26
+ });
27
+
28
+ type Params = z.infer<typeof ParamsSchema>;
29
+
30
+ interface FolderClassification {
31
+ type: 'code' | 'navigation' | 'skip';
32
+ codeFiles: number;
33
+ subdirs: number;
34
+ }
35
+
36
+ interface ClassificationResult {
37
+ path: string;
38
+ type: 'code' | 'navigation' | 'skip';
39
+ code_files: number;
40
+ subdirs: number;
41
+ }
42
+
43
+ interface ToolOutput {
44
+ total: number;
45
+ by_type: {
46
+ code: number;
47
+ navigation: number;
48
+ skip: number;
49
+ };
50
+ results: ClassificationResult[];
51
+ output: string;
52
+ }
53
+
54
+ /**
55
+ * Count code files in a directory (non-recursive)
56
+ */
57
+ function countCodeFiles(dirPath: string): number {
58
+ try {
59
+ const entries = readdirSync(dirPath, { withFileTypes: true });
60
+ return entries.filter(e => {
61
+ if (!e.isFile()) return false;
62
+ const ext = extname(e.name).toLowerCase();
63
+ return CODE_EXTENSIONS.includes(ext);
64
+ }).length;
65
+ } catch (e) {
66
+ return 0;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Count subdirectories in a directory
72
+ */
73
+ function countSubdirs(dirPath: string): number {
74
+ try {
75
+ const entries = readdirSync(dirPath, { withFileTypes: true });
76
+ return entries.filter(e => e.isDirectory() && !e.name.startsWith('.')).length;
77
+ } catch (e) {
78
+ return 0;
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Determine folder type
84
+ */
85
+ function classifyFolder(dirPath: string): FolderClassification {
86
+ const codeFiles = countCodeFiles(dirPath);
87
+ const subdirs = countSubdirs(dirPath);
88
+
89
+ if (codeFiles > 0) {
90
+ return { type: 'code', codeFiles, subdirs }; // Generates API.md + README.md
91
+ } else if (subdirs > 0) {
92
+ return { type: 'navigation', codeFiles, subdirs }; // README.md only
93
+ } else {
94
+ return { type: 'skip', codeFiles, subdirs }; // Empty or no relevant content
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Parse input from get_modules_by_depth format
100
+ * Format: depth:N|path:./path|files:N|types:[ext,ext]|has_claude:yes/no
101
+ */
102
+ function parseModuleInput(line: string): Record<string, string> {
103
+ const parts: Record<string, string> = {};
104
+ line.split('|').forEach(part => {
105
+ const [key, value] = part.split(':');
106
+ if (key && value !== undefined) {
107
+ parts[key] = value;
108
+ }
109
+ });
110
+ return parts;
111
+ }
112
+
113
+ // Tool schema for MCP
114
+ export const schema: ToolSchema = {
115
+ name: 'classify_folders',
116
+ description: `Classify folders by type for documentation generation.
117
+ Types:
118
+ - code: Contains code files (generates API.md + README.md)
119
+ - navigation: Contains subdirectories only (generates README.md only)
120
+ - skip: Empty or no relevant content
121
+
122
+ Input: Either piped output from get_modules_by_depth or a single directory path.`,
123
+ inputSchema: {
124
+ type: 'object',
125
+ properties: {
126
+ input: {
127
+ type: 'string',
128
+ description: 'Piped input from get_modules_by_depth (one module per line)'
129
+ },
130
+ path: {
131
+ type: 'string',
132
+ description: 'Single directory path to classify'
133
+ }
134
+ },
135
+ required: []
136
+ }
137
+ };
138
+
139
+ // Handler function
140
+ export async function handler(params: Record<string, unknown>): Promise<ToolResult<ToolOutput>> {
141
+ const parsed = ParamsSchema.safeParse(params);
142
+ if (!parsed.success) {
143
+ return { success: false, error: `Invalid params: ${parsed.error.message}` };
144
+ }
145
+
146
+ const { input, path: targetPath } = parsed.data;
147
+
148
+ const results: ClassificationResult[] = [];
149
+
150
+ try {
151
+ // Mode 1: Process piped input from get_modules_by_depth
152
+ if (input) {
153
+ let lines: string[];
154
+
155
+ // Check if input is JSON (from ccw tool exec output)
156
+ if (input.trim().startsWith('{')) {
157
+ try {
158
+ const jsonInput = JSON.parse(input);
159
+ // Handle output from get_modules_by_depth tool (wrapped in result)
160
+ const output = jsonInput.result?.output || jsonInput.output;
161
+ if (output) {
162
+ lines = output.split('\n');
163
+ } else {
164
+ lines = [input];
165
+ }
166
+ } catch {
167
+ // Not JSON, treat as line-delimited text
168
+ lines = input.split('\n');
169
+ }
170
+ } else {
171
+ lines = input.split('\n');
172
+ }
173
+
174
+ for (const line of lines) {
175
+ if (!line.trim()) continue;
176
+
177
+ const parsed = parseModuleInput(line);
178
+ const folderPath = parsed.path;
179
+
180
+ if (!folderPath) continue;
181
+
182
+ const basePath = targetPath ? resolve(process.cwd(), targetPath) : process.cwd();
183
+ const fullPath = resolve(basePath, folderPath);
184
+
185
+ if (!existsSync(fullPath) || !statSync(fullPath).isDirectory()) {
186
+ continue;
187
+ }
188
+
189
+ const classification = classifyFolder(fullPath);
190
+
191
+ results.push({
192
+ path: folderPath,
193
+ type: classification.type,
194
+ code_files: classification.codeFiles,
195
+ subdirs: classification.subdirs
196
+ });
197
+ }
198
+ }
199
+ // Mode 2: Classify a single directory
200
+ else if (targetPath) {
201
+ const fullPath = resolve(process.cwd(), targetPath);
202
+
203
+ if (!existsSync(fullPath)) {
204
+ return { success: false, error: `Directory not found: ${fullPath}` };
205
+ }
206
+
207
+ if (!statSync(fullPath).isDirectory()) {
208
+ return { success: false, error: `Not a directory: ${fullPath}` };
209
+ }
210
+
211
+ const classification = classifyFolder(fullPath);
212
+
213
+ results.push({
214
+ path: targetPath,
215
+ type: classification.type,
216
+ code_files: classification.codeFiles,
217
+ subdirs: classification.subdirs
218
+ });
219
+ }
220
+
221
+ // Format output
222
+ const output = results.map(r =>
223
+ `${r.path}|${r.type}|code:${r.code_files}|dirs:${r.subdirs}`
224
+ ).join('\n');
225
+
226
+ return {
227
+ success: true,
228
+ result: {
229
+ total: results.length,
230
+ by_type: {
231
+ code: results.filter(r => r.type === 'code').length,
232
+ navigation: results.filter(r => r.type === 'navigation').length,
233
+ skip: results.filter(r => r.type === 'skip').length
234
+ },
235
+ results,
236
+ output
237
+ }
238
+ };
239
+ } catch (error) {
240
+ return {
241
+ success: false,
242
+ error: `Failed to classify folders: ${(error as Error).message}`
243
+ };
244
+ }
245
+ }
@@ -0,0 +1,268 @@
1
+ /**
2
+ * CLI Configuration Manager
3
+ * Handles loading, saving, and managing CLI tool configurations
4
+ * Stores config in centralized storage (~/.ccw/projects/{id}/config/)
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import { StoragePaths, ensureStorageDir } from '../config/storage-paths.js';
9
+
10
+ // ========== Types ==========
11
+
12
+ export interface CliToolConfig {
13
+ enabled: boolean;
14
+ primaryModel: string; // For CLI endpoint calls (ccw cli -p)
15
+ secondaryModel: string; // For internal calls (llm_enhancer, generate_module_docs)
16
+ }
17
+
18
+ export interface CliConfig {
19
+ version: number;
20
+ tools: Record<string, CliToolConfig>;
21
+ }
22
+
23
+ export type CliToolName = 'gemini' | 'qwen' | 'codex';
24
+
25
+ // ========== Constants ==========
26
+
27
+ export const PREDEFINED_MODELS: Record<CliToolName, string[]> = {
28
+ gemini: ['gemini-2.5-pro', 'gemini-2.5-flash', 'gemini-2.0-flash', 'gemini-1.5-pro', 'gemini-1.5-flash'],
29
+ qwen: ['coder-model', 'vision-model', 'qwen2.5-coder-32b'],
30
+ codex: ['gpt-5.2', 'gpt-4.1', 'o4-mini', 'o3']
31
+ };
32
+
33
+ export const DEFAULT_CONFIG: CliConfig = {
34
+ version: 1,
35
+ tools: {
36
+ gemini: {
37
+ enabled: true,
38
+ primaryModel: 'gemini-2.5-pro',
39
+ secondaryModel: 'gemini-2.5-flash'
40
+ },
41
+ qwen: {
42
+ enabled: true,
43
+ primaryModel: 'coder-model',
44
+ secondaryModel: 'coder-model'
45
+ },
46
+ codex: {
47
+ enabled: true,
48
+ primaryModel: 'gpt-5.2',
49
+ secondaryModel: 'gpt-5.2'
50
+ }
51
+ }
52
+ };
53
+
54
+ // ========== Helper Functions ==========
55
+
56
+ function getConfigPath(baseDir: string): string {
57
+ return StoragePaths.project(baseDir).cliConfig;
58
+ }
59
+
60
+ function ensureConfigDirForProject(baseDir: string): void {
61
+ const configDir = StoragePaths.project(baseDir).config;
62
+ ensureStorageDir(configDir);
63
+ }
64
+
65
+ function isValidToolName(tool: string): tool is CliToolName {
66
+ return ['gemini', 'qwen', 'codex'].includes(tool);
67
+ }
68
+
69
+ function validateConfig(config: unknown): config is CliConfig {
70
+ if (!config || typeof config !== 'object') return false;
71
+ const c = config as Record<string, unknown>;
72
+
73
+ if (typeof c.version !== 'number') return false;
74
+ if (!c.tools || typeof c.tools !== 'object') return false;
75
+
76
+ const tools = c.tools as Record<string, unknown>;
77
+ for (const toolName of ['gemini', 'qwen', 'codex']) {
78
+ const tool = tools[toolName];
79
+ if (!tool || typeof tool !== 'object') return false;
80
+
81
+ const t = tool as Record<string, unknown>;
82
+ if (typeof t.enabled !== 'boolean') return false;
83
+ if (typeof t.primaryModel !== 'string') return false;
84
+ if (typeof t.secondaryModel !== 'string') return false;
85
+ }
86
+
87
+ return true;
88
+ }
89
+
90
+ function mergeWithDefaults(config: Partial<CliConfig>): CliConfig {
91
+ const result: CliConfig = {
92
+ version: config.version ?? DEFAULT_CONFIG.version,
93
+ tools: { ...DEFAULT_CONFIG.tools }
94
+ };
95
+
96
+ if (config.tools) {
97
+ for (const toolName of Object.keys(config.tools)) {
98
+ if (isValidToolName(toolName) && config.tools[toolName]) {
99
+ result.tools[toolName] = {
100
+ ...DEFAULT_CONFIG.tools[toolName],
101
+ ...config.tools[toolName]
102
+ };
103
+ }
104
+ }
105
+ }
106
+
107
+ return result;
108
+ }
109
+
110
+ // ========== Main Functions ==========
111
+
112
+ /**
113
+ * Load CLI configuration from .workflow/cli-config.json
114
+ * Returns default config if file doesn't exist or is invalid
115
+ */
116
+ export function loadCliConfig(baseDir: string): CliConfig {
117
+ const configPath = getConfigPath(baseDir);
118
+
119
+ try {
120
+ if (!fs.existsSync(configPath)) {
121
+ return { ...DEFAULT_CONFIG };
122
+ }
123
+
124
+ const content = fs.readFileSync(configPath, 'utf-8');
125
+ const parsed = JSON.parse(content);
126
+
127
+ if (validateConfig(parsed)) {
128
+ return mergeWithDefaults(parsed);
129
+ }
130
+
131
+ // Invalid config, return defaults
132
+ console.warn('[cli-config] Invalid config file, using defaults');
133
+ return { ...DEFAULT_CONFIG };
134
+ } catch (err) {
135
+ console.error('[cli-config] Error loading config:', err);
136
+ return { ...DEFAULT_CONFIG };
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Save CLI configuration to .workflow/cli-config.json
142
+ */
143
+ export function saveCliConfig(baseDir: string, config: CliConfig): void {
144
+ ensureConfigDirForProject(baseDir);
145
+ const configPath = getConfigPath(baseDir);
146
+
147
+ try {
148
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
149
+ } catch (err) {
150
+ console.error('[cli-config] Error saving config:', err);
151
+ throw new Error(`Failed to save CLI config: ${err}`);
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Get configuration for a specific tool
157
+ */
158
+ export function getToolConfig(baseDir: string, tool: string): CliToolConfig {
159
+ if (!isValidToolName(tool)) {
160
+ throw new Error(`Invalid tool name: ${tool}`);
161
+ }
162
+
163
+ const config = loadCliConfig(baseDir);
164
+ return config.tools[tool] || DEFAULT_CONFIG.tools[tool];
165
+ }
166
+
167
+ /**
168
+ * Update configuration for a specific tool
169
+ * Returns the updated tool config
170
+ */
171
+ export function updateToolConfig(
172
+ baseDir: string,
173
+ tool: string,
174
+ updates: Partial<CliToolConfig>
175
+ ): CliToolConfig {
176
+ if (!isValidToolName(tool)) {
177
+ throw new Error(`Invalid tool name: ${tool}`);
178
+ }
179
+
180
+ const config = loadCliConfig(baseDir);
181
+ const currentToolConfig = config.tools[tool] || DEFAULT_CONFIG.tools[tool];
182
+
183
+ // Apply updates
184
+ const updatedToolConfig: CliToolConfig = {
185
+ enabled: updates.enabled !== undefined ? updates.enabled : currentToolConfig.enabled,
186
+ primaryModel: updates.primaryModel || currentToolConfig.primaryModel,
187
+ secondaryModel: updates.secondaryModel || currentToolConfig.secondaryModel
188
+ };
189
+
190
+ // Save updated config
191
+ config.tools[tool] = updatedToolConfig;
192
+ saveCliConfig(baseDir, config);
193
+
194
+ return updatedToolConfig;
195
+ }
196
+
197
+ /**
198
+ * Enable a CLI tool
199
+ */
200
+ export function enableTool(baseDir: string, tool: string): CliToolConfig {
201
+ return updateToolConfig(baseDir, tool, { enabled: true });
202
+ }
203
+
204
+ /**
205
+ * Disable a CLI tool
206
+ */
207
+ export function disableTool(baseDir: string, tool: string): CliToolConfig {
208
+ return updateToolConfig(baseDir, tool, { enabled: false });
209
+ }
210
+
211
+ /**
212
+ * Check if a tool is enabled
213
+ */
214
+ export function isToolEnabled(baseDir: string, tool: string): boolean {
215
+ try {
216
+ const config = getToolConfig(baseDir, tool);
217
+ return config.enabled;
218
+ } catch {
219
+ return true; // Default to enabled if error
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Get primary model for a tool
225
+ */
226
+ export function getPrimaryModel(baseDir: string, tool: string): string {
227
+ try {
228
+ const config = getToolConfig(baseDir, tool);
229
+ return config.primaryModel;
230
+ } catch {
231
+ return isValidToolName(tool) ? DEFAULT_CONFIG.tools[tool].primaryModel : 'gemini-2.5-pro';
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Get secondary model for a tool (used for internal calls)
237
+ */
238
+ export function getSecondaryModel(baseDir: string, tool: string): string {
239
+ try {
240
+ const config = getToolConfig(baseDir, tool);
241
+ return config.secondaryModel;
242
+ } catch {
243
+ return isValidToolName(tool) ? DEFAULT_CONFIG.tools[tool].secondaryModel : 'gemini-2.5-flash';
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Get all predefined models for a tool
249
+ */
250
+ export function getPredefinedModels(tool: string): string[] {
251
+ if (!isValidToolName(tool)) {
252
+ return [];
253
+ }
254
+ return [...PREDEFINED_MODELS[tool]];
255
+ }
256
+
257
+ /**
258
+ * Get full config response for API (includes predefined models)
259
+ */
260
+ export function getFullConfigResponse(baseDir: string): {
261
+ config: CliConfig;
262
+ predefinedModels: Record<string, string[]>;
263
+ } {
264
+ return {
265
+ config: loadCliConfig(baseDir),
266
+ predefinedModels: { ...PREDEFINED_MODELS }
267
+ };
268
+ }