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.
- package/.claude/CLAUDE.md +10 -0
- package/.claude/agents/action-planning-agent.md +857 -778
- package/.claude/agents/cli-execution-agent.md +266 -269
- package/.claude/agents/cli-explore-agent.md +2 -2
- package/.claude/agents/cli-lite-planning-agent.md +142 -92
- package/.claude/agents/cli-planning-agent.md +4 -4
- package/.claude/agents/code-developer.md +7 -6
- package/.claude/agents/conceptual-planning-agent.md +2 -2
- package/.claude/agents/context-search-agent.md +31 -32
- package/.claude/agents/doc-generator.md +4 -4
- package/.claude/agents/memory-bridge.md +93 -93
- package/.claude/agents/test-context-search-agent.md +8 -7
- package/.claude/agents/test-fix-agent.md +7 -6
- package/.claude/commands/clean.md +516 -0
- package/.claude/commands/memory/compact.md +383 -0
- package/.claude/commands/memory/docs-full-cli.md +471 -471
- package/.claude/commands/memory/docs-related-cli.md +386 -386
- package/.claude/commands/memory/docs.md +615 -615
- package/.claude/commands/memory/load.md +5 -5
- package/.claude/commands/memory/tech-research-rules.md +310 -0
- package/.claude/commands/memory/update-full.md +332 -332
- package/.claude/commands/memory/workflow-skill-memory.md +4 -4
- package/.claude/commands/task/create.md +151 -151
- package/.claude/commands/version.md +254 -254
- package/.claude/commands/workflow/brainstorm/api-designer.md +587 -585
- package/.claude/commands/workflow/brainstorm/artifacts.md +1 -0
- package/.claude/commands/workflow/brainstorm/auto-parallel.md +443 -443
- package/.claude/commands/workflow/brainstorm/data-architect.md +220 -220
- package/.claude/commands/workflow/brainstorm/product-manager.md +200 -200
- package/.claude/commands/workflow/brainstorm/product-owner.md +200 -200
- package/.claude/commands/workflow/brainstorm/scrum-master.md +200 -200
- package/.claude/commands/workflow/brainstorm/subject-matter-expert.md +200 -200
- package/.claude/commands/workflow/brainstorm/system-architect.md +389 -387
- package/.claude/commands/workflow/brainstorm/ui-designer.md +221 -221
- package/.claude/commands/workflow/brainstorm/ux-expert.md +221 -221
- package/.claude/commands/workflow/debug.md +321 -0
- package/.claude/commands/workflow/execute.md +13 -0
- package/.claude/commands/workflow/init.md +165 -164
- package/.claude/commands/workflow/lite-execute.md +119 -13
- package/.claude/commands/workflow/lite-fix.md +623 -621
- package/.claude/commands/workflow/lite-plan.md +610 -592
- package/.claude/commands/workflow/plan.md +5 -5
- package/.claude/commands/workflow/review-module-cycle.md +2 -0
- package/.claude/commands/workflow/review-session-cycle.md +2 -0
- package/.claude/commands/workflow/review.md +297 -291
- package/.claude/commands/workflow/session/complete.md +153 -500
- package/.claude/commands/workflow/session/list.md +95 -95
- package/.claude/commands/workflow/session/resume.md +60 -60
- package/.claude/commands/workflow/session/start.md +199 -199
- package/.claude/commands/workflow/tdd-plan.md +3 -3
- package/.claude/commands/workflow/tdd-verify.md +23 -9
- package/.claude/commands/workflow/test-cycle-execute.md +2 -0
- package/.claude/commands/workflow/test-fix-gen.md +699 -699
- package/.claude/commands/workflow/tools/conflict-resolution.md +104 -18
- package/.claude/commands/workflow/tools/context-gather.md +436 -434
- package/.claude/commands/workflow/tools/task-generate-agent.md +490 -291
- package/.claude/commands/workflow/tools/task-generate-tdd.md +18 -10
- package/.claude/commands/workflow/tools/test-concept-enhanced.md +2 -1
- package/.claude/commands/workflow/tools/test-context-gather.md +1 -0
- package/.claude/commands/workflow/tools/test-task-generate.md +1 -0
- package/.claude/commands/workflow/ui-design/import-from-code.md +9 -6
- package/.claude/skills/command-guide/SKILL.md +5 -5
- package/.claude/skills/command-guide/index/all-commands.json +1 -1
- package/.claude/skills/command-guide/index/by-category.json +1 -1
- package/.claude/skills/command-guide/index/by-use-case.json +1 -1
- package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +857 -778
- package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +266 -269
- package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +2 -2
- package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +142 -92
- package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +4 -4
- package/.claude/skills/command-guide/reference/agents/code-developer.md +7 -6
- package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +2 -2
- package/.claude/skills/command-guide/reference/agents/context-search-agent.md +31 -32
- package/.claude/skills/command-guide/reference/agents/doc-generator.md +4 -4
- package/.claude/skills/command-guide/reference/agents/memory-bridge.md +93 -93
- package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +8 -7
- package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +7 -6
- package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -471
- package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -386
- package/.claude/skills/command-guide/reference/commands/memory/docs.md +17 -16
- package/.claude/skills/command-guide/reference/commands/memory/load.md +5 -5
- package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +194 -357
- package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -332
- package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +4 -4
- package/.claude/skills/command-guide/reference/commands/task/create.md +151 -151
- package/.claude/skills/command-guide/reference/commands/version.md +254 -254
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +585 -585
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +443 -443
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +220 -220
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +387 -387
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +221 -221
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +221 -221
- package/.claude/skills/command-guide/reference/commands/workflow/execute.md +25 -20
- package/.claude/skills/command-guide/reference/commands/workflow/init.md +164 -164
- package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +748 -686
- package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +664 -621
- package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +645 -592
- package/.claude/skills/command-guide/reference/commands/workflow/plan.md +5 -5
- package/.claude/skills/command-guide/reference/commands/workflow/review.md +25 -18
- package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +547 -500
- package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +45 -27
- package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +35 -19
- package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +90 -33
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +3 -3
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +23 -9
- package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +699 -699
- package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +103 -17
- package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -434
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +487 -291
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +17 -10
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +6 -6
- package/.claude/workflows/chinese-response.md +38 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-api.txt +122 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-components.txt +122 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-config.txt +89 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-core.txt +60 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-patterns.txt +70 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-testing.txt +81 -0
- package/.claude/workflows/cli-templates/prompts/rules/tech-rules-agent-prompt.txt +89 -0
- package/.claude/workflows/cli-templates/prompts/workflow/gemini-solution-design.txt +131 -131
- package/.claude/workflows/cli-templates/prompts/workflow/skill-conflict-patterns.txt +5 -9
- package/.claude/workflows/cli-templates/prompts/workflow/skill-lessons-learned.txt +5 -9
- package/.claude/workflows/cli-templates/protocols/analysis-protocol.md +112 -0
- package/.claude/workflows/cli-templates/protocols/write-protocol.md +201 -0
- package/.claude/workflows/cli-templates/schemas/conflict-resolution-schema.json +137 -0
- package/.claude/workflows/cli-templates/schemas/debug-log-json-schema.json +127 -0
- package/.claude/workflows/cli-templates/schemas/fix-plan-json-schema.json +25 -0
- package/.claude/workflows/cli-templates/schemas/plan-json-schema.json +25 -0
- package/.claude/workflows/cli-tools-usage.md +526 -0
- package/{CLAUDE.md → .claude/workflows/coding-philosophy.md} +24 -45
- package/.claude/workflows/context-tools.md +84 -0
- package/.claude/workflows/file-modification.md +64 -0
- package/.claude/workflows/tool-strategy.md +216 -79
- package/.claude/workflows/windows-platform.md +16 -0
- package/.claude/workflows/workflow-architecture.md +942 -942
- package/.codex/AGENTS.md +63 -330
- package/.codex/prompts/debug.md +318 -0
- package/.codex/prompts/execute.md +273 -0
- package/.codex/prompts/lite-execute.md +164 -0
- package/.codex/prompts/lite-plan.md +469 -0
- package/.codex/prompts.zip +0 -0
- package/.gemini/GEMINI.md +25 -164
- package/.qwen/QWEN.md +0 -139
- package/README.md +29 -9
- package/ccw/README.md +30 -6
- package/ccw/bin/ccw-mcp.js +7 -0
- package/ccw/bin/ccw.js +9 -9
- package/ccw/package.json +65 -47
- package/ccw/src/.workflow/.cli-history/history.db +0 -0
- package/ccw/src/.workflow/.cli-history/history.db-shm +0 -0
- package/ccw/src/.workflow/.cli-history/history.db-wal +0 -0
- package/ccw/src/cli.ts +244 -0
- package/ccw/src/commands/cli.ts +740 -0
- package/ccw/src/commands/core-memory.ts +770 -0
- package/ccw/src/commands/hook.ts +315 -0
- package/ccw/src/commands/install.ts +519 -0
- package/ccw/src/commands/{list.js → list.ts} +1 -1
- package/ccw/src/commands/memory.ts +1090 -0
- package/ccw/src/commands/{serve.js → serve.ts} +14 -5
- package/ccw/src/commands/session-path-resolver.ts +372 -0
- package/ccw/src/commands/session.ts +1141 -0
- package/ccw/src/commands/{stop.js → stop.ts} +16 -6
- package/ccw/src/commands/tool.ts +201 -0
- package/ccw/src/commands/{uninstall.js → uninstall.ts} +89 -40
- package/ccw/src/commands/{upgrade.js → upgrade.ts} +68 -23
- package/ccw/src/commands/{view.js → view.ts} +22 -8
- package/ccw/src/config/storage-paths.ts +670 -0
- package/ccw/src/core/cache-manager.ts +294 -0
- package/ccw/src/core/claude-freshness.ts +319 -0
- package/ccw/src/core/core-memory-store.ts +1528 -0
- package/ccw/src/core/{dashboard-generator-patch.js → dashboard-generator-patch.ts} +18 -0
- package/ccw/src/core/{dashboard-generator.js → dashboard-generator.ts} +69 -12
- package/ccw/src/core/data-aggregator.ts +584 -0
- package/ccw/src/core/history-importer.ts +625 -0
- package/ccw/src/core/{lite-scanner.js → lite-scanner-complete.ts} +162 -66
- package/ccw/src/core/lite-scanner.ts +469 -0
- package/ccw/src/core/{manifest.js → manifest.ts} +104 -34
- package/ccw/src/core/memory-embedder-bridge.ts +262 -0
- package/ccw/src/core/memory-store.ts +978 -0
- package/ccw/src/core/routes/ccw-routes.ts +96 -0
- package/ccw/src/core/routes/claude-routes.ts +1183 -0
- package/ccw/src/core/routes/cli-routes.ts +561 -0
- package/ccw/src/core/routes/codexlens-routes.ts +806 -0
- package/ccw/src/core/routes/core-memory-routes.ts +605 -0
- package/ccw/src/core/routes/files-routes.ts +428 -0
- package/ccw/src/core/routes/graph-routes.md +164 -0
- package/ccw/src/core/routes/graph-routes.ts +626 -0
- package/ccw/src/core/routes/help-routes.ts +308 -0
- package/ccw/src/core/routes/hooks-routes.ts +405 -0
- package/ccw/src/core/routes/mcp-routes.ts +1271 -0
- package/ccw/src/core/routes/mcp-routes.ts.backup +550 -0
- package/ccw/src/core/routes/mcp-templates-db.ts +268 -0
- package/ccw/src/core/routes/memory-routes.ts +1206 -0
- package/ccw/src/core/routes/rules-routes.ts +526 -0
- package/ccw/src/core/routes/session-routes.ts +467 -0
- package/ccw/src/core/routes/skills-routes.ts +599 -0
- package/ccw/src/core/routes/status-routes.ts +57 -0
- package/ccw/src/core/routes/system-routes.ts +427 -0
- package/ccw/src/core/server.ts +431 -0
- package/ccw/src/core/session-clustering-service.ts +1258 -0
- package/ccw/src/core/session-scanner.ts +283 -0
- package/ccw/src/core/websocket.ts +190 -0
- package/ccw/src/{index.js → index.ts} +1 -0
- package/ccw/src/mcp-server/index.ts +186 -0
- package/ccw/src/templates/assets/css/github-dark.min.css +10 -0
- package/ccw/src/templates/assets/css/github.min.css +10 -0
- package/ccw/src/templates/assets/js/cytoscape.min.js +32 -0
- package/ccw/src/templates/assets/js/d3.min.js +2 -0
- package/ccw/src/templates/assets/js/highlight.min.js +1244 -0
- package/ccw/src/templates/assets/js/lucide.min.js +12 -0
- package/ccw/src/templates/assets/js/marked.min.js +69 -0
- package/ccw/src/templates/assets/js/tailwind.js +83 -0
- package/ccw/src/templates/dashboard-css/01-base.css +11 -0
- package/ccw/src/templates/dashboard-css/02-session.css +22 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +10 -0
- package/ccw/src/templates/dashboard-css/06-cards.css +10 -4
- package/ccw/src/templates/dashboard-css/07-managers.css +1178 -7
- package/ccw/src/templates/dashboard-css/09-explorer.css +23 -12
- package/ccw/src/templates/dashboard-css/10-cli-status.css +337 -0
- package/ccw/src/templates/dashboard-css/11-cli-history.css +271 -0
- package/ccw/src/templates/dashboard-css/12-cli-legacy.css +796 -0
- package/ccw/src/templates/dashboard-css/13-cli-ccw.css +199 -0
- package/ccw/src/templates/dashboard-css/14-cli-modals.css +258 -0
- package/ccw/src/templates/dashboard-css/15-cli-endpoints.css +305 -0
- package/ccw/src/templates/dashboard-css/16-cli-session.css +241 -0
- package/ccw/src/templates/dashboard-css/17-cli-conversation.css +283 -0
- package/ccw/src/templates/dashboard-css/18-cli-settings.css +160 -0
- package/ccw/src/templates/dashboard-css/19-cli-native-session.css +496 -0
- package/ccw/src/templates/dashboard-css/20-cli-taskqueue.css +188 -0
- package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +310 -0
- package/ccw/src/templates/dashboard-css/22-cli-semantic.css +240 -0
- package/ccw/src/templates/dashboard-css/23-memory.css +2390 -0
- package/ccw/src/templates/dashboard-css/24-prompt-history.css +1089 -0
- package/ccw/src/templates/dashboard-css/25-skills-rules.css +326 -0
- package/ccw/src/templates/dashboard-css/26-claude-manager.css +908 -0
- package/ccw/src/templates/dashboard-css/27-graph-explorer.css +1678 -0
- package/ccw/src/templates/dashboard-css/28-mcp-manager.css +748 -0
- package/ccw/src/templates/dashboard-css/29-help.css +264 -0
- package/ccw/src/templates/dashboard-css/30-core-memory.css +1700 -0
- package/ccw/src/templates/dashboard-js/api.js +162 -142
- package/ccw/src/templates/dashboard-js/components/carousel.js +4 -4
- package/ccw/src/templates/dashboard-js/components/cli-history.js +876 -0
- package/ccw/src/templates/dashboard-js/components/cli-status.js +978 -0
- package/ccw/src/templates/dashboard-js/components/global-notifications.js +508 -219
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +1277 -282
- package/ccw/src/templates/dashboard-js/components/index-manager.js +302 -0
- package/ccw/src/templates/dashboard-js/components/mcp-manager.js +718 -27
- package/ccw/src/templates/dashboard-js/components/modals.js +66 -0
- package/ccw/src/templates/dashboard-js/components/navigation.js +80 -12
- package/ccw/src/templates/dashboard-js/components/notifications.js +758 -194
- package/ccw/src/templates/dashboard-js/components/storage-manager.js +478 -0
- package/ccw/src/templates/dashboard-js/components/tabs-other.js +157 -6
- package/ccw/src/templates/dashboard-js/components/task-queue-sidebar.js +716 -0
- package/ccw/src/templates/dashboard-js/help-i18n.js +272 -0
- package/ccw/src/templates/dashboard-js/i18n.js +2807 -0
- package/ccw/src/templates/dashboard-js/main.js +15 -0
- package/ccw/src/templates/dashboard-js/state.js +243 -42
- package/ccw/src/templates/dashboard-js/utils.js +47 -1
- package/ccw/src/templates/dashboard-js/views/claude-manager.js +912 -0
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +2272 -0
- package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +964 -0
- package/ccw/src/templates/dashboard-js/views/core-memory-clusters.js +503 -0
- package/ccw/src/templates/dashboard-js/views/core-memory.js +782 -0
- package/ccw/src/templates/dashboard-js/views/explorer.js +888 -852
- package/ccw/src/templates/dashboard-js/views/graph-explorer.js +1157 -0
- package/ccw/src/templates/dashboard-js/views/help.js +856 -0
- package/ccw/src/templates/dashboard-js/views/history.js +337 -0
- package/ccw/src/templates/dashboard-js/views/home.js +61 -15
- package/ccw/src/templates/dashboard-js/views/hook-manager.js +311 -43
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +204 -28
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +2187 -411
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js.backup +1729 -0
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js.new +928 -0
- package/ccw/src/templates/dashboard-js/views/memory.js +1221 -0
- package/ccw/src/templates/dashboard-js/views/prompt-history.js +713 -0
- package/ccw/src/templates/dashboard-js/views/rules-manager.js +828 -0
- package/ccw/src/templates/dashboard-js/views/session-detail.js +54 -53
- package/ccw/src/templates/dashboard-js/views/skills-manager.js +819 -0
- package/ccw/src/templates/dashboard.html +185 -85
- package/ccw/src/templates/hooks-config-example.json +60 -0
- package/ccw/src/tools/classify-folders.ts +245 -0
- package/ccw/src/tools/cli-config-manager.ts +268 -0
- package/ccw/src/tools/cli-executor.ts +2014 -0
- package/ccw/src/tools/cli-history-store.ts +1195 -0
- package/ccw/src/tools/codex-lens.ts +1141 -0
- package/ccw/src/tools/{convert-tokens-to-css.js → convert-tokens-to-css.ts} +73 -23
- package/ccw/src/tools/core-memory.ts +444 -0
- package/ccw/src/tools/detect-changed-modules.ts +325 -0
- package/ccw/src/tools/{discover-design-files.js → discover-design-files.ts} +74 -24
- package/ccw/src/tools/edit-file.ts +568 -0
- package/ccw/src/tools/{generate-module-docs.js → generate-module-docs.ts} +207 -185
- package/ccw/src/tools/{get-modules-by-depth.js → get-modules-by-depth.ts} +120 -79
- package/ccw/src/tools/index.ts +370 -0
- package/ccw/src/tools/native-session-discovery.ts +795 -0
- package/ccw/src/tools/notifier.ts +129 -0
- package/ccw/src/tools/read-file.ts +410 -0
- package/ccw/src/tools/resume-strategy.ts +345 -0
- package/ccw/src/tools/session-content-parser.ts +619 -0
- package/ccw/src/tools/session-manager.ts +1026 -0
- package/ccw/src/tools/smart-context.ts +228 -0
- package/ccw/src/tools/smart-search.ts +2065 -0
- package/ccw/src/tools/smart-search.ts.backup +1233 -0
- package/ccw/src/tools/storage-manager.ts +455 -0
- package/ccw/src/tools/write-file.ts +222 -0
- package/ccw/src/types/config.ts +11 -0
- package/ccw/src/types/index.ts +3 -0
- package/ccw/src/types/session.ts +25 -0
- package/ccw/src/types/tool.ts +41 -0
- package/ccw/src/utils/{browser-launcher.js → browser-launcher.ts} +10 -8
- package/ccw/src/utils/file-utils.ts +48 -0
- package/ccw/src/utils/{path-resolver.js → path-resolver.ts} +114 -78
- package/ccw/src/utils/path-validator.ts +153 -0
- package/ccw/src/utils/{ui.js → ui.ts} +32 -25
- package/codex-lens/pyproject.toml +48 -0
- package/codex-lens/src/codexlens/.workflow/.cli-history/history.db +0 -0
- package/codex-lens/src/codexlens/__init__.py +28 -0
- package/codex-lens/src/codexlens/__main__.py +14 -0
- package/codex-lens/src/codexlens/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/__main__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/errors.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__init__.py +27 -0
- package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/commands.py +1931 -0
- package/codex-lens/src/codexlens/cli/embedding_manager.py +620 -0
- package/codex-lens/src/codexlens/cli/model_manager.py +289 -0
- package/codex-lens/src/codexlens/cli/output.py +124 -0
- package/codex-lens/src/codexlens/config.py +201 -0
- package/codex-lens/src/codexlens/entities.py +121 -0
- package/codex-lens/src/codexlens/errors.py +55 -0
- package/codex-lens/src/codexlens/indexing/README.md +77 -0
- package/codex-lens/src/codexlens/indexing/__init__.py +4 -0
- package/codex-lens/src/codexlens/indexing/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/symbol_extractor.py +243 -0
- package/codex-lens/src/codexlens/parsers/__init__.py +8 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/encoding.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/encoding.py +202 -0
- package/codex-lens/src/codexlens/parsers/factory.py +256 -0
- package/codex-lens/src/codexlens/parsers/tokenizer.py +98 -0
- package/codex-lens/src/codexlens/parsers/treesitter_parser.py +335 -0
- package/codex-lens/src/codexlens/search/__init__.py +15 -0
- package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/enrichment.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/query_parser.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/chain_search.py +647 -0
- package/codex-lens/src/codexlens/search/enrichment.py +150 -0
- package/codex-lens/src/codexlens/search/hybrid_search.py +313 -0
- package/codex-lens/src/codexlens/search/query_parser.py +242 -0
- package/codex-lens/src/codexlens/search/ranking.py +274 -0
- package/codex-lens/src/codexlens/semantic/__init__.py +39 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/code_extractor.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/graph_analyzer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/llm_enhancer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/ann_index.py +414 -0
- package/codex-lens/src/codexlens/semantic/chunker.py +448 -0
- package/codex-lens/src/codexlens/semantic/code_extractor.py +274 -0
- package/codex-lens/src/codexlens/semantic/embedder.py +185 -0
- package/codex-lens/src/codexlens/semantic/vector_store.py +955 -0
- package/codex-lens/src/codexlens/storage/__init__.py +29 -0
- package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/file_cache.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/migration_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/dir_index.py +1850 -0
- package/codex-lens/src/codexlens/storage/file_cache.py +32 -0
- package/codex-lens/src/codexlens/storage/index_tree.py +776 -0
- package/codex-lens/src/codexlens/storage/migration_manager.py +154 -0
- package/codex-lens/src/codexlens/storage/migrations/__init__.py +1 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_001_normalize_keywords.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_002_add_token_metadata.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_003_code_relationships.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_004_dual_fts.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_005_cleanup_unused_fields.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_001_normalize_keywords.py +123 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_002_add_token_metadata.py +48 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_004_dual_fts.py +232 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_005_cleanup_unused_fields.py +196 -0
- package/codex-lens/src/codexlens/storage/path_mapper.py +274 -0
- package/codex-lens/src/codexlens/storage/registry.py +670 -0
- package/codex-lens/src/codexlens/storage/sqlite_store.py +576 -0
- package/codex-lens/src/codexlens/storage/sqlite_utils.py +64 -0
- package/package.json +4 -1
- package/.claude/commands/memory/tech-research.md +0 -477
- package/.claude/scripts/classify-folders.sh +0 -39
- package/.claude/scripts/convert_tokens_to_css.sh +0 -229
- package/.claude/scripts/detect_changed_modules.sh +0 -161
- package/.claude/scripts/discover-design-files.sh +0 -87
- package/.claude/scripts/extract-animations.js +0 -243
- package/.claude/scripts/extract-computed-styles.js +0 -118
- package/.claude/scripts/extract-layout-structure.js +0 -411
- package/.claude/scripts/generate_module_docs.sh +0 -717
- package/.claude/scripts/get_modules_by_depth.sh +0 -170
- package/.claude/scripts/ui-generate-preview.sh +0 -395
- package/.claude/scripts/ui-instantiate-prototypes.sh +0 -815
- package/.claude/scripts/update_module_claude.sh +0 -337
- package/.claude/workflows/context-search-strategy.md +0 -77
- package/.claude/workflows/intelligent-tools-strategy.md +0 -662
- package/ccw/src/cli.js +0 -119
- package/ccw/src/commands/install.js +0 -324
- package/ccw/src/commands/tool.js +0 -138
- package/ccw/src/core/data-aggregator.js +0 -409
- package/ccw/src/core/server.js +0 -2063
- package/ccw/src/core/session-scanner.js +0 -235
- package/ccw/src/tools/classify-folders.js +0 -204
- package/ccw/src/tools/detect-changed-modules.js +0 -288
- package/ccw/src/tools/edit-file.js +0 -266
- package/ccw/src/tools/index.js +0 -176
- 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, "'");
|
|
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
|
+
}
|