claude-code-workflow 6.0.0
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/agents/action-planning-agent.md +778 -0
- package/.claude/agents/cli-execution-agent.md +270 -0
- package/.claude/agents/cli-explore-agent.md +182 -0
- package/.claude/agents/cli-lite-planning-agent.md +396 -0
- package/.claude/agents/cli-planning-agent.md +558 -0
- package/.claude/agents/code-developer.md +310 -0
- package/.claude/agents/conceptual-planning-agent.md +308 -0
- package/.claude/agents/context-search-agent.md +582 -0
- package/.claude/agents/doc-generator.md +330 -0
- package/.claude/agents/memory-bridge.md +94 -0
- package/.claude/agents/test-context-search-agent.md +399 -0
- package/.claude/agents/test-fix-agent.md +343 -0
- package/.claude/agents/ui-design-agent.md +593 -0
- package/.claude/agents/universal-executor.md +131 -0
- package/.claude/commands/cli/cli-init.md +440 -0
- package/.claude/commands/enhance-prompt.md +93 -0
- package/.claude/commands/memory/code-map-memory.md +687 -0
- package/.claude/commands/memory/docs-full-cli.md +471 -0
- package/.claude/commands/memory/docs-related-cli.md +386 -0
- package/.claude/commands/memory/docs.md +615 -0
- package/.claude/commands/memory/load-skill-memory.md +182 -0
- package/.claude/commands/memory/load.md +240 -0
- package/.claude/commands/memory/skill-memory.md +525 -0
- package/.claude/commands/memory/style-skill-memory.md +396 -0
- package/.claude/commands/memory/tech-research.md +477 -0
- package/.claude/commands/memory/update-full.md +332 -0
- package/.claude/commands/memory/update-related.md +332 -0
- package/.claude/commands/memory/workflow-skill-memory.md +517 -0
- package/.claude/commands/task/breakdown.md +204 -0
- package/.claude/commands/task/create.md +152 -0
- package/.claude/commands/task/execute.md +270 -0
- package/.claude/commands/task/replan.md +437 -0
- package/.claude/commands/version.md +254 -0
- package/.claude/commands/workflow/action-plan-verify.md +447 -0
- package/.claude/commands/workflow/brainstorm/api-designer.md +585 -0
- package/.claude/commands/workflow/brainstorm/artifacts.md +452 -0
- package/.claude/commands/workflow/brainstorm/auto-parallel.md +443 -0
- package/.claude/commands/workflow/brainstorm/data-architect.md +220 -0
- package/.claude/commands/workflow/brainstorm/product-manager.md +200 -0
- package/.claude/commands/workflow/brainstorm/product-owner.md +200 -0
- package/.claude/commands/workflow/brainstorm/scrum-master.md +200 -0
- package/.claude/commands/workflow/brainstorm/subject-matter-expert.md +200 -0
- package/.claude/commands/workflow/brainstorm/synthesis.md +398 -0
- package/.claude/commands/workflow/brainstorm/system-architect.md +387 -0
- package/.claude/commands/workflow/brainstorm/ui-designer.md +221 -0
- package/.claude/commands/workflow/brainstorm/ux-expert.md +221 -0
- package/.claude/commands/workflow/execute.md +460 -0
- package/.claude/commands/workflow/init.md +164 -0
- package/.claude/commands/workflow/lite-execute.md +686 -0
- package/.claude/commands/workflow/lite-fix.md +621 -0
- package/.claude/commands/workflow/lite-plan.md +592 -0
- package/.claude/commands/workflow/plan.md +551 -0
- package/.claude/commands/workflow/replan.md +515 -0
- package/.claude/commands/workflow/review-fix.md +646 -0
- package/.claude/commands/workflow/review-module-cycle.md +795 -0
- package/.claude/commands/workflow/review-session-cycle.md +805 -0
- package/.claude/commands/workflow/review.md +291 -0
- package/.claude/commands/workflow/session/complete.md +500 -0
- package/.claude/commands/workflow/session/list.md +96 -0
- package/.claude/commands/workflow/session/resume.md +61 -0
- package/.claude/commands/workflow/session/start.md +200 -0
- package/.claude/commands/workflow/status.md +352 -0
- package/.claude/commands/workflow/tdd-plan.md +460 -0
- package/.claude/commands/workflow/tdd-verify.md +386 -0
- package/.claude/commands/workflow/test-cycle-execute.md +498 -0
- package/.claude/commands/workflow/test-fix-gen.md +699 -0
- package/.claude/commands/workflow/test-gen.md +529 -0
- package/.claude/commands/workflow/tools/conflict-resolution.md +680 -0
- package/.claude/commands/workflow/tools/context-gather.md +434 -0
- package/.claude/commands/workflow/tools/task-generate-agent.md +291 -0
- package/.claude/commands/workflow/tools/task-generate-tdd.md +518 -0
- package/.claude/commands/workflow/tools/tdd-coverage-analysis.md +309 -0
- package/.claude/commands/workflow/tools/test-concept-enhanced.md +163 -0
- package/.claude/commands/workflow/tools/test-context-gather.md +235 -0
- package/.claude/commands/workflow/tools/test-task-generate.md +256 -0
- package/.claude/commands/workflow/ui-design/animation-extract.md +1150 -0
- package/.claude/commands/workflow/ui-design/codify-style.md +652 -0
- package/.claude/commands/workflow/ui-design/design-sync.md +454 -0
- package/.claude/commands/workflow/ui-design/explore-auto.md +678 -0
- package/.claude/commands/workflow/ui-design/generate.md +504 -0
- package/.claude/commands/workflow/ui-design/imitate-auto.md +745 -0
- package/.claude/commands/workflow/ui-design/import-from-code.md +537 -0
- package/.claude/commands/workflow/ui-design/layout-extract.md +788 -0
- package/.claude/commands/workflow/ui-design/reference-page-generator.md +356 -0
- package/.claude/commands/workflow/ui-design/style-extract.md +773 -0
- package/.claude/scripts/classify-folders.sh +35 -0
- package/.claude/scripts/convert_tokens_to_css.sh +225 -0
- package/.claude/scripts/detect_changed_modules.sh +157 -0
- package/.claude/scripts/discover-design-files.sh +83 -0
- package/.claude/scripts/extract-animations.js +243 -0
- package/.claude/scripts/extract-computed-styles.js +118 -0
- package/.claude/scripts/extract-layout-structure.js +411 -0
- package/.claude/scripts/generate_module_docs.sh +713 -0
- package/.claude/scripts/get_modules_by_depth.sh +166 -0
- package/.claude/scripts/ui-generate-preview.sh +391 -0
- package/.claude/scripts/ui-instantiate-prototypes.sh +811 -0
- package/.claude/scripts/update_module_claude.sh +333 -0
- package/.claude/skills/command-guide/SKILL.md +388 -0
- package/.claude/skills/command-guide/UPDATE-GUIDELINE.md +592 -0
- package/.claude/skills/command-guide/guides/cli-tools-guide.md +410 -0
- package/.claude/skills/command-guide/guides/examples.md +537 -0
- package/.claude/skills/command-guide/guides/getting-started.md +242 -0
- package/.claude/skills/command-guide/guides/implementation-details.md +1010 -0
- package/.claude/skills/command-guide/guides/index-structure.md +326 -0
- package/.claude/skills/command-guide/guides/troubleshooting.md +92 -0
- package/.claude/skills/command-guide/guides/ui-design-workflow-guide.md +316 -0
- package/.claude/skills/command-guide/guides/workflow-patterns.md +662 -0
- package/.claude/skills/command-guide/index/all-commands.json +783 -0
- package/.claude/skills/command-guide/index/by-category.json +811 -0
- package/.claude/skills/command-guide/index/by-use-case.json +797 -0
- package/.claude/skills/command-guide/index/command-relationships.json +307 -0
- package/.claude/skills/command-guide/index/essential-commands.json +123 -0
- package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +722 -0
- package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +270 -0
- package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +182 -0
- package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +396 -0
- package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +558 -0
- package/.claude/skills/command-guide/reference/agents/code-developer.md +310 -0
- package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +328 -0
- package/.claude/skills/command-guide/reference/agents/context-search-agent.md +577 -0
- package/.claude/skills/command-guide/reference/agents/doc-generator.md +330 -0
- package/.claude/skills/command-guide/reference/agents/memory-bridge.md +94 -0
- package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +399 -0
- package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +343 -0
- package/.claude/skills/command-guide/reference/agents/ui-design-agent.md +593 -0
- package/.claude/skills/command-guide/reference/agents/universal-executor.md +131 -0
- package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +440 -0
- package/.claude/skills/command-guide/reference/commands/enhance-prompt.md +93 -0
- package/.claude/skills/command-guide/reference/commands/memory/code-map-memory.md +687 -0
- package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -0
- package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -0
- package/.claude/skills/command-guide/reference/commands/memory/docs.md +610 -0
- package/.claude/skills/command-guide/reference/commands/memory/load-skill-memory.md +182 -0
- package/.claude/skills/command-guide/reference/commands/memory/load.md +240 -0
- package/.claude/skills/command-guide/reference/commands/memory/skill-memory.md +525 -0
- package/.claude/skills/command-guide/reference/commands/memory/style-skill-memory.md +396 -0
- package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +477 -0
- package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -0
- package/.claude/skills/command-guide/reference/commands/memory/update-related.md +332 -0
- package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +517 -0
- package/.claude/skills/command-guide/reference/commands/task/breakdown.md +204 -0
- package/.claude/skills/command-guide/reference/commands/task/create.md +152 -0
- package/.claude/skills/command-guide/reference/commands/task/execute.md +270 -0
- package/.claude/skills/command-guide/reference/commands/task/replan.md +437 -0
- package/.claude/skills/command-guide/reference/commands/version.md +254 -0
- package/.claude/skills/command-guide/reference/commands/workflow/action-plan-verify.md +447 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +585 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +604 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +466 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +220 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +200 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +200 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +200 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +200 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +496 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +387 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +221 -0
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +221 -0
- package/.claude/skills/command-guide/reference/commands/workflow/execute.md +460 -0
- package/.claude/skills/command-guide/reference/commands/workflow/init.md +164 -0
- package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +634 -0
- package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +602 -0
- package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +582 -0
- package/.claude/skills/command-guide/reference/commands/workflow/plan.md +551 -0
- package/.claude/skills/command-guide/reference/commands/workflow/replan.md +515 -0
- package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +646 -0
- package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +795 -0
- package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +805 -0
- package/.claude/skills/command-guide/reference/commands/workflow/review.md +291 -0
- package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +500 -0
- package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +96 -0
- package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +61 -0
- package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +180 -0
- package/.claude/skills/command-guide/reference/commands/workflow/status.md +352 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +460 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +386 -0
- package/.claude/skills/command-guide/reference/commands/workflow/test-cycle-execute.md +498 -0
- package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +699 -0
- package/.claude/skills/command-guide/reference/commands/workflow/test-gen.md +529 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +680 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +151 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +518 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tools/tdd-coverage-analysis.md +309 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +163 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-context-gather.md +235 -0
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +256 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/animation-extract.md +1150 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/codify-style.md +652 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/design-sync.md +454 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/explore-auto.md +678 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +504 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/imitate-auto.md +745 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +537 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/layout-extract.md +788 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/reference-page-generator.md +356 -0
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/style-extract.md +773 -0
- package/.claude/skills/command-guide/scripts/analyze_commands.py +502 -0
- package/.claude/skills/command-guide/scripts/update-index.sh +130 -0
- package/.claude/skills/command-guide/templates/issue-bug.md +104 -0
- package/.claude/skills/command-guide/templates/issue-diagnosis.md +275 -0
- package/.claude/skills/command-guide/templates/issue-feature.md +97 -0
- package/.claude/skills/command-guide/templates/issue-question.md +141 -0
- package/.claude/skills/prompt-enhancer/SKILL.md +124 -0
- package/.claude/workflows/_template-compare-matrix.html +692 -0
- package/.claude/workflows/cli-templates/fix-plan-template.json +75 -0
- package/.claude/workflows/cli-templates/fix-progress-template.json +48 -0
- package/.claude/workflows/cli-templates/memory/style-skill-memory/skill-md-template.md +299 -0
- package/.claude/workflows/cli-templates/planning-roles/data-architect.md +120 -0
- package/.claude/workflows/cli-templates/planning-roles/product-manager.md +119 -0
- package/.claude/workflows/cli-templates/planning-roles/product-owner.md +261 -0
- package/.claude/workflows/cli-templates/planning-roles/scrum-master.md +186 -0
- package/.claude/workflows/cli-templates/planning-roles/subject-matter-expert.md +281 -0
- package/.claude/workflows/cli-templates/planning-roles/synthesis-role.md +414 -0
- package/.claude/workflows/cli-templates/planning-roles/system-architect.md +106 -0
- package/.claude/workflows/cli-templates/planning-roles/test-strategist.md +124 -0
- package/.claude/workflows/cli-templates/planning-roles/ui-designer.md +379 -0
- package/.claude/workflows/cli-templates/planning-roles/ux-expert.md +240 -0
- package/.claude/workflows/cli-templates/prompts/analysis/01-diagnose-bug-root-cause.txt +127 -0
- package/.claude/workflows/cli-templates/prompts/analysis/01-trace-code-execution.txt +115 -0
- package/.claude/workflows/cli-templates/prompts/analysis/02-analyze-code-patterns.txt +37 -0
- package/.claude/workflows/cli-templates/prompts/analysis/02-analyze-technical-document.txt +33 -0
- package/.claude/workflows/cli-templates/prompts/analysis/02-review-architecture.txt +29 -0
- package/.claude/workflows/cli-templates/prompts/analysis/02-review-code-quality.txt +28 -0
- package/.claude/workflows/cli-templates/prompts/analysis/03-analyze-performance.txt +29 -0
- package/.claude/workflows/cli-templates/prompts/analysis/03-assess-security-risks.txt +29 -0
- package/.claude/workflows/cli-templates/prompts/analysis/03-review-quality-standards.txt +29 -0
- package/.claude/workflows/cli-templates/prompts/development/02-generate-tests.txt +70 -0
- package/.claude/workflows/cli-templates/prompts/development/02-implement-component-ui.txt +55 -0
- package/.claude/workflows/cli-templates/prompts/development/02-implement-feature.txt +58 -0
- package/.claude/workflows/cli-templates/prompts/development/02-refactor-codebase.txt +55 -0
- package/.claude/workflows/cli-templates/prompts/development/03-debug-runtime-issues.txt +55 -0
- package/.claude/workflows/cli-templates/prompts/documentation/api.txt +15 -0
- package/.claude/workflows/cli-templates/prompts/documentation/folder-navigation.txt +27 -0
- package/.claude/workflows/cli-templates/prompts/documentation/module-readme.txt +49 -0
- package/.claude/workflows/cli-templates/prompts/documentation/project-architecture.txt +41 -0
- package/.claude/workflows/cli-templates/prompts/documentation/project-examples.txt +35 -0
- package/.claude/workflows/cli-templates/prompts/documentation/project-readme.txt +35 -0
- package/.claude/workflows/cli-templates/prompts/memory/02-document-module-structure.txt +165 -0
- package/.claude/workflows/cli-templates/prompts/planning/01-plan-architecture-design.txt +109 -0
- package/.claude/workflows/cli-templates/prompts/planning/02-breakdown-task-steps.txt +30 -0
- package/.claude/workflows/cli-templates/prompts/planning/02-design-component-spec.txt +28 -0
- package/.claude/workflows/cli-templates/prompts/planning/03-evaluate-concept-feasibility.txt +127 -0
- package/.claude/workflows/cli-templates/prompts/planning/03-plan-migration-strategy.txt +30 -0
- package/.claude/workflows/cli-templates/prompts/tech/tech-module-format.txt +359 -0
- package/.claude/workflows/cli-templates/prompts/tech/tech-skill-index.txt +185 -0
- package/.claude/workflows/cli-templates/prompts/test/test-concept-analysis.txt +179 -0
- package/.claude/workflows/cli-templates/prompts/universal/00-universal-creative-style.txt +95 -0
- package/.claude/workflows/cli-templates/prompts/universal/00-universal-rigorous-style.txt +92 -0
- package/.claude/workflows/cli-templates/prompts/verification/codex-technical.txt +28 -0
- package/.claude/workflows/cli-templates/prompts/verification/cross-validation.txt +28 -0
- package/.claude/workflows/cli-templates/prompts/verification/gemini-strategic.txt +27 -0
- package/.claude/workflows/cli-templates/prompts/workflow/analysis-results-structure.txt +224 -0
- package/.claude/workflows/cli-templates/prompts/workflow/codex-feasibility-validation.txt +176 -0
- package/.claude/workflows/cli-templates/prompts/workflow/gemini-solution-design.txt +131 -0
- package/.claude/workflows/cli-templates/prompts/workflow/impl-plan-template.txt +286 -0
- package/.claude/workflows/cli-templates/prompts/workflow/skill-aggregation.txt +172 -0
- package/.claude/workflows/cli-templates/prompts/workflow/skill-conflict-patterns.txt +98 -0
- package/.claude/workflows/cli-templates/prompts/workflow/skill-index.txt +224 -0
- package/.claude/workflows/cli-templates/prompts/workflow/skill-lessons-learned.txt +98 -0
- package/.claude/workflows/cli-templates/prompts/workflow/skill-sessions-timeline.txt +53 -0
- package/.claude/workflows/cli-templates/prompts/workflow/task-json-agent-mode.txt +123 -0
- package/.claude/workflows/cli-templates/prompts/workflow/task-json-cli-mode.txt +182 -0
- package/.claude/workflows/cli-templates/schemas/diagnosis-json-schema.json +234 -0
- package/.claude/workflows/cli-templates/schemas/explore-json-schema.json +124 -0
- package/.claude/workflows/cli-templates/schemas/fix-plan-json-schema.json +273 -0
- package/.claude/workflows/cli-templates/schemas/plan-json-schema.json +219 -0
- package/.claude/workflows/cli-templates/schemas/project-json-schema.json +221 -0
- package/.claude/workflows/cli-templates/schemas/review-deep-dive-results-schema.json +82 -0
- package/.claude/workflows/cli-templates/schemas/review-dimension-results-schema.json +51 -0
- package/.claude/workflows/cli-templates/tech-stacks/go-dev.md +91 -0
- package/.claude/workflows/cli-templates/tech-stacks/java-dev.md +107 -0
- package/.claude/workflows/cli-templates/tech-stacks/javascript-dev.md +58 -0
- package/.claude/workflows/cli-templates/tech-stacks/python-dev.md +79 -0
- package/.claude/workflows/cli-templates/tech-stacks/react-dev.md +103 -0
- package/.claude/workflows/cli-templates/tech-stacks/typescript-dev.md +83 -0
- package/.claude/workflows/cli-templates/ui-design/systems/animation-tokens.json +247 -0
- package/.claude/workflows/cli-templates/ui-design/systems/design-tokens.json +342 -0
- package/.claude/workflows/cli-templates/ui-design/systems/layout-templates.json +145 -0
- package/.claude/workflows/context-search-strategy.md +77 -0
- package/.claude/workflows/intelligent-tools-strategy.md +662 -0
- package/.claude/workflows/review-directory-specification.md +336 -0
- package/.claude/workflows/task-core.md +214 -0
- package/.claude/workflows/tool-strategy.md +71 -0
- package/.claude/workflows/workflow-architecture.md +942 -0
- package/.codex/AGENTS.md +330 -0
- package/.gemini/GEMINI.md +164 -0
- package/.qwen/QWEN.md +164 -0
- package/CLAUDE.md +91 -0
- package/LICENSE +21 -0
- package/README.md +219 -0
- package/ccw/README.md +121 -0
- package/ccw/bin/ccw.js +10 -0
- package/ccw/src/cli.js +100 -0
- package/ccw/src/commands/install.js +324 -0
- package/ccw/src/commands/list.js +37 -0
- package/ccw/src/commands/serve.js +67 -0
- package/ccw/src/commands/uninstall.js +238 -0
- package/ccw/src/commands/upgrade.js +307 -0
- package/ccw/src/commands/view.js +14 -0
- package/ccw/src/core/dashboard-generator-patch.js +29 -0
- package/ccw/src/core/dashboard-generator.js +667 -0
- package/ccw/src/core/data-aggregator.js +409 -0
- package/ccw/src/core/lite-scanner.js +290 -0
- package/ccw/src/core/manifest.js +201 -0
- package/ccw/src/core/server.js +1327 -0
- package/ccw/src/core/server.js.bak +385 -0
- package/ccw/src/core/server_original.bak +385 -0
- package/ccw/src/core/session-scanner.js +235 -0
- package/ccw/src/index.js +9 -0
- package/ccw/src/templates/dashboard-js/api.js +200 -0
- package/ccw/src/templates/dashboard-js/components/_conflict_tab.js +112 -0
- package/ccw/src/templates/dashboard-js/components/_exp_helpers.js +54 -0
- package/ccw/src/templates/dashboard-js/components/_review_tab.js +640 -0
- package/ccw/src/templates/dashboard-js/components/carousel.js +398 -0
- package/ccw/src/templates/dashboard-js/components/flowchart.js +493 -0
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +273 -0
- package/ccw/src/templates/dashboard-js/components/mcp-manager.js +506 -0
- package/ccw/src/templates/dashboard-js/components/modals.js +260 -0
- package/ccw/src/templates/dashboard-js/components/navigation.js +239 -0
- package/ccw/src/templates/dashboard-js/components/notifications.js +194 -0
- package/ccw/src/templates/dashboard-js/components/sidebar.js +31 -0
- package/ccw/src/templates/dashboard-js/components/tabs-context.js +1093 -0
- package/ccw/src/templates/dashboard-js/components/tabs-other.js +273 -0
- package/ccw/src/templates/dashboard-js/components/task-drawer-core.js +477 -0
- package/ccw/src/templates/dashboard-js/components/task-drawer-renderers.js +447 -0
- package/ccw/src/templates/dashboard-js/components/theme.js +21 -0
- package/ccw/src/templates/dashboard-js/main.js +57 -0
- package/ccw/src/templates/dashboard-js/state.js +37 -0
- package/ccw/src/templates/dashboard-js/utils.js +153 -0
- package/ccw/src/templates/dashboard-js/views/fix-session.js +180 -0
- package/ccw/src/templates/dashboard-js/views/home.js +193 -0
- package/ccw/src/templates/dashboard-js/views/hook-manager.js +387 -0
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +390 -0
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +271 -0
- package/ccw/src/templates/dashboard-js/views/project-overview.js +246 -0
- package/ccw/src/templates/dashboard-js/views/review-session.js +711 -0
- package/ccw/src/templates/dashboard-js/views/session-detail.js +770 -0
- package/ccw/src/templates/dashboard.css +7660 -0
- package/ccw/src/templates/dashboard.html +630 -0
- package/ccw/src/templates/dashboard_tailwind.html +42 -0
- package/ccw/src/templates/dashboard_test.html +37 -0
- package/ccw/src/templates/review-cycle-dashboard.html +1930 -0
- package/ccw/src/templates/tailwind-base.css +212 -0
- package/ccw/src/templates/workflow-dashboard.html +401 -0
- package/ccw/src/utils/browser-launcher.js +49 -0
- package/ccw/src/utils/file-utils.js +48 -0
- package/ccw/src/utils/path-resolver.js +279 -0
- package/ccw/src/utils/ui.js +148 -0
- package/package.json +66 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, statSync, copyFileSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join, dirname, basename } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { showHeader, createSpinner, info, warning, error, summaryBox, divider } from '../utils/ui.js';
|
|
8
|
+
import { createManifest, addFileEntry, addDirectoryEntry, saveManifest, findManifest, getAllManifests } from '../core/manifest.js';
|
|
9
|
+
import { validatePath } from '../utils/path-resolver.js';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
// Source directories to install
|
|
15
|
+
const SOURCE_DIRS = ['.claude', '.codex', '.gemini', '.qwen'];
|
|
16
|
+
|
|
17
|
+
// Get package root directory (ccw/src/commands -> ccw)
|
|
18
|
+
function getPackageRoot() {
|
|
19
|
+
return join(__dirname, '..', '..');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Get source installation directory (parent of ccw)
|
|
23
|
+
function getSourceDir() {
|
|
24
|
+
return join(getPackageRoot(), '..');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Install command handler
|
|
29
|
+
* @param {Object} options - Command options
|
|
30
|
+
*/
|
|
31
|
+
export async function installCommand(options) {
|
|
32
|
+
const version = getVersion();
|
|
33
|
+
|
|
34
|
+
// Show beautiful header
|
|
35
|
+
showHeader(version);
|
|
36
|
+
|
|
37
|
+
// Check for existing installations
|
|
38
|
+
const existingManifests = getAllManifests();
|
|
39
|
+
if (existingManifests.length > 0 && !options.force) {
|
|
40
|
+
info('Existing installations detected:');
|
|
41
|
+
console.log('');
|
|
42
|
+
existingManifests.forEach((m, i) => {
|
|
43
|
+
console.log(chalk.gray(` ${i + 1}. ${m.installation_mode} - ${m.installation_path}`));
|
|
44
|
+
console.log(chalk.gray(` Installed: ${new Date(m.installation_date).toLocaleDateString()}`));
|
|
45
|
+
});
|
|
46
|
+
console.log('');
|
|
47
|
+
|
|
48
|
+
const { proceed } = await inquirer.prompt([{
|
|
49
|
+
type: 'confirm',
|
|
50
|
+
name: 'proceed',
|
|
51
|
+
message: 'Continue with new installation?',
|
|
52
|
+
default: true
|
|
53
|
+
}]);
|
|
54
|
+
|
|
55
|
+
if (!proceed) {
|
|
56
|
+
info('Installation cancelled');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Local installation from package source
|
|
62
|
+
const sourceDir = getSourceDir();
|
|
63
|
+
|
|
64
|
+
// Interactive mode selection
|
|
65
|
+
const mode = options.mode || await selectMode();
|
|
66
|
+
|
|
67
|
+
let installPath;
|
|
68
|
+
if (mode === 'Global') {
|
|
69
|
+
installPath = homedir();
|
|
70
|
+
info(`Global installation to: ${installPath}`);
|
|
71
|
+
} else {
|
|
72
|
+
const inputPath = options.path || await selectPath();
|
|
73
|
+
|
|
74
|
+
// Validate the installation path
|
|
75
|
+
const pathValidation = validatePath(inputPath, { mustExist: true });
|
|
76
|
+
if (!pathValidation.valid) {
|
|
77
|
+
error(`Invalid installation path: ${pathValidation.error}`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
installPath = pathValidation.path;
|
|
82
|
+
info(`Path installation to: ${installPath}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Validate source directories exist
|
|
86
|
+
const availableDirs = SOURCE_DIRS.filter(dir => existsSync(join(sourceDir, dir)));
|
|
87
|
+
|
|
88
|
+
if (availableDirs.length === 0) {
|
|
89
|
+
error('No source directories found to install.');
|
|
90
|
+
error(`Expected directories in: ${sourceDir}`);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log('');
|
|
95
|
+
info(`Found ${availableDirs.length} directories to install: ${availableDirs.join(', ')}`);
|
|
96
|
+
divider();
|
|
97
|
+
|
|
98
|
+
// Check for existing installation at target path
|
|
99
|
+
const existingManifest = findManifest(installPath, mode);
|
|
100
|
+
if (existingManifest) {
|
|
101
|
+
warning('Existing installation found at this location');
|
|
102
|
+
const { backup } = await inquirer.prompt([{
|
|
103
|
+
type: 'confirm',
|
|
104
|
+
name: 'backup',
|
|
105
|
+
message: 'Create backup before reinstalling?',
|
|
106
|
+
default: true
|
|
107
|
+
}]);
|
|
108
|
+
|
|
109
|
+
if (backup) {
|
|
110
|
+
await createBackup(installPath, existingManifest);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Create manifest
|
|
115
|
+
const manifest = createManifest(mode, installPath);
|
|
116
|
+
|
|
117
|
+
// Perform installation
|
|
118
|
+
console.log('');
|
|
119
|
+
const spinner = createSpinner('Installing files...').start();
|
|
120
|
+
|
|
121
|
+
let totalFiles = 0;
|
|
122
|
+
let totalDirs = 0;
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
for (const dir of availableDirs) {
|
|
126
|
+
const srcPath = join(sourceDir, dir);
|
|
127
|
+
const destPath = join(installPath, dir);
|
|
128
|
+
|
|
129
|
+
spinner.text = `Installing ${dir}...`;
|
|
130
|
+
|
|
131
|
+
const { files, directories } = await copyDirectory(srcPath, destPath, manifest);
|
|
132
|
+
totalFiles += files;
|
|
133
|
+
totalDirs += directories;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Copy CLAUDE.md to .claude directory
|
|
137
|
+
const claudeMdSrc = join(sourceDir, 'CLAUDE.md');
|
|
138
|
+
const claudeMdDest = join(installPath, '.claude', 'CLAUDE.md');
|
|
139
|
+
if (existsSync(claudeMdSrc) && existsSync(dirname(claudeMdDest))) {
|
|
140
|
+
spinner.text = 'Installing CLAUDE.md...';
|
|
141
|
+
copyFileSync(claudeMdSrc, claudeMdDest);
|
|
142
|
+
addFileEntry(manifest, claudeMdDest);
|
|
143
|
+
totalFiles++;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Create version.json
|
|
147
|
+
const versionPath = join(installPath, '.claude', 'version.json');
|
|
148
|
+
if (existsSync(dirname(versionPath))) {
|
|
149
|
+
const versionData = {
|
|
150
|
+
version: version,
|
|
151
|
+
installedAt: new Date().toISOString(),
|
|
152
|
+
mode: mode,
|
|
153
|
+
installer: 'ccw'
|
|
154
|
+
};
|
|
155
|
+
writeFileSync(versionPath, JSON.stringify(versionData, null, 2), 'utf8');
|
|
156
|
+
addFileEntry(manifest, versionPath);
|
|
157
|
+
totalFiles++;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
spinner.succeed('Installation complete!');
|
|
161
|
+
|
|
162
|
+
} catch (err) {
|
|
163
|
+
spinner.fail('Installation failed');
|
|
164
|
+
error(err.message);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Save manifest
|
|
169
|
+
const manifestPath = saveManifest(manifest);
|
|
170
|
+
|
|
171
|
+
// Show summary
|
|
172
|
+
console.log('');
|
|
173
|
+
const summaryLines = [
|
|
174
|
+
chalk.green.bold('✓ Installation Successful'),
|
|
175
|
+
'',
|
|
176
|
+
chalk.white(`Mode: ${chalk.cyan(mode)}`),
|
|
177
|
+
chalk.white(`Path: ${chalk.cyan(installPath)}`),
|
|
178
|
+
chalk.white(`Version: ${chalk.cyan(version)}`),
|
|
179
|
+
'',
|
|
180
|
+
chalk.gray(`Files installed: ${totalFiles}`),
|
|
181
|
+
chalk.gray(`Directories created: ${totalDirs}`),
|
|
182
|
+
'',
|
|
183
|
+
chalk.gray(`Manifest: ${basename(manifestPath)}`)
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
summaryBox({
|
|
187
|
+
title: ' Installation Summary ',
|
|
188
|
+
lines: summaryLines,
|
|
189
|
+
borderColor: 'green'
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Show next steps
|
|
193
|
+
console.log('');
|
|
194
|
+
info('Next steps:');
|
|
195
|
+
console.log(chalk.gray(' 1. Restart Claude Code or your IDE'));
|
|
196
|
+
console.log(chalk.gray(' 2. Run: ccw view - to open the workflow dashboard'));
|
|
197
|
+
console.log(chalk.gray(' 3. Run: ccw uninstall - to remove this installation'));
|
|
198
|
+
console.log('');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Interactive mode selection
|
|
203
|
+
* @returns {Promise<string>} - Selected mode
|
|
204
|
+
*/
|
|
205
|
+
async function selectMode() {
|
|
206
|
+
const { mode } = await inquirer.prompt([{
|
|
207
|
+
type: 'list',
|
|
208
|
+
name: 'mode',
|
|
209
|
+
message: 'Select installation mode:',
|
|
210
|
+
choices: [
|
|
211
|
+
{
|
|
212
|
+
name: `${chalk.cyan('Global')} - Install to home directory (recommended)`,
|
|
213
|
+
value: 'Global'
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: `${chalk.yellow('Path')} - Install to specific project path`,
|
|
217
|
+
value: 'Path'
|
|
218
|
+
}
|
|
219
|
+
]
|
|
220
|
+
}]);
|
|
221
|
+
|
|
222
|
+
return mode;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Interactive path selection
|
|
227
|
+
* @returns {Promise<string>} - Selected path
|
|
228
|
+
*/
|
|
229
|
+
async function selectPath() {
|
|
230
|
+
const { path } = await inquirer.prompt([{
|
|
231
|
+
type: 'input',
|
|
232
|
+
name: 'path',
|
|
233
|
+
message: 'Enter installation path:',
|
|
234
|
+
default: process.cwd(),
|
|
235
|
+
validate: (input) => {
|
|
236
|
+
if (!input) return 'Path is required';
|
|
237
|
+
if (!existsSync(input)) {
|
|
238
|
+
return `Path does not exist: ${input}`;
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
}]);
|
|
243
|
+
|
|
244
|
+
return path;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Create backup of existing installation
|
|
249
|
+
* @param {string} installPath - Installation path
|
|
250
|
+
* @param {Object} manifest - Existing manifest
|
|
251
|
+
*/
|
|
252
|
+
async function createBackup(installPath, manifest) {
|
|
253
|
+
const spinner = createSpinner('Creating backup...').start();
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace('T', '-').split('.')[0];
|
|
257
|
+
const backupDir = join(installPath, `.claude-backup-${timestamp}`);
|
|
258
|
+
|
|
259
|
+
mkdirSync(backupDir, { recursive: true });
|
|
260
|
+
|
|
261
|
+
// Copy existing .claude directory
|
|
262
|
+
const claudeDir = join(installPath, '.claude');
|
|
263
|
+
if (existsSync(claudeDir)) {
|
|
264
|
+
await copyDirectory(claudeDir, join(backupDir, '.claude'));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
spinner.succeed(`Backup created: ${backupDir}`);
|
|
268
|
+
} catch (err) {
|
|
269
|
+
spinner.warn(`Backup failed: ${err.message}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Copy directory recursively
|
|
275
|
+
* @param {string} src - Source directory
|
|
276
|
+
* @param {string} dest - Destination directory
|
|
277
|
+
* @param {Object} manifest - Manifest to track files (optional)
|
|
278
|
+
* @returns {Object} - Count of files and directories
|
|
279
|
+
*/
|
|
280
|
+
async function copyDirectory(src, dest, manifest = null) {
|
|
281
|
+
let files = 0;
|
|
282
|
+
let directories = 0;
|
|
283
|
+
|
|
284
|
+
// Create destination directory
|
|
285
|
+
if (!existsSync(dest)) {
|
|
286
|
+
mkdirSync(dest, { recursive: true });
|
|
287
|
+
directories++;
|
|
288
|
+
if (manifest) addDirectoryEntry(manifest, dest);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const entries = readdirSync(src);
|
|
292
|
+
|
|
293
|
+
for (const entry of entries) {
|
|
294
|
+
const srcPath = join(src, entry);
|
|
295
|
+
const destPath = join(dest, entry);
|
|
296
|
+
const stat = statSync(srcPath);
|
|
297
|
+
|
|
298
|
+
if (stat.isDirectory()) {
|
|
299
|
+
const result = await copyDirectory(srcPath, destPath, manifest);
|
|
300
|
+
files += result.files;
|
|
301
|
+
directories += result.directories;
|
|
302
|
+
} else {
|
|
303
|
+
copyFileSync(srcPath, destPath);
|
|
304
|
+
files++;
|
|
305
|
+
if (manifest) addFileEntry(manifest, destPath);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return { files, directories };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Get package version
|
|
314
|
+
* @returns {string} - Version string
|
|
315
|
+
*/
|
|
316
|
+
function getVersion() {
|
|
317
|
+
try {
|
|
318
|
+
const pkgPath = join(getPackageRoot(), 'package.json');
|
|
319
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
320
|
+
return pkg.version || '1.0.0';
|
|
321
|
+
} catch {
|
|
322
|
+
return '1.0.0';
|
|
323
|
+
}
|
|
324
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { showBanner, divider, info } from '../utils/ui.js';
|
|
3
|
+
import { getAllManifests } from '../core/manifest.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* List command handler - shows all installations
|
|
7
|
+
*/
|
|
8
|
+
export async function listCommand() {
|
|
9
|
+
showBanner();
|
|
10
|
+
console.log(chalk.cyan.bold(' Installed Claude Code Workflow Instances\n'));
|
|
11
|
+
|
|
12
|
+
const manifests = getAllManifests();
|
|
13
|
+
|
|
14
|
+
if (manifests.length === 0) {
|
|
15
|
+
info('No installations found.');
|
|
16
|
+
console.log('');
|
|
17
|
+
console.log(chalk.gray(' Run: ccw install - to install Claude Code Workflow'));
|
|
18
|
+
console.log('');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
manifests.forEach((m, i) => {
|
|
23
|
+
const modeColor = m.installation_mode === 'Global' ? chalk.cyan : chalk.yellow;
|
|
24
|
+
|
|
25
|
+
console.log(chalk.white.bold(` ${i + 1}. `) + modeColor.bold(m.installation_mode));
|
|
26
|
+
console.log(chalk.gray(` Path: ${m.installation_path}`));
|
|
27
|
+
console.log(chalk.gray(` Date: ${new Date(m.installation_date).toLocaleDateString()}`));
|
|
28
|
+
console.log(chalk.gray(` Version: ${m.application_version}`));
|
|
29
|
+
console.log(chalk.gray(` Files: ${m.files_count}`));
|
|
30
|
+
console.log(chalk.gray(` Dirs: ${m.directories_count}`));
|
|
31
|
+
console.log('');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
divider();
|
|
35
|
+
console.log(chalk.gray(' Run: ccw uninstall - to remove an installation'));
|
|
36
|
+
console.log('');
|
|
37
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { startServer } from '../core/server.js';
|
|
2
|
+
import { launchBrowser } from '../utils/browser-launcher.js';
|
|
3
|
+
import { resolvePath, validatePath } from '../utils/path-resolver.js';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Serve command handler - starts dashboard server with live path switching
|
|
8
|
+
* @param {Object} options - Command options
|
|
9
|
+
*/
|
|
10
|
+
export async function serveCommand(options) {
|
|
11
|
+
const port = options.port || 3456;
|
|
12
|
+
|
|
13
|
+
// Validate project path
|
|
14
|
+
let initialPath = process.cwd();
|
|
15
|
+
if (options.path) {
|
|
16
|
+
const pathValidation = validatePath(options.path, { mustExist: true });
|
|
17
|
+
if (!pathValidation.valid) {
|
|
18
|
+
console.error(chalk.red(`\n Error: ${pathValidation.error}\n`));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
initialPath = pathValidation.path;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log(chalk.blue.bold('\n CCW Dashboard Server\n'));
|
|
25
|
+
console.log(chalk.gray(` Initial project: ${initialPath}`));
|
|
26
|
+
console.log(chalk.gray(` Port: ${port}\n`));
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
// Start server
|
|
30
|
+
console.log(chalk.cyan(' Starting server...'));
|
|
31
|
+
const server = await startServer({ port, initialPath });
|
|
32
|
+
|
|
33
|
+
const url = `http://localhost:${port}`;
|
|
34
|
+
console.log(chalk.green(` Server running at ${url}`));
|
|
35
|
+
|
|
36
|
+
// Open browser
|
|
37
|
+
if (options.browser !== false) {
|
|
38
|
+
console.log(chalk.cyan(' Opening in browser...'));
|
|
39
|
+
try {
|
|
40
|
+
await launchBrowser(url);
|
|
41
|
+
console.log(chalk.green.bold('\n Dashboard opened in browser!'));
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.log(chalk.yellow(`\n Could not open browser: ${err.message}`));
|
|
44
|
+
console.log(chalk.gray(` Open manually: ${url}`));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log(chalk.gray('\n Press Ctrl+C to stop the server\n'));
|
|
49
|
+
|
|
50
|
+
// Handle graceful shutdown
|
|
51
|
+
process.on('SIGINT', () => {
|
|
52
|
+
console.log(chalk.yellow('\n Shutting down server...'));
|
|
53
|
+
server.close(() => {
|
|
54
|
+
console.log(chalk.green(' Server stopped.\n'));
|
|
55
|
+
process.exit(0);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error(chalk.red(`\n Error: ${error.message}\n`));
|
|
61
|
+
if (error.code === 'EADDRINUSE') {
|
|
62
|
+
console.error(chalk.yellow(` Port ${port} is already in use.`));
|
|
63
|
+
console.error(chalk.gray(` Try a different port: ccw serve --port ${port + 1}\n`));
|
|
64
|
+
}
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { existsSync, unlinkSync, rmdirSync, readdirSync, statSync } from 'fs';
|
|
2
|
+
import { join, dirname, basename } from 'path';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { showBanner, createSpinner, success, info, warning, error, summaryBox, divider } from '../utils/ui.js';
|
|
6
|
+
import { getAllManifests, deleteManifest } from '../core/manifest.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Uninstall command handler
|
|
10
|
+
* @param {Object} options - Command options
|
|
11
|
+
*/
|
|
12
|
+
export async function uninstallCommand(options) {
|
|
13
|
+
showBanner();
|
|
14
|
+
console.log(chalk.cyan.bold(' Uninstall Claude Code Workflow\n'));
|
|
15
|
+
|
|
16
|
+
// Get all manifests
|
|
17
|
+
const manifests = getAllManifests();
|
|
18
|
+
|
|
19
|
+
if (manifests.length === 0) {
|
|
20
|
+
warning('No installations found.');
|
|
21
|
+
info('Nothing to uninstall.');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Display installations
|
|
26
|
+
console.log(chalk.white.bold(' Found installations:\n'));
|
|
27
|
+
|
|
28
|
+
manifests.forEach((m, i) => {
|
|
29
|
+
const modeColor = m.installation_mode === 'Global' ? chalk.cyan : chalk.yellow;
|
|
30
|
+
console.log(chalk.white(` ${i + 1}. `) + modeColor.bold(m.installation_mode));
|
|
31
|
+
console.log(chalk.gray(` Path: ${m.installation_path}`));
|
|
32
|
+
console.log(chalk.gray(` Date: ${new Date(m.installation_date).toLocaleDateString()}`));
|
|
33
|
+
console.log(chalk.gray(` Version: ${m.application_version}`));
|
|
34
|
+
console.log(chalk.gray(` Files: ${m.files_count} | Dirs: ${m.directories_count}`));
|
|
35
|
+
console.log('');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
divider();
|
|
39
|
+
|
|
40
|
+
// Select installation to uninstall
|
|
41
|
+
let selectedManifest;
|
|
42
|
+
|
|
43
|
+
if (manifests.length === 1) {
|
|
44
|
+
const { confirm } = await inquirer.prompt([{
|
|
45
|
+
type: 'confirm',
|
|
46
|
+
name: 'confirm',
|
|
47
|
+
message: `Uninstall ${manifests[0].installation_mode} installation at ${manifests[0].installation_path}?`,
|
|
48
|
+
default: false
|
|
49
|
+
}]);
|
|
50
|
+
|
|
51
|
+
if (!confirm) {
|
|
52
|
+
info('Uninstall cancelled');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
selectedManifest = manifests[0];
|
|
57
|
+
} else {
|
|
58
|
+
const choices = manifests.map((m, i) => ({
|
|
59
|
+
name: `${m.installation_mode} - ${m.installation_path}`,
|
|
60
|
+
value: i
|
|
61
|
+
}));
|
|
62
|
+
|
|
63
|
+
choices.push({ name: chalk.gray('Cancel'), value: -1 });
|
|
64
|
+
|
|
65
|
+
const { selection } = await inquirer.prompt([{
|
|
66
|
+
type: 'list',
|
|
67
|
+
name: 'selection',
|
|
68
|
+
message: 'Select installation to uninstall:',
|
|
69
|
+
choices
|
|
70
|
+
}]);
|
|
71
|
+
|
|
72
|
+
if (selection === -1) {
|
|
73
|
+
info('Uninstall cancelled');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
selectedManifest = manifests[selection];
|
|
78
|
+
|
|
79
|
+
// Confirm selection
|
|
80
|
+
const { confirm } = await inquirer.prompt([{
|
|
81
|
+
type: 'confirm',
|
|
82
|
+
name: 'confirm',
|
|
83
|
+
message: `Are you sure you want to uninstall ${selectedManifest.installation_mode} installation?`,
|
|
84
|
+
default: false
|
|
85
|
+
}]);
|
|
86
|
+
|
|
87
|
+
if (!confirm) {
|
|
88
|
+
info('Uninstall cancelled');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log('');
|
|
94
|
+
|
|
95
|
+
// Perform uninstallation
|
|
96
|
+
const spinner = createSpinner('Removing files...').start();
|
|
97
|
+
|
|
98
|
+
let removedFiles = 0;
|
|
99
|
+
let removedDirs = 0;
|
|
100
|
+
let failedFiles = [];
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
// Remove files first (in reverse order to handle nested files)
|
|
104
|
+
const files = [...(selectedManifest.files || [])].reverse();
|
|
105
|
+
|
|
106
|
+
for (const fileEntry of files) {
|
|
107
|
+
const filePath = fileEntry.path;
|
|
108
|
+
spinner.text = `Removing: ${basename(filePath)}`;
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
if (existsSync(filePath)) {
|
|
112
|
+
unlinkSync(filePath);
|
|
113
|
+
removedFiles++;
|
|
114
|
+
}
|
|
115
|
+
} catch (err) {
|
|
116
|
+
failedFiles.push({ path: filePath, error: err.message });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Remove directories (in reverse order to remove nested dirs first)
|
|
121
|
+
const directories = [...(selectedManifest.directories || [])].reverse();
|
|
122
|
+
|
|
123
|
+
// Sort by path length (deepest first)
|
|
124
|
+
directories.sort((a, b) => b.path.length - a.path.length);
|
|
125
|
+
|
|
126
|
+
for (const dirEntry of directories) {
|
|
127
|
+
const dirPath = dirEntry.path;
|
|
128
|
+
spinner.text = `Removing directory: ${basename(dirPath)}`;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
if (existsSync(dirPath)) {
|
|
132
|
+
// Only remove if empty
|
|
133
|
+
const contents = readdirSync(dirPath);
|
|
134
|
+
if (contents.length === 0) {
|
|
135
|
+
rmdirSync(dirPath);
|
|
136
|
+
removedDirs++;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
} catch (err) {
|
|
140
|
+
// Ignore directory removal errors (might not be empty)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Try to clean up parent directories if empty
|
|
145
|
+
const installPath = selectedManifest.installation_path;
|
|
146
|
+
for (const dir of ['.claude', '.codex', '.gemini', '.qwen']) {
|
|
147
|
+
const dirPath = join(installPath, dir);
|
|
148
|
+
try {
|
|
149
|
+
if (existsSync(dirPath)) {
|
|
150
|
+
await removeEmptyDirs(dirPath);
|
|
151
|
+
}
|
|
152
|
+
} catch {
|
|
153
|
+
// Ignore
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
spinner.succeed('Uninstall complete!');
|
|
158
|
+
|
|
159
|
+
} catch (err) {
|
|
160
|
+
spinner.fail('Uninstall failed');
|
|
161
|
+
error(err.message);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Delete manifest
|
|
166
|
+
deleteManifest(selectedManifest.manifest_file);
|
|
167
|
+
|
|
168
|
+
// Show summary
|
|
169
|
+
console.log('');
|
|
170
|
+
|
|
171
|
+
if (failedFiles.length > 0) {
|
|
172
|
+
summaryBox({
|
|
173
|
+
title: ' Uninstall Summary ',
|
|
174
|
+
lines: [
|
|
175
|
+
chalk.yellow.bold('⚠ Partially Completed'),
|
|
176
|
+
'',
|
|
177
|
+
chalk.white(`Files removed: ${chalk.green(removedFiles)}`),
|
|
178
|
+
chalk.white(`Directories removed: ${chalk.green(removedDirs)}`),
|
|
179
|
+
chalk.white(`Failed: ${chalk.red(failedFiles.length)}`),
|
|
180
|
+
'',
|
|
181
|
+
chalk.gray('Some files could not be removed.'),
|
|
182
|
+
chalk.gray('They may be in use or require elevated permissions.'),
|
|
183
|
+
],
|
|
184
|
+
borderColor: 'yellow'
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (process.env.DEBUG) {
|
|
188
|
+
console.log('');
|
|
189
|
+
console.log(chalk.gray('Failed files:'));
|
|
190
|
+
failedFiles.forEach(f => {
|
|
191
|
+
console.log(chalk.red(` ${f.path}: ${f.error}`));
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
summaryBox({
|
|
196
|
+
title: ' Uninstall Summary ',
|
|
197
|
+
lines: [
|
|
198
|
+
chalk.green.bold('✓ Successfully Uninstalled'),
|
|
199
|
+
'',
|
|
200
|
+
chalk.white(`Files removed: ${chalk.green(removedFiles)}`),
|
|
201
|
+
chalk.white(`Directories removed: ${chalk.green(removedDirs)}`),
|
|
202
|
+
'',
|
|
203
|
+
chalk.gray('Manifest removed'),
|
|
204
|
+
],
|
|
205
|
+
borderColor: 'green'
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
console.log('');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Recursively remove empty directories
|
|
214
|
+
* @param {string} dirPath - Directory path
|
|
215
|
+
*/
|
|
216
|
+
async function removeEmptyDirs(dirPath) {
|
|
217
|
+
if (!existsSync(dirPath)) return;
|
|
218
|
+
|
|
219
|
+
const stat = statSync(dirPath);
|
|
220
|
+
if (!stat.isDirectory()) return;
|
|
221
|
+
|
|
222
|
+
let files = readdirSync(dirPath);
|
|
223
|
+
|
|
224
|
+
// Recursively check subdirectories
|
|
225
|
+
for (const file of files) {
|
|
226
|
+
const filePath = join(dirPath, file);
|
|
227
|
+
if (statSync(filePath).isDirectory()) {
|
|
228
|
+
await removeEmptyDirs(filePath);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Re-check after processing subdirectories
|
|
233
|
+
files = readdirSync(dirPath);
|
|
234
|
+
if (files.length === 0) {
|
|
235
|
+
rmdirSync(dirPath);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|