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
@@ -15,6 +15,16 @@ let mcpCurrentProjectServers = {};
15
15
  let mcpConfigSources = [];
16
16
  let mcpCreateMode = 'form'; // 'form' or 'json'
17
17
 
18
+ // ========== CLI Toggle State (Claude / Codex) ==========
19
+ let currentCliMode = 'claude'; // 'claude' or 'codex'
20
+ let codexMcpConfig = null;
21
+ let codexMcpServers = {};
22
+
23
+ // ========== Project Config Type Preference ==========
24
+ // 'mcp' = .mcp.json (project root file, recommended)
25
+ // 'claude' = claude.json projects[path].mcpServers (shared config)
26
+ let preferredProjectConfigType = 'mcp';
27
+
18
28
  // ========== Initialization ==========
19
29
  function initMcpManager() {
20
30
  // Initialize MCP navigation
@@ -44,6 +54,12 @@ async function loadMcpConfig() {
44
54
  mcpEnterpriseServers = data.enterpriseServers || {};
45
55
  mcpConfigSources = data.configSources || [];
46
56
 
57
+ // Load Codex MCP config
58
+ if (data.codex) {
59
+ codexMcpConfig = data.codex;
60
+ codexMcpServers = data.codex.servers || {};
61
+ }
62
+
47
63
  // Get current project servers
48
64
  const currentPath = projectPath.replace(/\//g, '\\');
49
65
  mcpCurrentProjectServers = mcpAllProjects[currentPath]?.mcpServers || {};
@@ -58,6 +74,135 @@ async function loadMcpConfig() {
58
74
  }
59
75
  }
60
76
 
77
+ // ========== CLI Mode Toggle ==========
78
+ function setCliMode(mode) {
79
+ currentCliMode = mode;
80
+ renderMcpManager();
81
+ }
82
+
83
+ function getCliMode() {
84
+ return currentCliMode;
85
+ }
86
+
87
+ // ========== Codex MCP Functions ==========
88
+
89
+ /**
90
+ * Add MCP server to Codex config.toml
91
+ */
92
+ async function addCodexMcpServer(serverName, serverConfig) {
93
+ try {
94
+ const response = await fetch('/api/codex-mcp-add', {
95
+ method: 'POST',
96
+ headers: { 'Content-Type': 'application/json' },
97
+ body: JSON.stringify({
98
+ serverName: serverName,
99
+ serverConfig: serverConfig
100
+ })
101
+ });
102
+
103
+ if (!response.ok) throw new Error('Failed to add Codex MCP server');
104
+
105
+ const result = await response.json();
106
+ if (result.success) {
107
+ await loadMcpConfig();
108
+ renderMcpManager();
109
+ showRefreshToast(t('mcp.codex.serverAdded', { name: serverName }), 'success');
110
+ } else {
111
+ showRefreshToast(result.error || t('mcp.codex.addFailed'), 'error');
112
+ }
113
+ return result;
114
+ } catch (err) {
115
+ console.error('Failed to add Codex MCP server:', err);
116
+ showRefreshToast(t('mcp.codex.addFailed') + ': ' + err.message, 'error');
117
+ return null;
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Remove MCP server from Codex config.toml
123
+ */
124
+ async function removeCodexMcpServer(serverName) {
125
+ try {
126
+ const response = await fetch('/api/codex-mcp-remove', {
127
+ method: 'POST',
128
+ headers: { 'Content-Type': 'application/json' },
129
+ body: JSON.stringify({ serverName })
130
+ });
131
+
132
+ if (!response.ok) throw new Error('Failed to remove Codex MCP server');
133
+
134
+ const result = await response.json();
135
+ if (result.success) {
136
+ await loadMcpConfig();
137
+ renderMcpManager();
138
+ showRefreshToast(t('mcp.codex.serverRemoved', { name: serverName }), 'success');
139
+ } else {
140
+ showRefreshToast(result.error || t('mcp.codex.removeFailed'), 'error');
141
+ }
142
+ return result;
143
+ } catch (err) {
144
+ console.error('Failed to remove Codex MCP server:', err);
145
+ showRefreshToast(t('mcp.codex.removeFailed') + ': ' + err.message, 'error');
146
+ return null;
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Toggle Codex MCP server enabled state
152
+ */
153
+ async function toggleCodexMcpServer(serverName, enabled) {
154
+ try {
155
+ const response = await fetch('/api/codex-mcp-toggle', {
156
+ method: 'POST',
157
+ headers: { 'Content-Type': 'application/json' },
158
+ body: JSON.stringify({ serverName, enabled })
159
+ });
160
+
161
+ if (!response.ok) throw new Error('Failed to toggle Codex MCP server');
162
+
163
+ const result = await response.json();
164
+ if (result.success) {
165
+ await loadMcpConfig();
166
+ renderMcpManager();
167
+ showRefreshToast(t('mcp.codex.serverToggled', { name: serverName, state: enabled ? 'enabled' : 'disabled' }), 'success');
168
+ }
169
+ return result;
170
+ } catch (err) {
171
+ console.error('Failed to toggle Codex MCP server:', err);
172
+ showRefreshToast(t('mcp.codex.toggleFailed') + ': ' + err.message, 'error');
173
+ return null;
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Copy Claude MCP server to Codex
179
+ */
180
+ async function copyClaudeServerToCodex(serverName, serverConfig) {
181
+ return await addCodexMcpServer(serverName, serverConfig);
182
+ }
183
+
184
+ /**
185
+ * Copy Codex MCP server to Claude (global)
186
+ */
187
+ async function copyCodexServerToClaude(serverName, serverConfig) {
188
+ // Convert Codex format to Claude format
189
+ const claudeConfig = {
190
+ command: serverConfig.command,
191
+ args: serverConfig.args || [],
192
+ };
193
+
194
+ if (serverConfig.env) {
195
+ claudeConfig.env = serverConfig.env;
196
+ }
197
+
198
+ // If it's an HTTP server
199
+ if (serverConfig.url) {
200
+ claudeConfig.url = serverConfig.url;
201
+ }
202
+
203
+ return await addGlobalMcpServer(serverName, claudeConfig);
204
+ }
205
+
61
206
  async function toggleMcpServer(serverName, enable) {
62
207
  try {
63
208
  const response = await fetch('/api/mcp-toggle', {
@@ -87,15 +232,21 @@ async function toggleMcpServer(serverName, enable) {
87
232
  }
88
233
  }
89
234
 
90
- async function copyMcpServerToProject(serverName, serverConfig) {
235
+ async function copyMcpServerToProject(serverName, serverConfig, configType = null) {
91
236
  try {
237
+ // If configType not specified, use the preferred config type (toggle setting)
238
+ if (!configType) {
239
+ configType = preferredProjectConfigType;
240
+ }
241
+
92
242
  const response = await fetch('/api/mcp-copy-server', {
93
243
  method: 'POST',
94
244
  headers: { 'Content-Type': 'application/json' },
95
245
  body: JSON.stringify({
96
246
  projectPath: projectPath,
97
247
  serverName: serverName,
98
- serverConfig: serverConfig
248
+ serverConfig: serverConfig,
249
+ configType: configType // 'claude' for .claude.json, 'mcp' for .mcp.json
99
250
  })
100
251
  });
101
252
 
@@ -105,7 +256,8 @@ async function copyMcpServerToProject(serverName, serverConfig) {
105
256
  if (result.success) {
106
257
  await loadMcpConfig();
107
258
  renderMcpManager();
108
- showRefreshToast(`MCP server "${serverName}" added to project`, 'success');
259
+ const location = configType === 'mcp' ? '.mcp.json' : '.claude.json';
260
+ showRefreshToast(`MCP server "${serverName}" added to project (${location})`, 'success');
109
261
  }
110
262
  return result;
111
263
  } catch (err) {
@@ -115,6 +267,53 @@ async function copyMcpServerToProject(serverName, serverConfig) {
115
267
  }
116
268
  }
117
269
 
270
+ // Show dialog to let user choose config type
271
+ function showConfigTypeDialog() {
272
+ return new Promise((resolve) => {
273
+ const dialog = document.createElement('div');
274
+ dialog.className = 'fixed inset-0 bg-black/50 flex items-center justify-center z-50';
275
+ dialog.innerHTML = `
276
+ <div class="bg-card border border-border rounded-lg shadow-lg p-6 max-w-md w-full mx-4">
277
+ <h3 class="text-lg font-semibold mb-4">${t('mcp.chooseInstallLocation')}</h3>
278
+ <div class="space-y-3 mb-6">
279
+ <button class="config-type-option w-full text-left px-4 py-3 border border-border rounded-lg hover:bg-accent hover:border-primary transition-all" data-type="claude">
280
+ <div class="font-medium">${t('mcp.installToClaudeJson')}</div>
281
+ <div class="text-sm text-muted-foreground mt-1">${t('mcp.claudeJsonDesc')}</div>
282
+ </button>
283
+ <button class="config-type-option w-full text-left px-4 py-3 border border-border rounded-lg hover:bg-accent hover:border-primary transition-all" data-type="mcp">
284
+ <div class="font-medium">${t('mcp.installToMcpJson')}</div>
285
+ <div class="text-sm text-muted-foreground mt-1">${t('mcp.mcpJsonDesc')}</div>
286
+ </button>
287
+ </div>
288
+ <button class="cancel-btn w-full px-4 py-2 border border-border rounded-lg hover:bg-accent transition-colors">${t('common.cancel')}</button>
289
+ </div>
290
+ `;
291
+ document.body.appendChild(dialog);
292
+
293
+ const options = dialog.querySelectorAll('.config-type-option');
294
+ options.forEach(btn => {
295
+ btn.addEventListener('click', () => {
296
+ resolve(btn.dataset.type);
297
+ document.body.removeChild(dialog);
298
+ });
299
+ });
300
+
301
+ const cancelBtn = dialog.querySelector('.cancel-btn');
302
+ cancelBtn.addEventListener('click', () => {
303
+ resolve(null);
304
+ document.body.removeChild(dialog);
305
+ });
306
+
307
+ // Close on backdrop click
308
+ dialog.addEventListener('click', (e) => {
309
+ if (e.target === dialog) {
310
+ resolve(null);
311
+ document.body.removeChild(dialog);
312
+ }
313
+ });
314
+ });
315
+ }
316
+
118
317
  async function removeMcpServerFromProject(serverName) {
119
318
  try {
120
319
  const response = await fetch('/api/mcp-remove-server', {
@@ -142,47 +341,158 @@ async function removeMcpServerFromProject(serverName) {
142
341
  }
143
342
  }
144
343
 
344
+ async function addGlobalMcpServer(serverName, serverConfig) {
345
+ try {
346
+ const response = await fetch('/api/mcp-add-global-server', {
347
+ method: 'POST',
348
+ headers: { 'Content-Type': 'application/json' },
349
+ body: JSON.stringify({
350
+ serverName: serverName,
351
+ serverConfig: serverConfig
352
+ })
353
+ });
354
+
355
+ if (!response.ok) throw new Error('Failed to add global MCP server');
356
+
357
+ const result = await response.json();
358
+ if (result.success) {
359
+ await loadMcpConfig();
360
+ renderMcpManager();
361
+ showRefreshToast(`Global MCP server "${serverName}" added`, 'success');
362
+ }
363
+ return result;
364
+ } catch (err) {
365
+ console.error('Failed to add global MCP server:', err);
366
+ showRefreshToast(`Failed to add global MCP server: ${err.message}`, 'error');
367
+ return null;
368
+ }
369
+ }
370
+
371
+ async function removeGlobalMcpServer(serverName) {
372
+ try {
373
+ const response = await fetch('/api/mcp-remove-global-server', {
374
+ method: 'POST',
375
+ headers: { 'Content-Type': 'application/json' },
376
+ body: JSON.stringify({
377
+ serverName: serverName
378
+ })
379
+ });
380
+
381
+ if (!response.ok) throw new Error('Failed to remove global MCP server');
382
+
383
+ const result = await response.json();
384
+ if (result.success) {
385
+ await loadMcpConfig();
386
+ renderMcpManager();
387
+ showRefreshToast(`Global MCP server "${serverName}" removed`, 'success');
388
+ }
389
+ return result;
390
+ } catch (err) {
391
+ console.error('Failed to remove global MCP server:', err);
392
+ showRefreshToast(`Failed to remove global MCP server: ${err.message}`, 'error');
393
+ return null;
394
+ }
395
+ }
396
+
145
397
  // ========== Badge Update ==========
146
398
  function updateMcpBadge() {
147
399
  const badge = document.getElementById('badgeMcpServers');
148
400
  if (badge) {
149
- const currentPath = projectPath.replace(/\//g, '\\');
150
- const projectData = mcpAllProjects[currentPath];
401
+ // Try both path formats to find the matching key
402
+ const forwardSlashPath = projectPath.replace(/\\/g, '/');
403
+ const backSlashPath = projectPath.replace(/\//g, '\\');
404
+
405
+ // Find matching project data using either path format
406
+ const projectData = mcpAllProjects[forwardSlashPath] || mcpAllProjects[backSlashPath] || mcpAllProjects[projectPath];
151
407
  const servers = projectData?.mcpServers || {};
152
408
  const disabledServers = projectData?.disabledMcpServers || [];
153
409
 
154
410
  const totalServers = Object.keys(servers).length;
155
411
  const enabledServers = totalServers - disabledServers.length;
156
412
 
413
+ console.log('[MCP Badge]', { projectPath, forwardSlashPath, backSlashPath, totalServers, enabledServers });
157
414
  badge.textContent = `${enabledServers}/${totalServers}`;
158
415
  }
159
416
  }
160
417
 
161
418
  // ========== Helpers ==========
419
+
420
+ /**
421
+ * Generate a unique key for MCP server config comparison
422
+ * Used to distinguish servers with same name but different configurations
423
+ */
424
+ function getMcpConfigHash(config) {
425
+ const cmd = config.command || '';
426
+ const args = (config.args || []).join('|');
427
+ const envKeys = Object.keys(config.env || {}).sort().join(',');
428
+ return `${cmd}::${args}::${envKeys}`;
429
+ }
430
+
431
+ /**
432
+ * Get all available MCP servers from all sources
433
+ * Supports servers with same name but different configurations from different projects
434
+ */
162
435
  function getAllAvailableMcpServers() {
163
436
  const allServers = {};
437
+ const configHashes = {}; // Track unique configs per server name
164
438
 
165
439
  // Collect global servers first
166
440
  for (const [name, serverConfig] of Object.entries(mcpGlobalServers)) {
441
+ const hash = getMcpConfigHash(serverConfig);
167
442
  allServers[name] = {
168
443
  config: serverConfig,
169
444
  usedIn: [],
170
- isGlobal: true
445
+ isGlobal: true,
446
+ configHash: hash
171
447
  };
448
+ configHashes[name] = { [hash]: name };
172
449
  }
173
450
 
174
- // Collect servers from all projects
451
+ // Collect servers from all projects - handle same name with different configs
175
452
  for (const [path, config] of Object.entries(mcpAllProjects)) {
176
453
  const servers = config.mcpServers || {};
177
454
  for (const [name, serverConfig] of Object.entries(servers)) {
178
- if (!allServers[name]) {
179
- allServers[name] = {
180
- config: serverConfig,
181
- usedIn: [],
182
- isGlobal: false
183
- };
455
+ const hash = getMcpConfigHash(serverConfig);
456
+
457
+ if (!configHashes[name]) {
458
+ // First occurrence of this server name
459
+ configHashes[name] = {};
460
+ }
461
+
462
+ if (!configHashes[name][hash]) {
463
+ // New unique configuration for this server name
464
+ // Use suffixed key if name already exists with different config
465
+ let serverKey = name;
466
+ if (allServers[name] && allServers[name].configHash !== hash) {
467
+ // Generate unique key: name@project-folder
468
+ const projectFolder = path.split('\\').pop() || path.split('/').pop() || 'unknown';
469
+ serverKey = `${name}@${projectFolder}`;
470
+ // Avoid collisions
471
+ let suffix = 1;
472
+ while (allServers[serverKey]) {
473
+ serverKey = `${name}@${projectFolder}-${suffix++}`;
474
+ }
475
+ }
476
+
477
+ configHashes[name][hash] = serverKey;
478
+
479
+ if (!allServers[serverKey]) {
480
+ allServers[serverKey] = {
481
+ config: serverConfig,
482
+ usedIn: [],
483
+ isGlobal: false,
484
+ configHash: hash,
485
+ originalName: name, // Store original name for installation
486
+ sourceProject: path // Store source project for reference
487
+ };
488
+ }
489
+ }
490
+
491
+ // Track which projects use this config
492
+ const serverKey = configHashes[name][hash];
493
+ if (allServers[serverKey]) {
494
+ allServers[serverKey].usedIn.push(path);
184
495
  }
185
- allServers[name].usedIn.push(path);
186
496
  }
187
497
  }
188
498
 
@@ -207,8 +517,40 @@ function isServerInCurrentProject(serverName) {
207
517
  return serverName in servers;
208
518
  }
209
519
 
520
+ // Generate install command for MCP server
521
+ function generateMcpInstallCommand(serverName, serverConfig, scope = 'project') {
522
+ const command = serverConfig.command || '';
523
+ const args = serverConfig.args || [];
524
+
525
+ // Check if it's an npx-based package
526
+ if (command === 'npx' && args.length > 0) {
527
+ const packageName = args[0];
528
+ // Check if it's a scoped package or standard package
529
+ if (packageName.startsWith('@') || packageName.includes('/')) {
530
+ const scopeFlag = scope === 'global' ? ' --global' : '';
531
+ return `claude mcp add ${packageName}${scopeFlag}`;
532
+ }
533
+ }
534
+
535
+ // For custom servers, return JSON configuration
536
+ const scopeFlag = scope === 'global' ? ' --global' : '';
537
+ return `claude mcp add ${serverName}${scopeFlag}`;
538
+ }
539
+
540
+ // Copy install command to clipboard
541
+ async function copyMcpInstallCommand(serverName, serverConfig, scope = 'project') {
542
+ try {
543
+ const command = generateMcpInstallCommand(serverName, serverConfig, scope);
544
+ await navigator.clipboard.writeText(command);
545
+ showRefreshToast(t('mcp.installCmdCopied'), 'success');
546
+ } catch (error) {
547
+ console.error('Failed to copy install command:', error);
548
+ showRefreshToast(t('mcp.installCmdFailed'), 'error');
549
+ }
550
+ }
551
+
210
552
  // ========== MCP Create Modal ==========
211
- function openMcpCreateModal() {
553
+ function openMcpCreateModal(scope = 'project') {
212
554
  const modal = document.getElementById('mcpCreateModal');
213
555
  if (modal) {
214
556
  modal.classList.remove('hidden');
@@ -223,6 +565,11 @@ function openMcpCreateModal() {
223
565
  // Clear JSON input
224
566
  document.getElementById('mcpServerJson').value = '';
225
567
  document.getElementById('mcpJsonPreview').classList.add('hidden');
568
+ // Set scope (global or project)
569
+ const scopeSelect = document.getElementById('mcpServerScope');
570
+ if (scopeSelect) {
571
+ scopeSelect.value = scope;
572
+ }
226
573
  // Focus on name input
227
574
  document.getElementById('mcpServerName').focus();
228
575
  // Setup JSON input listener
@@ -374,6 +721,8 @@ async function submitMcpCreateFromForm() {
374
721
  const command = document.getElementById('mcpServerCommand').value.trim();
375
722
  const argsText = document.getElementById('mcpServerArgs').value.trim();
376
723
  const envText = document.getElementById('mcpServerEnv').value.trim();
724
+ const scopeSelect = document.getElementById('mcpServerScope');
725
+ const scope = scopeSelect ? scopeSelect.value : 'project';
377
726
 
378
727
  // Validate required fields
379
728
  if (!name) {
@@ -418,7 +767,7 @@ async function submitMcpCreateFromForm() {
418
767
  serverConfig.env = env;
419
768
  }
420
769
 
421
- await createMcpServerWithConfig(name, serverConfig);
770
+ await createMcpServerWithConfig(name, serverConfig, scope);
422
771
  }
423
772
 
424
773
  async function submitMcpCreateFromJson() {
@@ -497,18 +846,45 @@ async function submitMcpCreateFromJson() {
497
846
  }
498
847
  }
499
848
 
500
- async function createMcpServerWithConfig(name, serverConfig) {
849
+ async function createMcpServerWithConfig(name, serverConfig, scope = 'project') {
501
850
  // Submit to API
502
851
  try {
503
- const response = await fetch('/api/mcp-copy-server', {
504
- method: 'POST',
505
- headers: { 'Content-Type': 'application/json' },
506
- body: JSON.stringify({
507
- projectPath: projectPath,
508
- serverName: name,
509
- serverConfig: serverConfig
510
- })
511
- });
852
+ let response;
853
+ let scopeLabel;
854
+
855
+ if (scope === 'codex') {
856
+ // Create in Codex config.toml
857
+ response = await fetch('/api/codex-mcp-add', {
858
+ method: 'POST',
859
+ headers: { 'Content-Type': 'application/json' },
860
+ body: JSON.stringify({
861
+ serverName: name,
862
+ serverConfig: serverConfig
863
+ })
864
+ });
865
+ scopeLabel = 'Codex';
866
+ } else if (scope === 'global') {
867
+ response = await fetch('/api/mcp-add-global-server', {
868
+ method: 'POST',
869
+ headers: { 'Content-Type': 'application/json' },
870
+ body: JSON.stringify({
871
+ serverName: name,
872
+ serverConfig: serverConfig
873
+ })
874
+ });
875
+ scopeLabel = 'global';
876
+ } else {
877
+ response = await fetch('/api/mcp-copy-server', {
878
+ method: 'POST',
879
+ headers: { 'Content-Type': 'application/json' },
880
+ body: JSON.stringify({
881
+ projectPath: projectPath,
882
+ serverName: name,
883
+ serverConfig: serverConfig
884
+ })
885
+ });
886
+ scopeLabel = 'project';
887
+ }
512
888
 
513
889
  if (!response.ok) throw new Error('Failed to create MCP server');
514
890
 
@@ -517,7 +893,7 @@ async function createMcpServerWithConfig(name, serverConfig) {
517
893
  closeMcpCreateModal();
518
894
  await loadMcpConfig();
519
895
  renderMcpManager();
520
- showRefreshToast(`MCP server "${name}" created successfully`, 'success');
896
+ showRefreshToast(`MCP server "${name}" created in ${scopeLabel} scope`, 'success');
521
897
  } else {
522
898
  showRefreshToast(result.error || 'Failed to create MCP server', 'error');
523
899
  }
@@ -526,3 +902,318 @@ async function createMcpServerWithConfig(name, serverConfig) {
526
902
  showRefreshToast(`Failed to create MCP server: ${err.message}`, 'error');
527
903
  }
528
904
  }
905
+
906
+ // ========== CCW Tools MCP Installation ==========
907
+
908
+ // Get selected tools from checkboxes
909
+ function getSelectedCcwTools() {
910
+ const checkboxes = document.querySelectorAll('.ccw-tool-checkbox:checked');
911
+ return Array.from(checkboxes).map(cb => cb.dataset.tool);
912
+ }
913
+
914
+ // Select tools by category
915
+ function selectCcwTools(type) {
916
+ const checkboxes = document.querySelectorAll('.ccw-tool-checkbox');
917
+ const coreTools = ['write_file', 'edit_file', 'codex_lens', 'smart_search'];
918
+
919
+ checkboxes.forEach(cb => {
920
+ if (type === 'all') {
921
+ cb.checked = true;
922
+ } else if (type === 'none') {
923
+ cb.checked = false;
924
+ } else if (type === 'core') {
925
+ cb.checked = coreTools.includes(cb.dataset.tool);
926
+ }
927
+ });
928
+ }
929
+
930
+ // Get CCW path settings from input fields
931
+ function getCcwPathConfig() {
932
+ const projectRootInput = document.querySelector('.ccw-project-root-input');
933
+ const allowedDirsInput = document.querySelector('.ccw-allowed-dirs-input');
934
+ return {
935
+ projectRoot: projectRootInput?.value || '',
936
+ allowedDirs: allowedDirsInput?.value || ''
937
+ };
938
+ }
939
+
940
+ // Set CCW_PROJECT_ROOT to current project path
941
+ function setCcwProjectRootToCurrent() {
942
+ const input = document.querySelector('.ccw-project-root-input');
943
+ if (input && projectPath) {
944
+ input.value = projectPath;
945
+ }
946
+ }
947
+
948
+ // Build CCW Tools config with selected tools
949
+ // Uses isWindowsPlatform from state.js to generate platform-appropriate commands
950
+ function buildCcwToolsConfig(selectedTools, pathConfig = {}) {
951
+ const { projectRoot, allowedDirs } = pathConfig;
952
+ // Windows requires 'cmd /c' wrapper to execute npx
953
+ // Other platforms (macOS, Linux) can run npx directly
954
+ const config = isWindowsPlatform
955
+ ? {
956
+ command: "cmd",
957
+ args: ["/c", "npx", "-y", "ccw-mcp"]
958
+ }
959
+ : {
960
+ command: "npx",
961
+ args: ["-y", "ccw-mcp"]
962
+ };
963
+
964
+ // Add env if not all tools or not default 4 core tools
965
+ const coreTools = ['write_file', 'edit_file', 'codex_lens', 'smart_search'];
966
+ const isDefault = selectedTools.length === 4 &&
967
+ coreTools.every(t => selectedTools.includes(t)) &&
968
+ selectedTools.every(t => coreTools.includes(t));
969
+
970
+ // Initialize env if needed
971
+ if (selectedTools.length === 15) {
972
+ config.env = { CCW_ENABLED_TOOLS: 'all' };
973
+ } else if (!isDefault && selectedTools.length > 0) {
974
+ config.env = { CCW_ENABLED_TOOLS: selectedTools.join(',') };
975
+ }
976
+
977
+ // Add path settings if provided
978
+ if (!config.env) {
979
+ config.env = {};
980
+ }
981
+
982
+ if (projectRoot && projectRoot.trim()) {
983
+ config.env.CCW_PROJECT_ROOT = projectRoot.trim();
984
+ }
985
+ if (allowedDirs && allowedDirs.trim()) {
986
+ config.env.CCW_ALLOWED_DIRS = allowedDirs.trim();
987
+ }
988
+
989
+ // Remove env object if empty
990
+ if (config.env && Object.keys(config.env).length === 0) {
991
+ delete config.env;
992
+ }
993
+
994
+ return config;
995
+ }
996
+
997
+ async function installCcwToolsMcp(scope = 'workspace') {
998
+ const selectedTools = getSelectedCcwTools();
999
+
1000
+ if (selectedTools.length === 0) {
1001
+ showRefreshToast('Please select at least one tool', 'warning');
1002
+ return;
1003
+ }
1004
+
1005
+ const pathConfig = getCcwPathConfig();
1006
+ const ccwToolsConfig = buildCcwToolsConfig(selectedTools, pathConfig);
1007
+
1008
+ try {
1009
+ const scopeLabel = scope === 'global' ? 'globally' : 'to workspace';
1010
+ showRefreshToast(`Installing CCW Tools MCP ${scopeLabel}...`, 'info');
1011
+
1012
+ if (scope === 'global') {
1013
+ // Install to global (~/.claude.json mcpServers)
1014
+ const response = await fetch('/api/mcp-add-global-server', {
1015
+ method: 'POST',
1016
+ headers: { 'Content-Type': 'application/json' },
1017
+ body: JSON.stringify({
1018
+ serverName: 'ccw-tools',
1019
+ serverConfig: ccwToolsConfig
1020
+ })
1021
+ });
1022
+
1023
+ if (!response.ok) throw new Error('Failed to install CCW Tools MCP globally');
1024
+
1025
+ const result = await response.json();
1026
+ if (result.success) {
1027
+ await loadMcpConfig();
1028
+ renderMcpManager();
1029
+ showRefreshToast(`CCW Tools installed globally (${selectedTools.length} tools)`, 'success');
1030
+ } else {
1031
+ showRefreshToast(result.error || 'Failed to install CCW Tools MCP globally', 'error');
1032
+ }
1033
+ } else {
1034
+ // Install to workspace (use preferredProjectConfigType)
1035
+ const configType = preferredProjectConfigType;
1036
+ const response = await fetch('/api/mcp-copy-server', {
1037
+ method: 'POST',
1038
+ headers: { 'Content-Type': 'application/json' },
1039
+ body: JSON.stringify({
1040
+ projectPath: projectPath,
1041
+ serverName: 'ccw-tools',
1042
+ serverConfig: ccwToolsConfig,
1043
+ configType: configType
1044
+ })
1045
+ });
1046
+
1047
+ if (!response.ok) throw new Error('Failed to install CCW Tools MCP to workspace');
1048
+
1049
+ const result = await response.json();
1050
+ if (result.success) {
1051
+ await loadMcpConfig();
1052
+ renderMcpManager();
1053
+ const location = configType === 'mcp' ? '.mcp.json' : 'claude.json';
1054
+ showRefreshToast(`CCW Tools installed to ${location} (${selectedTools.length} tools)`, 'success');
1055
+ } else {
1056
+ showRefreshToast(result.error || 'Failed to install CCW Tools MCP to workspace', 'error');
1057
+ }
1058
+ }
1059
+ } catch (err) {
1060
+ console.error('Failed to install CCW Tools MCP:', err);
1061
+ showRefreshToast(`Failed to install CCW Tools MCP: ${err.message}`, 'error');
1062
+ }
1063
+ }
1064
+
1065
+ async function updateCcwToolsMcp(scope = 'workspace') {
1066
+ const selectedTools = getSelectedCcwTools();
1067
+
1068
+ if (selectedTools.length === 0) {
1069
+ showRefreshToast('Please select at least one tool', 'warning');
1070
+ return;
1071
+ }
1072
+
1073
+ const pathConfig = getCcwPathConfig();
1074
+ const ccwToolsConfig = buildCcwToolsConfig(selectedTools, pathConfig);
1075
+
1076
+ try {
1077
+ const scopeLabel = scope === 'global' ? 'globally' : 'in workspace';
1078
+ showRefreshToast(`Updating CCW Tools MCP ${scopeLabel}...`, 'info');
1079
+
1080
+ if (scope === 'global') {
1081
+ // Update global (~/.claude.json mcpServers)
1082
+ const response = await fetch('/api/mcp-add-global-server', {
1083
+ method: 'POST',
1084
+ headers: { 'Content-Type': 'application/json' },
1085
+ body: JSON.stringify({
1086
+ serverName: 'ccw-tools',
1087
+ serverConfig: ccwToolsConfig
1088
+ })
1089
+ });
1090
+
1091
+ if (!response.ok) throw new Error('Failed to update CCW Tools MCP globally');
1092
+
1093
+ const result = await response.json();
1094
+ if (result.success) {
1095
+ await loadMcpConfig();
1096
+ renderMcpManager();
1097
+ showRefreshToast(`CCW Tools updated globally (${selectedTools.length} tools)`, 'success');
1098
+ } else {
1099
+ showRefreshToast(result.error || 'Failed to update CCW Tools MCP globally', 'error');
1100
+ }
1101
+ } else {
1102
+ // Update workspace (use preferredProjectConfigType)
1103
+ const configType = preferredProjectConfigType;
1104
+ const response = await fetch('/api/mcp-copy-server', {
1105
+ method: 'POST',
1106
+ headers: { 'Content-Type': 'application/json' },
1107
+ body: JSON.stringify({
1108
+ projectPath: projectPath,
1109
+ serverName: 'ccw-tools',
1110
+ serverConfig: ccwToolsConfig,
1111
+ configType: configType
1112
+ })
1113
+ });
1114
+
1115
+ if (!response.ok) throw new Error('Failed to update CCW Tools MCP in workspace');
1116
+
1117
+ const result = await response.json();
1118
+ if (result.success) {
1119
+ await loadMcpConfig();
1120
+ renderMcpManager();
1121
+ const location = configType === 'mcp' ? '.mcp.json' : 'claude.json';
1122
+ showRefreshToast(`CCW Tools updated in ${location} (${selectedTools.length} tools)`, 'success');
1123
+ } else {
1124
+ showRefreshToast(result.error || 'Failed to update CCW Tools MCP in workspace', 'error');
1125
+ }
1126
+ }
1127
+ } catch (err) {
1128
+ console.error('Failed to update CCW Tools MCP:', err);
1129
+ showRefreshToast(`Failed to update CCW Tools MCP: ${err.message}`, 'error');
1130
+ }
1131
+ }
1132
+
1133
+ // ========================================
1134
+ // CCW Tools MCP for Codex
1135
+ // ========================================
1136
+
1137
+ // Get selected tools from Codex checkboxes
1138
+ function getSelectedCcwToolsCodex() {
1139
+ const checkboxes = document.querySelectorAll('.ccw-tool-checkbox-codex:checked');
1140
+ return Array.from(checkboxes).map(cb => cb.dataset.tool);
1141
+ }
1142
+
1143
+ // Select tools by category for Codex
1144
+ function selectCcwToolsCodex(type) {
1145
+ const checkboxes = document.querySelectorAll('.ccw-tool-checkbox-codex');
1146
+ const coreTools = ['write_file', 'edit_file', 'codex_lens', 'smart_search'];
1147
+
1148
+ checkboxes.forEach(cb => {
1149
+ if (type === 'all') {
1150
+ cb.checked = true;
1151
+ } else if (type === 'none') {
1152
+ cb.checked = false;
1153
+ } else if (type === 'core') {
1154
+ cb.checked = coreTools.includes(cb.dataset.tool);
1155
+ }
1156
+ });
1157
+ }
1158
+
1159
+ // Install/Update CCW Tools MCP to Codex
1160
+ async function installCcwToolsMcpToCodex() {
1161
+ const selectedTools = getSelectedCcwToolsCodex();
1162
+
1163
+ if (selectedTools.length === 0) {
1164
+ showRefreshToast('Please select at least one tool', 'warning');
1165
+ return;
1166
+ }
1167
+
1168
+ const pathConfig = getCcwPathConfig();
1169
+ const ccwToolsConfig = buildCcwToolsConfig(selectedTools, pathConfig);
1170
+
1171
+ try {
1172
+ const isUpdate = codexMcpServers && codexMcpServers['ccw-tools'];
1173
+ const actionLabel = isUpdate ? 'Updating' : 'Installing';
1174
+ showRefreshToast(`${actionLabel} CCW Tools MCP to Codex...`, 'info');
1175
+
1176
+ await addCodexMcpServer('ccw-tools', ccwToolsConfig);
1177
+
1178
+ // Reload MCP configuration and refresh the view
1179
+ await loadMcpConfig();
1180
+ renderMcpManager();
1181
+
1182
+ const resultLabel = isUpdate ? 'updated in' : 'installed to';
1183
+ showRefreshToast(`CCW Tools ${resultLabel} Codex (${selectedTools.length} tools)`, 'success');
1184
+ } catch (err) {
1185
+ console.error('Failed to install CCW Tools MCP to Codex:', err);
1186
+ showRefreshToast(`Failed to install CCW Tools MCP to Codex: ${err.message}`, 'error');
1187
+ }
1188
+ }
1189
+
1190
+ // ========== Project Config Type Toggle ==========
1191
+ function toggleProjectConfigType() {
1192
+ preferredProjectConfigType = preferredProjectConfigType === 'mcp' ? 'claude' : 'mcp';
1193
+ console.log('[MCP] Preferred project config type changed to:', preferredProjectConfigType);
1194
+ // Re-render to update toggle display
1195
+ renderMcpManager();
1196
+ }
1197
+
1198
+ function getPreferredProjectConfigType() {
1199
+ return preferredProjectConfigType;
1200
+ }
1201
+
1202
+ function setPreferredProjectConfigType(type) {
1203
+ if (type === 'mcp' || type === 'claude') {
1204
+ preferredProjectConfigType = type;
1205
+ console.log('[MCP] Preferred project config type set to:', preferredProjectConfigType);
1206
+ }
1207
+ }
1208
+
1209
+ // ========== Global Exports for onclick handlers ==========
1210
+ // Expose functions to global scope to support inline onclick handlers
1211
+ window.setCliMode = setCliMode;
1212
+ window.getCliMode = getCliMode;
1213
+ window.selectCcwTools = selectCcwTools;
1214
+ window.selectCcwToolsCodex = selectCcwToolsCodex;
1215
+ window.openMcpCreateModal = openMcpCreateModal;
1216
+ window.toggleProjectConfigType = toggleProjectConfigType;
1217
+ window.getPreferredProjectConfigType = getPreferredProjectConfigType;
1218
+ window.setPreferredProjectConfigType = setPreferredProjectConfigType;
1219
+ window.setCcwProjectRootToCurrent = setCcwProjectRootToCurrent;