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