claude-code-workflow 6.1.4 → 6.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +10 -0
- package/.claude/agents/action-planning-agent.md +857 -778
- package/.claude/agents/cli-execution-agent.md +266 -269
- package/.claude/agents/cli-explore-agent.md +2 -2
- package/.claude/agents/cli-lite-planning-agent.md +142 -92
- package/.claude/agents/cli-planning-agent.md +4 -4
- package/.claude/agents/code-developer.md +7 -6
- package/.claude/agents/conceptual-planning-agent.md +2 -2
- package/.claude/agents/context-search-agent.md +31 -32
- package/.claude/agents/doc-generator.md +4 -4
- package/.claude/agents/memory-bridge.md +93 -93
- package/.claude/agents/test-context-search-agent.md +8 -7
- package/.claude/agents/test-fix-agent.md +7 -6
- package/.claude/commands/clean.md +516 -0
- package/.claude/commands/memory/compact.md +383 -0
- package/.claude/commands/memory/docs-full-cli.md +471 -471
- package/.claude/commands/memory/docs-related-cli.md +386 -386
- package/.claude/commands/memory/docs.md +615 -615
- package/.claude/commands/memory/load.md +5 -5
- package/.claude/commands/memory/tech-research-rules.md +310 -0
- package/.claude/commands/memory/update-full.md +332 -332
- package/.claude/commands/memory/workflow-skill-memory.md +4 -4
- package/.claude/commands/task/create.md +151 -151
- package/.claude/commands/version.md +254 -254
- package/.claude/commands/workflow/brainstorm/api-designer.md +587 -585
- package/.claude/commands/workflow/brainstorm/artifacts.md +1 -0
- package/.claude/commands/workflow/brainstorm/auto-parallel.md +443 -443
- package/.claude/commands/workflow/brainstorm/data-architect.md +220 -220
- package/.claude/commands/workflow/brainstorm/product-manager.md +200 -200
- package/.claude/commands/workflow/brainstorm/product-owner.md +200 -200
- package/.claude/commands/workflow/brainstorm/scrum-master.md +200 -200
- package/.claude/commands/workflow/brainstorm/subject-matter-expert.md +200 -200
- package/.claude/commands/workflow/brainstorm/system-architect.md +389 -387
- package/.claude/commands/workflow/brainstorm/ui-designer.md +221 -221
- package/.claude/commands/workflow/brainstorm/ux-expert.md +221 -221
- package/.claude/commands/workflow/debug.md +321 -0
- package/.claude/commands/workflow/execute.md +13 -0
- package/.claude/commands/workflow/init.md +165 -164
- package/.claude/commands/workflow/lite-execute.md +119 -13
- package/.claude/commands/workflow/lite-fix.md +623 -621
- package/.claude/commands/workflow/lite-plan.md +610 -592
- package/.claude/commands/workflow/plan.md +5 -5
- package/.claude/commands/workflow/review-module-cycle.md +2 -0
- package/.claude/commands/workflow/review-session-cycle.md +2 -0
- package/.claude/commands/workflow/review.md +297 -291
- package/.claude/commands/workflow/session/complete.md +153 -500
- package/.claude/commands/workflow/session/list.md +95 -95
- package/.claude/commands/workflow/session/resume.md +60 -60
- package/.claude/commands/workflow/session/start.md +199 -199
- package/.claude/commands/workflow/tdd-plan.md +3 -3
- package/.claude/commands/workflow/tdd-verify.md +23 -9
- package/.claude/commands/workflow/test-cycle-execute.md +2 -0
- package/.claude/commands/workflow/test-fix-gen.md +699 -699
- package/.claude/commands/workflow/tools/conflict-resolution.md +104 -18
- package/.claude/commands/workflow/tools/context-gather.md +436 -434
- package/.claude/commands/workflow/tools/task-generate-agent.md +490 -291
- package/.claude/commands/workflow/tools/task-generate-tdd.md +18 -10
- package/.claude/commands/workflow/tools/test-concept-enhanced.md +2 -1
- package/.claude/commands/workflow/tools/test-context-gather.md +1 -0
- package/.claude/commands/workflow/tools/test-task-generate.md +1 -0
- package/.claude/commands/workflow/ui-design/import-from-code.md +9 -6
- package/.claude/skills/command-guide/SKILL.md +5 -5
- package/.claude/skills/command-guide/index/all-commands.json +1 -1
- package/.claude/skills/command-guide/index/by-category.json +1 -1
- package/.claude/skills/command-guide/index/by-use-case.json +1 -1
- package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +857 -778
- package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +266 -269
- package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +2 -2
- package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +142 -92
- package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +4 -4
- package/.claude/skills/command-guide/reference/agents/code-developer.md +7 -6
- package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +2 -2
- package/.claude/skills/command-guide/reference/agents/context-search-agent.md +31 -32
- package/.claude/skills/command-guide/reference/agents/doc-generator.md +4 -4
- package/.claude/skills/command-guide/reference/agents/memory-bridge.md +93 -93
- package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +8 -7
- package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +7 -6
- package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -471
- package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -386
- package/.claude/skills/command-guide/reference/commands/memory/docs.md +17 -16
- package/.claude/skills/command-guide/reference/commands/memory/load.md +5 -5
- package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +194 -357
- package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -332
- package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +4 -4
- package/.claude/skills/command-guide/reference/commands/task/create.md +151 -151
- package/.claude/skills/command-guide/reference/commands/version.md +254 -254
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +585 -585
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +443 -443
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +220 -220
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +387 -387
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +221 -221
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +221 -221
- package/.claude/skills/command-guide/reference/commands/workflow/execute.md +25 -20
- package/.claude/skills/command-guide/reference/commands/workflow/init.md +164 -164
- package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +748 -686
- package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +664 -621
- package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +645 -592
- package/.claude/skills/command-guide/reference/commands/workflow/plan.md +5 -5
- package/.claude/skills/command-guide/reference/commands/workflow/review.md +25 -18
- package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +547 -500
- package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +45 -27
- package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +35 -19
- package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +90 -33
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +3 -3
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +23 -9
- package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +699 -699
- package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +103 -17
- package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -434
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +487 -291
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +17 -10
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +6 -6
- package/.claude/workflows/chinese-response.md +38 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-api.txt +122 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-components.txt +122 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-config.txt +89 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-core.txt +60 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-patterns.txt +70 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-testing.txt +81 -0
- package/.claude/workflows/cli-templates/prompts/rules/tech-rules-agent-prompt.txt +89 -0
- package/.claude/workflows/cli-templates/prompts/workflow/gemini-solution-design.txt +131 -131
- package/.claude/workflows/cli-templates/prompts/workflow/skill-conflict-patterns.txt +5 -9
- package/.claude/workflows/cli-templates/prompts/workflow/skill-lessons-learned.txt +5 -9
- package/.claude/workflows/cli-templates/protocols/analysis-protocol.md +112 -0
- package/.claude/workflows/cli-templates/protocols/write-protocol.md +201 -0
- package/.claude/workflows/cli-templates/schemas/conflict-resolution-schema.json +137 -0
- package/.claude/workflows/cli-templates/schemas/debug-log-json-schema.json +127 -0
- package/.claude/workflows/cli-templates/schemas/fix-plan-json-schema.json +25 -0
- package/.claude/workflows/cli-templates/schemas/plan-json-schema.json +25 -0
- package/.claude/workflows/cli-tools-usage.md +526 -0
- package/{CLAUDE.md → .claude/workflows/coding-philosophy.md} +24 -45
- package/.claude/workflows/context-tools.md +84 -0
- package/.claude/workflows/file-modification.md +64 -0
- package/.claude/workflows/tool-strategy.md +216 -79
- package/.claude/workflows/windows-platform.md +16 -0
- package/.claude/workflows/workflow-architecture.md +942 -942
- package/.codex/AGENTS.md +63 -330
- package/.codex/prompts/debug.md +318 -0
- package/.codex/prompts/execute.md +273 -0
- package/.codex/prompts/lite-execute.md +164 -0
- package/.codex/prompts/lite-plan.md +469 -0
- package/.codex/prompts.zip +0 -0
- package/.gemini/GEMINI.md +25 -164
- package/.qwen/QWEN.md +0 -139
- package/README.md +29 -9
- package/ccw/README.md +30 -6
- package/ccw/bin/ccw-mcp.js +7 -0
- package/ccw/bin/ccw.js +9 -9
- package/ccw/package.json +65 -47
- package/ccw/src/.workflow/.cli-history/history.db +0 -0
- package/ccw/src/.workflow/.cli-history/history.db-shm +0 -0
- package/ccw/src/.workflow/.cli-history/history.db-wal +0 -0
- package/ccw/src/cli.ts +244 -0
- package/ccw/src/commands/cli.ts +740 -0
- package/ccw/src/commands/core-memory.ts +770 -0
- package/ccw/src/commands/hook.ts +315 -0
- package/ccw/src/commands/install.ts +519 -0
- package/ccw/src/commands/{list.js → list.ts} +1 -1
- package/ccw/src/commands/memory.ts +1090 -0
- package/ccw/src/commands/{serve.js → serve.ts} +14 -5
- package/ccw/src/commands/session-path-resolver.ts +372 -0
- package/ccw/src/commands/session.ts +1141 -0
- package/ccw/src/commands/{stop.js → stop.ts} +16 -6
- package/ccw/src/commands/tool.ts +201 -0
- package/ccw/src/commands/{uninstall.js → uninstall.ts} +89 -40
- package/ccw/src/commands/{upgrade.js → upgrade.ts} +68 -23
- package/ccw/src/commands/{view.js → view.ts} +22 -8
- package/ccw/src/config/storage-paths.ts +670 -0
- package/ccw/src/core/cache-manager.ts +294 -0
- package/ccw/src/core/claude-freshness.ts +319 -0
- package/ccw/src/core/core-memory-store.ts +1528 -0
- package/ccw/src/core/{dashboard-generator-patch.js → dashboard-generator-patch.ts} +18 -0
- package/ccw/src/core/{dashboard-generator.js → dashboard-generator.ts} +69 -12
- package/ccw/src/core/data-aggregator.ts +584 -0
- package/ccw/src/core/history-importer.ts +625 -0
- package/ccw/src/core/{lite-scanner.js → lite-scanner-complete.ts} +162 -66
- package/ccw/src/core/lite-scanner.ts +469 -0
- package/ccw/src/core/{manifest.js → manifest.ts} +104 -34
- package/ccw/src/core/memory-embedder-bridge.ts +262 -0
- package/ccw/src/core/memory-store.ts +978 -0
- package/ccw/src/core/routes/ccw-routes.ts +96 -0
- package/ccw/src/core/routes/claude-routes.ts +1183 -0
- package/ccw/src/core/routes/cli-routes.ts +561 -0
- package/ccw/src/core/routes/codexlens-routes.ts +806 -0
- package/ccw/src/core/routes/core-memory-routes.ts +605 -0
- package/ccw/src/core/routes/files-routes.ts +428 -0
- package/ccw/src/core/routes/graph-routes.md +164 -0
- package/ccw/src/core/routes/graph-routes.ts +626 -0
- package/ccw/src/core/routes/help-routes.ts +308 -0
- package/ccw/src/core/routes/hooks-routes.ts +405 -0
- package/ccw/src/core/routes/mcp-routes.ts +1271 -0
- package/ccw/src/core/routes/mcp-routes.ts.backup +550 -0
- package/ccw/src/core/routes/mcp-templates-db.ts +268 -0
- package/ccw/src/core/routes/memory-routes.ts +1206 -0
- package/ccw/src/core/routes/rules-routes.ts +526 -0
- package/ccw/src/core/routes/session-routes.ts +467 -0
- package/ccw/src/core/routes/skills-routes.ts +599 -0
- package/ccw/src/core/routes/status-routes.ts +57 -0
- package/ccw/src/core/routes/system-routes.ts +427 -0
- package/ccw/src/core/server.ts +431 -0
- package/ccw/src/core/session-clustering-service.ts +1258 -0
- package/ccw/src/core/session-scanner.ts +283 -0
- package/ccw/src/core/websocket.ts +190 -0
- package/ccw/src/{index.js → index.ts} +1 -0
- package/ccw/src/mcp-server/index.ts +186 -0
- package/ccw/src/templates/assets/css/github-dark.min.css +10 -0
- package/ccw/src/templates/assets/css/github.min.css +10 -0
- package/ccw/src/templates/assets/js/cytoscape.min.js +32 -0
- package/ccw/src/templates/assets/js/d3.min.js +2 -0
- package/ccw/src/templates/assets/js/highlight.min.js +1244 -0
- package/ccw/src/templates/assets/js/lucide.min.js +12 -0
- package/ccw/src/templates/assets/js/marked.min.js +69 -0
- package/ccw/src/templates/assets/js/tailwind.js +83 -0
- package/ccw/src/templates/dashboard-css/01-base.css +11 -0
- package/ccw/src/templates/dashboard-css/02-session.css +22 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +10 -0
- package/ccw/src/templates/dashboard-css/06-cards.css +10 -4
- package/ccw/src/templates/dashboard-css/07-managers.css +1178 -7
- package/ccw/src/templates/dashboard-css/09-explorer.css +23 -12
- package/ccw/src/templates/dashboard-css/10-cli-status.css +337 -0
- package/ccw/src/templates/dashboard-css/11-cli-history.css +271 -0
- package/ccw/src/templates/dashboard-css/12-cli-legacy.css +796 -0
- package/ccw/src/templates/dashboard-css/13-cli-ccw.css +199 -0
- package/ccw/src/templates/dashboard-css/14-cli-modals.css +258 -0
- package/ccw/src/templates/dashboard-css/15-cli-endpoints.css +305 -0
- package/ccw/src/templates/dashboard-css/16-cli-session.css +241 -0
- package/ccw/src/templates/dashboard-css/17-cli-conversation.css +283 -0
- package/ccw/src/templates/dashboard-css/18-cli-settings.css +160 -0
- package/ccw/src/templates/dashboard-css/19-cli-native-session.css +496 -0
- package/ccw/src/templates/dashboard-css/20-cli-taskqueue.css +188 -0
- package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +310 -0
- package/ccw/src/templates/dashboard-css/22-cli-semantic.css +240 -0
- package/ccw/src/templates/dashboard-css/23-memory.css +2390 -0
- package/ccw/src/templates/dashboard-css/24-prompt-history.css +1089 -0
- package/ccw/src/templates/dashboard-css/25-skills-rules.css +326 -0
- package/ccw/src/templates/dashboard-css/26-claude-manager.css +908 -0
- package/ccw/src/templates/dashboard-css/27-graph-explorer.css +1678 -0
- package/ccw/src/templates/dashboard-css/28-mcp-manager.css +748 -0
- package/ccw/src/templates/dashboard-css/29-help.css +264 -0
- package/ccw/src/templates/dashboard-css/30-core-memory.css +1700 -0
- package/ccw/src/templates/dashboard-js/api.js +162 -142
- package/ccw/src/templates/dashboard-js/components/carousel.js +4 -4
- package/ccw/src/templates/dashboard-js/components/cli-history.js +876 -0
- package/ccw/src/templates/dashboard-js/components/cli-status.js +978 -0
- package/ccw/src/templates/dashboard-js/components/global-notifications.js +508 -219
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +1277 -282
- package/ccw/src/templates/dashboard-js/components/index-manager.js +302 -0
- package/ccw/src/templates/dashboard-js/components/mcp-manager.js +718 -27
- package/ccw/src/templates/dashboard-js/components/modals.js +66 -0
- package/ccw/src/templates/dashboard-js/components/navigation.js +80 -12
- package/ccw/src/templates/dashboard-js/components/notifications.js +758 -194
- package/ccw/src/templates/dashboard-js/components/storage-manager.js +478 -0
- package/ccw/src/templates/dashboard-js/components/tabs-other.js +157 -6
- package/ccw/src/templates/dashboard-js/components/task-queue-sidebar.js +716 -0
- package/ccw/src/templates/dashboard-js/help-i18n.js +272 -0
- package/ccw/src/templates/dashboard-js/i18n.js +2807 -0
- package/ccw/src/templates/dashboard-js/main.js +15 -0
- package/ccw/src/templates/dashboard-js/state.js +243 -42
- package/ccw/src/templates/dashboard-js/utils.js +47 -1
- package/ccw/src/templates/dashboard-js/views/claude-manager.js +912 -0
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +2272 -0
- package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +964 -0
- package/ccw/src/templates/dashboard-js/views/core-memory-clusters.js +503 -0
- package/ccw/src/templates/dashboard-js/views/core-memory.js +782 -0
- package/ccw/src/templates/dashboard-js/views/explorer.js +888 -852
- package/ccw/src/templates/dashboard-js/views/graph-explorer.js +1157 -0
- package/ccw/src/templates/dashboard-js/views/help.js +856 -0
- package/ccw/src/templates/dashboard-js/views/history.js +337 -0
- package/ccw/src/templates/dashboard-js/views/home.js +61 -15
- package/ccw/src/templates/dashboard-js/views/hook-manager.js +311 -43
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +204 -28
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +2187 -411
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js.backup +1729 -0
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js.new +928 -0
- package/ccw/src/templates/dashboard-js/views/memory.js +1221 -0
- package/ccw/src/templates/dashboard-js/views/prompt-history.js +713 -0
- package/ccw/src/templates/dashboard-js/views/rules-manager.js +828 -0
- package/ccw/src/templates/dashboard-js/views/session-detail.js +54 -53
- package/ccw/src/templates/dashboard-js/views/skills-manager.js +819 -0
- package/ccw/src/templates/dashboard.html +185 -85
- package/ccw/src/templates/hooks-config-example.json +60 -0
- package/ccw/src/tools/classify-folders.ts +245 -0
- package/ccw/src/tools/cli-config-manager.ts +268 -0
- package/ccw/src/tools/cli-executor.ts +2014 -0
- package/ccw/src/tools/cli-history-store.ts +1195 -0
- package/ccw/src/tools/codex-lens.ts +1141 -0
- package/ccw/src/tools/{convert-tokens-to-css.js → convert-tokens-to-css.ts} +73 -23
- package/ccw/src/tools/core-memory.ts +444 -0
- package/ccw/src/tools/detect-changed-modules.ts +325 -0
- package/ccw/src/tools/{discover-design-files.js → discover-design-files.ts} +74 -24
- package/ccw/src/tools/edit-file.ts +568 -0
- package/ccw/src/tools/{generate-module-docs.js → generate-module-docs.ts} +207 -185
- package/ccw/src/tools/{get-modules-by-depth.js → get-modules-by-depth.ts} +120 -79
- package/ccw/src/tools/index.ts +370 -0
- package/ccw/src/tools/native-session-discovery.ts +795 -0
- package/ccw/src/tools/notifier.ts +129 -0
- package/ccw/src/tools/read-file.ts +410 -0
- package/ccw/src/tools/resume-strategy.ts +345 -0
- package/ccw/src/tools/session-content-parser.ts +619 -0
- package/ccw/src/tools/session-manager.ts +1026 -0
- package/ccw/src/tools/smart-context.ts +228 -0
- package/ccw/src/tools/smart-search.ts +2065 -0
- package/ccw/src/tools/smart-search.ts.backup +1233 -0
- package/ccw/src/tools/storage-manager.ts +455 -0
- package/ccw/src/tools/write-file.ts +222 -0
- package/ccw/src/types/config.ts +11 -0
- package/ccw/src/types/index.ts +3 -0
- package/ccw/src/types/session.ts +25 -0
- package/ccw/src/types/tool.ts +41 -0
- package/ccw/src/utils/{browser-launcher.js → browser-launcher.ts} +10 -8
- package/ccw/src/utils/file-utils.ts +48 -0
- package/ccw/src/utils/{path-resolver.js → path-resolver.ts} +114 -78
- package/ccw/src/utils/path-validator.ts +153 -0
- package/ccw/src/utils/{ui.js → ui.ts} +32 -25
- package/codex-lens/pyproject.toml +48 -0
- package/codex-lens/src/codexlens/.workflow/.cli-history/history.db +0 -0
- package/codex-lens/src/codexlens/__init__.py +28 -0
- package/codex-lens/src/codexlens/__main__.py +14 -0
- package/codex-lens/src/codexlens/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/__main__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/errors.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__init__.py +27 -0
- package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/commands.py +1931 -0
- package/codex-lens/src/codexlens/cli/embedding_manager.py +620 -0
- package/codex-lens/src/codexlens/cli/model_manager.py +289 -0
- package/codex-lens/src/codexlens/cli/output.py +124 -0
- package/codex-lens/src/codexlens/config.py +201 -0
- package/codex-lens/src/codexlens/entities.py +121 -0
- package/codex-lens/src/codexlens/errors.py +55 -0
- package/codex-lens/src/codexlens/indexing/README.md +77 -0
- package/codex-lens/src/codexlens/indexing/__init__.py +4 -0
- package/codex-lens/src/codexlens/indexing/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/symbol_extractor.py +243 -0
- package/codex-lens/src/codexlens/parsers/__init__.py +8 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/encoding.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/encoding.py +202 -0
- package/codex-lens/src/codexlens/parsers/factory.py +256 -0
- package/codex-lens/src/codexlens/parsers/tokenizer.py +98 -0
- package/codex-lens/src/codexlens/parsers/treesitter_parser.py +335 -0
- package/codex-lens/src/codexlens/search/__init__.py +15 -0
- package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/enrichment.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/query_parser.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/chain_search.py +647 -0
- package/codex-lens/src/codexlens/search/enrichment.py +150 -0
- package/codex-lens/src/codexlens/search/hybrid_search.py +313 -0
- package/codex-lens/src/codexlens/search/query_parser.py +242 -0
- package/codex-lens/src/codexlens/search/ranking.py +274 -0
- package/codex-lens/src/codexlens/semantic/__init__.py +39 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/code_extractor.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/graph_analyzer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/llm_enhancer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/ann_index.py +414 -0
- package/codex-lens/src/codexlens/semantic/chunker.py +448 -0
- package/codex-lens/src/codexlens/semantic/code_extractor.py +274 -0
- package/codex-lens/src/codexlens/semantic/embedder.py +185 -0
- package/codex-lens/src/codexlens/semantic/vector_store.py +955 -0
- package/codex-lens/src/codexlens/storage/__init__.py +29 -0
- package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/file_cache.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/migration_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/dir_index.py +1850 -0
- package/codex-lens/src/codexlens/storage/file_cache.py +32 -0
- package/codex-lens/src/codexlens/storage/index_tree.py +776 -0
- package/codex-lens/src/codexlens/storage/migration_manager.py +154 -0
- package/codex-lens/src/codexlens/storage/migrations/__init__.py +1 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_001_normalize_keywords.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_002_add_token_metadata.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_003_code_relationships.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_004_dual_fts.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_005_cleanup_unused_fields.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_001_normalize_keywords.py +123 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_002_add_token_metadata.py +48 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_004_dual_fts.py +232 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_005_cleanup_unused_fields.py +196 -0
- package/codex-lens/src/codexlens/storage/path_mapper.py +274 -0
- package/codex-lens/src/codexlens/storage/registry.py +670 -0
- package/codex-lens/src/codexlens/storage/sqlite_store.py +576 -0
- package/codex-lens/src/codexlens/storage/sqlite_utils.py +64 -0
- package/package.json +4 -1
- package/.claude/commands/memory/tech-research.md +0 -477
- package/.claude/scripts/classify-folders.sh +0 -39
- package/.claude/scripts/convert_tokens_to_css.sh +0 -229
- package/.claude/scripts/detect_changed_modules.sh +0 -161
- package/.claude/scripts/discover-design-files.sh +0 -87
- package/.claude/scripts/extract-animations.js +0 -243
- package/.claude/scripts/extract-computed-styles.js +0 -118
- package/.claude/scripts/extract-layout-structure.js +0 -411
- package/.claude/scripts/generate_module_docs.sh +0 -717
- package/.claude/scripts/get_modules_by_depth.sh +0 -170
- package/.claude/scripts/ui-generate-preview.sh +0 -395
- package/.claude/scripts/ui-instantiate-prototypes.sh +0 -815
- package/.claude/scripts/update_module_claude.sh +0 -337
- package/.claude/workflows/context-search-strategy.md +0 -77
- package/.claude/workflows/intelligent-tools-strategy.md +0 -662
- package/ccw/src/cli.js +0 -119
- package/ccw/src/commands/install.js +0 -324
- package/ccw/src/commands/tool.js +0 -138
- package/ccw/src/core/data-aggregator.js +0 -409
- package/ccw/src/core/server.js +0 -2063
- package/ccw/src/core/session-scanner.js +0 -235
- package/ccw/src/tools/classify-folders.js +0 -204
- package/ccw/src/tools/detect-changed-modules.js +0 -288
- package/ccw/src/tools/edit-file.js +0 -266
- package/ccw/src/tools/index.js +0 -176
- package/ccw/src/utils/file-utils.js +0 -48
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { glob } from 'glob';
|
|
2
|
+
import { readFile, readdir, stat, access } from 'fs/promises';
|
|
3
|
+
import { constants } from 'fs';
|
|
4
|
+
import { join, basename } from 'path';
|
|
5
|
+
import type { SessionMetadata, SessionType } from '../types/session.js';
|
|
6
|
+
async function fileExists(path: string): Promise<boolean> {
|
|
7
|
+
try {
|
|
8
|
+
await access(path, constants.F_OK);
|
|
9
|
+
return true;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface SessionData extends SessionMetadata {
|
|
16
|
+
path: string;
|
|
17
|
+
isActive: boolean;
|
|
18
|
+
archived_at?: string | null;
|
|
19
|
+
workflow_type?: string | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface ScanSessionsResult {
|
|
23
|
+
active: SessionData[];
|
|
24
|
+
archived: SessionData[];
|
|
25
|
+
hasReviewData: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Scan .workflow directory for active and archived sessions
|
|
30
|
+
* @param workflowDir - Path to .workflow directory
|
|
31
|
+
* @returns Active and archived sessions
|
|
32
|
+
*/
|
|
33
|
+
export async function scanSessions(workflowDir: string): Promise<ScanSessionsResult> {
|
|
34
|
+
const result: ScanSessionsResult = {
|
|
35
|
+
active: [],
|
|
36
|
+
archived: [],
|
|
37
|
+
hasReviewData: false
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (!await fileExists(workflowDir)) {
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Scan active sessions
|
|
45
|
+
const activeDir = join(workflowDir, 'active');
|
|
46
|
+
if (await fileExists(activeDir)) {
|
|
47
|
+
const activeSessions = await findWfsSessions(activeDir);
|
|
48
|
+
const activeSessionDataPromises = activeSessions.map(async (sessionName) => {
|
|
49
|
+
const sessionPath = join(activeDir, sessionName);
|
|
50
|
+
const sessionData = await readSessionData(sessionPath);
|
|
51
|
+
if (sessionData) {
|
|
52
|
+
// Check for review data
|
|
53
|
+
if (await fileExists(join(sessionPath, '.review'))) {
|
|
54
|
+
result.hasReviewData = true;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
...sessionData,
|
|
58
|
+
path: sessionPath,
|
|
59
|
+
isActive: true
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const activeSessionData = (await Promise.all(activeSessionDataPromises)).filter((s): s is SessionData => s !== null);
|
|
66
|
+
result.active.push(...activeSessionData);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Scan archived sessions
|
|
70
|
+
const archivesDir = join(workflowDir, 'archives');
|
|
71
|
+
if (await fileExists(archivesDir)) {
|
|
72
|
+
const archivedSessions = await findWfsSessions(archivesDir);
|
|
73
|
+
const archivedSessionDataPromises = archivedSessions.map(async (sessionName) => {
|
|
74
|
+
const sessionPath = join(archivesDir, sessionName);
|
|
75
|
+
const sessionData = await readSessionData(sessionPath);
|
|
76
|
+
if (sessionData) {
|
|
77
|
+
return {
|
|
78
|
+
...sessionData,
|
|
79
|
+
path: sessionPath,
|
|
80
|
+
isActive: false
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const archivedSessionData = (await Promise.all(archivedSessionDataPromises)).filter((s): s is SessionData => s !== null);
|
|
87
|
+
result.archived.push(...archivedSessionData);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Sort by creation date (newest first)
|
|
91
|
+
result.active.sort((a, b) => new Date(b.created || 0).getTime() - new Date(a.created || 0).getTime());
|
|
92
|
+
result.archived.sort((a, b) => {
|
|
93
|
+
const aDate = a.archived_at || a.created || 0;
|
|
94
|
+
const bDate = b.archived_at || b.created || 0;
|
|
95
|
+
return new Date(bDate).getTime() - new Date(aDate).getTime();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Find WFS-* directories in a given path
|
|
103
|
+
* @param dir - Directory to search
|
|
104
|
+
* @returns Array of session directory names
|
|
105
|
+
*/
|
|
106
|
+
async function findWfsSessions(dir: string): Promise<string[]> {
|
|
107
|
+
try {
|
|
108
|
+
// Use glob for cross-platform pattern matching
|
|
109
|
+
const sessions = await glob('WFS-*/', {
|
|
110
|
+
cwd: dir,
|
|
111
|
+
absolute: false
|
|
112
|
+
});
|
|
113
|
+
// Remove trailing slashes from directory names
|
|
114
|
+
return sessions.map(s => s.replace(/\/$/, ''));
|
|
115
|
+
} catch {
|
|
116
|
+
// Fallback: manual directory listing
|
|
117
|
+
try {
|
|
118
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
119
|
+
return entries
|
|
120
|
+
.filter(e => e.isDirectory() && e.name.startsWith('WFS-'))
|
|
121
|
+
.map(e => e.name);
|
|
122
|
+
} catch {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Parse timestamp from session name
|
|
130
|
+
* Supports formats: WFS-xxx-20251128172537 or WFS-xxx-20251120-170640
|
|
131
|
+
* @param sessionName - Session directory name
|
|
132
|
+
* @returns ISO date string or null
|
|
133
|
+
*/
|
|
134
|
+
function parseTimestampFromName(sessionName: string): string | null {
|
|
135
|
+
// Format: 14-digit timestamp (YYYYMMDDHHmmss)
|
|
136
|
+
const match14 = sessionName.match(/(\d{14})$/);
|
|
137
|
+
if (match14) {
|
|
138
|
+
const ts = match14[1];
|
|
139
|
+
return `${ts.slice(0,4)}-${ts.slice(4,6)}-${ts.slice(6,8)}T${ts.slice(8,10)}:${ts.slice(10,12)}:${ts.slice(12,14)}Z`;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Format: 8-digit date + 6-digit time separated by hyphen (YYYYMMDD-HHmmss)
|
|
143
|
+
const match8_6 = sessionName.match(/(\d{8})-(\d{6})$/);
|
|
144
|
+
if (match8_6) {
|
|
145
|
+
const d = match8_6[1];
|
|
146
|
+
const t = match8_6[2];
|
|
147
|
+
return `${d.slice(0,4)}-${d.slice(4,6)}-${d.slice(6,8)}T${t.slice(0,2)}:${t.slice(2,4)}:${t.slice(4,6)}Z`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Infer session type from session name pattern
|
|
155
|
+
* @param sessionName - Session directory name
|
|
156
|
+
* @returns Inferred type
|
|
157
|
+
*/
|
|
158
|
+
function inferTypeFromName(sessionName: string): SessionType {
|
|
159
|
+
const name = sessionName.toLowerCase();
|
|
160
|
+
|
|
161
|
+
if (name.includes('-review-') || name.includes('-code-review-')) {
|
|
162
|
+
return 'review';
|
|
163
|
+
}
|
|
164
|
+
if (name.includes('-test-')) {
|
|
165
|
+
return 'test';
|
|
166
|
+
}
|
|
167
|
+
if (name.includes('-docs-')) {
|
|
168
|
+
return 'docs';
|
|
169
|
+
}
|
|
170
|
+
if (name.includes('-tdd-')) {
|
|
171
|
+
return 'tdd';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return 'workflow';
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Read session data from workflow-session.json or create minimal from directory
|
|
179
|
+
* @param sessionPath - Path to session directory
|
|
180
|
+
* @returns Session data object or null if invalid
|
|
181
|
+
*/
|
|
182
|
+
async function readSessionData(sessionPath: string): Promise<SessionData | null> {
|
|
183
|
+
const sessionFile = join(sessionPath, 'workflow-session.json');
|
|
184
|
+
const sessionName = basename(sessionPath);
|
|
185
|
+
|
|
186
|
+
if (await fileExists(sessionFile)) {
|
|
187
|
+
try {
|
|
188
|
+
const data = JSON.parse(await readFile(sessionFile, 'utf8')) as Record<string, unknown>;
|
|
189
|
+
|
|
190
|
+
// Multi-level type detection: JSON type > workflow_type > infer from name
|
|
191
|
+
let type = (data.type as SessionType) || (data.workflow_type as SessionType) || inferTypeFromName(sessionName);
|
|
192
|
+
|
|
193
|
+
// Normalize workflow_type values
|
|
194
|
+
if (type === 'test_session' as SessionType) type = 'test';
|
|
195
|
+
if (type === 'implementation' as SessionType) type = 'workflow';
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
id: (data.session_id as string) || sessionName,
|
|
199
|
+
type,
|
|
200
|
+
status: (data.status as 'active' | 'paused' | 'completed' | 'archived') || 'active',
|
|
201
|
+
project: (data.project as string) || (data.description as string) || '',
|
|
202
|
+
description: (data.description as string) || (data.project as string) || '',
|
|
203
|
+
created: (data.created_at as string) || (data.initialized_at as string) || (data.timestamp as string) || '',
|
|
204
|
+
updated: (data.updated_at as string) || (data.created_at as string) || '',
|
|
205
|
+
path: sessionPath,
|
|
206
|
+
isActive: true,
|
|
207
|
+
archived_at: (data.archived_at as string) || null,
|
|
208
|
+
workflow_type: (data.workflow_type as string) || null // Keep original for reference
|
|
209
|
+
};
|
|
210
|
+
} catch {
|
|
211
|
+
// Fall through to minimal session
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Fallback: create minimal session from directory info
|
|
216
|
+
// Try to extract timestamp from session name first
|
|
217
|
+
const timestampFromName = parseTimestampFromName(sessionName);
|
|
218
|
+
const inferredType = inferTypeFromName(sessionName);
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
const stats = await stat(sessionPath);
|
|
222
|
+
const createdAt = timestampFromName || stats.birthtime.toISOString();
|
|
223
|
+
return {
|
|
224
|
+
id: sessionName,
|
|
225
|
+
type: inferredType,
|
|
226
|
+
status: 'active',
|
|
227
|
+
project: '',
|
|
228
|
+
description: '',
|
|
229
|
+
created: createdAt,
|
|
230
|
+
updated: createdAt,
|
|
231
|
+
path: sessionPath,
|
|
232
|
+
isActive: true,
|
|
233
|
+
archived_at: null,
|
|
234
|
+
workflow_type: null
|
|
235
|
+
};
|
|
236
|
+
} catch {
|
|
237
|
+
// Even if stat fails, return with name-extracted data
|
|
238
|
+
if (timestampFromName) {
|
|
239
|
+
return {
|
|
240
|
+
id: sessionName,
|
|
241
|
+
type: inferredType,
|
|
242
|
+
status: 'active',
|
|
243
|
+
project: '',
|
|
244
|
+
description: '',
|
|
245
|
+
created: timestampFromName,
|
|
246
|
+
updated: timestampFromName,
|
|
247
|
+
path: sessionPath,
|
|
248
|
+
isActive: true,
|
|
249
|
+
archived_at: null,
|
|
250
|
+
workflow_type: null
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Check if session has review data
|
|
259
|
+
* @param sessionPath - Path to session directory
|
|
260
|
+
* @returns True if review data exists
|
|
261
|
+
*/
|
|
262
|
+
export async function hasReviewData(sessionPath: string): Promise<boolean> {
|
|
263
|
+
const reviewDir = join(sessionPath, '.review');
|
|
264
|
+
return await fileExists(reviewDir);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Get list of task files in session
|
|
269
|
+
* @param sessionPath - Path to session directory
|
|
270
|
+
* @returns Array of task file names
|
|
271
|
+
*/
|
|
272
|
+
export async function getTaskFiles(sessionPath: string): Promise<string[]> {
|
|
273
|
+
const taskDir = join(sessionPath, '.task');
|
|
274
|
+
if (!await fileExists(taskDir)) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
return await glob('IMPL-*.json', { cwd: taskDir, absolute: false });
|
|
280
|
+
} catch {
|
|
281
|
+
return [];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
|
|
4
|
+
// WebSocket clients for real-time notifications
|
|
5
|
+
export const wsClients = new Set();
|
|
6
|
+
|
|
7
|
+
export function handleWebSocketUpgrade(req, socket, head) {
|
|
8
|
+
const key = req.headers['sec-websocket-key'];
|
|
9
|
+
const acceptKey = createHash('sha1')
|
|
10
|
+
.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
|
|
11
|
+
.digest('base64');
|
|
12
|
+
|
|
13
|
+
const responseHeaders = [
|
|
14
|
+
'HTTP/1.1 101 Switching Protocols',
|
|
15
|
+
'Upgrade: websocket',
|
|
16
|
+
'Connection: Upgrade',
|
|
17
|
+
`Sec-WebSocket-Accept: ${acceptKey}`,
|
|
18
|
+
'',
|
|
19
|
+
''
|
|
20
|
+
].join('\r\n');
|
|
21
|
+
|
|
22
|
+
socket.write(responseHeaders);
|
|
23
|
+
|
|
24
|
+
// Add to clients set
|
|
25
|
+
wsClients.add(socket);
|
|
26
|
+
console.log(`[WS] Client connected (${wsClients.size} total)`);
|
|
27
|
+
|
|
28
|
+
// Handle incoming messages
|
|
29
|
+
socket.on('data', (buffer) => {
|
|
30
|
+
try {
|
|
31
|
+
const frame = parseWebSocketFrame(buffer);
|
|
32
|
+
if (!frame) return;
|
|
33
|
+
|
|
34
|
+
const { opcode, payload } = frame;
|
|
35
|
+
|
|
36
|
+
switch (opcode) {
|
|
37
|
+
case 0x1: // Text frame
|
|
38
|
+
if (payload) {
|
|
39
|
+
console.log('[WS] Received:', payload);
|
|
40
|
+
}
|
|
41
|
+
break;
|
|
42
|
+
case 0x8: // Close frame
|
|
43
|
+
socket.end();
|
|
44
|
+
break;
|
|
45
|
+
case 0x9: // Ping frame - respond with Pong
|
|
46
|
+
const pongFrame = Buffer.alloc(2);
|
|
47
|
+
pongFrame[0] = 0x8A; // Pong opcode with FIN bit
|
|
48
|
+
pongFrame[1] = 0x00; // No payload
|
|
49
|
+
socket.write(pongFrame);
|
|
50
|
+
break;
|
|
51
|
+
case 0xA: // Pong frame - ignore
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
// Ignore other frame types (binary, continuation)
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
} catch (e) {
|
|
58
|
+
// Ignore parse errors
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Handle disconnect
|
|
63
|
+
socket.on('close', () => {
|
|
64
|
+
wsClients.delete(socket);
|
|
65
|
+
console.log(`[WS] Client disconnected (${wsClients.size} remaining)`);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
socket.on('error', () => {
|
|
69
|
+
wsClients.delete(socket);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parse WebSocket frame (simplified)
|
|
75
|
+
* Returns { opcode, payload } or null
|
|
76
|
+
*/
|
|
77
|
+
export function parseWebSocketFrame(buffer) {
|
|
78
|
+
if (buffer.length < 2) return null;
|
|
79
|
+
|
|
80
|
+
const firstByte = buffer[0];
|
|
81
|
+
const opcode = firstByte & 0x0f; // Extract opcode (bits 0-3)
|
|
82
|
+
|
|
83
|
+
// Opcode types:
|
|
84
|
+
// 0x0 = continuation, 0x1 = text, 0x2 = binary
|
|
85
|
+
// 0x8 = close, 0x9 = ping, 0xA = pong
|
|
86
|
+
|
|
87
|
+
const secondByte = buffer[1];
|
|
88
|
+
const isMasked = (secondByte & 0x80) !== 0;
|
|
89
|
+
let payloadLength = secondByte & 0x7f;
|
|
90
|
+
|
|
91
|
+
let offset = 2;
|
|
92
|
+
if (payloadLength === 126) {
|
|
93
|
+
payloadLength = buffer.readUInt16BE(2);
|
|
94
|
+
offset = 4;
|
|
95
|
+
} else if (payloadLength === 127) {
|
|
96
|
+
payloadLength = Number(buffer.readBigUInt64BE(2));
|
|
97
|
+
offset = 10;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let mask = null;
|
|
101
|
+
if (isMasked) {
|
|
102
|
+
mask = buffer.slice(offset, offset + 4);
|
|
103
|
+
offset += 4;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const payload = buffer.slice(offset, offset + payloadLength);
|
|
107
|
+
|
|
108
|
+
if (isMasked && mask) {
|
|
109
|
+
for (let i = 0; i < payload.length; i++) {
|
|
110
|
+
payload[i] ^= mask[i % 4];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return { opcode, payload: payload.toString('utf8') };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Create WebSocket frame
|
|
119
|
+
*/
|
|
120
|
+
export function createWebSocketFrame(data) {
|
|
121
|
+
const payload = Buffer.from(JSON.stringify(data), 'utf8');
|
|
122
|
+
const length = payload.length;
|
|
123
|
+
|
|
124
|
+
let frame;
|
|
125
|
+
if (length <= 125) {
|
|
126
|
+
frame = Buffer.alloc(2 + length);
|
|
127
|
+
frame[0] = 0x81; // Text frame, FIN
|
|
128
|
+
frame[1] = length;
|
|
129
|
+
payload.copy(frame, 2);
|
|
130
|
+
} else if (length <= 65535) {
|
|
131
|
+
frame = Buffer.alloc(4 + length);
|
|
132
|
+
frame[0] = 0x81;
|
|
133
|
+
frame[1] = 126;
|
|
134
|
+
frame.writeUInt16BE(length, 2);
|
|
135
|
+
payload.copy(frame, 4);
|
|
136
|
+
} else {
|
|
137
|
+
frame = Buffer.alloc(10 + length);
|
|
138
|
+
frame[0] = 0x81;
|
|
139
|
+
frame[1] = 127;
|
|
140
|
+
frame.writeBigUInt64BE(BigInt(length), 2);
|
|
141
|
+
payload.copy(frame, 10);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return frame;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Broadcast message to all connected WebSocket clients
|
|
149
|
+
*/
|
|
150
|
+
export function broadcastToClients(data) {
|
|
151
|
+
const frame = createWebSocketFrame(data);
|
|
152
|
+
|
|
153
|
+
for (const client of wsClients) {
|
|
154
|
+
try {
|
|
155
|
+
client.write(frame);
|
|
156
|
+
} catch (e) {
|
|
157
|
+
wsClients.delete(client);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log(`[WS] Broadcast to ${wsClients.size} clients:`, data.type);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Extract session ID from file path
|
|
166
|
+
*/
|
|
167
|
+
export function extractSessionIdFromPath(filePath) {
|
|
168
|
+
// Normalize path
|
|
169
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
170
|
+
|
|
171
|
+
// Look for session pattern: WFS-xxx, WRS-xxx, etc.
|
|
172
|
+
const sessionMatch = normalized.match(/\/(W[A-Z]S-[^/]+)\//);
|
|
173
|
+
if (sessionMatch) {
|
|
174
|
+
return sessionMatch[1];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Look for .workflow/.sessions/xxx pattern
|
|
178
|
+
const sessionsMatch = normalized.match(/\.workflow\/\.sessions\/([^/]+)/);
|
|
179
|
+
if (sessionsMatch) {
|
|
180
|
+
return sessionsMatch[1];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Look for lite-plan/lite-fix pattern
|
|
184
|
+
const liteMatch = normalized.match(/\.(lite-plan|lite-fix)\/([^/]+)/);
|
|
185
|
+
if (liteMatch) {
|
|
186
|
+
return liteMatch[2];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
@@ -7,3 +7,4 @@ export { run } from './cli.js';
|
|
|
7
7
|
export { scanSessions } from './core/session-scanner.js';
|
|
8
8
|
export { aggregateData } from './core/data-aggregator.js';
|
|
9
9
|
export { generateDashboard } from './core/dashboard-generator.js';
|
|
10
|
+
export { CacheManager, createDashboardCache } from './core/cache-manager.js';
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CCW MCP Server
|
|
4
|
+
* Exposes CCW tools through the Model Context Protocol
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
|
+
import {
|
|
10
|
+
CallToolRequestSchema,
|
|
11
|
+
ListToolsRequestSchema,
|
|
12
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
13
|
+
import { getAllToolSchemas, executeTool, executeToolWithProgress } from '../tools/index.js';
|
|
14
|
+
import type { ToolSchema, ToolResult } from '../types/tool.js';
|
|
15
|
+
import { getProjectRoot, getAllowedDirectories } from '../utils/path-validator.js';
|
|
16
|
+
|
|
17
|
+
const SERVER_NAME = 'ccw-tools';
|
|
18
|
+
const SERVER_VERSION = '6.2.0';
|
|
19
|
+
|
|
20
|
+
// Environment variable names for documentation
|
|
21
|
+
const ENV_PROJECT_ROOT = 'CCW_PROJECT_ROOT';
|
|
22
|
+
const ENV_ALLOWED_DIRS = 'CCW_ALLOWED_DIRS';
|
|
23
|
+
|
|
24
|
+
// Default enabled tools (core set)
|
|
25
|
+
const DEFAULT_TOOLS: string[] = ['write_file', 'edit_file', 'read_file', 'smart_search', 'core_memory'];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get list of enabled tools from environment or defaults
|
|
29
|
+
*/
|
|
30
|
+
function getEnabledTools(): string[] | null {
|
|
31
|
+
const envTools = process.env.CCW_ENABLED_TOOLS;
|
|
32
|
+
if (envTools) {
|
|
33
|
+
// Support "all" to enable all tools
|
|
34
|
+
if (envTools.toLowerCase() === 'all') {
|
|
35
|
+
return null; // null means all tools
|
|
36
|
+
}
|
|
37
|
+
return envTools.split(',').map(t => t.trim()).filter(Boolean);
|
|
38
|
+
}
|
|
39
|
+
return DEFAULT_TOOLS;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Filter tools based on enabled list
|
|
44
|
+
*/
|
|
45
|
+
function filterTools(tools: ToolSchema[], enabledList: string[] | null): ToolSchema[] {
|
|
46
|
+
if (!enabledList) return tools; // null = all tools
|
|
47
|
+
return tools.filter(tool => enabledList.includes(tool.name));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Format tool result for display
|
|
52
|
+
*/
|
|
53
|
+
function formatToolResult(result: unknown): string {
|
|
54
|
+
if (result === null || result === undefined) {
|
|
55
|
+
return 'Tool completed successfully (no output)';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (typeof result === 'string') {
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (typeof result === 'object') {
|
|
63
|
+
// Pretty print JSON with indentation
|
|
64
|
+
return JSON.stringify(result, null, 2);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return String(result);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Create and configure the MCP server
|
|
72
|
+
*/
|
|
73
|
+
function createServer(): Server {
|
|
74
|
+
const enabledTools = getEnabledTools();
|
|
75
|
+
|
|
76
|
+
const server = new Server(
|
|
77
|
+
{
|
|
78
|
+
name: SERVER_NAME,
|
|
79
|
+
version: SERVER_VERSION,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
capabilities: {
|
|
83
|
+
tools: {},
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Handler for tools/list - Returns enabled CCW tools
|
|
90
|
+
*/
|
|
91
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
92
|
+
const allTools = getAllToolSchemas().filter((tool): tool is ToolSchema => tool !== null);
|
|
93
|
+
const tools = filterTools(allTools, enabledTools);
|
|
94
|
+
return { tools };
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Handler for tools/call - Executes a CCW tool
|
|
99
|
+
*/
|
|
100
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
101
|
+
const { name, arguments: args } = request.params;
|
|
102
|
+
|
|
103
|
+
// Check if tool is enabled
|
|
104
|
+
if (enabledTools && !enabledTools.includes(name)) {
|
|
105
|
+
return {
|
|
106
|
+
content: [{ type: 'text' as const, text: `Tool "${name}" is not enabled` }],
|
|
107
|
+
isError: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
// For smart_search init action, use progress-aware execution
|
|
113
|
+
const isInitAction = name === 'smart_search' && args?.action === 'init';
|
|
114
|
+
|
|
115
|
+
let result: ToolResult;
|
|
116
|
+
if (isInitAction) {
|
|
117
|
+
// Execute with progress callback that writes to stderr
|
|
118
|
+
result = await executeToolWithProgress(name, args || {}, (progress) => {
|
|
119
|
+
// Output progress to stderr (visible in terminal, doesn't interfere with JSON-RPC)
|
|
120
|
+
console.error(`[Progress] ${progress.percent}% - ${progress.message}`);
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
result = await executeTool(name, args || {});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!result.success) {
|
|
127
|
+
return {
|
|
128
|
+
content: [{ type: 'text' as const, text: `Error: ${result.error}` }],
|
|
129
|
+
isError: true,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
content: [{ type: 'text' as const, text: formatToolResult(result.result) }],
|
|
135
|
+
};
|
|
136
|
+
} catch (error) {
|
|
137
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
138
|
+
return {
|
|
139
|
+
content: [{ type: 'text' as const, text: `Tool execution failed: ${errorMessage}` }],
|
|
140
|
+
isError: true,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
return server;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Main server execution
|
|
150
|
+
*/
|
|
151
|
+
async function main(): Promise<void> {
|
|
152
|
+
const server = createServer();
|
|
153
|
+
const transport = new StdioServerTransport();
|
|
154
|
+
|
|
155
|
+
// Connect server to transport
|
|
156
|
+
await server.connect(transport);
|
|
157
|
+
|
|
158
|
+
// Error handling
|
|
159
|
+
process.on('SIGINT', async () => {
|
|
160
|
+
await server.close();
|
|
161
|
+
process.exit(0);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
process.on('SIGTERM', async () => {
|
|
165
|
+
await server.close();
|
|
166
|
+
process.exit(0);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Log server start (to stderr to not interfere with stdio protocol)
|
|
170
|
+
const projectRoot = getProjectRoot();
|
|
171
|
+
const allowedDirs = getAllowedDirectories();
|
|
172
|
+
console.error(`${SERVER_NAME} v${SERVER_VERSION} started`);
|
|
173
|
+
console.error(`Project root: ${projectRoot}`);
|
|
174
|
+
console.error(`Allowed directories: ${allowedDirs.join(', ')}`);
|
|
175
|
+
if (!process.env[ENV_PROJECT_ROOT]) {
|
|
176
|
+
console.error(`[Warning] ${ENV_PROJECT_ROOT} not set, using process.cwd()`);
|
|
177
|
+
console.error(`[Tip] Set ${ENV_PROJECT_ROOT} in your MCP config to specify project directory`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Run server
|
|
182
|
+
main().catch((error: unknown) => {
|
|
183
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
184
|
+
console.error('Server error:', errorMessage);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
|
|
2
|
+
Theme: GitHub Dark
|
|
3
|
+
Description: Dark theme as seen on github.com
|
|
4
|
+
Author: github.com
|
|
5
|
+
Maintainer: @Hirse
|
|
6
|
+
Updated: 2021-05-15
|
|
7
|
+
|
|
8
|
+
Outdated base version: https://github.com/primer/github-syntax-dark
|
|
9
|
+
Current colors taken from GitHub's CSS
|
|
10
|
+
*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
|
|
2
|
+
Theme: GitHub
|
|
3
|
+
Description: Light theme as seen on github.com
|
|
4
|
+
Author: github.com
|
|
5
|
+
Maintainer: @Hirse
|
|
6
|
+
Updated: 2021-05-15
|
|
7
|
+
|
|
8
|
+
Outdated base version: https://github.com/primer/github-syntax-light
|
|
9
|
+
Current colors taken from GitHub's CSS
|
|
10
|
+
*/.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}
|