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,912 @@
1
+ // CLAUDE.md Manager View
2
+ // Three-column layout: File Tree | Viewer/Editor | Metadata & Actions
3
+
4
+ // ========== State Management ==========
5
+ var claudeFilesData = {
6
+ user: { main: null },
7
+ project: { main: null },
8
+ modules: [],
9
+ summary: { totalFiles: 0, totalSize: 0 }
10
+ };
11
+ var selectedFile = null;
12
+ var isEditMode = false;
13
+ var isDirty = false;
14
+ var fileTreeExpanded = {
15
+ user: true,
16
+ project: true,
17
+ modules: {}
18
+ };
19
+ var searchQuery = '';
20
+ var freshnessData = {}; // { [filePath]: FreshnessResult }
21
+ var freshnessSummary = null;
22
+
23
+ // ========== Main Render Function ==========
24
+ async function renderClaudeManager() {
25
+ var container = document.getElementById('mainContent');
26
+ if (!container) return;
27
+
28
+ // Hide stats grid and search for claude-manager view
29
+ var statsGrid = document.getElementById('statsGrid');
30
+ var searchInput = document.getElementById('searchInput');
31
+ if (statsGrid) statsGrid.style.display = 'none';
32
+ if (searchInput) searchInput.parentElement.style.display = 'none';
33
+
34
+ // Show loading state
35
+ container.innerHTML = '<div class="claude-manager-view loading">' +
36
+ '<div class="loading-spinner"><i data-lucide="loader-2" class="w-8 h-8 animate-spin"></i></div>' +
37
+ '<p>' + t('common.loading') + '</p>' +
38
+ '</div>';
39
+
40
+ // Load file data first (fast operation)
41
+ await loadClaudeFiles();
42
+
43
+ // Render layout immediately without waiting for freshness data
44
+ container.innerHTML = '<div class="claude-manager-view">' +
45
+ '<div class="claude-manager-header">' +
46
+ '<div class="claude-manager-header-left">' +
47
+ '<h2><i data-lucide="file-code" class="w-5 h-5"></i> ' + t('claudeManager.title') + '</h2>' +
48
+ '<span class="file-count-badge">' + claudeFilesData.summary.totalFiles + ' ' + t('claudeManager.files') + '</span>' +
49
+ '</div>' +
50
+ '<div class="claude-manager-header-right">' +
51
+ '<button class="btn btn-sm btn-primary" onclick="showCreateFileDialog()">' +
52
+ '<i data-lucide="file-plus" class="w-4 h-4"></i> ' + t('claude.createFile') +
53
+ '</button>' +
54
+ '<button class="btn btn-sm btn-secondary" onclick="refreshClaudeFiles()">' +
55
+ '<i data-lucide="refresh-cw" class="w-4 h-4"></i> ' + t('common.refresh') +
56
+ '</button>' +
57
+ '</div>' +
58
+ '</div>' +
59
+ '<div class="claude-manager-columns">' +
60
+ '<div class="claude-manager-column left" id="claude-file-tree"></div>' +
61
+ '<div class="claude-manager-column center" id="claude-file-viewer"></div>' +
62
+ '<div class="claude-manager-column right" id="claude-file-metadata"></div>' +
63
+ '</div>' +
64
+ '</div>';
65
+
66
+ // Render each column immediately (without freshness data)
67
+ renderFileTree();
68
+ renderFileViewer();
69
+ renderFileMetadata();
70
+
71
+ // Initialize Lucide icons
72
+ if (window.lucide) lucide.createIcons();
73
+
74
+ // Load freshness data asynchronously in the background (non-blocking)
75
+ loadFreshnessDataAsync();
76
+ }
77
+
78
+ // Async freshness loader - loads in background and updates UI when ready
79
+ function loadFreshnessDataAsync() {
80
+ // Use setTimeout to ensure UI is rendered first
81
+ setTimeout(async function() {
82
+ try {
83
+ await loadFreshnessData();
84
+ // Re-render file tree and metadata with freshness data
85
+ renderFileTree();
86
+ if (selectedFile) {
87
+ renderFileMetadata();
88
+ }
89
+ if (window.lucide) lucide.createIcons();
90
+ } catch (error) {
91
+ console.error('Error loading freshness data in background:', error);
92
+ }
93
+ }, 100);
94
+ }
95
+
96
+ // ========== Data Loading ==========
97
+ async function loadClaudeFiles() {
98
+ try {
99
+ var res = await fetch('/api/memory/claude/scan?path=' + encodeURIComponent(projectPath || ''));
100
+ if (!res.ok) throw new Error('Failed to load CLAUDE.md files');
101
+ claudeFilesData = await res.json();
102
+ updateClaudeBadge(); // Update navigation badge
103
+ } catch (error) {
104
+ console.error('Error loading CLAUDE.md files:', error);
105
+ addGlobalNotification('error', t('claudeManager.loadError'), null, 'CLAUDE.md');
106
+ }
107
+ }
108
+
109
+ async function refreshClaudeFiles() {
110
+ await loadClaudeFiles();
111
+ // Re-render file tree immediately
112
+ renderFileTree();
113
+ renderFileViewer();
114
+ renderFileMetadata();
115
+ if (window.lucide) lucide.createIcons();
116
+ addGlobalNotification('success', t('claudeManager.refreshed'), null, 'CLAUDE.md');
117
+ // Load freshness data in background
118
+ loadFreshnessDataAsync();
119
+ }
120
+
121
+ // ========== Freshness Data Loading ==========
122
+ async function loadFreshnessData() {
123
+ try {
124
+ var res = await fetch('/api/memory/claude/freshness?path=' + encodeURIComponent(projectPath || ''));
125
+ if (!res.ok) throw new Error('Failed to load freshness data');
126
+ var data = await res.json();
127
+
128
+ // Build lookup map
129
+ freshnessData = {};
130
+ if (data.files) {
131
+ data.files.forEach(function(f) {
132
+ freshnessData[f.path] = f;
133
+ });
134
+ }
135
+ freshnessSummary = data.summary || null;
136
+ } catch (error) {
137
+ console.error('Error loading freshness data:', error);
138
+ freshnessData = {};
139
+ freshnessSummary = null;
140
+ }
141
+ }
142
+
143
+ async function markFileAsUpdated() {
144
+ if (!selectedFile) return;
145
+
146
+ try {
147
+ var res = await fetch('/api/memory/claude/mark-updated', {
148
+ method: 'POST',
149
+ headers: { 'Content-Type': 'application/json' },
150
+ body: JSON.stringify({
151
+ path: selectedFile.path,
152
+ source: 'dashboard'
153
+ })
154
+ });
155
+
156
+ if (!res.ok) throw new Error('Failed to mark file as updated');
157
+
158
+ addGlobalNotification('success', t('claudeManager.markedAsUpdated') || 'Marked as updated', null, 'CLAUDE.md');
159
+
160
+ // Reload freshness data
161
+ await loadFreshnessData();
162
+ renderFileTree();
163
+ renderFileMetadata();
164
+ } catch (error) {
165
+ console.error('Error marking file as updated:', error);
166
+ addGlobalNotification('error', t('claudeManager.markUpdateError') || 'Failed to mark as updated', null, 'CLAUDE.md');
167
+ }
168
+ }
169
+
170
+ // ========== File Tree Rendering ==========
171
+ function renderFileTree() {
172
+ var container = document.getElementById('claude-file-tree');
173
+ if (!container) return;
174
+
175
+ var html = '<div class="file-tree">' +
176
+ // Search Box
177
+ '<div class="file-tree-search">' +
178
+ '<input type="text" id="fileSearchInput" placeholder="' + t('claude.searchPlaceholder') + '" ' +
179
+ 'value="' + escapeHtml(searchQuery) + '" oninput="filterFileTree(this.value)">' +
180
+ '<i data-lucide="search" class="w-4 h-4"></i>' +
181
+ '</div>' +
182
+ renderClaudeFilesTree() +
183
+ '</div>'; // end file-tree
184
+
185
+ container.innerHTML = html;
186
+ if (window.lucide) lucide.createIcons();
187
+ }
188
+
189
+ function renderClaudeFilesTree() {
190
+ var html = '<div class="file-tree-section">' +
191
+ '<div class="file-tree-header" onclick="toggleTreeSection(\'user\')">' +
192
+ '<i data-lucide="' + (fileTreeExpanded.user ? 'chevron-down' : 'chevron-right') + '" class="w-4 h-4"></i>' +
193
+ '<i data-lucide="user" class="w-4 h-4 text-orange-500"></i>' +
194
+ '<span>' + t('claudeManager.userLevel') + '</span>' +
195
+ '<span class="file-count">' + (claudeFilesData.user.main ? 1 : 0) + '</span>' +
196
+ '</div>';
197
+
198
+ if (fileTreeExpanded.user) {
199
+ // User CLAUDE.md (only main file, no rules)
200
+ if (claudeFilesData.user.main) {
201
+ html += renderFileTreeItem(claudeFilesData.user.main, 1);
202
+ } else {
203
+ html += '<div class="file-tree-item empty" style="padding-left: 1.5rem;">' +
204
+ '<i data-lucide="file-x" class="w-4 h-4"></i>' +
205
+ '<span>' + t('claudeManager.noFile') + '</span>' +
206
+ '</div>';
207
+ }
208
+ }
209
+
210
+ html += '</div>'; // end user section
211
+
212
+ // Project section
213
+ html += '<div class="file-tree-section">' +
214
+ '<div class="file-tree-header" onclick="toggleTreeSection(\'project\')">' +
215
+ '<i data-lucide="' + (fileTreeExpanded.project ? 'chevron-down' : 'chevron-right') + '" class="w-4 h-4"></i>' +
216
+ '<i data-lucide="folder" class="w-4 h-4 text-green-500"></i>' +
217
+ '<span>' + t('claudeManager.projectLevel') + '</span>' +
218
+ '<span class="file-count">' + (claudeFilesData.project.main ? 1 : 0) + '</span>' +
219
+ '</div>';
220
+
221
+ if (fileTreeExpanded.project) {
222
+ // Project CLAUDE.md (only main file, no rules)
223
+ if (claudeFilesData.project.main) {
224
+ html += renderFileTreeItem(claudeFilesData.project.main, 1);
225
+ } else {
226
+ html += '<div class="file-tree-item empty" style="padding-left: 1.5rem;">' +
227
+ '<i data-lucide="file-x" class="w-4 h-4"></i>' +
228
+ '<span>' + t('claudeManager.noFile') + '</span>' +
229
+ '</div>';
230
+ }
231
+ }
232
+
233
+ html += '</div>'; // end project section
234
+
235
+ // Modules section
236
+ html += '<div class="file-tree-section">' +
237
+ '<div class="file-tree-header">' +
238
+ '<i data-lucide="package" class="w-4 h-4 text-blue-500"></i>' +
239
+ '<span>' + t('claudeManager.moduleLevel') + '</span>' +
240
+ '<span class="file-count">' + claudeFilesData.modules.length + '</span>' +
241
+ '</div>';
242
+
243
+ if (claudeFilesData.modules.length > 0) {
244
+ claudeFilesData.modules.forEach(function (file) {
245
+ html += renderFileTreeItem(file, 1);
246
+ });
247
+ } else {
248
+ html += '<div class="file-tree-item empty" style="padding-left: 1.5rem;">' +
249
+ '<i data-lucide="file-x" class="w-4 h-4"></i>' +
250
+ '<span>' + t('claudeManager.noModules') + '</span>' +
251
+ '</div>';
252
+ }
253
+
254
+ html += '</div>'; // end modules section
255
+
256
+ return html;
257
+ }
258
+
259
+ function renderFileTreeItem(file, indentLevel) {
260
+ var isSelected = selectedFile && selectedFile.id === file.id;
261
+ var indentPx = indentLevel * 1.5;
262
+ var safeId = file.id.replace(/'/g, "&apos;");
263
+
264
+ // Get freshness data for this file
265
+ var fd = freshnessData[file.path];
266
+ var freshnessClass = '';
267
+ var freshnessBadge = '';
268
+
269
+ // Check if freshness data is loaded (freshnessSummary is set after load)
270
+ var freshnessLoaded = freshnessSummary !== null || Object.keys(freshnessData).length > 0;
271
+
272
+ if (fd) {
273
+ if (fd.freshness >= 75) {
274
+ freshnessClass = ' freshness-good';
275
+ freshnessBadge = '<span class="freshness-badge good">' + fd.freshness + '%</span>';
276
+ } else if (fd.freshness >= 50) {
277
+ freshnessClass = ' freshness-warn';
278
+ freshnessBadge = '<span class="freshness-badge warn">' + fd.freshness + '%</span>';
279
+ } else {
280
+ freshnessClass = ' freshness-stale';
281
+ freshnessBadge = '<span class="freshness-badge stale">' + fd.freshness + '%</span>';
282
+ }
283
+ } else if (!freshnessLoaded) {
284
+ // Show loading badge while freshness data is being fetched
285
+ freshnessBadge = '<span class="freshness-badge loading">...</span>';
286
+ }
287
+
288
+ return '<div class="file-tree-item' + freshnessClass + (isSelected ? ' selected' : '') + '" ' +
289
+ 'onclick="selectClaudeFile(\'' + safeId + '\')" ' +
290
+ 'style="padding-left: ' + indentPx + 'rem;">' +
291
+ '<i data-lucide="file-text" class="w-4 h-4"></i>' +
292
+ '<span class="file-name">' + escapeHtml(file.name) + '</span>' +
293
+ freshnessBadge +
294
+ (file.parentDirectory ? '<span class="file-path-hint">' + escapeHtml(file.parentDirectory) + '</span>' : '') +
295
+ '</div>';
296
+ }
297
+
298
+ function toggleTreeSection(section) {
299
+ fileTreeExpanded[section] = !fileTreeExpanded[section];
300
+ renderFileTree();
301
+ }
302
+
303
+ async function selectClaudeFile(fileId) {
304
+ // Find file in data (only main CLAUDE.md files, no rules)
305
+ var allFiles = [
306
+ claudeFilesData.user.main,
307
+ claudeFilesData.project.main,
308
+ ...claudeFilesData.modules
309
+ ].filter(function (f) { return f !== null; });
310
+
311
+ selectedFile = allFiles.find(function (f) { return f.id === fileId; }) || null;
312
+
313
+ if (selectedFile) {
314
+ // Load full content if not already loaded
315
+ if (!selectedFile.content) {
316
+ try {
317
+ var res = await fetch('/api/memory/claude/file?path=' + encodeURIComponent(selectedFile.path));
318
+ if (res.ok) {
319
+ var data = await res.json();
320
+ selectedFile.content = data.content;
321
+ selectedFile.stats = data.stats;
322
+ }
323
+ } catch (error) {
324
+ console.error('Error loading file content:', error);
325
+ }
326
+ }
327
+ }
328
+
329
+ renderFileTree();
330
+ renderFileViewer();
331
+ renderFileMetadata();
332
+ }
333
+
334
+ // ========== File Viewer Rendering ==========
335
+ function renderFileViewer() {
336
+ var container = document.getElementById('claude-file-viewer');
337
+ if (!container) return;
338
+
339
+ if (!selectedFile) {
340
+ container.innerHTML = '<div class="empty-state">' +
341
+ '<i data-lucide="file-search" class="w-12 h-12 opacity-20"></i>' +
342
+ '<p>' + t('claudeManager.selectFile') + '</p>' +
343
+ '</div>';
344
+ if (window.lucide) lucide.createIcons();
345
+ return;
346
+ }
347
+
348
+ container.innerHTML = '<div class="file-viewer">' +
349
+ '<div class="file-viewer-header">' +
350
+ '<h3>' + escapeHtml(selectedFile.name) + '</h3>' +
351
+ '<div class="file-viewer-actions">' +
352
+ '<button class="btn btn-sm btn-secondary" onclick="copyFileContent()" title="' + t('claude.copyContent') + '">' +
353
+ '<i data-lucide="copy" class="w-4 h-4"></i>' +
354
+ '</button>' +
355
+ '<button class="btn btn-sm btn-secondary" onclick="toggleEditMode()" title="' + t('common.edit') + '">' +
356
+ '<i data-lucide="' + (isEditMode ? 'eye' : 'edit-2') + '" class="w-4 h-4"></i>' +
357
+ '</button>' +
358
+ '</div>' +
359
+ '</div>' +
360
+ '<div class="file-viewer-content">' +
361
+ (isEditMode ? renderEditor() : renderMarkdownContent(selectedFile.content || '')) +
362
+ '</div>' +
363
+ '</div>';
364
+
365
+ if (window.lucide) lucide.createIcons();
366
+ }
367
+
368
+ function renderMarkdownContent(content) {
369
+ // Check if marked.js is available for enhanced rendering
370
+ if (typeof marked !== 'undefined') {
371
+ try {
372
+ marked.setOptions({
373
+ gfm: true,
374
+ breaks: true,
375
+ tables: true,
376
+ smartLists: true,
377
+ highlight: function(code, lang) {
378
+ // Check if highlight.js or Prism is available
379
+ if (typeof hljs !== 'undefined' && lang) {
380
+ try {
381
+ return hljs.highlight(code, { language: lang }).value;
382
+ } catch (e) {
383
+ return escapeHtml(code);
384
+ }
385
+ } else if (typeof Prism !== 'undefined' && lang && Prism.languages[lang]) {
386
+ return Prism.highlight(code, Prism.languages[lang], lang);
387
+ }
388
+ return escapeHtml(code);
389
+ }
390
+ });
391
+ return '<div class="markdown-content">' + marked.parse(content) + '</div>';
392
+ } catch (e) {
393
+ console.error('Error rendering markdown with marked.js:', e);
394
+ }
395
+ }
396
+
397
+ // Fallback: Enhanced basic rendering
398
+ var html = escapeHtml(content);
399
+
400
+ // Headers
401
+ html = html
402
+ .replace(/^# (.*$)/gim, '<h1>$1</h1>')
403
+ .replace(/^## (.*$)/gim, '<h2>$1</h2>')
404
+ .replace(/^### (.*$)/gim, '<h3>$1</h3>')
405
+ .replace(/^#### (.*$)/gim, '<h4>$1</h4>');
406
+
407
+ // Inline formatting
408
+ html = html
409
+ .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
410
+ .replace(/\*(.+?)\*/g, '<em>$1</em>')
411
+ .replace(/`([^`]+)`/g, '<code>$1</code>');
412
+
413
+ // Links
414
+ html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>');
415
+
416
+ // Task lists
417
+ html = html
418
+ .replace(/- \[ \] (.+)$/gim, '<li class="task-list-item"><input type="checkbox" disabled> $1</li>')
419
+ .replace(/- \[x\] (.+)$/gim, '<li class="task-list-item"><input type="checkbox" disabled checked> $1</li>');
420
+
421
+ // Lists
422
+ html = html.replace(/^- (.+)$/gim, '<li>$1</li>');
423
+ html = html.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>');
424
+
425
+ // Code blocks
426
+ html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, function(match, lang, code) {
427
+ return '<pre><code class="language-' + (lang || 'plaintext') + '">' + code + '</code></pre>';
428
+ });
429
+
430
+ // Line breaks
431
+ html = html.replace(/\n/g, '<br>');
432
+
433
+ return '<div class="markdown-content">' + html + '</div>';
434
+ }
435
+
436
+ function renderEditor() {
437
+ return '<textarea id="claudeFileEditor" class="file-editor" ' +
438
+ 'oninput="markDirty()">' +
439
+ escapeHtml(selectedFile.content || '') +
440
+ '</textarea>';
441
+ }
442
+
443
+ function toggleEditMode() {
444
+ if (isEditMode && isDirty) {
445
+ if (!confirm(t('claudeManager.unsavedChanges'))) {
446
+ return;
447
+ }
448
+ }
449
+
450
+ isEditMode = !isEditMode;
451
+ isDirty = false;
452
+ renderFileViewer();
453
+ }
454
+
455
+ function markDirty() {
456
+ isDirty = true;
457
+ }
458
+
459
+ async function saveClaudeFile() {
460
+ if (!selectedFile || !isEditMode) return;
461
+
462
+ var editor = document.getElementById('claudeFileEditor');
463
+ if (!editor) return;
464
+
465
+ var newContent = editor.value;
466
+
467
+ try {
468
+ var res = await fetch('/api/memory/claude/file', {
469
+ method: 'POST',
470
+ headers: { 'Content-Type': 'application/json' },
471
+ body: JSON.stringify({
472
+ path: selectedFile.path,
473
+ content: newContent,
474
+ createBackup: true
475
+ })
476
+ });
477
+
478
+ if (!res.ok) throw new Error('Failed to save file');
479
+
480
+ selectedFile.content = newContent;
481
+ selectedFile.stats = calculateFileStats(newContent);
482
+ isDirty = false;
483
+
484
+ addGlobalNotification('success', t('claudeManager.saved'), null, 'CLAUDE.md');
485
+ renderFileMetadata();
486
+ } catch (error) {
487
+ console.error('Error saving file:', error);
488
+ addGlobalNotification('error', t('claudeManager.saveError'), null, 'CLAUDE.md');
489
+ }
490
+ }
491
+
492
+ function calculateFileStats(content) {
493
+ var lines = content.split('\n').length;
494
+ var words = content.split(/\s+/).filter(function (w) { return w.length > 0; }).length;
495
+ var characters = content.length;
496
+ return { lines: lines, words: words, characters: characters };
497
+ }
498
+
499
+ // ========== File Metadata Rendering ==========
500
+ function renderFileMetadata() {
501
+ var container = document.getElementById('claude-file-metadata');
502
+ if (!container) return;
503
+
504
+ if (!selectedFile) {
505
+ container.innerHTML = '<div class="empty-state">' +
506
+ '<i data-lucide="info" class="w-8 h-8 opacity-20"></i>' +
507
+ '<p>' + t('claudeManager.noMetadata') + '</p>' +
508
+ '</div>';
509
+ if (window.lucide) lucide.createIcons();
510
+ return;
511
+ }
512
+
513
+ var html = '<div class="file-metadata">' +
514
+ '<div class="metadata-section">' +
515
+ '<h4>' + t('claudeManager.fileInfo') + '</h4>' +
516
+ '<div class="metadata-item">' +
517
+ '<span class="label">' + t('claudeManager.level') + '</span>' +
518
+ '<span class="value">' + t('claudeManager.level_' + selectedFile.level) + '</span>' +
519
+ '</div>' +
520
+ '<div class="metadata-item">' +
521
+ '<span class="label">' + t('claudeManager.path') + '</span>' +
522
+ '<span class="value path">' + escapeHtml(selectedFile.relativePath) + '</span>' +
523
+ '</div>' +
524
+ '<div class="metadata-item">' +
525
+ '<span class="label">' + t('claudeManager.size') + '</span>' +
526
+ '<span class="value">' + formatFileSize(selectedFile.size) + '</span>' +
527
+ '</div>' +
528
+ '<div class="metadata-item">' +
529
+ '<span class="label">' + t('claudeManager.modified') + '</span>' +
530
+ '<span class="value">' + formatDate(selectedFile.lastModified) + '</span>' +
531
+ '</div>' +
532
+ '</div>';
533
+
534
+ if (selectedFile.stats) {
535
+ html += '<div class="metadata-section">' +
536
+ '<h4>' + t('claudeManager.statistics') + '</h4>' +
537
+ '<div class="metadata-item">' +
538
+ '<span class="label">' + t('claudeManager.lines') + '</span>' +
539
+ '<span class="value">' + selectedFile.stats.lines + '</span>' +
540
+ '</div>' +
541
+ '<div class="metadata-item">' +
542
+ '<span class="label">' + t('claudeManager.words') + '</span>' +
543
+ '<span class="value">' + selectedFile.stats.words + '</span>' +
544
+ '</div>' +
545
+ '<div class="metadata-item">' +
546
+ '<span class="label">' + t('claudeManager.characters') + '</span>' +
547
+ '<span class="value">' + selectedFile.stats.characters + '</span>' +
548
+ '</div>' +
549
+ '</div>';
550
+ }
551
+
552
+ // Freshness section
553
+ var fd = freshnessData[selectedFile.path];
554
+ var freshnessLoaded = freshnessSummary !== null || Object.keys(freshnessData).length > 0;
555
+
556
+ if (fd) {
557
+ var freshnessBarClass = fd.freshness >= 75 ? 'good' : fd.freshness >= 50 ? 'warn' : 'stale';
558
+ html += '<div class="metadata-section freshness-section">' +
559
+ '<h4><i data-lucide="activity" class="w-4 h-4"></i> ' + (t('claudeManager.freshness') || 'Freshness') + '</h4>' +
560
+ '<div class="freshness-gauge">' +
561
+ '<div class="freshness-bar ' + freshnessBarClass + '" style="width: ' + fd.freshness + '%"></div>' +
562
+ '</div>' +
563
+ '<div class="freshness-value-display">' + fd.freshness + '%</div>' +
564
+ '<div class="metadata-item">' +
565
+ '<span class="label">' + (t('claudeManager.lastContentUpdate') || 'Last Content Update') + '</span>' +
566
+ '<span class="value">' + (fd.lastUpdated ? formatDate(fd.lastUpdated) : (t('claudeManager.never') || 'Never tracked')) + '</span>' +
567
+ '</div>' +
568
+ '<div class="metadata-item">' +
569
+ '<span class="label">' + (t('claudeManager.changedFiles') || 'Changed Files') + '</span>' +
570
+ '<span class="value">' + fd.changedFilesCount + ' ' + (t('claudeManager.filesSinceUpdate') || 'files since update') + '</span>' +
571
+ '</div>';
572
+
573
+ if (fd.needsUpdate) {
574
+ html += '<div class="update-reminder">' +
575
+ '<i data-lucide="alert-triangle" class="w-4 h-4"></i>' +
576
+ '<span>' + (t('claudeManager.updateReminder') || 'This file may need updating') + '</span>' +
577
+ '</div>';
578
+ }
579
+
580
+ html += '<button class="btn btn-sm btn-secondary full-width" onclick="markFileAsUpdated()">' +
581
+ '<i data-lucide="check-circle" class="w-4 h-4"></i> ' + (t('claudeManager.markAsUpdated') || 'Mark as Updated') +
582
+ '</button>' +
583
+ '</div>';
584
+ } else if (!freshnessLoaded) {
585
+ // Show loading state while freshness data is being fetched
586
+ html += '<div class="metadata-section freshness-section">' +
587
+ '<h4><i data-lucide="activity" class="w-4 h-4"></i> ' + (t('claudeManager.freshness') || 'Freshness') + '</h4>' +
588
+ '<div class="freshness-loading">' +
589
+ '<i data-lucide="loader-2" class="w-5 h-5 animate-spin"></i>' +
590
+ '<span>' + (t('claudeManager.loadingFreshness') || 'Loading freshness data...') + '</span>' +
591
+ '</div>' +
592
+ '</div>';
593
+ }
594
+
595
+ html += '<div class="metadata-section">' +
596
+ '<h4>' + t('claudeManager.actions') + '</h4>';
597
+
598
+ if (isEditMode) {
599
+ html += '<button class="btn btn-sm btn-primary full-width" onclick="saveClaudeFile()"' +
600
+ (isDirty ? '' : ' disabled') + '>' +
601
+ '<i data-lucide="save" class="w-4 h-4"></i> ' + t('common.save') +
602
+ '</button>';
603
+ html += '<button class="btn btn-sm btn-secondary full-width" onclick="toggleEditMode()">' +
604
+ '<i data-lucide="x" class="w-4 h-4"></i> ' + t('common.cancel') +
605
+ '</button>';
606
+ } else {
607
+ html += '<button class="btn btn-sm btn-secondary full-width" onclick="toggleEditMode()">' +
608
+ '<i data-lucide="edit-2" class="w-4 h-4"></i> ' + t('common.edit') +
609
+ '</button>';
610
+ }
611
+
612
+ // Delete button (only for CLAUDE.md files, not in edit mode)
613
+ if (!isEditMode && selectedFile.level !== 'file') {
614
+ html += '<button class="btn btn-sm btn-danger full-width" onclick="confirmDeleteFile()">' +
615
+ '<i data-lucide="trash-2" class="w-4 h-4"></i> ' + t('claude.deleteFile') +
616
+ '</button>';
617
+ }
618
+
619
+ html += '</div>'; // end actions section
620
+
621
+ // CLI Sync Panel
622
+ html += '<div class="metadata-section cli-sync-panel">' +
623
+ '<div class="panel-header">' +
624
+ '<i data-lucide="sparkles" class="w-4 h-4"></i>' +
625
+ '<span>' + (t('claude.cliSync') || 'CLI Auto-Sync') + '</span>' +
626
+ '</div>' +
627
+ '<div class="sync-config">' +
628
+ '<label>' + (t('claude.tool') || 'Tool') + '</label>' +
629
+ '<select id="cliToolSelect" class="sync-select">' +
630
+ '<option value="gemini">Gemini</option>' +
631
+ '<option value="qwen">Qwen</option>' +
632
+ '</select>' +
633
+ '<label>' + (t('claude.mode') || 'Mode') + '</label>' +
634
+ '<select id="cliModeSelect" class="sync-select">' +
635
+ '<option value="update">' + (t('claude.modeUpdate') || 'Update (Smart Merge)') + '</option>' +
636
+ '<option value="generate">' + (t('claude.modeGenerate') || 'Generate (Full Replace)') + '</option>' +
637
+ '<option value="append">' + (t('claude.modeAppend') || 'Append') + '</option>' +
638
+ '</select>' +
639
+ '</div>' +
640
+ '<button class="btn btn-sm btn-primary full-width sync-button" onclick="syncFileWithCLI()" id="cliSyncButton">' +
641
+ '<i data-lucide="refresh-cw" class="w-4 h-4"></i> ' +
642
+ (t('claude.syncButton') || 'Sync with CLI') +
643
+ '</button>' +
644
+ '<div id="syncProgress" class="sync-progress" style="display:none;">' +
645
+ '<i data-lucide="loader" class="w-4 h-4"></i>' +
646
+ '<span id="syncProgressText">' + (t('claude.syncing') || 'Analyzing...') + '</span>' +
647
+ '</div>' +
648
+ '</div>'; // end cli-sync-panel
649
+
650
+ html += '</div>'; // end file-metadata
651
+
652
+ container.innerHTML = html;
653
+ if (window.lucide) lucide.createIcons();
654
+ }
655
+
656
+ // ========== CLI Sync Functions ==========
657
+ async function syncFileWithCLI() {
658
+ if (!selectedFile) return;
659
+
660
+ var tool = document.getElementById('cliToolSelect').value;
661
+ var mode = document.getElementById('cliModeSelect').value;
662
+
663
+ // Show progress
664
+ showSyncProgress(true, tool);
665
+
666
+ // Disable sync button
667
+ var syncButton = document.getElementById('cliSyncButton');
668
+ if (syncButton) syncButton.disabled = true;
669
+
670
+ try {
671
+ var response = await fetch('/api/memory/claude/sync', {
672
+ method: 'POST',
673
+ headers: { 'Content-Type': 'application/json' },
674
+ body: JSON.stringify({
675
+ level: selectedFile.level,
676
+ path: selectedFile.level === 'module' ? selectedFile.path.replace(/CLAUDE\.md$/, '').replace(/\/$/, '') : undefined,
677
+ tool: tool,
678
+ mode: mode
679
+ })
680
+ });
681
+
682
+ var result = await response.json();
683
+
684
+ if (result.success) {
685
+ // Reload file content and freshness data
686
+ var fileData = await loadFileContent(selectedFile.path);
687
+ if (fileData) {
688
+ selectedFile = fileData;
689
+ await loadFreshnessData();
690
+ renderFileTree();
691
+ renderFileViewer();
692
+ renderFileMetadata();
693
+ }
694
+ showClaudeNotification('success', (t('claude.syncSuccess') || 'Synced successfully').replace('{file}', selectedFile.name));
695
+ } else {
696
+ showClaudeNotification('error', (t('claude.syncError') || 'Sync failed').replace('{error}', result.error || 'Unknown error'));
697
+ }
698
+ } catch (error) {
699
+ console.error('CLI sync error:', error);
700
+ showClaudeNotification('error', (t('claude.syncError') || 'Sync failed').replace('{error}', error.message));
701
+ } finally {
702
+ showSyncProgress(false);
703
+ if (syncButton) syncButton.disabled = false;
704
+ }
705
+ }
706
+
707
+ function showSyncProgress(show, tool) {
708
+ var progressEl = document.getElementById('syncProgress');
709
+ var progressText = document.getElementById('syncProgressText');
710
+ if (!progressEl) return;
711
+
712
+ if (show) {
713
+ progressEl.style.display = 'flex';
714
+ if (progressText) {
715
+ var text = (t('claude.syncing') || 'Analyzing with {tool}...').replace('{tool}', tool || 'CLI');
716
+ progressText.textContent = text;
717
+ }
718
+ if (window.lucide) lucide.createIcons();
719
+ } else {
720
+ progressEl.style.display = 'none';
721
+ }
722
+ }
723
+
724
+ async function loadFileContent(filePath) {
725
+ try {
726
+ var res = await fetch('/api/memory/claude/file?path=' + encodeURIComponent(filePath));
727
+ if (!res.ok) return null;
728
+ return await res.json();
729
+ } catch (error) {
730
+ console.error('Error loading file content:', error);
731
+ return null;
732
+ }
733
+ }
734
+
735
+ function showClaudeNotification(type, message) {
736
+ // Use global notification system if available
737
+ if (typeof addGlobalNotification === 'function') {
738
+ addGlobalNotification(type, message, null, 'CLAUDE.md');
739
+ } else {
740
+ // Fallback to simple alert
741
+ alert(message);
742
+ }
743
+ }
744
+
745
+ // ========== Search Functions ==========
746
+ function filterFileTree(query) {
747
+ searchQuery = query.toLowerCase();
748
+ renderFileTree();
749
+
750
+ // Add keyboard shortcut handler
751
+ if (query && !window.claudeSearchKeyboardHandlerAdded) {
752
+ document.addEventListener('keydown', handleSearchKeyboard);
753
+ window.claudeSearchKeyboardHandlerAdded = true;
754
+ }
755
+ }
756
+
757
+ function handleSearchKeyboard(e) {
758
+ // Ctrl+F or Cmd+F
759
+ if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
760
+ e.preventDefault();
761
+ var searchInput = document.getElementById('fileSearchInput');
762
+ if (searchInput) {
763
+ searchInput.focus();
764
+ searchInput.select();
765
+ }
766
+ }
767
+ }
768
+
769
+ // ========== File Creation Functions ==========
770
+ function showCreateFileDialog() {
771
+ var dialog = '<div class="modal-overlay" onclick="closeCreateDialog()">' +
772
+ '<div class="create-dialog" onclick="event.stopPropagation()">' +
773
+ '<h3>' + t('claude.createDialogTitle') + '</h3>' +
774
+ '<div class="dialog-form">' +
775
+ '<label>' + t('claude.selectLevel') + '</label>' +
776
+ '<select id="createLevel" onchange="toggleModulePathInput(this.value)">' +
777
+ '<option value="user">' + t('claude.levelUser') + '</option>' +
778
+ '<option value="project">' + t('claude.levelProject') + '</option>' +
779
+ '<option value="module">' + t('claude.levelModule') + '</option>' +
780
+ '</select>' +
781
+ '<label id="modulePathLabel" style="display:none;">' + t('claude.modulePath') + '</label>' +
782
+ '<input id="modulePath" type="text" style="display:none;" placeholder="e.g., src/components">' +
783
+ '<label>' + t('claude.selectTemplate') + '</label>' +
784
+ '<select id="createTemplate">' +
785
+ '<option value="default">' + t('claude.templateDefault') + '</option>' +
786
+ '<option value="minimal">' + t('claude.templateMinimal') + '</option>' +
787
+ '<option value="comprehensive">' + t('claude.templateComprehensive') + '</option>' +
788
+ '</select>' +
789
+ '</div>' +
790
+ '<div class="dialog-buttons">' +
791
+ '<button onclick="closeCreateDialog()" class="btn btn-sm btn-secondary">' + t('common.cancel') + '</button>' +
792
+ '<button onclick="createNewFile()" class="btn btn-sm btn-primary">' + t('claude.createFile') + '</button>' +
793
+ '</div>' +
794
+ '</div>' +
795
+ '</div>';
796
+
797
+ document.body.insertAdjacentHTML('beforeend', dialog);
798
+ if (window.lucide) lucide.createIcons();
799
+ }
800
+
801
+ function closeCreateDialog() {
802
+ var overlay = document.querySelector('.modal-overlay');
803
+ if (overlay) overlay.remove();
804
+ }
805
+
806
+ function toggleModulePathInput(level) {
807
+ var pathLabel = document.getElementById('modulePathLabel');
808
+ var pathInput = document.getElementById('modulePath');
809
+
810
+ if (level === 'module') {
811
+ pathLabel.style.display = 'block';
812
+ pathInput.style.display = 'block';
813
+ } else {
814
+ pathLabel.style.display = 'none';
815
+ pathInput.style.display = 'none';
816
+ }
817
+ }
818
+
819
+ async function createNewFile() {
820
+ var level = document.getElementById('createLevel').value;
821
+ var template = document.getElementById('createTemplate').value;
822
+ var modulePath = document.getElementById('modulePath').value;
823
+
824
+ if (level === 'module' && !modulePath) {
825
+ addGlobalNotification('error', t('claude.modulePathRequired') || 'Module path is required', null, 'CLAUDE.md');
826
+ return;
827
+ }
828
+
829
+ try {
830
+ var res = await fetch('/api/memory/claude/create', {
831
+ method: 'POST',
832
+ headers: { 'Content-Type': 'application/json' },
833
+ body: JSON.stringify({
834
+ level: level,
835
+ path: modulePath || undefined,
836
+ template: template
837
+ })
838
+ });
839
+
840
+ if (!res.ok) throw new Error('Failed to create file');
841
+
842
+ var result = await res.json();
843
+ closeCreateDialog();
844
+ addGlobalNotification('success', t('claude.fileCreated') || 'File created successfully', null, 'CLAUDE.md');
845
+
846
+ // Refresh file tree
847
+ await refreshClaudeFiles();
848
+ } catch (error) {
849
+ console.error('Error creating file:', error);
850
+ addGlobalNotification('error', t('claude.createFileError') || 'Failed to create file', null, 'CLAUDE.md');
851
+ }
852
+ }
853
+
854
+ // ========== File Deletion Functions ==========
855
+ async function confirmDeleteFile() {
856
+ if (!selectedFile) return;
857
+
858
+ var confirmed = confirm(
859
+ (t('claude.deleteConfirm') || 'Are you sure you want to delete {file}?').replace('{file}', selectedFile.name) + '\n\n' +
860
+ 'Path: ' + selectedFile.path + '\n\n' +
861
+ (t('claude.deleteWarning') || 'This action cannot be undone.')
862
+ );
863
+
864
+ if (!confirmed) return;
865
+
866
+ try {
867
+ var res = await fetch('/api/memory/claude/file?path=' + encodeURIComponent(selectedFile.path) + '&confirm=true', {
868
+ method: 'DELETE'
869
+ });
870
+
871
+ if (!res.ok) throw new Error('Failed to delete file');
872
+
873
+ addGlobalNotification('success', t('claude.fileDeleted') || 'File deleted successfully', null, 'CLAUDE.md');
874
+ selectedFile = null;
875
+
876
+ // Refresh file tree
877
+ await refreshClaudeFiles();
878
+ } catch (error) {
879
+ console.error('Error deleting file:', error);
880
+ addGlobalNotification('error', t('claude.deleteFileError') || 'Failed to delete file', null, 'CLAUDE.md');
881
+ }
882
+ }
883
+
884
+ // ========== Copy Content Function ==========
885
+ function copyFileContent() {
886
+ if (!selectedFile || !selectedFile.content) return;
887
+
888
+ navigator.clipboard.writeText(selectedFile.content).then(function() {
889
+ addGlobalNotification('success', t('claude.contentCopied') || 'Content copied to clipboard', null, 'CLAUDE.md');
890
+ }).catch(function(error) {
891
+ console.error('Error copying content:', error);
892
+ addGlobalNotification('error', t('claude.copyError') || 'Failed to copy content', null, 'CLAUDE.md');
893
+ });
894
+ }
895
+
896
+ // ========== Utility Functions ==========
897
+ // Note: escapeHtml and formatDate are imported from utils.js
898
+
899
+ function formatFileSize(bytes) {
900
+ if (bytes < 1024) return bytes + ' B';
901
+ if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
902
+ return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
903
+ }
904
+
905
+ // Update navigation badge with total file count
906
+ function updateClaudeBadge() {
907
+ var badge = document.getElementById('badgeClaude');
908
+ if (badge && claudeFilesData && claudeFilesData.summary) {
909
+ var total = claudeFilesData.summary.totalFiles;
910
+ badge.textContent = total;
911
+ }
912
+ }