claude-code-workflow 6.1.4 → 6.2.1
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/README.md +145 -274
- package/bin/ccw-mcp.js +7 -0
- package/bin/ccw.js +10 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +219 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/cli.d.ts +32 -0
- package/dist/commands/cli.d.ts.map +1 -0
- package/dist/commands/cli.js +619 -0
- package/dist/commands/cli.js.map +1 -0
- package/dist/commands/core-memory.d.ts +32 -0
- package/dist/commands/core-memory.d.ts.map +1 -0
- package/dist/commands/core-memory.js +640 -0
- package/dist/commands/core-memory.js.map +1 -0
- package/dist/commands/hook.d.ts +16 -0
- package/dist/commands/hook.d.ts.map +1 -0
- package/dist/commands/hook.js +276 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/install.d.ts +12 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +443 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/list.d.ts +5 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +32 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/memory.d.ts +57 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +890 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/serve.d.ts +12 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +63 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/session-path-resolver.d.ts +45 -0
- package/dist/commands/session-path-resolver.d.ts.map +1 -0
- package/dist/commands/session-path-resolver.js +302 -0
- package/dist/commands/session-path-resolver.js.map +1 -0
- package/dist/commands/session.d.ts +12 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +954 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/stop.d.ts +11 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +96 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/tool.d.ts +29 -0
- package/dist/commands/tool.d.ts.map +1 -0
- package/dist/commands/tool.js +173 -0
- package/dist/commands/tool.js.map +1 -0
- package/dist/commands/uninstall.d.ts +9 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +239 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/upgrade.d.ts +10 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +288 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/view.d.ts +14 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +100 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/config/storage-paths.d.ts +184 -0
- package/dist/config/storage-paths.d.ts.map +1 -0
- package/dist/config/storage-paths.js +536 -0
- package/dist/config/storage-paths.js.map +1 -0
- package/dist/core/cache-manager.d.ts +80 -0
- package/dist/core/cache-manager.d.ts.map +1 -0
- package/dist/core/cache-manager.js +260 -0
- package/dist/core/cache-manager.js.map +1 -0
- package/dist/core/claude-freshness.d.ts +53 -0
- package/dist/core/claude-freshness.d.ts.map +1 -0
- package/dist/core/claude-freshness.js +232 -0
- package/dist/core/claude-freshness.js.map +1 -0
- package/dist/core/core-memory-store.d.ts +320 -0
- package/dist/core/core-memory-store.d.ts.map +1 -0
- package/dist/core/core-memory-store.js +1177 -0
- package/dist/core/core-memory-store.js.map +1 -0
- package/dist/core/dashboard-generator-patch.d.ts +2 -0
- package/dist/core/dashboard-generator-patch.d.ts.map +1 -0
- package/dist/core/dashboard-generator-patch.js +48 -0
- package/dist/core/dashboard-generator-patch.js.map +1 -0
- package/dist/core/dashboard-generator.d.ts +8 -0
- package/dist/core/dashboard-generator.d.ts.map +1 -0
- package/dist/core/dashboard-generator.js +695 -0
- package/dist/core/dashboard-generator.js.map +1 -0
- package/dist/core/data-aggregator.d.ts +145 -0
- package/dist/core/data-aggregator.d.ts.map +1 -0
- package/dist/core/data-aggregator.js +416 -0
- package/dist/core/data-aggregator.js.map +1 -0
- package/dist/core/history-importer.d.ts +102 -0
- package/dist/core/history-importer.d.ts.map +1 -0
- package/dist/core/history-importer.js +493 -0
- package/dist/core/history-importer.js.map +1 -0
- package/dist/core/lite-scanner-complete.d.ts +81 -0
- package/dist/core/lite-scanner-complete.d.ts.map +1 -0
- package/dist/core/lite-scanner-complete.js +368 -0
- package/dist/core/lite-scanner-complete.js.map +1 -0
- package/dist/core/lite-scanner.d.ts +81 -0
- package/dist/core/lite-scanner.d.ts.map +1 -0
- package/dist/core/lite-scanner.js +368 -0
- package/dist/core/lite-scanner.js.map +1 -0
- package/dist/core/manifest.d.ts +88 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +214 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/core/memory-embedder-bridge.d.ts +83 -0
- package/dist/core/memory-embedder-bridge.d.ts.map +1 -0
- package/dist/core/memory-embedder-bridge.js +181 -0
- package/dist/core/memory-embedder-bridge.js.map +1 -0
- package/dist/core/memory-store.d.ts +249 -0
- package/dist/core/memory-store.d.ts.map +1 -0
- package/dist/core/memory-store.js +781 -0
- package/dist/core/memory-store.js.map +1 -0
- package/dist/core/routes/ccw-routes.d.ts +20 -0
- package/dist/core/routes/ccw-routes.d.ts.map +1 -0
- package/dist/core/routes/ccw-routes.js +70 -0
- package/dist/core/routes/ccw-routes.js.map +1 -0
- package/dist/core/routes/claude-routes.d.ts +19 -0
- package/dist/core/routes/claude-routes.d.ts.map +1 -0
- package/dist/core/routes/claude-routes.js +1017 -0
- package/dist/core/routes/claude-routes.js.map +1 -0
- package/dist/core/routes/cli-routes.d.ts +20 -0
- package/dist/core/routes/cli-routes.d.ts.map +1 -0
- package/dist/core/routes/cli-routes.js +468 -0
- package/dist/core/routes/cli-routes.js.map +1 -0
- package/dist/core/routes/codexlens-routes.d.ts +20 -0
- package/dist/core/routes/codexlens-routes.d.ts.map +1 -0
- package/dist/core/routes/codexlens-routes.js +754 -0
- package/dist/core/routes/codexlens-routes.js.map +1 -0
- package/dist/core/routes/core-memory-routes.d.ts +21 -0
- package/dist/core/routes/core-memory-routes.d.ts.map +1 -0
- package/dist/core/routes/core-memory-routes.js +520 -0
- package/dist/core/routes/core-memory-routes.js.map +1 -0
- package/dist/core/routes/files-routes.d.ts +20 -0
- package/dist/core/routes/files-routes.d.ts.map +1 -0
- package/dist/core/routes/files-routes.js +374 -0
- package/dist/core/routes/files-routes.js.map +1 -0
- package/dist/core/routes/graph-routes.d.ts +20 -0
- package/dist/core/routes/graph-routes.d.ts.map +1 -0
- package/dist/core/routes/graph-routes.js +517 -0
- package/dist/core/routes/graph-routes.js.map +1 -0
- package/dist/core/routes/help-routes.d.ts +20 -0
- package/dist/core/routes/help-routes.d.ts.map +1 -0
- package/dist/core/routes/help-routes.js +250 -0
- package/dist/core/routes/help-routes.js.map +1 -0
- package/dist/core/routes/hooks-routes.d.ts +21 -0
- package/dist/core/routes/hooks-routes.d.ts.map +1 -0
- package/dist/core/routes/hooks-routes.js +346 -0
- package/dist/core/routes/hooks-routes.js.map +1 -0
- package/dist/core/routes/mcp-routes.d.ts +20 -0
- package/dist/core/routes/mcp-routes.d.ts.map +1 -0
- package/dist/core/routes/mcp-routes.js +1129 -0
- package/dist/core/routes/mcp-routes.js.map +1 -0
- package/dist/core/routes/mcp-templates-db.d.ts +54 -0
- package/dist/core/routes/mcp-templates-db.d.ts.map +1 -0
- package/dist/core/routes/mcp-templates-db.js +226 -0
- package/dist/core/routes/mcp-templates-db.js.map +1 -0
- package/dist/core/routes/memory-routes.d.ts +21 -0
- package/dist/core/routes/memory-routes.d.ts.map +1 -0
- package/dist/core/routes/memory-routes.js +1095 -0
- package/dist/core/routes/memory-routes.js.map +1 -0
- package/dist/core/routes/rules-routes.d.ts +20 -0
- package/dist/core/routes/rules-routes.d.ts.map +1 -0
- package/dist/core/routes/rules-routes.js +442 -0
- package/dist/core/routes/rules-routes.js.map +1 -0
- package/dist/core/routes/session-routes.d.ts +20 -0
- package/dist/core/routes/session-routes.d.ts.map +1 -0
- package/dist/core/routes/session-routes.js +423 -0
- package/dist/core/routes/session-routes.js.map +1 -0
- package/dist/core/routes/skills-routes.d.ts +20 -0
- package/dist/core/routes/skills-routes.d.ts.map +1 -0
- package/dist/core/routes/skills-routes.js +533 -0
- package/dist/core/routes/skills-routes.js.map +1 -0
- package/dist/core/routes/status-routes.d.ts +20 -0
- package/dist/core/routes/status-routes.d.ts.map +1 -0
- package/dist/core/routes/status-routes.js +38 -0
- package/dist/core/routes/status-routes.js.map +1 -0
- package/dist/core/routes/system-routes.d.ts +22 -0
- package/dist/core/routes/system-routes.d.ts.map +1 -0
- package/dist/core/routes/system-routes.js +354 -0
- package/dist/core/routes/system-routes.js.map +1 -0
- package/dist/core/server.d.ts +17 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +386 -0
- package/dist/core/server.js.map +1 -0
- package/dist/core/session-clustering-service.d.ts +153 -0
- package/dist/core/session-clustering-service.d.ts.map +1 -0
- package/dist/core/session-clustering-service.js +1065 -0
- package/dist/core/session-clustering-service.js.map +1 -0
- package/dist/core/session-scanner.d.ts +32 -0
- package/dist/core/session-scanner.d.ts.map +1 -0
- package/dist/core/session-scanner.js +253 -0
- package/dist/core/session-scanner.js.map +1 -0
- package/dist/core/websocket.d.ts +23 -0
- package/dist/core/websocket.d.ts.map +1 -0
- package/dist/core/websocket.js +168 -0
- package/dist/core/websocket.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/index.d.ts +7 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +157 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/tools/classify-folders.d.ts +26 -0
- package/dist/tools/classify-folders.d.ts.map +1 -0
- package/dist/tools/classify-folders.js +201 -0
- package/dist/tools/classify-folders.js.map +1 -0
- package/dist/tools/cli-config-manager.d.ts +62 -0
- package/dist/tools/cli-config-manager.d.ts.map +1 -0
- package/dist/tools/cli-config-manager.js +221 -0
- package/dist/tools/cli-config-manager.js.map +1 -0
- package/dist/tools/cli-executor.d.ts +373 -0
- package/dist/tools/cli-executor.d.ts.map +1 -0
- package/dist/tools/cli-executor.js +1625 -0
- package/dist/tools/cli-executor.js.map +1 -0
- package/dist/tools/cli-history-store.d.ts +330 -0
- package/dist/tools/cli-history-store.d.ts.map +1 -0
- package/dist/tools/cli-history-store.js +916 -0
- package/dist/tools/cli-history-store.js.map +1 -0
- package/dist/tools/codex-lens.d.ts +118 -0
- package/dist/tools/codex-lens.d.ts.map +1 -0
- package/dist/tools/codex-lens.js +962 -0
- package/dist/tools/codex-lens.js.map +1 -0
- package/dist/tools/convert-tokens-to-css.d.ts +14 -0
- package/dist/tools/convert-tokens-to-css.d.ts.map +1 -0
- package/dist/tools/convert-tokens-to-css.js +244 -0
- package/dist/tools/convert-tokens-to-css.js.map +1 -0
- package/dist/tools/core-memory.d.ts +66 -0
- package/dist/tools/core-memory.d.ts.map +1 -0
- package/dist/tools/core-memory.js +324 -0
- package/dist/tools/core-memory.js.map +1 -0
- package/dist/tools/detect-changed-modules.d.ts +24 -0
- package/dist/tools/detect-changed-modules.d.ts.map +1 -0
- package/dist/tools/detect-changed-modules.js +277 -0
- package/dist/tools/detect-changed-modules.js.map +1 -0
- package/dist/tools/discover-design-files.d.ts +36 -0
- package/dist/tools/discover-design-files.d.ts.map +1 -0
- package/dist/tools/discover-design-files.js +147 -0
- package/dist/tools/discover-design-files.js.map +1 -0
- package/dist/tools/edit-file.d.ts +28 -0
- package/dist/tools/edit-file.d.ts.map +1 -0
- package/dist/tools/edit-file.js +479 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/generate-module-docs.d.ts +22 -0
- package/dist/tools/generate-module-docs.d.ts.map +1 -0
- package/dist/tools/generate-module-docs.js +379 -0
- package/dist/tools/generate-module-docs.js.map +1 -0
- package/dist/tools/get-modules-by-depth.d.ts +15 -0
- package/dist/tools/get-modules-by-depth.d.ts.map +1 -0
- package/dist/tools/get-modules-by-depth.js +296 -0
- package/dist/tools/get-modules-by-depth.js.map +1 -0
- package/dist/tools/index.d.ts +55 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +304 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/native-session-discovery.d.ts +97 -0
- package/dist/tools/native-session-discovery.d.ts.map +1 -0
- package/dist/tools/native-session-discovery.js +700 -0
- package/dist/tools/native-session-discovery.js.map +1 -0
- package/dist/tools/notifier.d.ts +50 -0
- package/dist/tools/notifier.d.ts.map +1 -0
- package/dist/tools/notifier.js +90 -0
- package/dist/tools/notifier.js.map +1 -0
- package/dist/tools/read-file.d.ts +32 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +329 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/resume-strategy.d.ts +48 -0
- package/dist/tools/resume-strategy.d.ts.map +1 -0
- package/dist/tools/resume-strategy.js +248 -0
- package/dist/tools/resume-strategy.js.map +1 -0
- package/dist/tools/session-content-parser.d.ts +58 -0
- package/dist/tools/session-content-parser.d.ts.map +1 -0
- package/dist/tools/session-content-parser.js +420 -0
- package/dist/tools/session-content-parser.js.map +1 -0
- package/dist/tools/session-manager.d.ts +9 -0
- package/dist/tools/session-manager.d.ts.map +1 -0
- package/dist/tools/session-manager.js +834 -0
- package/dist/tools/session-manager.js.map +1 -0
- package/dist/tools/smart-context.d.ts +35 -0
- package/dist/tools/smart-context.d.ts.map +1 -0
- package/dist/tools/smart-context.js +182 -0
- package/dist/tools/smart-context.js.map +1 -0
- package/dist/tools/smart-search.d.ts +105 -0
- package/dist/tools/smart-search.d.ts.map +1 -0
- package/dist/tools/smart-search.js +1753 -0
- package/dist/tools/smart-search.js.map +1 -0
- package/dist/tools/storage-manager.d.ts +114 -0
- package/dist/tools/storage-manager.d.ts.map +1 -0
- package/dist/tools/storage-manager.js +392 -0
- package/dist/tools/storage-manager.js.map +1 -0
- package/dist/tools/ui-generate-preview.d.ts +39 -0
- package/dist/tools/ui-generate-preview.d.ts.map +1 -0
- package/dist/tools/ui-generate-preview.js +300 -0
- package/dist/tools/ui-generate-preview.js.map +1 -0
- package/dist/tools/ui-instantiate-prototypes.d.ts +75 -0
- package/dist/tools/ui-instantiate-prototypes.d.ts.map +1 -0
- package/dist/tools/ui-instantiate-prototypes.js +256 -0
- package/dist/tools/ui-instantiate-prototypes.js.map +1 -0
- package/dist/tools/update-module-claude.d.ts +80 -0
- package/dist/tools/update-module-claude.d.ts.map +1 -0
- package/dist/tools/update-module-claude.js +351 -0
- package/dist/tools/update-module-claude.js.map +1 -0
- package/dist/tools/write-file.d.ts +19 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +193 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/types/config.d.ts +11 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/session.d.ts +20 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +2 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/tool.d.ts +36 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/tool.js +11 -0
- package/dist/types/tool.js.map +1 -0
- package/dist/utils/browser-launcher.d.ts +13 -0
- package/dist/utils/browser-launcher.d.ts.map +1 -0
- package/dist/utils/browser-launcher.js +60 -0
- package/dist/utils/browser-launcher.js.map +1 -0
- package/dist/utils/file-utils.d.ts +25 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +48 -0
- package/dist/utils/file-utils.js.map +1 -0
- package/dist/utils/path-resolver.d.ts +80 -0
- package/dist/utils/path-resolver.d.ts.map +1 -0
- package/dist/utils/path-resolver.js +260 -0
- package/dist/utils/path-resolver.js.map +1 -0
- package/dist/utils/path-validator.d.ts +49 -0
- package/dist/utils/path-validator.d.ts.map +1 -0
- package/dist/utils/path-validator.js +123 -0
- package/dist/utils/path-validator.js.map +1 -0
- package/dist/utils/ui.d.ts +62 -0
- package/dist/utils/ui.d.ts.map +1 -0
- package/dist/utils/ui.js +129 -0
- package/dist/utils/ui.js.map +1 -0
- package/package.json +32 -34
- package/src/.workflow/.cli-history/history.db +0 -0
- package/src/.workflow/.cli-history/history.db-shm +0 -0
- package/src/.workflow/.cli-history/history.db-wal +0 -0
- package/src/cli.ts +244 -0
- package/src/commands/cli.ts +740 -0
- package/src/commands/core-memory.ts +770 -0
- package/src/commands/hook.ts +315 -0
- package/src/commands/install.ts +519 -0
- package/src/commands/list.ts +37 -0
- package/src/commands/memory.ts +1090 -0
- package/src/commands/serve.ts +76 -0
- package/src/commands/session-path-resolver.ts +372 -0
- package/src/commands/session.ts +1141 -0
- package/src/commands/stop.ts +111 -0
- package/src/commands/tool.ts +201 -0
- package/src/commands/uninstall.ts +287 -0
- package/src/commands/upgrade.ts +352 -0
- package/src/commands/view.ts +119 -0
- package/src/config/storage-paths.ts +670 -0
- package/src/core/cache-manager.ts +294 -0
- package/src/core/claude-freshness.ts +319 -0
- package/src/core/core-memory-store.ts +1528 -0
- package/src/core/dashboard-generator-patch.ts +47 -0
- package/src/core/dashboard-generator.ts +739 -0
- package/src/core/data-aggregator.ts +584 -0
- package/src/core/history-importer.ts +625 -0
- package/src/core/lite-scanner-complete.ts +469 -0
- package/src/core/lite-scanner.ts +469 -0
- package/src/core/manifest.ts +271 -0
- package/src/core/memory-embedder-bridge.ts +262 -0
- package/src/core/memory-store.ts +978 -0
- package/src/core/routes/ccw-routes.ts +96 -0
- package/src/core/routes/claude-routes.ts +1183 -0
- package/src/core/routes/cli-routes.ts +561 -0
- package/src/core/routes/codexlens-routes.ts +806 -0
- package/src/core/routes/core-memory-routes.ts +605 -0
- package/src/core/routes/files-routes.ts +428 -0
- package/src/core/routes/graph-routes.md +164 -0
- package/src/core/routes/graph-routes.ts +626 -0
- package/src/core/routes/help-routes.ts +308 -0
- package/src/core/routes/hooks-routes.ts +405 -0
- package/src/core/routes/mcp-routes.ts +1271 -0
- package/src/core/routes/mcp-routes.ts.backup +550 -0
- package/src/core/routes/mcp-templates-db.ts +268 -0
- package/src/core/routes/memory-routes.ts +1206 -0
- package/src/core/routes/rules-routes.ts +526 -0
- package/src/core/routes/session-routes.ts +467 -0
- package/src/core/routes/skills-routes.ts +599 -0
- package/src/core/routes/status-routes.ts +57 -0
- package/src/core/routes/system-routes.ts +427 -0
- package/src/core/server.ts +431 -0
- package/src/core/session-clustering-service.ts +1258 -0
- package/src/core/session-scanner.ts +283 -0
- package/src/core/websocket.ts +190 -0
- package/src/index.ts +10 -0
- package/src/mcp-server/index.ts +186 -0
- package/src/templates/assets/css/github-dark.min.css +10 -0
- package/src/templates/assets/css/github.min.css +10 -0
- package/src/templates/assets/js/cytoscape.min.js +32 -0
- package/src/templates/assets/js/d3.min.js +2 -0
- package/src/templates/assets/js/highlight.min.js +1244 -0
- package/src/templates/assets/js/lucide.min.js +12 -0
- package/src/templates/assets/js/marked.min.js +69 -0
- package/src/templates/assets/js/tailwind.js +83 -0
- package/src/templates/dashboard-css/01-base.css +302 -0
- package/src/templates/dashboard-css/02-session.css +748 -0
- package/src/templates/dashboard-css/04-lite-tasks.css +1181 -0
- package/src/templates/dashboard-css/06-cards.css +1576 -0
- package/src/templates/dashboard-css/07-managers.css +2107 -0
- package/src/templates/dashboard-css/09-explorer.css +1408 -0
- package/src/templates/dashboard-css/10-cli-status.css +337 -0
- package/src/templates/dashboard-css/11-cli-history.css +271 -0
- package/src/templates/dashboard-css/12-cli-legacy.css +796 -0
- package/src/templates/dashboard-css/13-cli-ccw.css +199 -0
- package/src/templates/dashboard-css/14-cli-modals.css +258 -0
- package/src/templates/dashboard-css/15-cli-endpoints.css +305 -0
- package/src/templates/dashboard-css/16-cli-session.css +241 -0
- package/src/templates/dashboard-css/17-cli-conversation.css +283 -0
- package/src/templates/dashboard-css/18-cli-settings.css +160 -0
- package/src/templates/dashboard-css/19-cli-native-session.css +496 -0
- package/src/templates/dashboard-css/20-cli-taskqueue.css +188 -0
- package/src/templates/dashboard-css/21-cli-toolmgmt.css +310 -0
- package/src/templates/dashboard-css/22-cli-semantic.css +240 -0
- package/src/templates/dashboard-css/23-memory.css +2390 -0
- package/src/templates/dashboard-css/24-prompt-history.css +1089 -0
- package/src/templates/dashboard-css/25-skills-rules.css +326 -0
- package/src/templates/dashboard-css/26-claude-manager.css +908 -0
- package/src/templates/dashboard-css/27-graph-explorer.css +1678 -0
- package/src/templates/dashboard-css/28-mcp-manager.css +748 -0
- package/src/templates/dashboard-css/29-help.css +264 -0
- package/src/templates/dashboard-css/30-core-memory.css +1700 -0
- package/src/templates/dashboard-js/api.js +220 -0
- package/src/templates/dashboard-js/components/carousel.js +398 -0
- package/src/templates/dashboard-js/components/cli-history.js +876 -0
- package/src/templates/dashboard-js/components/cli-status.js +978 -0
- package/src/templates/dashboard-js/components/global-notifications.js +508 -0
- package/src/templates/dashboard-js/components/hook-manager.js +1278 -0
- package/src/templates/dashboard-js/components/index-manager.js +302 -0
- package/src/templates/dashboard-js/components/mcp-manager.js +1219 -0
- package/src/templates/dashboard-js/components/modals.js +326 -0
- package/src/templates/dashboard-js/components/navigation.js +313 -0
- package/src/templates/dashboard-js/components/notifications.js +758 -0
- package/src/templates/dashboard-js/components/storage-manager.js +478 -0
- package/src/templates/dashboard-js/components/tabs-other.js +424 -0
- package/src/templates/dashboard-js/components/task-queue-sidebar.js +716 -0
- package/src/templates/dashboard-js/help-i18n.js +272 -0
- package/src/templates/dashboard-js/i18n.js +2807 -0
- package/src/templates/dashboard-js/main.js +87 -0
- package/src/templates/dashboard-js/state.js +243 -0
- package/src/templates/dashboard-js/utils.js +199 -0
- package/src/templates/dashboard-js/views/claude-manager.js +912 -0
- package/src/templates/dashboard-js/views/cli-manager.js +2272 -0
- package/src/templates/dashboard-js/views/codexlens-manager.js +964 -0
- package/src/templates/dashboard-js/views/core-memory-clusters.js +503 -0
- package/src/templates/dashboard-js/views/core-memory.js +782 -0
- package/src/templates/dashboard-js/views/explorer.js +888 -0
- package/src/templates/dashboard-js/views/graph-explorer.js +1157 -0
- package/src/templates/dashboard-js/views/help.js +856 -0
- package/src/templates/dashboard-js/views/history.js +337 -0
- package/src/templates/dashboard-js/views/home.js +243 -0
- package/src/templates/dashboard-js/views/hook-manager.js +660 -0
- package/src/templates/dashboard-js/views/lite-tasks.js +861 -0
- package/src/templates/dashboard-js/views/mcp-manager.js +2187 -0
- package/src/templates/dashboard-js/views/mcp-manager.js.backup +1729 -0
- package/src/templates/dashboard-js/views/mcp-manager.js.new +928 -0
- package/src/templates/dashboard-js/views/memory.js +1221 -0
- package/src/templates/dashboard-js/views/prompt-history.js +713 -0
- package/src/templates/dashboard-js/views/rules-manager.js +828 -0
- package/src/templates/dashboard-js/views/session-detail.js +781 -0
- package/src/templates/dashboard-js/views/skills-manager.js +819 -0
- package/src/templates/dashboard.html +831 -0
- package/src/templates/hooks-config-example.json +60 -0
- package/src/tools/classify-folders.ts +245 -0
- package/src/tools/cli-config-manager.ts +268 -0
- package/src/tools/cli-executor.ts +2014 -0
- package/src/tools/cli-history-store.ts +1195 -0
- package/src/tools/codex-lens.ts +1141 -0
- package/src/tools/convert-tokens-to-css.ts +300 -0
- package/src/tools/core-memory.ts +444 -0
- package/src/tools/detect-changed-modules.ts +325 -0
- package/src/tools/discover-design-files.ts +184 -0
- package/src/tools/edit-file.ts +568 -0
- package/src/tools/generate-module-docs.ts +438 -0
- package/src/tools/get-modules-by-depth.ts +349 -0
- package/src/tools/index.ts +370 -0
- package/src/tools/native-session-discovery.ts +795 -0
- package/src/tools/notifier.ts +129 -0
- package/src/tools/read-file.ts +410 -0
- package/src/tools/resume-strategy.ts +345 -0
- package/src/tools/session-content-parser.ts +619 -0
- package/src/tools/session-manager.ts +1026 -0
- package/src/tools/smart-context.ts +228 -0
- package/src/tools/smart-search.ts +2065 -0
- package/src/tools/smart-search.ts.backup +1233 -0
- package/src/tools/storage-manager.ts +455 -0
- package/src/tools/write-file.ts +222 -0
- package/src/types/config.ts +11 -0
- package/src/types/index.ts +3 -0
- package/src/types/session.ts +25 -0
- package/src/types/tool.ts +41 -0
- package/src/utils/browser-launcher.ts +62 -0
- package/src/utils/file-utils.ts +48 -0
- package/src/utils/path-resolver.ts +315 -0
- package/src/utils/path-validator.ts +153 -0
- package/src/utils/ui.ts +155 -0
- package/.claude/agents/action-planning-agent.md +0 -778
- package/.claude/agents/cli-execution-agent.md +0 -270
- package/.claude/agents/cli-explore-agent.md +0 -182
- package/.claude/agents/cli-lite-planning-agent.md +0 -396
- package/.claude/agents/cli-planning-agent.md +0 -558
- package/.claude/agents/code-developer.md +0 -310
- package/.claude/agents/conceptual-planning-agent.md +0 -308
- package/.claude/agents/context-search-agent.md +0 -582
- package/.claude/agents/doc-generator.md +0 -330
- package/.claude/agents/memory-bridge.md +0 -94
- package/.claude/agents/test-context-search-agent.md +0 -399
- package/.claude/agents/test-fix-agent.md +0 -343
- package/.claude/agents/ui-design-agent.md +0 -593
- package/.claude/agents/universal-executor.md +0 -131
- package/.claude/commands/cli/cli-init.md +0 -440
- package/.claude/commands/enhance-prompt.md +0 -93
- package/.claude/commands/memory/code-map-memory.md +0 -687
- package/.claude/commands/memory/docs-full-cli.md +0 -471
- package/.claude/commands/memory/docs-related-cli.md +0 -386
- package/.claude/commands/memory/docs.md +0 -615
- package/.claude/commands/memory/load-skill-memory.md +0 -182
- package/.claude/commands/memory/load.md +0 -240
- package/.claude/commands/memory/skill-memory.md +0 -525
- package/.claude/commands/memory/style-skill-memory.md +0 -396
- package/.claude/commands/memory/tech-research.md +0 -477
- package/.claude/commands/memory/update-full.md +0 -332
- package/.claude/commands/memory/update-related.md +0 -332
- package/.claude/commands/memory/workflow-skill-memory.md +0 -517
- package/.claude/commands/task/breakdown.md +0 -204
- package/.claude/commands/task/create.md +0 -152
- package/.claude/commands/task/execute.md +0 -270
- package/.claude/commands/task/replan.md +0 -437
- package/.claude/commands/version.md +0 -254
- package/.claude/commands/workflow/action-plan-verify.md +0 -447
- package/.claude/commands/workflow/brainstorm/api-designer.md +0 -585
- package/.claude/commands/workflow/brainstorm/artifacts.md +0 -452
- package/.claude/commands/workflow/brainstorm/auto-parallel.md +0 -443
- package/.claude/commands/workflow/brainstorm/data-architect.md +0 -220
- package/.claude/commands/workflow/brainstorm/product-manager.md +0 -200
- package/.claude/commands/workflow/brainstorm/product-owner.md +0 -200
- package/.claude/commands/workflow/brainstorm/scrum-master.md +0 -200
- package/.claude/commands/workflow/brainstorm/subject-matter-expert.md +0 -200
- package/.claude/commands/workflow/brainstorm/synthesis.md +0 -398
- package/.claude/commands/workflow/brainstorm/system-architect.md +0 -387
- package/.claude/commands/workflow/brainstorm/ui-designer.md +0 -221
- package/.claude/commands/workflow/brainstorm/ux-expert.md +0 -221
- package/.claude/commands/workflow/execute.md +0 -462
- package/.claude/commands/workflow/init.md +0 -164
- package/.claude/commands/workflow/lite-execute.md +0 -686
- package/.claude/commands/workflow/lite-fix.md +0 -621
- package/.claude/commands/workflow/lite-plan.md +0 -592
- package/.claude/commands/workflow/plan.md +0 -551
- package/.claude/commands/workflow/replan.md +0 -515
- package/.claude/commands/workflow/review-fix.md +0 -606
- package/.claude/commands/workflow/review-module-cycle.md +0 -765
- package/.claude/commands/workflow/review-session-cycle.md +0 -776
- package/.claude/commands/workflow/review.md +0 -291
- package/.claude/commands/workflow/session/complete.md +0 -500
- package/.claude/commands/workflow/session/list.md +0 -96
- package/.claude/commands/workflow/session/resume.md +0 -61
- package/.claude/commands/workflow/session/start.md +0 -200
- package/.claude/commands/workflow/tdd-plan.md +0 -460
- package/.claude/commands/workflow/tdd-verify.md +0 -386
- package/.claude/commands/workflow/test-cycle-execute.md +0 -498
- package/.claude/commands/workflow/test-fix-gen.md +0 -699
- package/.claude/commands/workflow/test-gen.md +0 -529
- package/.claude/commands/workflow/tools/conflict-resolution.md +0 -680
- package/.claude/commands/workflow/tools/context-gather.md +0 -434
- package/.claude/commands/workflow/tools/task-generate-agent.md +0 -291
- package/.claude/commands/workflow/tools/task-generate-tdd.md +0 -518
- package/.claude/commands/workflow/tools/tdd-coverage-analysis.md +0 -309
- package/.claude/commands/workflow/tools/test-concept-enhanced.md +0 -163
- package/.claude/commands/workflow/tools/test-context-gather.md +0 -235
- package/.claude/commands/workflow/tools/test-task-generate.md +0 -256
- package/.claude/commands/workflow/ui-design/animation-extract.md +0 -1150
- package/.claude/commands/workflow/ui-design/codify-style.md +0 -652
- package/.claude/commands/workflow/ui-design/design-sync.md +0 -454
- package/.claude/commands/workflow/ui-design/explore-auto.md +0 -678
- package/.claude/commands/workflow/ui-design/generate.md +0 -504
- package/.claude/commands/workflow/ui-design/imitate-auto.md +0 -745
- package/.claude/commands/workflow/ui-design/import-from-code.md +0 -537
- package/.claude/commands/workflow/ui-design/layout-extract.md +0 -788
- package/.claude/commands/workflow/ui-design/reference-page-generator.md +0 -356
- package/.claude/commands/workflow/ui-design/style-extract.md +0 -773
- 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/skills/command-guide/SKILL.md +0 -388
- package/.claude/skills/command-guide/UPDATE-GUIDELINE.md +0 -592
- package/.claude/skills/command-guide/guides/cli-tools-guide.md +0 -410
- package/.claude/skills/command-guide/guides/examples.md +0 -537
- package/.claude/skills/command-guide/guides/getting-started.md +0 -242
- package/.claude/skills/command-guide/guides/implementation-details.md +0 -1010
- package/.claude/skills/command-guide/guides/index-structure.md +0 -326
- package/.claude/skills/command-guide/guides/troubleshooting.md +0 -92
- package/.claude/skills/command-guide/guides/ui-design-workflow-guide.md +0 -316
- package/.claude/skills/command-guide/guides/workflow-patterns.md +0 -662
- package/.claude/skills/command-guide/index/all-commands.json +0 -772
- package/.claude/skills/command-guide/index/by-category.json +0 -800
- package/.claude/skills/command-guide/index/by-use-case.json +0 -786
- package/.claude/skills/command-guide/index/command-relationships.json +0 -307
- package/.claude/skills/command-guide/index/essential-commands.json +0 -112
- package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +0 -778
- package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +0 -270
- package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +0 -182
- package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +0 -396
- package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +0 -558
- package/.claude/skills/command-guide/reference/agents/code-developer.md +0 -310
- package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +0 -308
- package/.claude/skills/command-guide/reference/agents/context-search-agent.md +0 -582
- package/.claude/skills/command-guide/reference/agents/doc-generator.md +0 -330
- package/.claude/skills/command-guide/reference/agents/memory-bridge.md +0 -94
- package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +0 -399
- package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +0 -343
- package/.claude/skills/command-guide/reference/agents/ui-design-agent.md +0 -593
- package/.claude/skills/command-guide/reference/agents/universal-executor.md +0 -131
- package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +0 -440
- package/.claude/skills/command-guide/reference/commands/enhance-prompt.md +0 -93
- package/.claude/skills/command-guide/reference/commands/memory/code-map-memory.md +0 -687
- package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +0 -471
- package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +0 -386
- package/.claude/skills/command-guide/reference/commands/memory/docs.md +0 -615
- package/.claude/skills/command-guide/reference/commands/memory/load-skill-memory.md +0 -182
- package/.claude/skills/command-guide/reference/commands/memory/load.md +0 -240
- package/.claude/skills/command-guide/reference/commands/memory/skill-memory.md +0 -525
- package/.claude/skills/command-guide/reference/commands/memory/style-skill-memory.md +0 -396
- package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +0 -477
- package/.claude/skills/command-guide/reference/commands/memory/update-full.md +0 -332
- package/.claude/skills/command-guide/reference/commands/memory/update-related.md +0 -332
- package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +0 -517
- package/.claude/skills/command-guide/reference/commands/task/breakdown.md +0 -204
- package/.claude/skills/command-guide/reference/commands/task/create.md +0 -152
- package/.claude/skills/command-guide/reference/commands/task/execute.md +0 -270
- package/.claude/skills/command-guide/reference/commands/task/replan.md +0 -437
- package/.claude/skills/command-guide/reference/commands/version.md +0 -254
- package/.claude/skills/command-guide/reference/commands/workflow/action-plan-verify.md +0 -447
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +0 -585
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +0 -452
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +0 -443
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +0 -220
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +0 -398
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +0 -387
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +0 -221
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +0 -221
- package/.claude/skills/command-guide/reference/commands/workflow/execute.md +0 -460
- package/.claude/skills/command-guide/reference/commands/workflow/init.md +0 -164
- package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +0 -686
- package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +0 -621
- package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +0 -592
- package/.claude/skills/command-guide/reference/commands/workflow/plan.md +0 -551
- package/.claude/skills/command-guide/reference/commands/workflow/replan.md +0 -515
- package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +0 -606
- package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +0 -765
- package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +0 -776
- package/.claude/skills/command-guide/reference/commands/workflow/review.md +0 -291
- package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +0 -500
- package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +0 -96
- package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +0 -61
- package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +0 -200
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +0 -460
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +0 -386
- package/.claude/skills/command-guide/reference/commands/workflow/test-cycle-execute.md +0 -498
- package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +0 -699
- package/.claude/skills/command-guide/reference/commands/workflow/test-gen.md +0 -529
- package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +0 -680
- package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +0 -434
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +0 -291
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +0 -518
- package/.claude/skills/command-guide/reference/commands/workflow/tools/tdd-coverage-analysis.md +0 -309
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +0 -163
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-context-gather.md +0 -235
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +0 -256
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/animation-extract.md +0 -1150
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/codify-style.md +0 -652
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/design-sync.md +0 -454
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/explore-auto.md +0 -678
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +0 -504
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/imitate-auto.md +0 -745
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +0 -537
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/layout-extract.md +0 -788
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/reference-page-generator.md +0 -356
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/style-extract.md +0 -773
- package/.claude/skills/command-guide/scripts/analyze_commands.py +0 -502
- package/.claude/skills/command-guide/scripts/update-index.sh +0 -130
- package/.claude/skills/command-guide/templates/issue-bug.md +0 -104
- package/.claude/skills/command-guide/templates/issue-diagnosis.md +0 -275
- package/.claude/skills/command-guide/templates/issue-feature.md +0 -97
- package/.claude/skills/command-guide/templates/issue-question.md +0 -141
- package/.claude/skills/prompt-enhancer/SKILL.md +0 -124
- package/.claude/workflows/_template-compare-matrix.html +0 -692
- package/.claude/workflows/cli-templates/fix-plan-template.json +0 -75
- package/.claude/workflows/cli-templates/fix-progress-template.json +0 -48
- package/.claude/workflows/cli-templates/memory/style-skill-memory/skill-md-template.md +0 -299
- package/.claude/workflows/cli-templates/planning-roles/data-architect.md +0 -120
- package/.claude/workflows/cli-templates/planning-roles/product-manager.md +0 -119
- package/.claude/workflows/cli-templates/planning-roles/product-owner.md +0 -261
- package/.claude/workflows/cli-templates/planning-roles/scrum-master.md +0 -186
- package/.claude/workflows/cli-templates/planning-roles/subject-matter-expert.md +0 -281
- package/.claude/workflows/cli-templates/planning-roles/synthesis-role.md +0 -414
- package/.claude/workflows/cli-templates/planning-roles/system-architect.md +0 -106
- package/.claude/workflows/cli-templates/planning-roles/test-strategist.md +0 -124
- package/.claude/workflows/cli-templates/planning-roles/ui-designer.md +0 -379
- package/.claude/workflows/cli-templates/planning-roles/ux-expert.md +0 -240
- package/.claude/workflows/cli-templates/prompts/analysis/01-diagnose-bug-root-cause.txt +0 -127
- package/.claude/workflows/cli-templates/prompts/analysis/01-trace-code-execution.txt +0 -115
- package/.claude/workflows/cli-templates/prompts/analysis/02-analyze-code-patterns.txt +0 -37
- package/.claude/workflows/cli-templates/prompts/analysis/02-analyze-technical-document.txt +0 -33
- package/.claude/workflows/cli-templates/prompts/analysis/02-review-architecture.txt +0 -29
- package/.claude/workflows/cli-templates/prompts/analysis/02-review-code-quality.txt +0 -28
- package/.claude/workflows/cli-templates/prompts/analysis/03-analyze-performance.txt +0 -29
- package/.claude/workflows/cli-templates/prompts/analysis/03-assess-security-risks.txt +0 -29
- package/.claude/workflows/cli-templates/prompts/analysis/03-review-quality-standards.txt +0 -29
- package/.claude/workflows/cli-templates/prompts/development/02-generate-tests.txt +0 -70
- package/.claude/workflows/cli-templates/prompts/development/02-implement-component-ui.txt +0 -55
- package/.claude/workflows/cli-templates/prompts/development/02-implement-feature.txt +0 -58
- package/.claude/workflows/cli-templates/prompts/development/02-refactor-codebase.txt +0 -55
- package/.claude/workflows/cli-templates/prompts/development/03-debug-runtime-issues.txt +0 -55
- package/.claude/workflows/cli-templates/prompts/documentation/api.txt +0 -15
- package/.claude/workflows/cli-templates/prompts/documentation/folder-navigation.txt +0 -27
- package/.claude/workflows/cli-templates/prompts/documentation/module-readme.txt +0 -49
- package/.claude/workflows/cli-templates/prompts/documentation/project-architecture.txt +0 -41
- package/.claude/workflows/cli-templates/prompts/documentation/project-examples.txt +0 -35
- package/.claude/workflows/cli-templates/prompts/documentation/project-readme.txt +0 -35
- package/.claude/workflows/cli-templates/prompts/memory/02-document-module-structure.txt +0 -165
- package/.claude/workflows/cli-templates/prompts/planning/01-plan-architecture-design.txt +0 -109
- package/.claude/workflows/cli-templates/prompts/planning/02-breakdown-task-steps.txt +0 -30
- package/.claude/workflows/cli-templates/prompts/planning/02-design-component-spec.txt +0 -28
- package/.claude/workflows/cli-templates/prompts/planning/03-evaluate-concept-feasibility.txt +0 -127
- package/.claude/workflows/cli-templates/prompts/planning/03-plan-migration-strategy.txt +0 -30
- package/.claude/workflows/cli-templates/prompts/tech/tech-module-format.txt +0 -359
- package/.claude/workflows/cli-templates/prompts/tech/tech-skill-index.txt +0 -185
- package/.claude/workflows/cli-templates/prompts/test/test-concept-analysis.txt +0 -179
- package/.claude/workflows/cli-templates/prompts/universal/00-universal-creative-style.txt +0 -95
- package/.claude/workflows/cli-templates/prompts/universal/00-universal-rigorous-style.txt +0 -92
- package/.claude/workflows/cli-templates/prompts/verification/codex-technical.txt +0 -28
- package/.claude/workflows/cli-templates/prompts/verification/cross-validation.txt +0 -28
- package/.claude/workflows/cli-templates/prompts/verification/gemini-strategic.txt +0 -27
- package/.claude/workflows/cli-templates/prompts/workflow/analysis-results-structure.txt +0 -224
- package/.claude/workflows/cli-templates/prompts/workflow/codex-feasibility-validation.txt +0 -176
- package/.claude/workflows/cli-templates/prompts/workflow/gemini-solution-design.txt +0 -131
- package/.claude/workflows/cli-templates/prompts/workflow/impl-plan-template.txt +0 -286
- package/.claude/workflows/cli-templates/prompts/workflow/skill-aggregation.txt +0 -172
- package/.claude/workflows/cli-templates/prompts/workflow/skill-conflict-patterns.txt +0 -98
- package/.claude/workflows/cli-templates/prompts/workflow/skill-index.txt +0 -224
- package/.claude/workflows/cli-templates/prompts/workflow/skill-lessons-learned.txt +0 -98
- package/.claude/workflows/cli-templates/prompts/workflow/skill-sessions-timeline.txt +0 -53
- package/.claude/workflows/cli-templates/prompts/workflow/task-json-agent-mode.txt +0 -123
- package/.claude/workflows/cli-templates/prompts/workflow/task-json-cli-mode.txt +0 -182
- package/.claude/workflows/cli-templates/schemas/diagnosis-json-schema.json +0 -234
- package/.claude/workflows/cli-templates/schemas/explore-json-schema.json +0 -124
- package/.claude/workflows/cli-templates/schemas/fix-plan-json-schema.json +0 -273
- package/.claude/workflows/cli-templates/schemas/plan-json-schema.json +0 -219
- package/.claude/workflows/cli-templates/schemas/project-json-schema.json +0 -221
- package/.claude/workflows/cli-templates/schemas/review-deep-dive-results-schema.json +0 -82
- package/.claude/workflows/cli-templates/schemas/review-dimension-results-schema.json +0 -51
- package/.claude/workflows/cli-templates/tech-stacks/go-dev.md +0 -91
- package/.claude/workflows/cli-templates/tech-stacks/java-dev.md +0 -107
- package/.claude/workflows/cli-templates/tech-stacks/javascript-dev.md +0 -58
- package/.claude/workflows/cli-templates/tech-stacks/python-dev.md +0 -79
- package/.claude/workflows/cli-templates/tech-stacks/react-dev.md +0 -103
- package/.claude/workflows/cli-templates/tech-stacks/typescript-dev.md +0 -83
- package/.claude/workflows/cli-templates/ui-design/systems/animation-tokens.json +0 -247
- package/.claude/workflows/cli-templates/ui-design/systems/design-tokens.json +0 -342
- package/.claude/workflows/cli-templates/ui-design/systems/layout-templates.json +0 -145
- package/.claude/workflows/context-search-strategy.md +0 -77
- package/.claude/workflows/intelligent-tools-strategy.md +0 -662
- package/.claude/workflows/review-directory-specification.md +0 -336
- package/.claude/workflows/task-core.md +0 -214
- package/.claude/workflows/tool-strategy.md +0 -79
- package/.claude/workflows/workflow-architecture.md +0 -942
- package/.codex/AGENTS.md +0 -330
- package/.gemini/GEMINI.md +0 -164
- package/.qwen/QWEN.md +0 -164
- package/CLAUDE.md +0 -91
- package/LICENSE +0 -21
- package/ccw/README.md +0 -121
- package/ccw/bin/ccw.js +0 -10
- package/ccw/package.json +0 -47
- package/ccw/src/cli.js +0 -119
- package/ccw/src/commands/install.js +0 -324
- package/ccw/src/commands/list.js +0 -37
- package/ccw/src/commands/serve.js +0 -67
- package/ccw/src/commands/stop.js +0 -101
- package/ccw/src/commands/tool.js +0 -138
- package/ccw/src/commands/uninstall.js +0 -238
- package/ccw/src/commands/upgrade.js +0 -307
- package/ccw/src/commands/view.js +0 -105
- package/ccw/src/core/dashboard-generator-patch.js +0 -29
- package/ccw/src/core/dashboard-generator.js +0 -682
- package/ccw/src/core/data-aggregator.js +0 -409
- package/ccw/src/core/lite-scanner.js +0 -373
- package/ccw/src/core/manifest.js +0 -201
- package/ccw/src/core/server.js +0 -2063
- package/ccw/src/core/session-scanner.js +0 -235
- package/ccw/src/index.js +0 -9
- package/ccw/src/templates/dashboard-css/01-base.css +0 -291
- package/ccw/src/templates/dashboard-css/02-session.css +0 -726
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +0 -1171
- package/ccw/src/templates/dashboard-css/06-cards.css +0 -1570
- package/ccw/src/templates/dashboard-css/07-managers.css +0 -936
- package/ccw/src/templates/dashboard-css/09-explorer.css +0 -1397
- package/ccw/src/templates/dashboard-js/api.js +0 -200
- package/ccw/src/templates/dashboard-js/components/carousel.js +0 -398
- package/ccw/src/templates/dashboard-js/components/global-notifications.js +0 -219
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +0 -283
- package/ccw/src/templates/dashboard-js/components/mcp-manager.js +0 -528
- package/ccw/src/templates/dashboard-js/components/modals.js +0 -260
- package/ccw/src/templates/dashboard-js/components/navigation.js +0 -245
- package/ccw/src/templates/dashboard-js/components/notifications.js +0 -194
- package/ccw/src/templates/dashboard-js/components/tabs-other.js +0 -273
- package/ccw/src/templates/dashboard-js/main.js +0 -72
- package/ccw/src/templates/dashboard-js/state.js +0 -42
- package/ccw/src/templates/dashboard-js/utils.js +0 -153
- package/ccw/src/templates/dashboard-js/views/explorer.js +0 -852
- package/ccw/src/templates/dashboard-js/views/home.js +0 -197
- package/ccw/src/templates/dashboard-js/views/hook-manager.js +0 -392
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +0 -685
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +0 -411
- package/ccw/src/templates/dashboard-js/views/session-detail.js +0 -780
- package/ccw/src/templates/dashboard.html +0 -731
- package/ccw/src/tools/classify-folders.js +0 -204
- package/ccw/src/tools/convert-tokens-to-css.js +0 -250
- package/ccw/src/tools/detect-changed-modules.js +0 -288
- package/ccw/src/tools/discover-design-files.js +0 -134
- package/ccw/src/tools/edit-file.js +0 -266
- package/ccw/src/tools/generate-module-docs.js +0 -416
- package/ccw/src/tools/get-modules-by-depth.js +0 -308
- package/ccw/src/tools/index.js +0 -176
- package/ccw/src/utils/browser-launcher.js +0 -60
- package/ccw/src/utils/file-utils.js +0 -48
- package/ccw/src/utils/path-resolver.js +0 -279
- package/ccw/src/utils/ui.js +0 -148
- /package/{ccw/src → src}/templates/dashboard-css/03-tasks.css +0 -0
- /package/{ccw/src → src}/templates/dashboard-css/05-context.css +0 -0
- /package/{ccw/src → src}/templates/dashboard-css/08-review.css +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/_conflict_tab.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/_exp_helpers.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/_review_tab.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/flowchart.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/sidebar.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/tabs-context.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/task-drawer-core.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/task-drawer-renderers.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/theme.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/components/version-check.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/views/fix-session.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/views/project-overview.js +0 -0
- /package/{ccw/src → src}/templates/dashboard-js/views/review-session.js +0 -0
- /package/{ccw/src → src}/templates/review-cycle-dashboard.html +0 -0
- /package/{ccw/src → src}/templates/workflow-dashboard.html +0 -0
- /package/{ccw/src → src}/tools/ui-generate-preview.js +0 -0
- /package/{ccw/src → src}/tools/ui-instantiate-prototypes.js +0 -0
- /package/{ccw/src → src}/tools/update-module-claude.js +0 -0
|
@@ -0,0 +1,1271 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* MCP Routes Module
|
|
4
|
+
* Handles all MCP-related API endpoints
|
|
5
|
+
*/
|
|
6
|
+
import type { IncomingMessage, ServerResponse } from 'http';
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'fs';
|
|
8
|
+
import { join, dirname } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
import * as McpTemplatesDb from './mcp-templates-db.js';
|
|
11
|
+
|
|
12
|
+
// Claude config file path
|
|
13
|
+
const CLAUDE_CONFIG_PATH = join(homedir(), '.claude.json');
|
|
14
|
+
|
|
15
|
+
// Codex config file path (TOML format)
|
|
16
|
+
const CODEX_CONFIG_PATH = join(homedir(), '.codex', 'config.toml');
|
|
17
|
+
|
|
18
|
+
// Workspace root path for scanning .mcp.json files
|
|
19
|
+
let WORKSPACE_ROOT = process.cwd();
|
|
20
|
+
|
|
21
|
+
// ========================================
|
|
22
|
+
// TOML Parser for Codex Config
|
|
23
|
+
// ========================================
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Simple TOML parser for Codex config.toml
|
|
27
|
+
* Supports basic types: strings, numbers, booleans, arrays, inline tables
|
|
28
|
+
*/
|
|
29
|
+
function parseToml(content: string): Record<string, any> {
|
|
30
|
+
const result: Record<string, any> = {};
|
|
31
|
+
let currentSection: string[] = [];
|
|
32
|
+
const lines = content.split('\n');
|
|
33
|
+
|
|
34
|
+
for (let i = 0; i < lines.length; i++) {
|
|
35
|
+
let line = lines[i].trim();
|
|
36
|
+
|
|
37
|
+
// Skip empty lines and comments
|
|
38
|
+
if (!line || line.startsWith('#')) continue;
|
|
39
|
+
|
|
40
|
+
// Handle section headers [section] or [section.subsection]
|
|
41
|
+
const sectionMatch = line.match(/^\[([^\]]+)\]$/);
|
|
42
|
+
if (sectionMatch) {
|
|
43
|
+
currentSection = sectionMatch[1].split('.');
|
|
44
|
+
// Ensure nested sections exist
|
|
45
|
+
let obj = result;
|
|
46
|
+
for (const part of currentSection) {
|
|
47
|
+
if (!obj[part]) obj[part] = {};
|
|
48
|
+
obj = obj[part];
|
|
49
|
+
}
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Handle key = value pairs
|
|
54
|
+
const keyValueMatch = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/);
|
|
55
|
+
if (keyValueMatch) {
|
|
56
|
+
const key = keyValueMatch[1];
|
|
57
|
+
const rawValue = keyValueMatch[2].trim();
|
|
58
|
+
const value = parseTomlValue(rawValue);
|
|
59
|
+
|
|
60
|
+
// Navigate to current section
|
|
61
|
+
let obj = result;
|
|
62
|
+
for (const part of currentSection) {
|
|
63
|
+
if (!obj[part]) obj[part] = {};
|
|
64
|
+
obj = obj[part];
|
|
65
|
+
}
|
|
66
|
+
obj[key] = value;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parse a TOML value
|
|
75
|
+
*/
|
|
76
|
+
function parseTomlValue(value: string): any {
|
|
77
|
+
// String (double-quoted)
|
|
78
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
79
|
+
return value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// String (single-quoted - literal)
|
|
83
|
+
if (value.startsWith("'") && value.endsWith("'")) {
|
|
84
|
+
return value.slice(1, -1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Boolean
|
|
88
|
+
if (value === 'true') return true;
|
|
89
|
+
if (value === 'false') return false;
|
|
90
|
+
|
|
91
|
+
// Number
|
|
92
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
93
|
+
return value.includes('.') ? parseFloat(value) : parseInt(value, 10);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Array
|
|
97
|
+
if (value.startsWith('[') && value.endsWith(']')) {
|
|
98
|
+
const inner = value.slice(1, -1).trim();
|
|
99
|
+
if (!inner) return [];
|
|
100
|
+
// Simple array parsing (handles basic cases)
|
|
101
|
+
const items: any[] = [];
|
|
102
|
+
let depth = 0;
|
|
103
|
+
let current = '';
|
|
104
|
+
let inString = false;
|
|
105
|
+
let stringChar = '';
|
|
106
|
+
|
|
107
|
+
for (const char of inner) {
|
|
108
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
109
|
+
inString = true;
|
|
110
|
+
stringChar = char;
|
|
111
|
+
current += char;
|
|
112
|
+
} else if (inString && char === stringChar) {
|
|
113
|
+
inString = false;
|
|
114
|
+
current += char;
|
|
115
|
+
} else if (!inString && (char === '[' || char === '{')) {
|
|
116
|
+
depth++;
|
|
117
|
+
current += char;
|
|
118
|
+
} else if (!inString && (char === ']' || char === '}')) {
|
|
119
|
+
depth--;
|
|
120
|
+
current += char;
|
|
121
|
+
} else if (!inString && char === ',' && depth === 0) {
|
|
122
|
+
items.push(parseTomlValue(current.trim()));
|
|
123
|
+
current = '';
|
|
124
|
+
} else {
|
|
125
|
+
current += char;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (current.trim()) {
|
|
129
|
+
items.push(parseTomlValue(current.trim()));
|
|
130
|
+
}
|
|
131
|
+
return items;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Inline table { key = value, ... }
|
|
135
|
+
if (value.startsWith('{') && value.endsWith('}')) {
|
|
136
|
+
const inner = value.slice(1, -1).trim();
|
|
137
|
+
if (!inner) return {};
|
|
138
|
+
const table: Record<string, any> = {};
|
|
139
|
+
// Simple inline table parsing
|
|
140
|
+
const pairs = inner.split(',');
|
|
141
|
+
for (const pair of pairs) {
|
|
142
|
+
const match = pair.trim().match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/);
|
|
143
|
+
if (match) {
|
|
144
|
+
table[match[1]] = parseTomlValue(match[2].trim());
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return table;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Return as string if nothing else matches
|
|
151
|
+
return value;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Serialize object to TOML format for Codex config
|
|
156
|
+
*
|
|
157
|
+
* Handles mixed objects containing both simple values and sub-objects.
|
|
158
|
+
* For example: { command: "cmd", args: [...], env: { KEY: "value" } }
|
|
159
|
+
* becomes:
|
|
160
|
+
* [section]
|
|
161
|
+
* command = "cmd"
|
|
162
|
+
* args = [...]
|
|
163
|
+
* [section.env]
|
|
164
|
+
* KEY = "value"
|
|
165
|
+
*/
|
|
166
|
+
function serializeToml(obj: Record<string, any>, prefix: string = ''): string {
|
|
167
|
+
let result = '';
|
|
168
|
+
|
|
169
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
170
|
+
if (value === null || value === undefined) continue;
|
|
171
|
+
|
|
172
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
173
|
+
// Handle nested sections (like mcp_servers.server_name)
|
|
174
|
+
const sectionKey = prefix ? `${prefix}.${key}` : key;
|
|
175
|
+
|
|
176
|
+
// Separate simple values from sub-objects
|
|
177
|
+
const simpleEntries: [string, any][] = [];
|
|
178
|
+
const objectEntries: [string, any][] = [];
|
|
179
|
+
|
|
180
|
+
for (const [subKey, subValue] of Object.entries(value)) {
|
|
181
|
+
if (subValue === null || subValue === undefined) continue;
|
|
182
|
+
if (typeof subValue === 'object' && !Array.isArray(subValue)) {
|
|
183
|
+
objectEntries.push([subKey, subValue]);
|
|
184
|
+
} else {
|
|
185
|
+
simpleEntries.push([subKey, subValue]);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Write section header if there are simple values
|
|
190
|
+
if (simpleEntries.length > 0) {
|
|
191
|
+
result += `\n[${sectionKey}]\n`;
|
|
192
|
+
for (const [subKey, subValue] of simpleEntries) {
|
|
193
|
+
result += `${subKey} = ${serializeTomlValue(subValue)}\n`;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Recursively handle sub-objects
|
|
198
|
+
if (objectEntries.length > 0) {
|
|
199
|
+
for (const [subKey, subValue] of objectEntries) {
|
|
200
|
+
const subSectionKey = `${sectionKey}.${subKey}`;
|
|
201
|
+
|
|
202
|
+
// Check if sub-object has nested objects
|
|
203
|
+
const hasNestedObjects = Object.values(subValue).some(
|
|
204
|
+
v => typeof v === 'object' && v !== null && !Array.isArray(v)
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
if (hasNestedObjects) {
|
|
208
|
+
// Recursively process nested objects
|
|
209
|
+
result += serializeToml({ [subKey]: subValue }, sectionKey);
|
|
210
|
+
} else {
|
|
211
|
+
// Write sub-section with simple values
|
|
212
|
+
result += `\n[${subSectionKey}]\n`;
|
|
213
|
+
for (const [nestedKey, nestedValue] of Object.entries(subValue)) {
|
|
214
|
+
if (nestedValue !== null && nestedValue !== undefined) {
|
|
215
|
+
result += `${nestedKey} = ${serializeTomlValue(nestedValue)}\n`;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// If no simple values but has object entries, still need to process
|
|
223
|
+
if (simpleEntries.length === 0 && objectEntries.length === 0) {
|
|
224
|
+
// Empty section - write header only
|
|
225
|
+
result += `\n[${sectionKey}]\n`;
|
|
226
|
+
}
|
|
227
|
+
} else if (!prefix) {
|
|
228
|
+
// Top-level simple values
|
|
229
|
+
result += `${key} = ${serializeTomlValue(value)}\n`;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Serialize a value to TOML format
|
|
238
|
+
*/
|
|
239
|
+
function serializeTomlValue(value: any): string {
|
|
240
|
+
if (typeof value === 'string') {
|
|
241
|
+
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
242
|
+
}
|
|
243
|
+
if (typeof value === 'boolean') {
|
|
244
|
+
return value ? 'true' : 'false';
|
|
245
|
+
}
|
|
246
|
+
if (typeof value === 'number') {
|
|
247
|
+
return String(value);
|
|
248
|
+
}
|
|
249
|
+
if (Array.isArray(value)) {
|
|
250
|
+
return `[${value.map(v => serializeTomlValue(v)).join(', ')}]`;
|
|
251
|
+
}
|
|
252
|
+
if (typeof value === 'object' && value !== null) {
|
|
253
|
+
const pairs = Object.entries(value)
|
|
254
|
+
.filter(([_, v]) => v !== null && v !== undefined)
|
|
255
|
+
.map(([k, v]) => `${k} = ${serializeTomlValue(v)}`);
|
|
256
|
+
return `{ ${pairs.join(', ')} }`;
|
|
257
|
+
}
|
|
258
|
+
return String(value);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// ========================================
|
|
262
|
+
// Codex MCP Functions
|
|
263
|
+
// ========================================
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Read Codex config.toml and extract MCP servers
|
|
267
|
+
*/
|
|
268
|
+
function getCodexMcpConfig(): { servers: Record<string, any>; configPath: string; exists: boolean } {
|
|
269
|
+
try {
|
|
270
|
+
if (!existsSync(CODEX_CONFIG_PATH)) {
|
|
271
|
+
return { servers: {}, configPath: CODEX_CONFIG_PATH, exists: false };
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const content = readFileSync(CODEX_CONFIG_PATH, 'utf8');
|
|
275
|
+
const config = parseToml(content);
|
|
276
|
+
|
|
277
|
+
// MCP servers are under [mcp_servers] section
|
|
278
|
+
const mcpServers = config.mcp_servers || {};
|
|
279
|
+
|
|
280
|
+
return {
|
|
281
|
+
servers: mcpServers,
|
|
282
|
+
configPath: CODEX_CONFIG_PATH,
|
|
283
|
+
exists: true
|
|
284
|
+
};
|
|
285
|
+
} catch (error: unknown) {
|
|
286
|
+
console.error('Error reading Codex config:', error);
|
|
287
|
+
return { servers: {}, configPath: CODEX_CONFIG_PATH, exists: false };
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Add or update MCP server in Codex config.toml
|
|
293
|
+
*/
|
|
294
|
+
function addCodexMcpServer(serverName: string, serverConfig: Record<string, any>): { success?: boolean; error?: string } {
|
|
295
|
+
try {
|
|
296
|
+
const codexDir = join(homedir(), '.codex');
|
|
297
|
+
|
|
298
|
+
// Ensure .codex directory exists
|
|
299
|
+
if (!existsSync(codexDir)) {
|
|
300
|
+
mkdirSync(codexDir, { recursive: true });
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
let config: Record<string, any> = {};
|
|
304
|
+
|
|
305
|
+
// Read existing config if it exists
|
|
306
|
+
if (existsSync(CODEX_CONFIG_PATH)) {
|
|
307
|
+
const content = readFileSync(CODEX_CONFIG_PATH, 'utf8');
|
|
308
|
+
config = parseToml(content);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Ensure mcp_servers section exists
|
|
312
|
+
if (!config.mcp_servers) {
|
|
313
|
+
config.mcp_servers = {};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Convert serverConfig from Claude format to Codex format
|
|
317
|
+
const codexServerConfig: Record<string, any> = {};
|
|
318
|
+
|
|
319
|
+
// Handle STDIO servers (command-based)
|
|
320
|
+
if (serverConfig.command) {
|
|
321
|
+
codexServerConfig.command = serverConfig.command;
|
|
322
|
+
if (serverConfig.args && serverConfig.args.length > 0) {
|
|
323
|
+
codexServerConfig.args = serverConfig.args;
|
|
324
|
+
}
|
|
325
|
+
if (serverConfig.env && Object.keys(serverConfig.env).length > 0) {
|
|
326
|
+
codexServerConfig.env = serverConfig.env;
|
|
327
|
+
}
|
|
328
|
+
if (serverConfig.cwd) {
|
|
329
|
+
codexServerConfig.cwd = serverConfig.cwd;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Handle HTTP servers (url-based)
|
|
334
|
+
if (serverConfig.url) {
|
|
335
|
+
codexServerConfig.url = serverConfig.url;
|
|
336
|
+
if (serverConfig.bearer_token_env_var) {
|
|
337
|
+
codexServerConfig.bearer_token_env_var = serverConfig.bearer_token_env_var;
|
|
338
|
+
}
|
|
339
|
+
if (serverConfig.http_headers) {
|
|
340
|
+
codexServerConfig.http_headers = serverConfig.http_headers;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Copy optional fields
|
|
345
|
+
if (serverConfig.startup_timeout_sec !== undefined) {
|
|
346
|
+
codexServerConfig.startup_timeout_sec = serverConfig.startup_timeout_sec;
|
|
347
|
+
}
|
|
348
|
+
if (serverConfig.tool_timeout_sec !== undefined) {
|
|
349
|
+
codexServerConfig.tool_timeout_sec = serverConfig.tool_timeout_sec;
|
|
350
|
+
}
|
|
351
|
+
if (serverConfig.enabled !== undefined) {
|
|
352
|
+
codexServerConfig.enabled = serverConfig.enabled;
|
|
353
|
+
}
|
|
354
|
+
if (serverConfig.enabled_tools) {
|
|
355
|
+
codexServerConfig.enabled_tools = serverConfig.enabled_tools;
|
|
356
|
+
}
|
|
357
|
+
if (serverConfig.disabled_tools) {
|
|
358
|
+
codexServerConfig.disabled_tools = serverConfig.disabled_tools;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Add the server
|
|
362
|
+
config.mcp_servers[serverName] = codexServerConfig;
|
|
363
|
+
|
|
364
|
+
// Serialize and write back
|
|
365
|
+
const tomlContent = serializeToml(config);
|
|
366
|
+
writeFileSync(CODEX_CONFIG_PATH, tomlContent, 'utf8');
|
|
367
|
+
|
|
368
|
+
return { success: true };
|
|
369
|
+
} catch (error: unknown) {
|
|
370
|
+
console.error('Error adding Codex MCP server:', error);
|
|
371
|
+
return { error: (error as Error).message };
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Remove MCP server from Codex config.toml
|
|
377
|
+
*/
|
|
378
|
+
function removeCodexMcpServer(serverName: string): { success?: boolean; error?: string } {
|
|
379
|
+
try {
|
|
380
|
+
if (!existsSync(CODEX_CONFIG_PATH)) {
|
|
381
|
+
return { error: 'Codex config.toml not found' };
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const content = readFileSync(CODEX_CONFIG_PATH, 'utf8');
|
|
385
|
+
const config = parseToml(content);
|
|
386
|
+
|
|
387
|
+
if (!config.mcp_servers || !config.mcp_servers[serverName]) {
|
|
388
|
+
return { error: `Server not found: ${serverName}` };
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Remove the server
|
|
392
|
+
delete config.mcp_servers[serverName];
|
|
393
|
+
|
|
394
|
+
// Serialize and write back
|
|
395
|
+
const tomlContent = serializeToml(config);
|
|
396
|
+
writeFileSync(CODEX_CONFIG_PATH, tomlContent, 'utf8');
|
|
397
|
+
|
|
398
|
+
return { success: true };
|
|
399
|
+
} catch (error: unknown) {
|
|
400
|
+
console.error('Error removing Codex MCP server:', error);
|
|
401
|
+
return { error: (error as Error).message };
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Toggle Codex MCP server enabled state
|
|
407
|
+
*/
|
|
408
|
+
function toggleCodexMcpServer(serverName: string, enabled: boolean): { success?: boolean; error?: string } {
|
|
409
|
+
try {
|
|
410
|
+
if (!existsSync(CODEX_CONFIG_PATH)) {
|
|
411
|
+
return { error: 'Codex config.toml not found' };
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const content = readFileSync(CODEX_CONFIG_PATH, 'utf8');
|
|
415
|
+
const config = parseToml(content);
|
|
416
|
+
|
|
417
|
+
if (!config.mcp_servers || !config.mcp_servers[serverName]) {
|
|
418
|
+
return { error: `Server not found: ${serverName}` };
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Set enabled state
|
|
422
|
+
config.mcp_servers[serverName].enabled = enabled;
|
|
423
|
+
|
|
424
|
+
// Serialize and write back
|
|
425
|
+
const tomlContent = serializeToml(config);
|
|
426
|
+
writeFileSync(CODEX_CONFIG_PATH, tomlContent, 'utf8');
|
|
427
|
+
|
|
428
|
+
return { success: true };
|
|
429
|
+
} catch (error: unknown) {
|
|
430
|
+
console.error('Error toggling Codex MCP server:', error);
|
|
431
|
+
return { error: (error as Error).message };
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
export interface RouteContext {
|
|
436
|
+
pathname: string;
|
|
437
|
+
url: URL;
|
|
438
|
+
req: IncomingMessage;
|
|
439
|
+
res: ServerResponse;
|
|
440
|
+
initialPath: string;
|
|
441
|
+
handlePostRequest: (req: IncomingMessage, res: ServerResponse, handler: (body: unknown) => Promise<any>) => void;
|
|
442
|
+
broadcastToClients: (data: unknown) => void;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// ========================================
|
|
446
|
+
// Helper Functions
|
|
447
|
+
// ========================================
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Get enterprise managed MCP path (platform-specific)
|
|
451
|
+
*/
|
|
452
|
+
function getEnterpriseMcpPath(): string {
|
|
453
|
+
const platform = process.platform;
|
|
454
|
+
if (platform === 'darwin') {
|
|
455
|
+
return '/Library/Application Support/ClaudeCode/managed-mcp.json';
|
|
456
|
+
} else if (platform === 'win32') {
|
|
457
|
+
return 'C:\\Program Files\\ClaudeCode\\managed-mcp.json';
|
|
458
|
+
} else {
|
|
459
|
+
// Linux and WSL
|
|
460
|
+
return '/etc/claude-code/managed-mcp.json';
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Safely read and parse JSON file
|
|
466
|
+
*/
|
|
467
|
+
function safeReadJson(filePath) {
|
|
468
|
+
try {
|
|
469
|
+
if (!existsSync(filePath)) return null;
|
|
470
|
+
const content = readFileSync(filePath, 'utf8');
|
|
471
|
+
return JSON.parse(content);
|
|
472
|
+
} catch {
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Get MCP servers from a JSON file (expects mcpServers key at top level)
|
|
479
|
+
* @param {string} filePath
|
|
480
|
+
* @returns {Object} mcpServers object or empty object
|
|
481
|
+
*/
|
|
482
|
+
function getMcpServersFromFile(filePath) {
|
|
483
|
+
const config = safeReadJson(filePath);
|
|
484
|
+
if (!config) return {};
|
|
485
|
+
return config.mcpServers || {};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Add or update MCP server in project's .mcp.json file
|
|
490
|
+
* @param {string} projectPath - Project directory path
|
|
491
|
+
* @param {string} serverName - MCP server name
|
|
492
|
+
* @param {Object} serverConfig - MCP server configuration
|
|
493
|
+
* @returns {Object} Result with success/error
|
|
494
|
+
*/
|
|
495
|
+
function addMcpServerToMcpJson(projectPath, serverName, serverConfig) {
|
|
496
|
+
try {
|
|
497
|
+
const normalizedPath = normalizePathForFileSystem(projectPath);
|
|
498
|
+
const mcpJsonPath = join(normalizedPath, '.mcp.json');
|
|
499
|
+
|
|
500
|
+
// Read existing .mcp.json or create new structure
|
|
501
|
+
let mcpJson = safeReadJson(mcpJsonPath) || { mcpServers: {} };
|
|
502
|
+
|
|
503
|
+
// Ensure mcpServers exists
|
|
504
|
+
if (!mcpJson.mcpServers) {
|
|
505
|
+
mcpJson.mcpServers = {};
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// Add or update the server
|
|
509
|
+
mcpJson.mcpServers[serverName] = serverConfig;
|
|
510
|
+
|
|
511
|
+
// Write back to .mcp.json
|
|
512
|
+
writeFileSync(mcpJsonPath, JSON.stringify(mcpJson, null, 2), 'utf8');
|
|
513
|
+
|
|
514
|
+
return {
|
|
515
|
+
success: true,
|
|
516
|
+
serverName,
|
|
517
|
+
serverConfig,
|
|
518
|
+
scope: 'project-mcp-json',
|
|
519
|
+
path: mcpJsonPath
|
|
520
|
+
};
|
|
521
|
+
} catch (error: unknown) {
|
|
522
|
+
console.error('Error adding MCP server to .mcp.json:', error);
|
|
523
|
+
return { error: (error as Error).message };
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Remove MCP server from project's .mcp.json file
|
|
529
|
+
* @param {string} projectPath - Project directory path
|
|
530
|
+
* @param {string} serverName - MCP server name
|
|
531
|
+
* @returns {Object} Result with success/error
|
|
532
|
+
*/
|
|
533
|
+
function removeMcpServerFromMcpJson(projectPath, serverName) {
|
|
534
|
+
try {
|
|
535
|
+
const normalizedPath = normalizePathForFileSystem(projectPath);
|
|
536
|
+
const mcpJsonPath = join(normalizedPath, '.mcp.json');
|
|
537
|
+
|
|
538
|
+
if (!existsSync(mcpJsonPath)) {
|
|
539
|
+
return { error: '.mcp.json not found' };
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const mcpJson = safeReadJson(mcpJsonPath);
|
|
543
|
+
if (!mcpJson || !mcpJson.mcpServers || !mcpJson.mcpServers[serverName]) {
|
|
544
|
+
return { error: `Server not found: ${serverName}` };
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Remove the server
|
|
548
|
+
delete mcpJson.mcpServers[serverName];
|
|
549
|
+
|
|
550
|
+
// Write back to .mcp.json
|
|
551
|
+
writeFileSync(mcpJsonPath, JSON.stringify(mcpJson, null, 2), 'utf8');
|
|
552
|
+
|
|
553
|
+
return {
|
|
554
|
+
success: true,
|
|
555
|
+
serverName,
|
|
556
|
+
removed: true,
|
|
557
|
+
scope: 'project-mcp-json'
|
|
558
|
+
};
|
|
559
|
+
} catch (error: unknown) {
|
|
560
|
+
console.error('Error removing MCP server from .mcp.json:', error);
|
|
561
|
+
return { error: (error as Error).message };
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Get MCP configuration from multiple sources (per official Claude Code docs):
|
|
567
|
+
*
|
|
568
|
+
* Priority (highest to lowest):
|
|
569
|
+
* 1. Enterprise managed-mcp.json (cannot be overridden)
|
|
570
|
+
* 2. Local scope (project-specific private in ~/.claude.json)
|
|
571
|
+
* 3. Project scope (.mcp.json in project root)
|
|
572
|
+
* 4. User scope (mcpServers in ~/.claude.json)
|
|
573
|
+
*
|
|
574
|
+
* Note: ~/.claude/settings.json is for MCP PERMISSIONS, NOT definitions!
|
|
575
|
+
*
|
|
576
|
+
* @returns {Object}
|
|
577
|
+
*/
|
|
578
|
+
function getMcpConfig() {
|
|
579
|
+
try {
|
|
580
|
+
const result = {
|
|
581
|
+
projects: {},
|
|
582
|
+
userServers: {}, // User-level servers from ~/.claude.json mcpServers
|
|
583
|
+
enterpriseServers: {}, // Enterprise managed servers (highest priority)
|
|
584
|
+
configSources: [] // Track where configs came from for debugging
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
// 1. Read Enterprise managed MCP servers (highest priority)
|
|
588
|
+
const enterprisePath = getEnterpriseMcpPath();
|
|
589
|
+
if (existsSync(enterprisePath)) {
|
|
590
|
+
const enterpriseConfig = safeReadJson(enterprisePath);
|
|
591
|
+
if (enterpriseConfig?.mcpServers) {
|
|
592
|
+
result.enterpriseServers = enterpriseConfig.mcpServers;
|
|
593
|
+
result.configSources.push({ type: 'enterprise', path: enterprisePath, count: Object.keys(enterpriseConfig.mcpServers).length });
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// 2. Read from ~/.claude.json
|
|
598
|
+
if (existsSync(CLAUDE_CONFIG_PATH)) {
|
|
599
|
+
const claudeConfig = safeReadJson(CLAUDE_CONFIG_PATH);
|
|
600
|
+
if (claudeConfig) {
|
|
601
|
+
// 2a. User-level mcpServers (top-level mcpServers key)
|
|
602
|
+
if (claudeConfig.mcpServers) {
|
|
603
|
+
result.userServers = claudeConfig.mcpServers;
|
|
604
|
+
result.configSources.push({ type: 'user', path: CLAUDE_CONFIG_PATH, count: Object.keys(claudeConfig.mcpServers).length });
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// 2b. Project-specific configurations (projects[path].mcpServers)
|
|
608
|
+
if (claudeConfig.projects) {
|
|
609
|
+
result.projects = claudeConfig.projects;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// 3. For each known project, check for .mcp.json (project-level config)
|
|
615
|
+
// .mcp.json is now the PRIMARY source for project-level MCP servers
|
|
616
|
+
const projectPaths = Object.keys(result.projects);
|
|
617
|
+
for (const projectPath of projectPaths) {
|
|
618
|
+
const mcpJsonPath = join(projectPath, '.mcp.json');
|
|
619
|
+
if (existsSync(mcpJsonPath)) {
|
|
620
|
+
const mcpJsonConfig = safeReadJson(mcpJsonPath);
|
|
621
|
+
if (mcpJsonConfig?.mcpServers) {
|
|
622
|
+
// Merge .mcp.json servers into project config
|
|
623
|
+
// .mcp.json has HIGHER priority than ~/.claude.json projects[path].mcpServers
|
|
624
|
+
const existingServers = result.projects[projectPath]?.mcpServers || {};
|
|
625
|
+
result.projects[projectPath] = {
|
|
626
|
+
...result.projects[projectPath],
|
|
627
|
+
mcpServers: {
|
|
628
|
+
...existingServers, // ~/.claude.json projects[path] (lower priority, legacy)
|
|
629
|
+
...mcpJsonConfig.mcpServers // .mcp.json (higher priority, new default)
|
|
630
|
+
},
|
|
631
|
+
mcpJsonPath: mcpJsonPath, // Track source for debugging
|
|
632
|
+
hasMcpJson: true
|
|
633
|
+
};
|
|
634
|
+
result.configSources.push({
|
|
635
|
+
type: 'project-mcp-json',
|
|
636
|
+
path: mcpJsonPath,
|
|
637
|
+
count: Object.keys(mcpJsonConfig.mcpServers).length
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// Build globalServers by merging user and enterprise servers
|
|
644
|
+
// Enterprise servers override user servers
|
|
645
|
+
result.globalServers = {
|
|
646
|
+
...result.userServers,
|
|
647
|
+
...result.enterpriseServers
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
return result;
|
|
651
|
+
} catch (error: unknown) {
|
|
652
|
+
console.error('Error reading MCP config:', error);
|
|
653
|
+
return { projects: {}, globalServers: {}, userServers: {}, enterpriseServers: {}, configSources: [], error: (error as Error).message };
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Normalize path to filesystem format (for accessing .mcp.json files)
|
|
659
|
+
* Always uses forward slashes for cross-platform compatibility
|
|
660
|
+
* @param {string} path
|
|
661
|
+
* @returns {string}
|
|
662
|
+
*/
|
|
663
|
+
function normalizePathForFileSystem(path) {
|
|
664
|
+
let normalized = path.replace(/\\/g, '/');
|
|
665
|
+
|
|
666
|
+
// Handle /d/path format -> D:/path
|
|
667
|
+
if (normalized.match(/^\/[a-zA-Z]\//)) {
|
|
668
|
+
normalized = normalized.charAt(1).toUpperCase() + ':' + normalized.slice(2);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return normalized;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Normalize project path to match existing format in .claude.json
|
|
676
|
+
* Checks both forward slash and backslash formats to find existing entry
|
|
677
|
+
* @param {string} path
|
|
678
|
+
* @param {Object} claudeConfig - Optional existing config to check format
|
|
679
|
+
* @returns {string}
|
|
680
|
+
*/
|
|
681
|
+
function normalizeProjectPathForConfig(path, claudeConfig = null) {
|
|
682
|
+
// IMPORTANT: Always normalize to forward slashes to prevent duplicate entries
|
|
683
|
+
// (e.g., prevents both "D:/Claude_dms3" and "D:\\Claude_dms3")
|
|
684
|
+
let normalizedForward = path.replace(/\\/g, '/');
|
|
685
|
+
|
|
686
|
+
// Handle /d/path format -> D:/path
|
|
687
|
+
if (normalizedForward.match(/^\/[a-zA-Z]\//)) {
|
|
688
|
+
normalizedForward = normalizedForward.charAt(1).toUpperCase() + ':' + normalizedForward.slice(2);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// ALWAYS return forward slash format to prevent duplicates
|
|
692
|
+
return normalizedForward;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Toggle MCP server enabled/disabled
|
|
697
|
+
* @param {string} projectPath
|
|
698
|
+
* @param {string} serverName
|
|
699
|
+
* @param {boolean} enable
|
|
700
|
+
* @returns {Object}
|
|
701
|
+
*/
|
|
702
|
+
function toggleMcpServerEnabled(projectPath, serverName, enable) {
|
|
703
|
+
try {
|
|
704
|
+
if (!existsSync(CLAUDE_CONFIG_PATH)) {
|
|
705
|
+
return { error: '.claude.json not found' };
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
|
709
|
+
const config = JSON.parse(content);
|
|
710
|
+
|
|
711
|
+
const normalizedPath = normalizeProjectPathForConfig(projectPath, config);
|
|
712
|
+
|
|
713
|
+
if (!config.projects || !config.projects[normalizedPath]) {
|
|
714
|
+
return { error: `Project not found: ${normalizedPath}` };
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
const projectConfig = config.projects[normalizedPath];
|
|
718
|
+
|
|
719
|
+
// Ensure disabledMcpServers array exists
|
|
720
|
+
if (!projectConfig.disabledMcpServers) {
|
|
721
|
+
projectConfig.disabledMcpServers = [];
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
if (enable) {
|
|
725
|
+
// Remove from disabled list
|
|
726
|
+
projectConfig.disabledMcpServers = projectConfig.disabledMcpServers.filter(s => s !== serverName);
|
|
727
|
+
} else {
|
|
728
|
+
// Add to disabled list if not already there
|
|
729
|
+
if (!projectConfig.disabledMcpServers.includes(serverName)) {
|
|
730
|
+
projectConfig.disabledMcpServers.push(serverName);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Write back to file
|
|
735
|
+
writeFileSync(CLAUDE_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
|
|
736
|
+
|
|
737
|
+
return {
|
|
738
|
+
success: true,
|
|
739
|
+
serverName,
|
|
740
|
+
enabled: enable,
|
|
741
|
+
disabledMcpServers: projectConfig.disabledMcpServers
|
|
742
|
+
};
|
|
743
|
+
} catch (error: unknown) {
|
|
744
|
+
console.error('Error toggling MCP server:', error);
|
|
745
|
+
return { error: (error as Error).message };
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Add MCP server to project
|
|
751
|
+
* Now defaults to using .mcp.json instead of .claude.json
|
|
752
|
+
* @param {string} projectPath
|
|
753
|
+
* @param {string} serverName
|
|
754
|
+
* @param {Object} serverConfig
|
|
755
|
+
* @param {boolean} useLegacyConfig - If true, use .claude.json instead of .mcp.json
|
|
756
|
+
* @returns {Object}
|
|
757
|
+
*/
|
|
758
|
+
function addMcpServerToProject(projectPath, serverName, serverConfig, useLegacyConfig = false) {
|
|
759
|
+
try {
|
|
760
|
+
// Default: Use .mcp.json for project-level MCP servers
|
|
761
|
+
if (!useLegacyConfig) {
|
|
762
|
+
return addMcpServerToMcpJson(projectPath, serverName, serverConfig);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// Legacy: Use .claude.json (kept for backward compatibility)
|
|
766
|
+
if (!existsSync(CLAUDE_CONFIG_PATH)) {
|
|
767
|
+
return { error: '.claude.json not found' };
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
|
771
|
+
const config = JSON.parse(content);
|
|
772
|
+
|
|
773
|
+
const normalizedPath = normalizeProjectPathForConfig(projectPath, config);
|
|
774
|
+
|
|
775
|
+
// Create project entry if it doesn't exist
|
|
776
|
+
if (!config.projects) {
|
|
777
|
+
config.projects = {};
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if (!config.projects[normalizedPath]) {
|
|
781
|
+
config.projects[normalizedPath] = {
|
|
782
|
+
allowedTools: [],
|
|
783
|
+
mcpContextUris: [],
|
|
784
|
+
mcpServers: {},
|
|
785
|
+
enabledMcpjsonServers: [],
|
|
786
|
+
disabledMcpjsonServers: [],
|
|
787
|
+
hasTrustDialogAccepted: false,
|
|
788
|
+
projectOnboardingSeenCount: 0,
|
|
789
|
+
hasClaudeMdExternalIncludesApproved: false,
|
|
790
|
+
hasClaudeMdExternalIncludesWarningShown: false
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
const projectConfig = config.projects[normalizedPath];
|
|
795
|
+
|
|
796
|
+
// Ensure mcpServers exists
|
|
797
|
+
if (!projectConfig.mcpServers) {
|
|
798
|
+
projectConfig.mcpServers = {};
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// Add the server
|
|
802
|
+
projectConfig.mcpServers[serverName] = serverConfig;
|
|
803
|
+
|
|
804
|
+
// Write back to file
|
|
805
|
+
writeFileSync(CLAUDE_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
|
|
806
|
+
|
|
807
|
+
return {
|
|
808
|
+
success: true,
|
|
809
|
+
serverName,
|
|
810
|
+
serverConfig,
|
|
811
|
+
scope: 'project-legacy'
|
|
812
|
+
};
|
|
813
|
+
} catch (error: unknown) {
|
|
814
|
+
console.error('Error adding MCP server:', error);
|
|
815
|
+
return { error: (error as Error).message };
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* Remove MCP server from project
|
|
821
|
+
* Checks both .mcp.json and .claude.json
|
|
822
|
+
* @param {string} projectPath
|
|
823
|
+
* @param {string} serverName
|
|
824
|
+
* @returns {Object}
|
|
825
|
+
*/
|
|
826
|
+
function removeMcpServerFromProject(projectPath, serverName) {
|
|
827
|
+
try {
|
|
828
|
+
const normalizedPathForFile = normalizePathForFileSystem(projectPath);
|
|
829
|
+
const mcpJsonPath = join(normalizedPathForFile, '.mcp.json');
|
|
830
|
+
|
|
831
|
+
let removedFromMcpJson = false;
|
|
832
|
+
let removedFromClaudeJson = false;
|
|
833
|
+
|
|
834
|
+
// Try to remove from .mcp.json first (new default)
|
|
835
|
+
if (existsSync(mcpJsonPath)) {
|
|
836
|
+
const mcpJson = safeReadJson(mcpJsonPath);
|
|
837
|
+
if (mcpJson?.mcpServers?.[serverName]) {
|
|
838
|
+
const result = removeMcpServerFromMcpJson(projectPath, serverName);
|
|
839
|
+
if (result.success) {
|
|
840
|
+
removedFromMcpJson = true;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// Also try to remove from .claude.json (legacy - may coexist)
|
|
846
|
+
if (existsSync(CLAUDE_CONFIG_PATH)) {
|
|
847
|
+
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
|
848
|
+
const config = JSON.parse(content);
|
|
849
|
+
|
|
850
|
+
// Get normalized path that matches existing config format
|
|
851
|
+
const normalizedPath = normalizeProjectPathForConfig(projectPath, config);
|
|
852
|
+
|
|
853
|
+
if (config.projects && config.projects[normalizedPath]) {
|
|
854
|
+
const projectConfig = config.projects[normalizedPath];
|
|
855
|
+
|
|
856
|
+
if (projectConfig.mcpServers && projectConfig.mcpServers[serverName]) {
|
|
857
|
+
// Remove the server
|
|
858
|
+
delete projectConfig.mcpServers[serverName];
|
|
859
|
+
|
|
860
|
+
// Also remove from disabled list if present
|
|
861
|
+
if (projectConfig.disabledMcpServers) {
|
|
862
|
+
projectConfig.disabledMcpServers = projectConfig.disabledMcpServers.filter(s => s !== serverName);
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
// Write back to file
|
|
866
|
+
writeFileSync(CLAUDE_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
|
|
867
|
+
removedFromClaudeJson = true;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// Return success if removed from either location
|
|
873
|
+
if (removedFromMcpJson || removedFromClaudeJson) {
|
|
874
|
+
return {
|
|
875
|
+
success: true,
|
|
876
|
+
serverName,
|
|
877
|
+
removed: true,
|
|
878
|
+
scope: removedFromMcpJson ? 'project-mcp-json' : 'project-legacy',
|
|
879
|
+
removedFrom: removedFromMcpJson && removedFromClaudeJson ? 'both' :
|
|
880
|
+
removedFromMcpJson ? '.mcp.json' : '.claude.json'
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
return { error: `Server not found: ${serverName}` };
|
|
885
|
+
} catch (error: unknown) {
|
|
886
|
+
console.error('Error removing MCP server:', error);
|
|
887
|
+
return { error: (error as Error).message };
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* Add MCP server to global/user scope (top-level mcpServers in ~/.claude.json)
|
|
893
|
+
* @param {string} serverName
|
|
894
|
+
* @param {Object} serverConfig
|
|
895
|
+
* @returns {Object}
|
|
896
|
+
*/
|
|
897
|
+
function addGlobalMcpServer(serverName, serverConfig) {
|
|
898
|
+
try {
|
|
899
|
+
if (!existsSync(CLAUDE_CONFIG_PATH)) {
|
|
900
|
+
return { error: '.claude.json not found' };
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
|
904
|
+
const config = JSON.parse(content);
|
|
905
|
+
|
|
906
|
+
// Ensure top-level mcpServers exists
|
|
907
|
+
if (!config.mcpServers) {
|
|
908
|
+
config.mcpServers = {};
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// Add the server to top-level mcpServers
|
|
912
|
+
config.mcpServers[serverName] = serverConfig;
|
|
913
|
+
|
|
914
|
+
// Write back to file
|
|
915
|
+
writeFileSync(CLAUDE_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
|
|
916
|
+
|
|
917
|
+
return {
|
|
918
|
+
success: true,
|
|
919
|
+
serverName,
|
|
920
|
+
serverConfig,
|
|
921
|
+
scope: 'global'
|
|
922
|
+
};
|
|
923
|
+
} catch (error: unknown) {
|
|
924
|
+
console.error('Error adding global MCP server:', error);
|
|
925
|
+
return { error: (error as Error).message };
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* Remove MCP server from global/user scope (top-level mcpServers)
|
|
931
|
+
* @param {string} serverName
|
|
932
|
+
* @returns {Object}
|
|
933
|
+
*/
|
|
934
|
+
function removeGlobalMcpServer(serverName) {
|
|
935
|
+
try {
|
|
936
|
+
if (!existsSync(CLAUDE_CONFIG_PATH)) {
|
|
937
|
+
return { error: '.claude.json not found' };
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
const content = readFileSync(CLAUDE_CONFIG_PATH, 'utf8');
|
|
941
|
+
const config = JSON.parse(content);
|
|
942
|
+
|
|
943
|
+
if (!config.mcpServers || !config.mcpServers[serverName]) {
|
|
944
|
+
return { error: `Global server not found: ${serverName}` };
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// Remove the server from top-level mcpServers
|
|
948
|
+
delete config.mcpServers[serverName];
|
|
949
|
+
|
|
950
|
+
// Write back to file
|
|
951
|
+
writeFileSync(CLAUDE_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
|
|
952
|
+
|
|
953
|
+
return {
|
|
954
|
+
success: true,
|
|
955
|
+
serverName,
|
|
956
|
+
removed: true,
|
|
957
|
+
scope: 'global'
|
|
958
|
+
};
|
|
959
|
+
} catch (error: unknown) {
|
|
960
|
+
console.error('Error removing global MCP server:', error);
|
|
961
|
+
return { error: (error as Error).message };
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Read settings file safely
|
|
967
|
+
* @param {string} filePath
|
|
968
|
+
* @returns {Object}
|
|
969
|
+
*/
|
|
970
|
+
function readSettingsFile(filePath) {
|
|
971
|
+
try {
|
|
972
|
+
if (!existsSync(filePath)) {
|
|
973
|
+
return {};
|
|
974
|
+
}
|
|
975
|
+
const content = readFileSync(filePath, 'utf8');
|
|
976
|
+
return JSON.parse(content);
|
|
977
|
+
} catch (error: unknown) {
|
|
978
|
+
console.error(`Error reading settings file ${filePath}:`, error);
|
|
979
|
+
return {};
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* Write settings file safely
|
|
985
|
+
* @param {string} filePath
|
|
986
|
+
* @param {Object} settings
|
|
987
|
+
*/
|
|
988
|
+
function writeSettingsFile(filePath, settings) {
|
|
989
|
+
const dirPath = dirname(filePath);
|
|
990
|
+
// Ensure directory exists
|
|
991
|
+
if (!existsSync(dirPath)) {
|
|
992
|
+
mkdirSync(dirPath, { recursive: true });
|
|
993
|
+
}
|
|
994
|
+
writeFileSync(filePath, JSON.stringify(settings, null, 2), 'utf8');
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/**
|
|
998
|
+
* Get project settings path
|
|
999
|
+
* @param {string} projectPath
|
|
1000
|
+
* @returns {string}
|
|
1001
|
+
*/
|
|
1002
|
+
function getProjectSettingsPath(projectPath) {
|
|
1003
|
+
const normalizedPath = projectPath.replace(/\//g, '\\').replace(/^\\([a-zA-Z])\\/, '$1:\\');
|
|
1004
|
+
return join(normalizedPath, '.claude', 'settings.json');
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// ========================================
|
|
1008
|
+
// Route Handlers
|
|
1009
|
+
// ========================================
|
|
1010
|
+
|
|
1011
|
+
/**
|
|
1012
|
+
* Handle MCP routes
|
|
1013
|
+
* @returns true if route was handled, false otherwise
|
|
1014
|
+
*/
|
|
1015
|
+
export async function handleMcpRoutes(ctx: RouteContext): Promise<boolean> {
|
|
1016
|
+
const { pathname, url, req, res, initialPath, handlePostRequest, broadcastToClients } = ctx;
|
|
1017
|
+
|
|
1018
|
+
// API: Get MCP configuration (includes both Claude and Codex)
|
|
1019
|
+
if (pathname === '/api/mcp-config') {
|
|
1020
|
+
const mcpData = getMcpConfig();
|
|
1021
|
+
const codexData = getCodexMcpConfig();
|
|
1022
|
+
const combinedData = {
|
|
1023
|
+
...mcpData,
|
|
1024
|
+
codex: codexData
|
|
1025
|
+
};
|
|
1026
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1027
|
+
res.end(JSON.stringify(combinedData));
|
|
1028
|
+
return true;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// ========================================
|
|
1032
|
+
// Codex MCP API Endpoints
|
|
1033
|
+
// ========================================
|
|
1034
|
+
|
|
1035
|
+
// API: Get Codex MCP configuration
|
|
1036
|
+
if (pathname === '/api/codex-mcp-config') {
|
|
1037
|
+
const codexData = getCodexMcpConfig();
|
|
1038
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1039
|
+
res.end(JSON.stringify(codexData));
|
|
1040
|
+
return true;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// API: Add Codex MCP server
|
|
1044
|
+
if (pathname === '/api/codex-mcp-add' && req.method === 'POST') {
|
|
1045
|
+
handlePostRequest(req, res, async (body) => {
|
|
1046
|
+
const { serverName, serverConfig } = body;
|
|
1047
|
+
if (!serverName || !serverConfig) {
|
|
1048
|
+
return { error: 'serverName and serverConfig are required', status: 400 };
|
|
1049
|
+
}
|
|
1050
|
+
return addCodexMcpServer(serverName, serverConfig);
|
|
1051
|
+
});
|
|
1052
|
+
return true;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
// API: Remove Codex MCP server
|
|
1056
|
+
if (pathname === '/api/codex-mcp-remove' && req.method === 'POST') {
|
|
1057
|
+
handlePostRequest(req, res, async (body) => {
|
|
1058
|
+
const { serverName } = body;
|
|
1059
|
+
if (!serverName) {
|
|
1060
|
+
return { error: 'serverName is required', status: 400 };
|
|
1061
|
+
}
|
|
1062
|
+
return removeCodexMcpServer(serverName);
|
|
1063
|
+
});
|
|
1064
|
+
return true;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// API: Toggle Codex MCP server enabled state
|
|
1068
|
+
if (pathname === '/api/codex-mcp-toggle' && req.method === 'POST') {
|
|
1069
|
+
handlePostRequest(req, res, async (body) => {
|
|
1070
|
+
const { serverName, enabled } = body;
|
|
1071
|
+
if (!serverName || enabled === undefined) {
|
|
1072
|
+
return { error: 'serverName and enabled are required', status: 400 };
|
|
1073
|
+
}
|
|
1074
|
+
return toggleCodexMcpServer(serverName, enabled);
|
|
1075
|
+
});
|
|
1076
|
+
return true;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
// API: Toggle MCP server enabled/disabled
|
|
1080
|
+
if (pathname === '/api/mcp-toggle' && req.method === 'POST') {
|
|
1081
|
+
handlePostRequest(req, res, async (body) => {
|
|
1082
|
+
const { projectPath, serverName, enable } = body;
|
|
1083
|
+
if (!projectPath || !serverName) {
|
|
1084
|
+
return { error: 'projectPath and serverName are required', status: 400 };
|
|
1085
|
+
}
|
|
1086
|
+
return toggleMcpServerEnabled(projectPath, serverName, enable);
|
|
1087
|
+
});
|
|
1088
|
+
return true;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
// API: Copy MCP server to project
|
|
1092
|
+
if (pathname === '/api/mcp-copy-server' && req.method === 'POST') {
|
|
1093
|
+
handlePostRequest(req, res, async (body) => {
|
|
1094
|
+
const { projectPath, serverName, serverConfig, configType } = body;
|
|
1095
|
+
if (!projectPath || !serverName || !serverConfig) {
|
|
1096
|
+
return { error: 'projectPath, serverName, and serverConfig are required', status: 400 };
|
|
1097
|
+
}
|
|
1098
|
+
// configType: 'mcp' = use .mcp.json (default), 'claude' = use .claude.json
|
|
1099
|
+
const useLegacyConfig = configType === 'claude';
|
|
1100
|
+
return addMcpServerToProject(projectPath, serverName, serverConfig, useLegacyConfig);
|
|
1101
|
+
});
|
|
1102
|
+
return true;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
// API: Install CCW MCP server to project
|
|
1106
|
+
if (pathname === '/api/mcp-install-ccw' && req.method === 'POST') {
|
|
1107
|
+
handlePostRequest(req, res, async (body) => {
|
|
1108
|
+
const { projectPath } = body;
|
|
1109
|
+
if (!projectPath) {
|
|
1110
|
+
return { error: 'projectPath is required', status: 400 };
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
// Generate CCW MCP server config
|
|
1114
|
+
// Use cmd /c to inherit Claude Code's working directory
|
|
1115
|
+
const ccwMcpConfig = {
|
|
1116
|
+
command: "cmd",
|
|
1117
|
+
args: ["/c", "npx", "-y", "ccw-mcp"],
|
|
1118
|
+
env: {
|
|
1119
|
+
CCW_ENABLED_TOOLS: "all"
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1123
|
+
// Use existing addMcpServerToProject to install CCW MCP
|
|
1124
|
+
return addMcpServerToProject(projectPath, 'ccw-tools', ccwMcpConfig);
|
|
1125
|
+
});
|
|
1126
|
+
return true;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// API: Remove MCP server from project
|
|
1130
|
+
if (pathname === '/api/mcp-remove-server' && req.method === 'POST') {
|
|
1131
|
+
handlePostRequest(req, res, async (body) => {
|
|
1132
|
+
const { projectPath, serverName } = body;
|
|
1133
|
+
if (!projectPath || !serverName) {
|
|
1134
|
+
return { error: 'projectPath and serverName are required', status: 400 };
|
|
1135
|
+
}
|
|
1136
|
+
return removeMcpServerFromProject(projectPath, serverName);
|
|
1137
|
+
});
|
|
1138
|
+
return true;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
// API: Add MCP server to global scope (top-level mcpServers in ~/.claude.json)
|
|
1142
|
+
if (pathname === '/api/mcp-add-global-server' && req.method === 'POST') {
|
|
1143
|
+
handlePostRequest(req, res, async (body) => {
|
|
1144
|
+
const { serverName, serverConfig } = body;
|
|
1145
|
+
if (!serverName || !serverConfig) {
|
|
1146
|
+
return { error: 'serverName and serverConfig are required', status: 400 };
|
|
1147
|
+
}
|
|
1148
|
+
return addGlobalMcpServer(serverName, serverConfig);
|
|
1149
|
+
});
|
|
1150
|
+
return true;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
// API: Remove MCP server from global scope
|
|
1154
|
+
if (pathname === '/api/mcp-remove-global-server' && req.method === 'POST') {
|
|
1155
|
+
handlePostRequest(req, res, async (body) => {
|
|
1156
|
+
const { serverName } = body;
|
|
1157
|
+
if (!serverName) {
|
|
1158
|
+
return { error: 'serverName is required', status: 400 };
|
|
1159
|
+
}
|
|
1160
|
+
return removeGlobalMcpServer(serverName);
|
|
1161
|
+
});
|
|
1162
|
+
return true;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// ========================================
|
|
1166
|
+
// MCP Templates API
|
|
1167
|
+
// ========================================
|
|
1168
|
+
|
|
1169
|
+
// API: Get all MCP templates
|
|
1170
|
+
if (pathname === '/api/mcp-templates' && req.method === 'GET') {
|
|
1171
|
+
const templates = McpTemplatesDb.getAllTemplates();
|
|
1172
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1173
|
+
res.end(JSON.stringify({ success: true, templates }));
|
|
1174
|
+
return true;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
// API: Save MCP template
|
|
1178
|
+
if (pathname === '/api/mcp-templates' && req.method === 'POST') {
|
|
1179
|
+
handlePostRequest(req, res, async (body) => {
|
|
1180
|
+
const { name, description, serverConfig, tags, category } = body;
|
|
1181
|
+
if (!name || !serverConfig) {
|
|
1182
|
+
return { error: 'name and serverConfig are required', status: 400 };
|
|
1183
|
+
}
|
|
1184
|
+
return McpTemplatesDb.saveTemplate({
|
|
1185
|
+
name,
|
|
1186
|
+
description,
|
|
1187
|
+
serverConfig,
|
|
1188
|
+
tags,
|
|
1189
|
+
category
|
|
1190
|
+
});
|
|
1191
|
+
});
|
|
1192
|
+
return true;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
// API: Get template by name
|
|
1196
|
+
if (pathname.startsWith('/api/mcp-templates/') && req.method === 'GET') {
|
|
1197
|
+
const templateName = decodeURIComponent(pathname.split('/api/mcp-templates/')[1]);
|
|
1198
|
+
const template = McpTemplatesDb.getTemplateByName(templateName);
|
|
1199
|
+
if (template) {
|
|
1200
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1201
|
+
res.end(JSON.stringify({ success: true, template }));
|
|
1202
|
+
} else {
|
|
1203
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
1204
|
+
res.end(JSON.stringify({ success: false, error: 'Template not found' }));
|
|
1205
|
+
}
|
|
1206
|
+
return true;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
// API: Delete MCP template
|
|
1210
|
+
if (pathname.startsWith('/api/mcp-templates/') && req.method === 'DELETE') {
|
|
1211
|
+
const templateName = decodeURIComponent(pathname.split('/api/mcp-templates/')[1]);
|
|
1212
|
+
const result = McpTemplatesDb.deleteTemplate(templateName);
|
|
1213
|
+
res.writeHead(result.success ? 200 : 404, { 'Content-Type': 'application/json' });
|
|
1214
|
+
res.end(JSON.stringify(result));
|
|
1215
|
+
return true;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
// API: Search MCP templates
|
|
1219
|
+
if (pathname === '/api/mcp-templates/search' && req.method === 'GET') {
|
|
1220
|
+
const keyword = url.searchParams.get('q') || '';
|
|
1221
|
+
const templates = McpTemplatesDb.searchTemplates(keyword);
|
|
1222
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1223
|
+
res.end(JSON.stringify({ success: true, templates }));
|
|
1224
|
+
return true;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// API: Get all categories
|
|
1228
|
+
if (pathname === '/api/mcp-templates/categories' && req.method === 'GET') {
|
|
1229
|
+
const categories = McpTemplatesDb.getAllCategories();
|
|
1230
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1231
|
+
res.end(JSON.stringify({ success: true, categories }));
|
|
1232
|
+
return true;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
// API: Get templates by category
|
|
1236
|
+
if (pathname.startsWith('/api/mcp-templates/category/') && req.method === 'GET') {
|
|
1237
|
+
const category = decodeURIComponent(pathname.split('/api/mcp-templates/category/')[1]);
|
|
1238
|
+
const templates = McpTemplatesDb.getTemplatesByCategory(category);
|
|
1239
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1240
|
+
res.end(JSON.stringify({ success: true, templates }));
|
|
1241
|
+
return true;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
// API: Install template to project or global
|
|
1245
|
+
if (pathname === '/api/mcp-templates/install' && req.method === 'POST') {
|
|
1246
|
+
handlePostRequest(req, res, async (body) => {
|
|
1247
|
+
const { templateName, projectPath, scope } = body;
|
|
1248
|
+
if (!templateName) {
|
|
1249
|
+
return { error: 'templateName is required', status: 400 };
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
const template = McpTemplatesDb.getTemplateByName(templateName);
|
|
1253
|
+
if (!template) {
|
|
1254
|
+
return { error: 'Template not found', status: 404 };
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
// Install to global or project
|
|
1258
|
+
if (scope === 'global') {
|
|
1259
|
+
return addGlobalMcpServer(templateName, template.serverConfig);
|
|
1260
|
+
} else {
|
|
1261
|
+
if (!projectPath) {
|
|
1262
|
+
return { error: 'projectPath is required for project scope', status: 400 };
|
|
1263
|
+
}
|
|
1264
|
+
return addMcpServerToProject(projectPath, templateName, template.serverConfig);
|
|
1265
|
+
}
|
|
1266
|
+
});
|
|
1267
|
+
return true;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
return false;
|
|
1271
|
+
}
|