moai-adk 0.35.1__py3-none-any.whl
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.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/__init__.py +10 -0
- moai_adk/__main__.py +199 -0
- moai_adk/cli/__init__.py +6 -0
- moai_adk/cli/commands/__init__.py +17 -0
- moai_adk/cli/commands/analyze.py +116 -0
- moai_adk/cli/commands/doctor.py +272 -0
- moai_adk/cli/commands/init.py +372 -0
- moai_adk/cli/commands/language.py +248 -0
- moai_adk/cli/commands/status.py +104 -0
- moai_adk/cli/commands/update.py +2686 -0
- moai_adk/cli/main.py +13 -0
- moai_adk/cli/prompts/__init__.py +5 -0
- moai_adk/cli/prompts/init_prompts.py +219 -0
- moai_adk/cli/spec_status.py +263 -0
- moai_adk/cli/ui/__init__.py +44 -0
- moai_adk/cli/ui/progress.py +422 -0
- moai_adk/cli/ui/prompts.py +389 -0
- moai_adk/cli/ui/theme.py +129 -0
- moai_adk/cli/worktree/__init__.py +27 -0
- moai_adk/cli/worktree/__main__.py +31 -0
- moai_adk/cli/worktree/cli.py +683 -0
- moai_adk/cli/worktree/exceptions.py +89 -0
- moai_adk/cli/worktree/manager.py +493 -0
- moai_adk/cli/worktree/models.py +65 -0
- moai_adk/cli/worktree/registry.py +422 -0
- moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
- moai_adk/core/__init__.py +1 -0
- moai_adk/core/analysis/__init__.py +9 -0
- moai_adk/core/analysis/session_analyzer.py +400 -0
- moai_adk/core/claude_integration.py +393 -0
- moai_adk/core/command_helpers.py +270 -0
- moai_adk/core/comprehensive_monitoring_system.py +1183 -0
- moai_adk/core/config/__init__.py +19 -0
- moai_adk/core/config/auto_spec_config.py +340 -0
- moai_adk/core/config/migration.py +244 -0
- moai_adk/core/config/unified.py +436 -0
- moai_adk/core/context_manager.py +273 -0
- moai_adk/core/diagnostics/__init__.py +19 -0
- moai_adk/core/diagnostics/slash_commands.py +159 -0
- moai_adk/core/enterprise_features.py +1404 -0
- moai_adk/core/error_recovery_system.py +1902 -0
- moai_adk/core/event_driven_hook_system.py +1371 -0
- moai_adk/core/git/__init__.py +31 -0
- moai_adk/core/git/branch.py +25 -0
- moai_adk/core/git/branch_manager.py +129 -0
- moai_adk/core/git/checkpoint.py +134 -0
- moai_adk/core/git/commit.py +67 -0
- moai_adk/core/git/conflict_detector.py +413 -0
- moai_adk/core/git/event_detector.py +79 -0
- moai_adk/core/git/manager.py +216 -0
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +901 -0
- moai_adk/core/input_validation_middleware.py +1006 -0
- moai_adk/core/integration/__init__.py +22 -0
- moai_adk/core/integration/engine.py +157 -0
- moai_adk/core/integration/integration_tester.py +226 -0
- moai_adk/core/integration/models.py +88 -0
- moai_adk/core/integration/utils.py +211 -0
- moai_adk/core/issue_creator.py +305 -0
- moai_adk/core/jit_context_loader.py +956 -0
- moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
- moai_adk/core/language_config.py +202 -0
- moai_adk/core/language_config_resolver.py +572 -0
- moai_adk/core/language_validator.py +543 -0
- moai_adk/core/mcp/setup.py +116 -0
- moai_adk/core/merge/__init__.py +9 -0
- moai_adk/core/merge/analyzer.py +605 -0
- moai_adk/core/migration/__init__.py +18 -0
- moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
- moai_adk/core/migration/backup_manager.py +277 -0
- moai_adk/core/migration/custom_element_scanner.py +358 -0
- moai_adk/core/migration/file_migrator.py +209 -0
- moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
- moai_adk/core/migration/selective_restorer.py +470 -0
- moai_adk/core/migration/template_utils.py +74 -0
- moai_adk/core/migration/user_selection_ui.py +338 -0
- moai_adk/core/migration/version_detector.py +139 -0
- moai_adk/core/migration/version_migrator.py +228 -0
- moai_adk/core/performance/__init__.py +6 -0
- moai_adk/core/performance/cache_system.py +316 -0
- moai_adk/core/performance/parallel_processor.py +116 -0
- moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
- moai_adk/core/project/__init__.py +1 -0
- moai_adk/core/project/backup_utils.py +70 -0
- moai_adk/core/project/checker.py +300 -0
- moai_adk/core/project/detector.py +293 -0
- moai_adk/core/project/initializer.py +387 -0
- moai_adk/core/project/phase_executor.py +716 -0
- moai_adk/core/project/validator.py +139 -0
- moai_adk/core/quality/__init__.py +6 -0
- moai_adk/core/quality/trust_checker.py +377 -0
- moai_adk/core/quality/validators/__init__.py +6 -0
- moai_adk/core/quality/validators/base_validator.py +19 -0
- moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
- moai_adk/core/robust_json_parser.py +611 -0
- moai_adk/core/rollback_manager.py +918 -0
- moai_adk/core/session_manager.py +651 -0
- moai_adk/core/skill_loading_system.py +579 -0
- moai_adk/core/spec/confidence_scoring.py +680 -0
- moai_adk/core/spec/ears_template_engine.py +1247 -0
- moai_adk/core/spec/quality_validator.py +687 -0
- moai_adk/core/spec_status_manager.py +478 -0
- moai_adk/core/template/__init__.py +7 -0
- moai_adk/core/template/backup.py +174 -0
- moai_adk/core/template/config.py +191 -0
- moai_adk/core/template/languages.py +43 -0
- moai_adk/core/template/merger.py +233 -0
- moai_adk/core/template/processor.py +1200 -0
- moai_adk/core/template_engine.py +310 -0
- moai_adk/core/template_variable_synchronizer.py +417 -0
- moai_adk/core/unified_permission_manager.py +745 -0
- moai_adk/core/user_behavior_analytics.py +851 -0
- moai_adk/core/version_sync.py +429 -0
- moai_adk/foundation/__init__.py +56 -0
- moai_adk/foundation/backend.py +1027 -0
- moai_adk/foundation/database.py +1115 -0
- moai_adk/foundation/devops.py +1585 -0
- moai_adk/foundation/ears.py +431 -0
- moai_adk/foundation/frontend.py +870 -0
- moai_adk/foundation/git/commit_templates.py +557 -0
- moai_adk/foundation/git.py +376 -0
- moai_adk/foundation/langs.py +484 -0
- moai_adk/foundation/ml_ops.py +1162 -0
- moai_adk/foundation/testing.py +1524 -0
- moai_adk/foundation/trust/trust_principles.py +676 -0
- moai_adk/foundation/trust/validation_checklist.py +1573 -0
- moai_adk/project/__init__.py +0 -0
- moai_adk/project/configuration.py +1084 -0
- moai_adk/project/documentation.py +566 -0
- moai_adk/project/schema.py +447 -0
- moai_adk/statusline/__init__.py +38 -0
- moai_adk/statusline/alfred_detector.py +105 -0
- moai_adk/statusline/config.py +376 -0
- moai_adk/statusline/enhanced_output_style_detector.py +372 -0
- moai_adk/statusline/git_collector.py +190 -0
- moai_adk/statusline/main.py +322 -0
- moai_adk/statusline/metrics_tracker.py +78 -0
- moai_adk/statusline/renderer.py +343 -0
- moai_adk/statusline/update_checker.py +129 -0
- moai_adk/statusline/version_reader.py +741 -0
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +714 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +474 -0
- moai_adk/templates/.claude/agents/moai/builder-command.md +1172 -0
- moai_adk/templates/.claude/agents/moai/builder-plugin.md +637 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +666 -0
- moai_adk/templates/.claude/agents/moai/expert-backend.md +899 -0
- moai_adk/templates/.claude/agents/moai/expert-database.md +777 -0
- moai_adk/templates/.claude/agents/moai/expert-debug.md +401 -0
- moai_adk/templates/.claude/agents/moai/expert-devops.md +720 -0
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +734 -0
- moai_adk/templates/.claude/agents/moai/expert-performance.md +657 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +513 -0
- moai_adk/templates/.claude/agents/moai/expert-testing.md +733 -0
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +1041 -0
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +432 -0
- moai_adk/templates/.claude/agents/moai/manager-docs.md +573 -0
- moai_adk/templates/.claude/agents/moai/manager-git.md +1060 -0
- moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
- moai_adk/templates/.claude/agents/moai/manager-quality.md +624 -0
- moai_adk/templates/.claude/agents/moai/manager-spec.md +809 -0
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +780 -0
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +784 -0
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +458 -0
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +1607 -0
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +789 -0
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +469 -0
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +1032 -0
- moai_adk/templates/.claude/commands/moai/0-project.md +1386 -0
- moai_adk/templates/.claude/commands/moai/1-plan.md +1427 -0
- moai_adk/templates/.claude/commands/moai/2-run.md +943 -0
- moai_adk/templates/.claude/commands/moai/3-sync.md +1324 -0
- moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
- moai_adk/templates/.claude/hooks/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
- moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
- moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
- moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
- moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +1083 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +560 -0
- moai_adk/templates/.claude/output-styles/moai/yoda.md +359 -0
- moai_adk/templates/.claude/settings.json +172 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +307 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +431 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/batch_generate.py +560 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/generate_image.py +362 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +249 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +406 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +328 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +320 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +718 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +464 -0
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +323 -0
- moai_adk/templates/.claude/skills/moai-domain-database/examples.md +830 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
- moai_adk/templates/.claude/skills/moai-domain-database/reference.md +545 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +968 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +664 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +455 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +492 -0
- moai_adk/templates/.claude/skills/moai-formats-data/examples.md +804 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
- moai_adk/templates/.claude/skills/moai-formats-data/reference.md +585 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +202 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/examples.md +732 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference.md +209 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +441 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/examples.md +1048 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/reference.md +246 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +420 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/examples.md +358 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +359 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/reference.md +478 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +315 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/examples.md +228 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/assumption-matrix.md +80 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/cognitive-bias.md +199 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/first-principles.md +140 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/trade-off-analysis.md +154 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/reference.md +157 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +364 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +649 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +478 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +612 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +477 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/examples.md +1090 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/reference.md +686 -0
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +376 -0
- moai_adk/templates/.claude/skills/moai-lang-go/examples.md +919 -0
- moai_adk/templates/.claude/skills/moai-lang-go/reference.md +737 -0
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +385 -0
- moai_adk/templates/.claude/skills/moai-lang-java/examples.md +864 -0
- moai_adk/templates/.claude/skills/moai-lang-java/reference.md +291 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +382 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +1006 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +562 -0
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +644 -0
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +481 -0
- moai_adk/templates/.claude/skills/moai-lang-python/examples.md +977 -0
- moai_adk/templates/.claude/skills/moai-lang-python/reference.md +804 -0
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +579 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +687 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +372 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +659 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +504 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +633 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +423 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +918 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +672 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +368 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +1089 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +731 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +300 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +319 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/examples.md +592 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/reference.md +379 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +372 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
- moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +402 -0
- moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +607 -0
- moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +300 -0
- moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +537 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +291 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +390 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +398 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +379 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +358 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +467 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +377 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +466 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +482 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/SKILL.md +474 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/examples.md +621 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/migration.md +341 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/reference.md +463 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/validation.md +373 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/SKILL.md +275 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/adaptive-mfa.md +233 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/akamai-integration.md +215 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/application-credentials.md +280 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-log-events.md +225 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-overview.md +140 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/bot-detection.md +144 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/breached-password-detection.md +187 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/brute-force-protection.md +189 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/certifications.md +282 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/compliance-overview.md +263 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/continuous-session-protection.md +307 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/customize-mfa.md +178 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/dpop-implementation.md +283 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/fapi-implementation.md +259 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/gdpr-compliance.md +313 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/guardian-configuration.md +269 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/highly-regulated-identity.md +272 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/jwt-fundamentals.md +248 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mdl-verification.md +211 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-api-management.md +278 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-factors.md +226 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-overview.md +174 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mtls-sender-constraining.md +316 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/ropg-flow-mfa.md +217 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-center.md +325 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-guidance.md +277 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/state-parameters.md +178 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/step-up-authentication.md +251 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/suspicious-ip-throttling.md +240 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/tenant-access-control.md +180 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/webauthn-fido.md +235 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +449 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/examples.md +544 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/reference.md +307 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +390 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +175 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples.md +547 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/reference.md +275 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1434 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +92 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +534 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/examples.md +900 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/reference.md +704 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +377 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/examples.md +552 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/reference.md +346 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +456 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples.md +672 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference.md +440 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +411 -0
- moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
- moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
- moai_adk/templates/.git-hooks/pre-commit +128 -0
- moai_adk/templates/.git-hooks/pre-push +365 -0
- moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
- moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +337 -0
- moai_adk/templates/.gitignore +222 -0
- moai_adk/templates/.mcp.json +13 -0
- moai_adk/templates/.moai/config/config.yaml +58 -0
- moai_adk/templates/.moai/config/questions/_schema.yaml +174 -0
- moai_adk/templates/.moai/config/questions/tab0-init.yaml +251 -0
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +107 -0
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +79 -0
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +632 -0
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +182 -0
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +96 -0
- moai_adk/templates/.moai/config/sections/git-strategy.yaml +116 -0
- moai_adk/templates/.moai/config/sections/language.yaml +11 -0
- moai_adk/templates/.moai/config/sections/project.yaml +13 -0
- moai_adk/templates/.moai/config/sections/quality.yaml +17 -0
- moai_adk/templates/.moai/config/sections/system.yaml +24 -0
- moai_adk/templates/.moai/config/sections/user.yaml +5 -0
- moai_adk/templates/.moai/config/statusline-config.yaml +92 -0
- moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
- moai_adk/templates/CLAUDE.md +642 -0
- moai_adk/utils/__init__.py +30 -0
- moai_adk/utils/banner.py +38 -0
- moai_adk/utils/common.py +294 -0
- moai_adk/utils/link_validator.py +241 -0
- moai_adk/utils/logger.py +147 -0
- moai_adk/utils/safe_file_reader.py +206 -0
- moai_adk/utils/timeout.py +160 -0
- moai_adk/utils/toon_utils.py +256 -0
- moai_adk/version.py +22 -0
- moai_adk-0.35.1.dist-info/METADATA +3018 -0
- moai_adk-0.35.1.dist-info/RECORD +502 -0
- moai_adk-0.35.1.dist-info/WHEEL +4 -0
- moai_adk-0.35.1.dist-info/entry_points.txt +3 -0
- moai_adk-0.35.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
"""CLI commands for Git worktree management."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
|
|
10
|
+
from moai_adk.cli.worktree.exceptions import (
|
|
11
|
+
GitOperationError,
|
|
12
|
+
MergeConflictError,
|
|
13
|
+
UncommittedChangesError,
|
|
14
|
+
WorktreeExistsError,
|
|
15
|
+
WorktreeNotFoundError,
|
|
16
|
+
)
|
|
17
|
+
from moai_adk.cli.worktree.manager import WorktreeManager
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
from git import Repo
|
|
21
|
+
except ImportError:
|
|
22
|
+
Repo = None # type: ignore[misc,assignment]
|
|
23
|
+
|
|
24
|
+
# Initialize Rich console for formatted output
|
|
25
|
+
console = Console()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_manager(
|
|
29
|
+
repo_path: Path | None = None, worktree_root: Path | None = None, project_name: str | None = None
|
|
30
|
+
) -> WorktreeManager: # noqa: E501
|
|
31
|
+
"""Get or create a WorktreeManager instance.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
repo_path: Path to Git repository. Defaults to current directory.
|
|
35
|
+
worktree_root: Root directory for worktrees. Auto-detects optimal location.
|
|
36
|
+
project_name: Project name for namespace organization. Auto-detected from repo if not provided.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
WorktreeManager instance.
|
|
40
|
+
"""
|
|
41
|
+
# 1. Find Git repository if not specified
|
|
42
|
+
if repo_path is None:
|
|
43
|
+
current_path = Path.cwd()
|
|
44
|
+
# Walk up to find .git directory
|
|
45
|
+
while current_path != current_path.parent:
|
|
46
|
+
if (current_path / ".git").exists():
|
|
47
|
+
repo_path = current_path
|
|
48
|
+
break
|
|
49
|
+
current_path = current_path.parent
|
|
50
|
+
|
|
51
|
+
# Fallback to current directory if no .git found
|
|
52
|
+
if repo_path is None:
|
|
53
|
+
repo_path = Path.cwd()
|
|
54
|
+
|
|
55
|
+
# 2. Auto-detect worktree root if not specified
|
|
56
|
+
if worktree_root is None:
|
|
57
|
+
worktree_root = _detect_worktree_root(repo_path)
|
|
58
|
+
|
|
59
|
+
# 3. Auto-detect project_name if not specified
|
|
60
|
+
if project_name is None:
|
|
61
|
+
project_name = repo_path.name
|
|
62
|
+
|
|
63
|
+
return WorktreeManager(repo_path=repo_path, worktree_root=worktree_root, project_name=project_name)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _detect_worktree_root(repo_path: Path) -> Path:
|
|
67
|
+
"""Auto-detect the most appropriate worktree root directory.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
repo_path: Path to the Git repository.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Detected worktree root path.
|
|
74
|
+
"""
|
|
75
|
+
# Special handling: if we're in a worktree, find the main repo
|
|
76
|
+
main_repo_path = _find_main_repository(repo_path)
|
|
77
|
+
|
|
78
|
+
# Strategy 1: Look for existing registry files in common locations
|
|
79
|
+
potential_roots = [
|
|
80
|
+
Path.home() / "moai" / "worktrees", # MoAI worktrees directory (highest priority)
|
|
81
|
+
Path.home() / "worktrees", # User's worktrees directory
|
|
82
|
+
Path.home() / "moai" / "worktrees" / main_repo_path.name, # MoAI project-specific
|
|
83
|
+
main_repo_path.parent / "worktrees", # Project-level worktrees
|
|
84
|
+
Path("/Users") / Path.home().name / "worktrees", # macOS user worktrees
|
|
85
|
+
Path.home() / "worktrees" / main_repo_path.name, # Alternative organization
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
for root in potential_roots:
|
|
89
|
+
registry_path = root / ".moai-worktree-registry.json"
|
|
90
|
+
if registry_path.exists():
|
|
91
|
+
try:
|
|
92
|
+
with open(registry_path, "r") as f:
|
|
93
|
+
content = f.read().strip()
|
|
94
|
+
if content and content != "{}":
|
|
95
|
+
return root
|
|
96
|
+
except Exception:
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
# Strategy 2: Check if there are actual worktrees in standard locations
|
|
100
|
+
for root in potential_roots:
|
|
101
|
+
if root.exists() and any(root.iterdir()):
|
|
102
|
+
# Look for directories that might be worktrees
|
|
103
|
+
for item in root.iterdir():
|
|
104
|
+
if item.is_dir() and (item / ".git").exists():
|
|
105
|
+
return root
|
|
106
|
+
|
|
107
|
+
# Strategy 3: Create a sensible default based on user's system
|
|
108
|
+
# Prefer ~/moai/worktrees for MoAI projects
|
|
109
|
+
default_root = Path.home() / "moai" / "worktrees"
|
|
110
|
+
if default_root.exists() or default_root.parent.exists():
|
|
111
|
+
return default_root
|
|
112
|
+
|
|
113
|
+
# Fallback to user worktrees
|
|
114
|
+
return Path.home() / "worktrees"
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _find_main_repository(start_path: Path) -> Path:
|
|
118
|
+
"""Find the main Git repository (not a worktree).
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
start_path: Starting path to search from.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Path to the main repository.
|
|
125
|
+
"""
|
|
126
|
+
current_path = start_path
|
|
127
|
+
|
|
128
|
+
# Walk up to find the main repository (non-worktree)
|
|
129
|
+
while current_path != current_path.parent:
|
|
130
|
+
git_path = current_path / ".git"
|
|
131
|
+
if git_path.exists():
|
|
132
|
+
# Check if this is a worktree or main repo
|
|
133
|
+
if git_path.is_file():
|
|
134
|
+
# This is a worktree - read the main repo path
|
|
135
|
+
try:
|
|
136
|
+
with open(git_path, "r") as f:
|
|
137
|
+
for line in f:
|
|
138
|
+
if line.startswith("gitdir:"):
|
|
139
|
+
gitdir_path = line[8:].strip()
|
|
140
|
+
main_git_path = Path(current_path / gitdir_path).parent.parent
|
|
141
|
+
return main_git_path.resolve()
|
|
142
|
+
except Exception:
|
|
143
|
+
pass
|
|
144
|
+
elif (git_path / "objects").exists():
|
|
145
|
+
# This is the main repository
|
|
146
|
+
return current_path.resolve()
|
|
147
|
+
|
|
148
|
+
current_path = current_path.parent
|
|
149
|
+
|
|
150
|
+
# Fallback to the original path
|
|
151
|
+
return start_path.resolve()
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@click.group()
|
|
155
|
+
def worktree() -> None:
|
|
156
|
+
"""Manage Git worktrees for parallel SPEC development."""
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@worktree.command(name="new")
|
|
161
|
+
@click.argument("spec_id")
|
|
162
|
+
@click.option("--branch", "-b", default=None, help="Custom branch name")
|
|
163
|
+
@click.option("--base", default="main", help="Base branch to create from")
|
|
164
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
165
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
166
|
+
@click.option("--force", "-f", is_flag=True, help="Force creation even if worktree exists")
|
|
167
|
+
def new_worktree(
|
|
168
|
+
spec_id: str,
|
|
169
|
+
branch: str | None,
|
|
170
|
+
base: str,
|
|
171
|
+
repo: str | None,
|
|
172
|
+
worktree_root: str | None,
|
|
173
|
+
force: bool,
|
|
174
|
+
) -> None:
|
|
175
|
+
"""Create a new worktree for a SPEC.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
spec_id: SPEC ID (e.g., SPEC-AUTH-001)
|
|
179
|
+
branch: Custom branch name (optional)
|
|
180
|
+
base: Base branch to create from (default: main)
|
|
181
|
+
repo: Repository path (optional)
|
|
182
|
+
worktree_root: Worktree root directory (optional)
|
|
183
|
+
"""
|
|
184
|
+
try:
|
|
185
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
186
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
187
|
+
|
|
188
|
+
manager = get_manager(repo_path, wt_root)
|
|
189
|
+
info = manager.create(
|
|
190
|
+
spec_id=spec_id,
|
|
191
|
+
branch_name=branch,
|
|
192
|
+
base_branch=base,
|
|
193
|
+
force=force,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
console.print("[green]✓[/green] Worktree created successfully")
|
|
197
|
+
console.print(f" SPEC ID: {info.spec_id}")
|
|
198
|
+
console.print(f" Path: {info.path}")
|
|
199
|
+
console.print(f" Branch: {info.branch}")
|
|
200
|
+
console.print(f" Status: {info.status}")
|
|
201
|
+
console.print()
|
|
202
|
+
console.print("[yellow]Next steps:[/yellow]")
|
|
203
|
+
console.print(f" moai-worktree go {spec_id} # Go to this worktree")
|
|
204
|
+
|
|
205
|
+
except WorktreeExistsError as e:
|
|
206
|
+
console.print(f"[red]✗[/red] {e}")
|
|
207
|
+
raise click.Abort()
|
|
208
|
+
except GitOperationError as e:
|
|
209
|
+
console.print(f"[red]✗[/red] {e}")
|
|
210
|
+
raise click.Abort()
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
@worktree.command(name="list")
|
|
214
|
+
@click.option(
|
|
215
|
+
"--format",
|
|
216
|
+
type=click.Choice(["table", "json"]),
|
|
217
|
+
default="table",
|
|
218
|
+
help="Output format",
|
|
219
|
+
)
|
|
220
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
221
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
222
|
+
def list_worktrees(format: str, repo: str | None, worktree_root: str | None) -> None:
|
|
223
|
+
"""List all active worktrees.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
format: Output format (table or json)
|
|
227
|
+
repo: Repository path (optional)
|
|
228
|
+
worktree_root: Worktree root directory (optional)
|
|
229
|
+
"""
|
|
230
|
+
try:
|
|
231
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
232
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
233
|
+
|
|
234
|
+
manager = get_manager(repo_path, wt_root)
|
|
235
|
+
worktrees = manager.list()
|
|
236
|
+
|
|
237
|
+
if not worktrees:
|
|
238
|
+
console.print("[yellow]No worktrees found[/yellow]")
|
|
239
|
+
return
|
|
240
|
+
|
|
241
|
+
if format == "json":
|
|
242
|
+
data = [w.to_dict() for w in worktrees]
|
|
243
|
+
console.print_json(data=data)
|
|
244
|
+
else: # table
|
|
245
|
+
table = Table(title="Git Worktrees")
|
|
246
|
+
table.add_column("SPEC ID", style="cyan")
|
|
247
|
+
table.add_column("Branch", style="magenta")
|
|
248
|
+
table.add_column("Path", style="green")
|
|
249
|
+
table.add_column("Status", style="yellow")
|
|
250
|
+
table.add_column("Created", style="blue")
|
|
251
|
+
|
|
252
|
+
for info in worktrees:
|
|
253
|
+
created = datetime.fromisoformat(info.created_at.replace("Z", "+00:00"))
|
|
254
|
+
table.add_row(
|
|
255
|
+
info.spec_id,
|
|
256
|
+
info.branch,
|
|
257
|
+
str(info.path),
|
|
258
|
+
info.status,
|
|
259
|
+
created.strftime("%Y-%m-%d %H:%M:%S"),
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
console.print(table)
|
|
263
|
+
|
|
264
|
+
except Exception as e:
|
|
265
|
+
console.print(f"[red]✗[/red] Error listing worktrees: {e}")
|
|
266
|
+
raise click.Abort()
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
@worktree.command(name="go")
|
|
270
|
+
@click.argument("spec_id")
|
|
271
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
272
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
273
|
+
def go_worktree(spec_id: str, repo: str | None, worktree_root: str | None) -> None:
|
|
274
|
+
"""Go to a worktree (opens new shell).
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
spec_id: SPEC ID to go to
|
|
278
|
+
repo: Repository path (optional)
|
|
279
|
+
worktree_root: Worktree root directory (optional)
|
|
280
|
+
"""
|
|
281
|
+
try:
|
|
282
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
283
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
284
|
+
|
|
285
|
+
manager = get_manager(repo_path, wt_root)
|
|
286
|
+
info = manager.registry.get(spec_id, project_name=manager.project_name)
|
|
287
|
+
|
|
288
|
+
if not info:
|
|
289
|
+
console.print(f"[red]✗[/red] Worktree not found: {spec_id}")
|
|
290
|
+
raise click.Abort()
|
|
291
|
+
|
|
292
|
+
import os
|
|
293
|
+
import subprocess
|
|
294
|
+
|
|
295
|
+
shell = os.environ.get("SHELL", "/bin/bash")
|
|
296
|
+
console.print(f"[green]→[/green] Opening new shell in {info.path}")
|
|
297
|
+
subprocess.call([shell], cwd=str(info.path))
|
|
298
|
+
|
|
299
|
+
except Exception as e:
|
|
300
|
+
console.print(f"[red]✗[/red] Error: {e}")
|
|
301
|
+
raise click.Abort()
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
@worktree.command(name="remove")
|
|
305
|
+
@click.argument("spec_id")
|
|
306
|
+
@click.option("--force", "-f", is_flag=True, help="Force remove with uncommitted changes")
|
|
307
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
308
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
309
|
+
def remove_worktree(spec_id: str, force: bool, repo: str | None, worktree_root: str | None) -> None:
|
|
310
|
+
"""Remove a worktree.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
spec_id: SPEC ID to remove
|
|
314
|
+
force: Force removal even with uncommitted changes
|
|
315
|
+
repo: Repository path (optional)
|
|
316
|
+
worktree_root: Worktree root directory (optional)
|
|
317
|
+
"""
|
|
318
|
+
try:
|
|
319
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
320
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
321
|
+
|
|
322
|
+
manager = get_manager(repo_path, wt_root)
|
|
323
|
+
manager.remove(spec_id=spec_id, force=force)
|
|
324
|
+
|
|
325
|
+
console.print(f"[green]✓[/green] Worktree removed: {spec_id}")
|
|
326
|
+
|
|
327
|
+
except WorktreeNotFoundError as e:
|
|
328
|
+
console.print(f"[red]✗[/red] {e}")
|
|
329
|
+
raise click.Abort()
|
|
330
|
+
except UncommittedChangesError as e:
|
|
331
|
+
console.print(f"[red]✗[/red] {e}")
|
|
332
|
+
raise click.Abort()
|
|
333
|
+
except GitOperationError as e:
|
|
334
|
+
console.print(f"[red]✗[/red] {e}")
|
|
335
|
+
raise click.Abort()
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
@worktree.command(name="status")
|
|
339
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
340
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
341
|
+
def status_worktrees(repo: str | None, worktree_root: str | None) -> None:
|
|
342
|
+
"""Show worktree status and sync registry.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
repo: Repository path (optional)
|
|
346
|
+
worktree_root: Worktree root directory (optional)
|
|
347
|
+
"""
|
|
348
|
+
try:
|
|
349
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
350
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
351
|
+
|
|
352
|
+
manager = get_manager(repo_path, wt_root)
|
|
353
|
+
|
|
354
|
+
# Sync registry with Git
|
|
355
|
+
manager.registry.sync_with_git(manager.repo)
|
|
356
|
+
|
|
357
|
+
worktrees = manager.list()
|
|
358
|
+
|
|
359
|
+
if not worktrees:
|
|
360
|
+
console.print("[yellow]No worktrees found[/yellow]")
|
|
361
|
+
return
|
|
362
|
+
|
|
363
|
+
console.print(f"[cyan]Total worktrees: {len(worktrees)}[/cyan]")
|
|
364
|
+
console.print()
|
|
365
|
+
|
|
366
|
+
for info in worktrees:
|
|
367
|
+
status_color = "green" if info.status == "active" else "yellow"
|
|
368
|
+
console.print(f"[{status_color}]{info.spec_id}[/{status_color}]")
|
|
369
|
+
console.print(f" Branch: {info.branch}")
|
|
370
|
+
console.print(f" Path: {info.path}")
|
|
371
|
+
console.print(f" Status: {info.status}")
|
|
372
|
+
console.print()
|
|
373
|
+
|
|
374
|
+
except Exception as e:
|
|
375
|
+
console.print(f"[red]✗[/red] Error getting status: {e}")
|
|
376
|
+
raise click.Abort()
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
@worktree.command(name="sync")
|
|
380
|
+
@click.argument("spec_id", required=False)
|
|
381
|
+
@click.option("--base", default="main", help="Base branch to sync from")
|
|
382
|
+
@click.option("--rebase", is_flag=True, help="Use rebase instead of merge")
|
|
383
|
+
@click.option("--ff-only", is_flag=True, help="Only sync if fast-forward is possible")
|
|
384
|
+
@click.option("--all", "sync_all", is_flag=True, help="Sync all worktrees")
|
|
385
|
+
@click.option("--auto-resolve", is_flag=True, help="Automatically resolve conflicts")
|
|
386
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
387
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
388
|
+
def sync_worktree(
|
|
389
|
+
spec_id: str | None,
|
|
390
|
+
base: str,
|
|
391
|
+
rebase: bool,
|
|
392
|
+
ff_only: bool,
|
|
393
|
+
sync_all: bool,
|
|
394
|
+
auto_resolve: bool,
|
|
395
|
+
repo: str | None,
|
|
396
|
+
worktree_root: str | None,
|
|
397
|
+
) -> None:
|
|
398
|
+
"""Sync worktree with base branch.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
spec_id: SPEC ID to sync (optional with --all)
|
|
402
|
+
base: Base branch to sync from (default: main)
|
|
403
|
+
rebase: Use rebase instead of merge
|
|
404
|
+
ff_only: Only sync if fast-forward is possible
|
|
405
|
+
sync_all: Sync all worktrees
|
|
406
|
+
auto_resolve: Automatically resolve conflicts
|
|
407
|
+
repo: Repository path (optional)
|
|
408
|
+
worktree_root: Worktree root directory (optional)
|
|
409
|
+
"""
|
|
410
|
+
if not spec_id and not sync_all:
|
|
411
|
+
console.print("[red]✗[/red] Either SPEC_ID or --all option is required")
|
|
412
|
+
raise click.Abort()
|
|
413
|
+
|
|
414
|
+
if spec_id and sync_all:
|
|
415
|
+
console.print("[red]✗[/red] Cannot use both SPEC_ID and --all option")
|
|
416
|
+
raise click.Abort()
|
|
417
|
+
|
|
418
|
+
try:
|
|
419
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
420
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
421
|
+
|
|
422
|
+
manager = get_manager(repo_path, wt_root)
|
|
423
|
+
|
|
424
|
+
if sync_all:
|
|
425
|
+
# Sync all worktrees
|
|
426
|
+
worktrees = manager.list()
|
|
427
|
+
if not worktrees:
|
|
428
|
+
console.print("[yellow]No worktrees found to sync[/yellow]")
|
|
429
|
+
return
|
|
430
|
+
|
|
431
|
+
console.print(f"[cyan]Syncing {len(worktrees)} worktrees...[/cyan]")
|
|
432
|
+
success_count = 0
|
|
433
|
+
conflict_count = 0
|
|
434
|
+
|
|
435
|
+
for info in worktrees:
|
|
436
|
+
try:
|
|
437
|
+
manager.sync(
|
|
438
|
+
spec_id=info.spec_id,
|
|
439
|
+
base_branch=base,
|
|
440
|
+
rebase=rebase,
|
|
441
|
+
ff_only=ff_only,
|
|
442
|
+
auto_resolve=auto_resolve,
|
|
443
|
+
)
|
|
444
|
+
sync_method = "rebase" if rebase else ("fast-forward" if ff_only else "merge")
|
|
445
|
+
console.print(f"[green]✓[/green] {info.spec_id} ({sync_method})")
|
|
446
|
+
success_count += 1
|
|
447
|
+
except MergeConflictError:
|
|
448
|
+
if auto_resolve:
|
|
449
|
+
# Try to auto-resolve conflicts
|
|
450
|
+
try:
|
|
451
|
+
worktree_repo = Repo(info.path)
|
|
452
|
+
conflicted_files = [info.spec_id] # This will be handled by the method
|
|
453
|
+
manager.auto_resolve_conflicts(worktree_repo, info.spec_id, conflicted_files)
|
|
454
|
+
console.print(f"[yellow]![/yellow] {info.spec_id} (auto-resolved)")
|
|
455
|
+
success_count += 1
|
|
456
|
+
except Exception as e:
|
|
457
|
+
console.print(f"[red]✗[/red] {info.spec_id} (auto-resolve failed: {e})")
|
|
458
|
+
conflict_count += 1
|
|
459
|
+
else:
|
|
460
|
+
console.print(f"[red]✗[/red] {info.spec_id} (conflicts)")
|
|
461
|
+
conflict_count += 1
|
|
462
|
+
except Exception as e:
|
|
463
|
+
console.print(f"[red]✗[/red] {info.spec_id} (failed: {e})")
|
|
464
|
+
conflict_count += 1
|
|
465
|
+
|
|
466
|
+
console.print()
|
|
467
|
+
console.print(f"[green]Summary:[/green] {success_count} synced, {conflict_count} failed")
|
|
468
|
+
else:
|
|
469
|
+
# Sync single worktree
|
|
470
|
+
manager.sync(
|
|
471
|
+
spec_id=spec_id,
|
|
472
|
+
base_branch=base,
|
|
473
|
+
rebase=rebase,
|
|
474
|
+
ff_only=ff_only,
|
|
475
|
+
auto_resolve=auto_resolve,
|
|
476
|
+
)
|
|
477
|
+
sync_method = "rebase" if rebase else ("fast-forward" if ff_only else "merge")
|
|
478
|
+
console.print(f"[green]✓[/green] Worktree synced: {spec_id} ({sync_method})")
|
|
479
|
+
|
|
480
|
+
except WorktreeNotFoundError as e:
|
|
481
|
+
console.print(f"[red]✗[/red] {e}")
|
|
482
|
+
raise click.Abort()
|
|
483
|
+
except GitOperationError as e:
|
|
484
|
+
console.print(f"[red]✗[/red] {e}")
|
|
485
|
+
raise click.Abort()
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
@worktree.command(name="clean")
|
|
489
|
+
@click.option("--merged-only", is_flag=True, help="Only remove merged branch worktrees")
|
|
490
|
+
@click.option("--interactive", is_flag=True, help="Interactive cleanup with confirmation prompts")
|
|
491
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
492
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
493
|
+
def clean_worktrees(merged_only: bool, interactive: bool, repo: str | None, worktree_root: str | None) -> None:
|
|
494
|
+
"""Remove worktrees for merged branches.
|
|
495
|
+
|
|
496
|
+
Args:
|
|
497
|
+
merged_only: Only remove worktrees for merged branches
|
|
498
|
+
interactive: Interactive cleanup with confirmation prompts
|
|
499
|
+
repo: Repository path (optional)
|
|
500
|
+
worktree_root: Worktree root directory (optional)
|
|
501
|
+
"""
|
|
502
|
+
try:
|
|
503
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
504
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
505
|
+
|
|
506
|
+
manager = get_manager(repo_path, wt_root)
|
|
507
|
+
|
|
508
|
+
if merged_only:
|
|
509
|
+
# Only clean merged branches (default behavior)
|
|
510
|
+
cleaned = manager.clean_merged()
|
|
511
|
+
elif interactive:
|
|
512
|
+
# Interactive cleanup
|
|
513
|
+
worktrees = manager.list()
|
|
514
|
+
if not worktrees:
|
|
515
|
+
console.print("[yellow]No worktrees found to clean[/yellow]")
|
|
516
|
+
return
|
|
517
|
+
|
|
518
|
+
console.print(f"[cyan]Found {len(worktrees)} worktrees:[/cyan]")
|
|
519
|
+
for i, info in enumerate(worktrees, 1):
|
|
520
|
+
console.print(f" {i}. [cyan]{info.spec_id}[/cyan] ({info.branch}) - {info.status}")
|
|
521
|
+
|
|
522
|
+
console.print()
|
|
523
|
+
console.print("[yellow]Select worktrees to remove (comma-separated numbers, or 'all'):[/yellow]")
|
|
524
|
+
|
|
525
|
+
try:
|
|
526
|
+
selection = input("> ").strip()
|
|
527
|
+
if selection.lower() == "all":
|
|
528
|
+
cleaned = [info.spec_id for info in worktrees]
|
|
529
|
+
else:
|
|
530
|
+
indices = [int(x.strip()) for x in selection.split(",") if x.strip().isdigit()]
|
|
531
|
+
for idx in indices:
|
|
532
|
+
if 1 <= idx <= len(worktrees):
|
|
533
|
+
cleaned.append(worktrees[idx - 1].spec_id)
|
|
534
|
+
else:
|
|
535
|
+
console.print(f"[red]✗[/red] Invalid index: {idx}")
|
|
536
|
+
raise click.Abort()
|
|
537
|
+
|
|
538
|
+
if not cleaned:
|
|
539
|
+
console.print("[yellow]No worktrees selected for cleanup[/yellow]")
|
|
540
|
+
return
|
|
541
|
+
|
|
542
|
+
# Final confirmation
|
|
543
|
+
console.print(f"[yellow]About to remove {len(cleaned)} worktrees: {', '.join(cleaned)}[/yellow]")
|
|
544
|
+
if input("Continue? [y/N]: ").strip().lower() in ["y", "yes"]:
|
|
545
|
+
for spec_id in cleaned:
|
|
546
|
+
try:
|
|
547
|
+
manager.remove(spec_id, force=True)
|
|
548
|
+
except Exception as e:
|
|
549
|
+
console.print(f"[red]✗[/red] Failed to remove {spec_id}: {e}")
|
|
550
|
+
|
|
551
|
+
console.print("[green]✓[/green] Interactive cleanup completed")
|
|
552
|
+
|
|
553
|
+
except (ValueError, KeyboardInterrupt):
|
|
554
|
+
console.print("[yellow]Interactive cleanup cancelled[/yellow]")
|
|
555
|
+
raise click.Abort()
|
|
556
|
+
else:
|
|
557
|
+
# Default: clean all (legacy behavior)
|
|
558
|
+
worktrees = manager.list()
|
|
559
|
+
if not worktrees:
|
|
560
|
+
console.print("[yellow]No worktrees found to clean[/yellow]")
|
|
561
|
+
return
|
|
562
|
+
|
|
563
|
+
cleaned = [info.spec_id for info in worktrees]
|
|
564
|
+
console.print(
|
|
565
|
+
"[yellow]Removing all worktrees. "
|
|
566
|
+
"Use --merged-only for merged branches only "
|
|
567
|
+
"or --interactive for selective cleanup.[/yellow]"
|
|
568
|
+
)
|
|
569
|
+
|
|
570
|
+
for spec_id in cleaned:
|
|
571
|
+
try:
|
|
572
|
+
manager.remove(spec_id, force=True)
|
|
573
|
+
except Exception as e:
|
|
574
|
+
console.print(f"[red]✗[/red] Failed to remove {spec_id}: {e}")
|
|
575
|
+
cleaned.remove(spec_id)
|
|
576
|
+
|
|
577
|
+
if cleaned:
|
|
578
|
+
console.print(f"[green]✓[/green] Cleaned {len(cleaned)} worktree(s)")
|
|
579
|
+
for spec_id in cleaned:
|
|
580
|
+
console.print(f" - {spec_id}")
|
|
581
|
+
else:
|
|
582
|
+
console.print("[yellow]No worktrees were cleaned[/yellow]")
|
|
583
|
+
|
|
584
|
+
except Exception as e:
|
|
585
|
+
console.print(f"[red]✗[/red] Error cleaning worktrees: {e}")
|
|
586
|
+
raise click.Abort()
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
@worktree.command(name="recover")
|
|
590
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
591
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
592
|
+
def recover_worktrees(repo: str | None, worktree_root: str | None) -> None:
|
|
593
|
+
"""Recover worktree registry from existing directories.
|
|
594
|
+
|
|
595
|
+
Scans the worktree root directory for existing worktrees and
|
|
596
|
+
re-registers them in the registry file.
|
|
597
|
+
|
|
598
|
+
Args:
|
|
599
|
+
repo: Repository path (optional)
|
|
600
|
+
worktree_root: Worktree root directory (optional)
|
|
601
|
+
"""
|
|
602
|
+
try:
|
|
603
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
604
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
605
|
+
|
|
606
|
+
manager = get_manager(repo_path, wt_root)
|
|
607
|
+
|
|
608
|
+
console.print(f"[cyan]Scanning {manager.worktree_root} for worktrees...[/cyan]")
|
|
609
|
+
recovered = manager.registry.recover_from_disk()
|
|
610
|
+
|
|
611
|
+
if recovered > 0:
|
|
612
|
+
console.print(f"[green]✓[/green] Recovered {recovered} worktree(s)")
|
|
613
|
+
|
|
614
|
+
# Show recovered worktrees
|
|
615
|
+
worktrees = manager.list()
|
|
616
|
+
for info in worktrees:
|
|
617
|
+
if info.status == "recovered":
|
|
618
|
+
console.print(f" - {info.spec_id} ({info.branch})")
|
|
619
|
+
else:
|
|
620
|
+
console.print("[yellow]No new worktrees found to recover[/yellow]")
|
|
621
|
+
|
|
622
|
+
except Exception as e:
|
|
623
|
+
console.print(f"[red]✗[/red] Error recovering worktrees: {e}")
|
|
624
|
+
raise click.Abort()
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
@worktree.command(name="config")
|
|
628
|
+
@click.argument("key", required=False)
|
|
629
|
+
@click.argument("value", required=False)
|
|
630
|
+
@click.option("--repo", type=click.Path(), default=None, help="Repository path")
|
|
631
|
+
@click.option("--worktree-root", type=click.Path(), default=None, help="Worktree root directory")
|
|
632
|
+
def config_worktree(key: str | None, value: str | None, repo: str | None, worktree_root: str | None) -> None:
|
|
633
|
+
"""Get or set worktree configuration.
|
|
634
|
+
|
|
635
|
+
Supported configuration keys:
|
|
636
|
+
- root: Worktree root directory
|
|
637
|
+
- auto-sync: Enable automatic sync on worktree creation
|
|
638
|
+
|
|
639
|
+
Args:
|
|
640
|
+
key: Configuration key
|
|
641
|
+
value: Configuration value (optional for get)
|
|
642
|
+
repo: Repository path (optional)
|
|
643
|
+
worktree_root: Worktree root directory (optional)
|
|
644
|
+
"""
|
|
645
|
+
try:
|
|
646
|
+
repo_path = Path(repo) if repo else Path.cwd()
|
|
647
|
+
wt_root = Path(worktree_root) if worktree_root else None
|
|
648
|
+
|
|
649
|
+
manager = get_manager(repo_path, wt_root)
|
|
650
|
+
|
|
651
|
+
if key is None:
|
|
652
|
+
# No arguments - show all configuration
|
|
653
|
+
console.print("[cyan]Configuration:[/cyan]")
|
|
654
|
+
console.print(f" root: {manager.worktree_root}")
|
|
655
|
+
console.print(f" registry: {manager.registry.registry_path}")
|
|
656
|
+
console.print()
|
|
657
|
+
console.print("[yellow]Available commands:[/yellow]")
|
|
658
|
+
console.print(" moai-worktree config all # Show all config")
|
|
659
|
+
console.print(" moai-worktree config root # Show worktree root")
|
|
660
|
+
console.print(" moai-worktree config registry # Show registry path")
|
|
661
|
+
elif value is None:
|
|
662
|
+
# Get configuration
|
|
663
|
+
if key == "root":
|
|
664
|
+
console.print(f"[cyan]Worktree root:[/cyan] {manager.worktree_root}")
|
|
665
|
+
elif key == "registry":
|
|
666
|
+
console.print(f"[cyan]Registry path:[/cyan] {manager.registry.registry_path}")
|
|
667
|
+
elif key == "all":
|
|
668
|
+
console.print("[cyan]Configuration:[/cyan]")
|
|
669
|
+
console.print(f" root: {manager.worktree_root}")
|
|
670
|
+
console.print(f" registry: {manager.registry.registry_path}")
|
|
671
|
+
else:
|
|
672
|
+
console.print(f"[yellow]Unknown config key: {key}[/yellow]")
|
|
673
|
+
console.print("[yellow]Available keys: root, registry, all[/yellow]")
|
|
674
|
+
else:
|
|
675
|
+
# Set configuration (limited support)
|
|
676
|
+
if key == "root":
|
|
677
|
+
console.print("[yellow]Use --worktree-root option to change root directory[/yellow]")
|
|
678
|
+
else:
|
|
679
|
+
console.print(f"[yellow]Cannot set configuration key: {key}[/yellow]")
|
|
680
|
+
|
|
681
|
+
except Exception as e:
|
|
682
|
+
console.print(f"[red]✗[/red] Error: {e}")
|
|
683
|
+
raise click.Abort()
|