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,782 @@
|
|
|
1
|
+
# Worktree Management Module
|
|
2
|
+
|
|
3
|
+
Purpose: Core architecture and management patterns for Git worktree operations including registry management, lifecycle control, and resource optimization.
|
|
4
|
+
|
|
5
|
+
Version: 1.0.0
|
|
6
|
+
Last Updated: 2025-11-29
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Quick Reference (30 seconds)
|
|
11
|
+
|
|
12
|
+
Core Components:
|
|
13
|
+
- Registry - Central worktree database and metadata tracking
|
|
14
|
+
- Manager - Core operations (create, sync, remove, cleanup)
|
|
15
|
+
- Models - Data structures for worktree metadata
|
|
16
|
+
- Lifecycle - Worktree creation, maintenance, and removal patterns
|
|
17
|
+
|
|
18
|
+
Key Patterns:
|
|
19
|
+
- Automatic registration and tracking
|
|
20
|
+
- Atomic operations with rollback
|
|
21
|
+
- Resource optimization and cleanup
|
|
22
|
+
- Conflict detection and resolution
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Registry Architecture
|
|
27
|
+
|
|
28
|
+
### Worktree Registry Structure
|
|
29
|
+
|
|
30
|
+
The registry is the central database that tracks all worktrees and their metadata.
|
|
31
|
+
|
|
32
|
+
Registry File: `~/.worktrees/{PROJECT_NAME}/.moai-worktree-registry.json`
|
|
33
|
+
|
|
34
|
+
Complete Registry Schema:
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"version": "1.0.0",
|
|
38
|
+
"created_at": "2025-11-29T20:00:00Z",
|
|
39
|
+
"last_updated": "2025-11-29T22:00:00Z",
|
|
40
|
+
"config": {
|
|
41
|
+
"worktree_root": "/Users/goos/worktrees/MoAI-ADK",
|
|
42
|
+
"auto_sync": true,
|
|
43
|
+
"cleanup_merged": true,
|
|
44
|
+
"default_base": "main",
|
|
45
|
+
"sync_strategy": "merge",
|
|
46
|
+
"registry_type": "local",
|
|
47
|
+
"max_worktrees": 50
|
|
48
|
+
},
|
|
49
|
+
"worktrees": {
|
|
50
|
+
"SPEC-001": {
|
|
51
|
+
"id": "SPEC-001",
|
|
52
|
+
"description": "User Authentication System",
|
|
53
|
+
"path": "/Users/goos/worktrees/MoAI-ADK/SPEC-001",
|
|
54
|
+
"branch": "feature/SPEC-001-user-auth",
|
|
55
|
+
"base_branch": "main",
|
|
56
|
+
"status": "active",
|
|
57
|
+
"created_at": "2025-11-29T20:00:00Z",
|
|
58
|
+
"last_accessed": "2025-11-29T22:00:00Z",
|
|
59
|
+
"last_sync": "2025-11-29T22:30:00Z",
|
|
60
|
+
"git_info": {
|
|
61
|
+
"commits_ahead": 5,
|
|
62
|
+
"commits_behind": 0,
|
|
63
|
+
"uncommitted_changes": true,
|
|
64
|
+
"branch_status": "ahead",
|
|
65
|
+
"merge_conflicts": false
|
|
66
|
+
},
|
|
67
|
+
"metadata": {
|
|
68
|
+
"template": "backend",
|
|
69
|
+
"developer": "alice",
|
|
70
|
+
"priority": "high",
|
|
71
|
+
"estimated_size": "125MB",
|
|
72
|
+
"tags": ["authentication", "security", "api"]
|
|
73
|
+
},
|
|
74
|
+
"operations": {
|
|
75
|
+
"total_syncs": 15,
|
|
76
|
+
"total_conflicts": 2,
|
|
77
|
+
"last_operation": "sync",
|
|
78
|
+
"last_operation_status": "success"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"statistics": {
|
|
83
|
+
"total_worktrees": 3,
|
|
84
|
+
"active_worktrees": 2,
|
|
85
|
+
"merged_worktrees": 1,
|
|
86
|
+
"total_disk_usage": "500MB",
|
|
87
|
+
"last_cleanup": "2025-11-28T10:00:00Z"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Registry Management Patterns
|
|
93
|
+
|
|
94
|
+
Atomic Registry Operations:
|
|
95
|
+
```python
|
|
96
|
+
class RegistryManager:
|
|
97
|
+
def update_worktree(self, spec_id: str, updates: dict) -> bool:
|
|
98
|
+
"""Atomic registry update with backup and rollback."""
|
|
99
|
+
|
|
100
|
+
# 1. Create backup
|
|
101
|
+
backup_path = self.registry_path.with_suffix('.backup.json')
|
|
102
|
+
shutil.copy2(self.registry_path, backup_path)
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
# 2. Load current registry
|
|
106
|
+
registry = self.load_registry()
|
|
107
|
+
|
|
108
|
+
# 3. Validate updates
|
|
109
|
+
self.validate_worktree_updates(registry, spec_id, updates)
|
|
110
|
+
|
|
111
|
+
# 4. Apply updates atomically
|
|
112
|
+
registry['worktrees'][spec_id].update(updates)
|
|
113
|
+
registry['last_updated'] = datetime.utcnow().isoformat()
|
|
114
|
+
|
|
115
|
+
# 5. Write to temporary file first
|
|
116
|
+
temp_path = self.registry_path.with_suffix('.tmp.json')
|
|
117
|
+
self.save_registry(registry, temp_path)
|
|
118
|
+
|
|
119
|
+
# 6. Atomic rename
|
|
120
|
+
temp_path.replace(self.registry_path)
|
|
121
|
+
|
|
122
|
+
# 7. Cleanup backup
|
|
123
|
+
backup_path.unlink()
|
|
124
|
+
|
|
125
|
+
return True
|
|
126
|
+
|
|
127
|
+
except Exception as e:
|
|
128
|
+
# Rollback on failure
|
|
129
|
+
if backup_path.exists():
|
|
130
|
+
backup_path.replace(self.registry_path)
|
|
131
|
+
raise RegistryError(f"Failed to update registry: {e}")
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Concurrent Access Protection:
|
|
135
|
+
```python
|
|
136
|
+
import fcntl
|
|
137
|
+
import time
|
|
138
|
+
|
|
139
|
+
class ConcurrentRegistryManager:
|
|
140
|
+
def with_registry_lock(self, operation_func):
|
|
141
|
+
"""Execute operation with file-based locking."""
|
|
142
|
+
|
|
143
|
+
lock_path = self.registry_path.with_suffix('.lock')
|
|
144
|
+
|
|
145
|
+
with open(lock_path, 'w') as lock_file:
|
|
146
|
+
# Acquire exclusive lock (with timeout)
|
|
147
|
+
try:
|
|
148
|
+
fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
|
|
149
|
+
except IOError:
|
|
150
|
+
# Lock held by another process, wait with timeout
|
|
151
|
+
for _ in range(30): # 30 second timeout
|
|
152
|
+
time.sleep(1)
|
|
153
|
+
try:
|
|
154
|
+
fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
|
|
155
|
+
break
|
|
156
|
+
except IOError:
|
|
157
|
+
continue
|
|
158
|
+
else:
|
|
159
|
+
raise RegistryError("Registry lock timeout")
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
# Execute operation with lock held
|
|
163
|
+
return operation_func()
|
|
164
|
+
finally:
|
|
165
|
+
# Release lock
|
|
166
|
+
fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
|
|
167
|
+
lock_path.unlink()
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Registry Validation and Integrity
|
|
171
|
+
|
|
172
|
+
Schema Validation:
|
|
173
|
+
```python
|
|
174
|
+
import jsonschema
|
|
175
|
+
from typing import Dict, Any
|
|
176
|
+
|
|
177
|
+
class RegistryValidator:
|
|
178
|
+
REGISTRY_SCHEMA = {
|
|
179
|
+
"type": "object",
|
|
180
|
+
"required": ["version", "created_at", "last_updated", "config", "worktrees"],
|
|
181
|
+
"properties": {
|
|
182
|
+
"version": {"type": "string"},
|
|
183
|
+
"config": {
|
|
184
|
+
"type": "object",
|
|
185
|
+
"required": ["worktree_root", "default_base"],
|
|
186
|
+
"properties": {
|
|
187
|
+
"worktree_root": {"type": "string"},
|
|
188
|
+
"auto_sync": {"type": "boolean"},
|
|
189
|
+
"cleanup_merged": {"type": "boolean"},
|
|
190
|
+
"default_base": {"type": "string"}
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"worktrees": {
|
|
194
|
+
"type": "object",
|
|
195
|
+
"patternProperties": {
|
|
196
|
+
"^SPEC-[0-9]+$": {
|
|
197
|
+
"type": "object",
|
|
198
|
+
"required": ["id", "path", "branch", "status", "created_at"],
|
|
199
|
+
"properties": {
|
|
200
|
+
"id": {"type": "string"},
|
|
201
|
+
"path": {"type": "string"},
|
|
202
|
+
"branch": {"type": "string"},
|
|
203
|
+
"status": {"enum": ["active", "merged", "stale", "error"]},
|
|
204
|
+
"created_at": {"type": "string", "format": "date-time"}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
def validate_registry(self, registry: Dict[str, Any]) -> bool:
|
|
213
|
+
"""Validate registry schema and integrity."""
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
jsonschema.validate(registry, self.REGISTRY_SCHEMA)
|
|
217
|
+
except jsonschema.ValidationError as e:
|
|
218
|
+
raise RegistryError(f"Registry schema validation failed: {e}")
|
|
219
|
+
|
|
220
|
+
# Additional integrity checks
|
|
221
|
+
self._validate_worktree_paths(registry)
|
|
222
|
+
self._validate_unique_paths(registry)
|
|
223
|
+
self._validate_git_repositories(registry)
|
|
224
|
+
|
|
225
|
+
return True
|
|
226
|
+
|
|
227
|
+
def _validate_worktree_paths(self, registry: Dict[str, Any]) -> None:
|
|
228
|
+
"""Validate that all worktree paths exist and are Git repositories."""
|
|
229
|
+
|
|
230
|
+
for spec_id, worktree in registry['worktrees'].items():
|
|
231
|
+
path = Path(worktree['path'])
|
|
232
|
+
|
|
233
|
+
if not path.exists():
|
|
234
|
+
raise RegistryError(f"Worktree path does not exist: {path}")
|
|
235
|
+
|
|
236
|
+
if not (path / '.git').exists():
|
|
237
|
+
raise RegistryError(f"Worktree is not a Git repository: {path}")
|
|
238
|
+
|
|
239
|
+
def _validate_unique_paths(self, registry: Dict[str, Any]) -> None:
|
|
240
|
+
"""Ensure no duplicate worktree paths."""
|
|
241
|
+
|
|
242
|
+
paths = [wt['path'] for wt in registry['worktrees'].values()]
|
|
243
|
+
duplicates = set([p for p in paths if paths.count(p) > 1])
|
|
244
|
+
|
|
245
|
+
if duplicates:
|
|
246
|
+
raise RegistryError(f"Duplicate worktree paths detected: {duplicates}")
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Manager Architecture
|
|
252
|
+
|
|
253
|
+
### WorktreeManager Core Operations
|
|
254
|
+
|
|
255
|
+
Manager Class Structure:
|
|
256
|
+
```python
|
|
257
|
+
class WorktreeManager:
|
|
258
|
+
def __init__(self, repo_path: Path, worktree_root: Path):
|
|
259
|
+
self.repo_path = Path(repo_path).resolve()
|
|
260
|
+
self.worktree_root = Path(worktree_root).resolve()
|
|
261
|
+
self.registry = RegistryManager(self.worktree_root)
|
|
262
|
+
self.git_manager = GitManager(self.repo_path)
|
|
263
|
+
|
|
264
|
+
# Core Operations
|
|
265
|
+
def create_worktree(self, spec_id: str, description: str = "", options) -> WorktreeInfo
|
|
266
|
+
def sync_worktree(self, spec_id: str, options) -> SyncResult
|
|
267
|
+
def remove_worktree(self, spec_id: str, options) -> RemoveResult
|
|
268
|
+
def switch_worktree(self, spec_id: str, options) -> SwitchResult
|
|
269
|
+
def cleanup_worktrees(self, options) -> CleanupResult
|
|
270
|
+
|
|
271
|
+
# Query Operations
|
|
272
|
+
def list_worktrees(self, filters) -> List[WorktreeInfo]
|
|
273
|
+
def get_worktree(self, spec_id: str) -> Optional[WorktreeInfo]
|
|
274
|
+
def get_current_worktree(self) -> Optional[WorktreeInfo]
|
|
275
|
+
def get_worktree_status(self, spec_id: str) -> WorktreeStatus
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Worktree Creation Patterns
|
|
279
|
+
|
|
280
|
+
Complete Creation Workflow:
|
|
281
|
+
```python
|
|
282
|
+
def create_worktree(self, spec_id: str, description: str = "", options) -> WorktreeInfo:
|
|
283
|
+
"""Create a new worktree with comprehensive validation and setup."""
|
|
284
|
+
|
|
285
|
+
# 1. Validate input
|
|
286
|
+
self._validate_spec_id(spec_id)
|
|
287
|
+
self._validate_worktree_doesnt_exist(spec_id)
|
|
288
|
+
|
|
289
|
+
# 2. Determine configuration
|
|
290
|
+
branch = options.get('branch') or self._generate_branch_name(spec_id, description)
|
|
291
|
+
base_branch = options.get('base') or self.config.default_base
|
|
292
|
+
template = options.get('template')
|
|
293
|
+
|
|
294
|
+
# 3. Create worktree path
|
|
295
|
+
worktree_path = self.worktree_root / spec_id
|
|
296
|
+
|
|
297
|
+
try:
|
|
298
|
+
# 4. Create Git worktree
|
|
299
|
+
self.git_manager.create_worktree(
|
|
300
|
+
worktree_path=worktree_path,
|
|
301
|
+
branch=branch,
|
|
302
|
+
base_branch=base_branch,
|
|
303
|
+
force=options.get('force', False)
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
# 5. Apply template if specified
|
|
307
|
+
if template:
|
|
308
|
+
self._apply_template(worktree_path, template)
|
|
309
|
+
|
|
310
|
+
# 6. Register worktree
|
|
311
|
+
worktree_info = WorktreeInfo(
|
|
312
|
+
id=spec_id,
|
|
313
|
+
description=description,
|
|
314
|
+
path=str(worktree_path),
|
|
315
|
+
branch=branch,
|
|
316
|
+
base_branch=base_branch,
|
|
317
|
+
status=WorktreeStatus.ACTIVE,
|
|
318
|
+
created_at=datetime.utcnow(),
|
|
319
|
+
metadata=options.get('metadata', {})
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
self.registry.register_worktree(worktree_info)
|
|
323
|
+
|
|
324
|
+
# 7. Post-creation hooks
|
|
325
|
+
self._run_creation_hooks(worktree_info)
|
|
326
|
+
|
|
327
|
+
return worktree_info
|
|
328
|
+
|
|
329
|
+
except Exception as e:
|
|
330
|
+
# Cleanup on failure
|
|
331
|
+
if worktree_path.exists():
|
|
332
|
+
shutil.rmtree(worktree_path, ignore_errors=True)
|
|
333
|
+
raise WorktreeCreationError(f"Failed to create worktree {spec_id}: {e}")
|
|
334
|
+
|
|
335
|
+
def _apply_template(self, worktree_path: Path, template_name: str) -> None:
|
|
336
|
+
"""Apply worktree template for initial setup."""
|
|
337
|
+
import shlex
|
|
338
|
+
|
|
339
|
+
template_config = self._load_template_config(template_name)
|
|
340
|
+
|
|
341
|
+
# Execute setup commands safely (shell=False to prevent command injection CWE-78)
|
|
342
|
+
for command in template_config.get('setup_commands', []):
|
|
343
|
+
# Parse command string into list for safe execution
|
|
344
|
+
cmd_list = shlex.split(command) if isinstance(command, str) else command
|
|
345
|
+
result = subprocess.run(
|
|
346
|
+
cmd_list,
|
|
347
|
+
cwd=worktree_path,
|
|
348
|
+
capture_output=True,
|
|
349
|
+
text=True
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
if result.returncode != 0:
|
|
353
|
+
raise TemplateError(f"Template command failed: {command}\n{result.stderr}")
|
|
354
|
+
|
|
355
|
+
# Create template files
|
|
356
|
+
for file_path, content in template_config.get('files', {}).items():
|
|
357
|
+
full_path = worktree_path / file_path
|
|
358
|
+
full_path.parent.mkdir(parents=True, exist_ok=True)
|
|
359
|
+
full_path.write_text(content)
|
|
360
|
+
|
|
361
|
+
# Set environment variables
|
|
362
|
+
for key, value in template_config.get('env_vars', {}).items():
|
|
363
|
+
env_file = worktree_path / '.env.local'
|
|
364
|
+
with open(env_file, 'a') as f:
|
|
365
|
+
f.write(f"{key}={value}\n")
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Synchronization Patterns
|
|
369
|
+
|
|
370
|
+
Smart Synchronization Strategy:
|
|
371
|
+
```python
|
|
372
|
+
def sync_worktree(self, spec_id: str, options) -> SyncResult:
|
|
373
|
+
"""Synchronize worktree with base branch using intelligent strategies."""
|
|
374
|
+
|
|
375
|
+
worktree = self.get_worktree(spec_id)
|
|
376
|
+
if not worktree:
|
|
377
|
+
raise WorktreeNotFoundError(f"Worktree not found: {spec_id}")
|
|
378
|
+
|
|
379
|
+
sync_strategy = options.get('strategy', self.config.sync_strategy)
|
|
380
|
+
|
|
381
|
+
try:
|
|
382
|
+
# 1. Check for uncommitted changes
|
|
383
|
+
if self._has_uncommitted_changes(worktree.path) and not options.get('force'):
|
|
384
|
+
raise UncommittedChangesError("Worktree has uncommitted changes")
|
|
385
|
+
|
|
386
|
+
# 2. Fetch latest changes
|
|
387
|
+
self.git_manager.fetch_updates(worktree.path)
|
|
388
|
+
|
|
389
|
+
# 3. Analyze synchronization needs
|
|
390
|
+
sync_analysis = self._analyze_sync_needs(worktree)
|
|
391
|
+
|
|
392
|
+
if not sync_analysis.needs_sync:
|
|
393
|
+
return SyncResult(skipped=True, reason="Already up to date")
|
|
394
|
+
|
|
395
|
+
# 4. Execute synchronization based on strategy
|
|
396
|
+
if sync_strategy == "merge":
|
|
397
|
+
result = self._merge_sync(worktree, sync_analysis, options)
|
|
398
|
+
elif sync_strategy == "rebase":
|
|
399
|
+
result = self._rebase_sync(worktree, sync_analysis, options)
|
|
400
|
+
elif sync_strategy == "squash":
|
|
401
|
+
result = self._squash_sync(worktree, sync_analysis, options)
|
|
402
|
+
else:
|
|
403
|
+
raise ValueError(f"Unknown sync strategy: {sync_strategy}")
|
|
404
|
+
|
|
405
|
+
# 5. Update registry
|
|
406
|
+
self._update_sync_timestamp(spec_id)
|
|
407
|
+
|
|
408
|
+
# 6. Post-sync hooks
|
|
409
|
+
self._run_sync_hooks(worktree, result)
|
|
410
|
+
|
|
411
|
+
return result
|
|
412
|
+
|
|
413
|
+
except Exception as e:
|
|
414
|
+
self._update_sync_timestamp(spec_id, status="error")
|
|
415
|
+
raise SynchronizationError(f"Sync failed for {spec_id}: {e}")
|
|
416
|
+
|
|
417
|
+
def _merge_sync(self, worktree: WorktreeInfo, analysis: SyncAnalysis, options: dict) -> SyncResult:
|
|
418
|
+
"""Perform merge-based synchronization."""
|
|
419
|
+
|
|
420
|
+
worktree_path = Path(worktree.path)
|
|
421
|
+
|
|
422
|
+
# Check for conflicts
|
|
423
|
+
if analysis.has_conflicts:
|
|
424
|
+
if options.get('auto_resolve'):
|
|
425
|
+
self._auto_resolve_conflicts(worktree_path, analysis.conflicts)
|
|
426
|
+
elif options.get('interactive'):
|
|
427
|
+
self._interactive_resolve_conflicts(worktree_path, analysis.conflicts)
|
|
428
|
+
else:
|
|
429
|
+
raise MergeConflictError(f"Merge conflicts detected in {worktree.id}")
|
|
430
|
+
|
|
431
|
+
# Perform merge
|
|
432
|
+
merge_result = self.git_manager.merge_branch(
|
|
433
|
+
worktree_path=worktree_path,
|
|
434
|
+
source_branch=worktree.base_branch,
|
|
435
|
+
target_branch=worktree.branch,
|
|
436
|
+
strategy=options.get('merge_strategy', 'recursive')
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
return SyncResult(
|
|
440
|
+
strategy="merge",
|
|
441
|
+
files_changed=merge_result.files_changed,
|
|
442
|
+
conflicts_resolved=len(analysis.conflicts) if analysis.has_conflicts else 0,
|
|
443
|
+
commits_merged=analysis.commits_behind
|
|
444
|
+
)
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Cleanup and Optimization Patterns
|
|
448
|
+
|
|
449
|
+
Intelligent Cleanup Strategy:
|
|
450
|
+
```python
|
|
451
|
+
def cleanup_worktrees(self, options) -> CleanupResult:
|
|
452
|
+
"""Perform intelligent cleanup of worktrees based on various criteria."""
|
|
453
|
+
|
|
454
|
+
cleanup_candidates = []
|
|
455
|
+
|
|
456
|
+
# 1. Find merged worktrees
|
|
457
|
+
if options.get('merged_only', False):
|
|
458
|
+
merged_worktrees = self._find_merged_worktrees()
|
|
459
|
+
cleanup_candidates.extend(merged_worktrees)
|
|
460
|
+
|
|
461
|
+
# 2. Find stale worktrees
|
|
462
|
+
if options.get('stale', False):
|
|
463
|
+
stale_threshold = options.get('days', 30)
|
|
464
|
+
stale_worktrees = self._find_stale_worktrees(stale_threshold)
|
|
465
|
+
cleanup_candidates.extend(stale_worktrees)
|
|
466
|
+
|
|
467
|
+
# 3. Find large worktrees
|
|
468
|
+
if options.get('large_only', False):
|
|
469
|
+
size_threshold = options.get('size_threshold', '1GB')
|
|
470
|
+
large_worktrees = self._find_large_worktrees(size_threshold)
|
|
471
|
+
cleanup_candidates.extend(large_worktrees)
|
|
472
|
+
|
|
473
|
+
# 4. Remove duplicates and sort by priority
|
|
474
|
+
cleanup_candidates = list(set(cleanup_candidates))
|
|
475
|
+
cleanup_candidates.sort(key=lambda w: self._cleanup_priority(w), reverse=True)
|
|
476
|
+
|
|
477
|
+
# 5. Interactive selection if requested
|
|
478
|
+
if options.get('interactive'):
|
|
479
|
+
cleanup_candidates = self._interactive_cleanup_selection(cleanup_candidates)
|
|
480
|
+
|
|
481
|
+
# 6. Perform cleanup
|
|
482
|
+
removed_count = 0
|
|
483
|
+
total_size_freed = 0
|
|
484
|
+
|
|
485
|
+
for worktree in cleanup_candidates:
|
|
486
|
+
try:
|
|
487
|
+
result = self.remove_worktree(
|
|
488
|
+
worktree.id,
|
|
489
|
+
backup=options.get('backup', False),
|
|
490
|
+
force=options.get('force', False)
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
removed_count += 1
|
|
494
|
+
total_size_freed += result.size_freed
|
|
495
|
+
|
|
496
|
+
except Exception as e:
|
|
497
|
+
logger.warning(f"Failed to remove worktree {worktree.id}: {e}")
|
|
498
|
+
|
|
499
|
+
return CleanupResult(
|
|
500
|
+
worktrees_removed=removed_count,
|
|
501
|
+
size_freed=total_size_freed,
|
|
502
|
+
candidates=len(cleanup_candidates)
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
def _find_merged_worktrees(self) -> List[WorktreeInfo]:
|
|
506
|
+
"""Find worktrees whose branches have been merged to base."""
|
|
507
|
+
|
|
508
|
+
merged_worktrees = []
|
|
509
|
+
|
|
510
|
+
for worktree in self.list_worktrees(status='active'):
|
|
511
|
+
if self.git_manager.is_branch_merged(
|
|
512
|
+
branch=worktree.branch,
|
|
513
|
+
into=worktree.base_branch,
|
|
514
|
+
repo_path=worktree.path
|
|
515
|
+
):
|
|
516
|
+
merged_worktrees.append(worktree)
|
|
517
|
+
|
|
518
|
+
return merged_worktrees
|
|
519
|
+
|
|
520
|
+
def _find_stale_worktrees(self, days_threshold: int) -> List[WorktreeInfo]:
|
|
521
|
+
"""Find worktrees not accessed in specified days."""
|
|
522
|
+
|
|
523
|
+
threshold_date = datetime.utcnow() - timedelta(days=days_threshold)
|
|
524
|
+
stale_worktrees = []
|
|
525
|
+
|
|
526
|
+
for worktree in self.list_worktrees():
|
|
527
|
+
last_accessed = datetime.fromisoformat(worktree.last_accessed)
|
|
528
|
+
if last_accessed < threshold_date:
|
|
529
|
+
stale_worktrees.append(worktree)
|
|
530
|
+
|
|
531
|
+
return stale_worktrees
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## Resource Optimization
|
|
537
|
+
|
|
538
|
+
### Disk Space Management
|
|
539
|
+
|
|
540
|
+
Disk Usage Analysis:
|
|
541
|
+
```python
|
|
542
|
+
def analyze_disk_usage(self) -> DiskUsageReport:
|
|
543
|
+
"""Analyze disk usage of all worktrees."""
|
|
544
|
+
|
|
545
|
+
total_size = 0
|
|
546
|
+
worktree_sizes = {}
|
|
547
|
+
|
|
548
|
+
for worktree in self.list_worktrees():
|
|
549
|
+
size = self._calculate_worktree_size(worktree.path)
|
|
550
|
+
worktree_sizes[worktree.id] = size
|
|
551
|
+
total_size += size
|
|
552
|
+
|
|
553
|
+
# Find size anomalies
|
|
554
|
+
large_worktrees = [
|
|
555
|
+
(wid, size) for wid, size in worktree_sizes.items()
|
|
556
|
+
if size > self._get_size_threshold(wid)
|
|
557
|
+
]
|
|
558
|
+
|
|
559
|
+
return DiskUsageReport(
|
|
560
|
+
total_size=total_size,
|
|
561
|
+
worktree_sizes=worktree_sizes,
|
|
562
|
+
large_worktrees=large_worktrees,
|
|
563
|
+
optimization_suggestions=self._generate_optimization_suggestions(worktree_sizes)
|
|
564
|
+
)
|
|
565
|
+
|
|
566
|
+
def _calculate_worktree_size(self, worktree_path: str) -> int:
|
|
567
|
+
"""Calculate total size of worktree in bytes."""
|
|
568
|
+
|
|
569
|
+
total_size = 0
|
|
570
|
+
worktree_path = Path(worktree_path)
|
|
571
|
+
|
|
572
|
+
for file_path in worktree_path.rglob('*'):
|
|
573
|
+
if file_path.is_file():
|
|
574
|
+
total_size += file_path.stat().st_size
|
|
575
|
+
|
|
576
|
+
return total_size
|
|
577
|
+
|
|
578
|
+
def optimize_disk_usage(self, aggressive: bool = False) -> OptimizationResult:
|
|
579
|
+
"""Optimize disk usage across worktrees."""
|
|
580
|
+
|
|
581
|
+
optimizations = []
|
|
582
|
+
total_freed = 0
|
|
583
|
+
|
|
584
|
+
# 1. Remove unnecessary files
|
|
585
|
+
for worktree in self.list_worktrees():
|
|
586
|
+
worktree_path = Path(worktree.path)
|
|
587
|
+
|
|
588
|
+
# Remove build artifacts
|
|
589
|
+
build_artifacts = self._find_build_artifacts(worktree_path)
|
|
590
|
+
if build_artifacts:
|
|
591
|
+
freed = self._remove_files(build_artifacts)
|
|
592
|
+
optimizations.append(f"Removed {len(build_artifacts)} build artifacts from {worktree.id}")
|
|
593
|
+
total_freed += freed
|
|
594
|
+
|
|
595
|
+
# Clean Git garbage
|
|
596
|
+
if aggressive:
|
|
597
|
+
git_freed = self._git_gc(worktree_path)
|
|
598
|
+
optimizations.append(f"Git GC freed {git_freed} from {worktree.id}")
|
|
599
|
+
total_freed += git_freed
|
|
600
|
+
|
|
601
|
+
# 2. Compress old worktrees
|
|
602
|
+
if aggressive:
|
|
603
|
+
old_worktrees = self._find_old_worktrees(days=90)
|
|
604
|
+
for worktree in old_worktrees:
|
|
605
|
+
compressed = self._compress_worktree(worktree)
|
|
606
|
+
if compressed:
|
|
607
|
+
optimizations.append(f"Compressed {worktree.id}")
|
|
608
|
+
total_freed += compressed
|
|
609
|
+
|
|
610
|
+
return OptimizationResult(
|
|
611
|
+
optimizations=optimizations,
|
|
612
|
+
total_freed=total_freed
|
|
613
|
+
)
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### Memory and Performance Optimization
|
|
617
|
+
|
|
618
|
+
Memory-Efficient Operations:
|
|
619
|
+
```python
|
|
620
|
+
class MemoryOptimizedManager:
|
|
621
|
+
def __init__(self, repo_path: Path, worktree_root: Path):
|
|
622
|
+
self.repo_path = repo_path
|
|
623
|
+
self.worktree_root = worktree_root
|
|
624
|
+
self._registry_cache = None
|
|
625
|
+
self._cache_timestamp = None
|
|
626
|
+
self._cache_ttl = timedelta(minutes=5)
|
|
627
|
+
|
|
628
|
+
@property
|
|
629
|
+
def registry(self) -> Dict[str, Any]:
|
|
630
|
+
"""Lazy-loaded registry with caching."""
|
|
631
|
+
|
|
632
|
+
now = datetime.utcnow()
|
|
633
|
+
|
|
634
|
+
if (self._registry_cache is None or
|
|
635
|
+
self._cache_timestamp is None or
|
|
636
|
+
now - self._cache_timestamp > self._cache_ttl):
|
|
637
|
+
|
|
638
|
+
self._registry_cache = self._load_registry()
|
|
639
|
+
self._cache_timestamp = now
|
|
640
|
+
|
|
641
|
+
return self._registry_cache
|
|
642
|
+
|
|
643
|
+
def list_worktrees_streaming(self, filters: Dict[str, Any] = None) -> Iterator[WorktreeInfo]:
|
|
644
|
+
"""Stream worktrees without loading entire registry."""
|
|
645
|
+
|
|
646
|
+
registry_path = self.worktree_root / ".moai-worktree-registry.json"
|
|
647
|
+
|
|
648
|
+
if not registry_path.exists():
|
|
649
|
+
return
|
|
650
|
+
|
|
651
|
+
# Stream JSON parsing for large registries
|
|
652
|
+
import ijson
|
|
653
|
+
|
|
654
|
+
with open(registry_path, 'rb') as f:
|
|
655
|
+
worktrees = ijson.items(f, 'worktrees.item')
|
|
656
|
+
|
|
657
|
+
for worktree_data in worktrees:
|
|
658
|
+
worktree = WorktreeInfo.from_dict(worktree_data)
|
|
659
|
+
|
|
660
|
+
if self._matches_filters(worktree, filters):
|
|
661
|
+
yield worktree
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## Error Handling and Recovery
|
|
667
|
+
|
|
668
|
+
### Comprehensive Error Handling
|
|
669
|
+
|
|
670
|
+
Error Hierarchy and Recovery:
|
|
671
|
+
```python
|
|
672
|
+
class WorktreeError(Exception):
|
|
673
|
+
"""Base class for worktree-related errors."""
|
|
674
|
+
pass
|
|
675
|
+
|
|
676
|
+
class WorktreeCreationError(WorktreeError):
|
|
677
|
+
"""Errors during worktree creation."""
|
|
678
|
+
def __init__(self, message: str, partial_worktree: Optional[Path] = None):
|
|
679
|
+
super().__init__(message)
|
|
680
|
+
self.partial_worktree = partial_worktree
|
|
681
|
+
|
|
682
|
+
class SynchronizationError(WorktreeError):
|
|
683
|
+
"""Errors during synchronization."""
|
|
684
|
+
def __init__(self, message: str, sync_state: Optional[Dict] = None):
|
|
685
|
+
super().__init__(message)
|
|
686
|
+
self.sync_state = sync_state
|
|
687
|
+
|
|
688
|
+
class RecoveryManager:
|
|
689
|
+
def recover_from_creation_failure(self, error: WorktreeCreationError) -> RecoveryResult:
|
|
690
|
+
"""Recover from worktree creation failure."""
|
|
691
|
+
|
|
692
|
+
if error.partial_worktree:
|
|
693
|
+
# Clean up partial worktree
|
|
694
|
+
if error.partial_worktree.exists():
|
|
695
|
+
shutil.rmtree(error.partial_worktree, ignore_errors=True)
|
|
696
|
+
|
|
697
|
+
# Remove any registry entries
|
|
698
|
+
self.registry.remove_worktree(error.spec_id, ignore_missing=True)
|
|
699
|
+
|
|
700
|
+
return RecoveryResult(success=True, message="Cleanup completed")
|
|
701
|
+
|
|
702
|
+
def recover_from_sync_failure(self, error: SynchronizationError) -> RecoveryResult:
|
|
703
|
+
"""Recover from synchronization failure."""
|
|
704
|
+
|
|
705
|
+
worktree_id = error.worktree_id
|
|
706
|
+
|
|
707
|
+
# Reset worktree to last known good state
|
|
708
|
+
if error.sync_state and 'backup_ref' in error.sync_state:
|
|
709
|
+
self.git_manager.reset_to_ref(
|
|
710
|
+
worktree_id=worktree_id,
|
|
711
|
+
ref=error.sync_state['backup_ref']
|
|
712
|
+
)
|
|
713
|
+
|
|
714
|
+
# Mark worktree as needing manual intervention
|
|
715
|
+
self.registry.update_worktree(worktree_id, {
|
|
716
|
+
'status': 'error',
|
|
717
|
+
'last_error': str(error),
|
|
718
|
+
'needs_manual_intervention': True
|
|
719
|
+
})
|
|
720
|
+
|
|
721
|
+
return RecoveryResult(
|
|
722
|
+
success=True,
|
|
723
|
+
message=f"Worktree {worktree_id} reset to safe state"
|
|
724
|
+
)
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
---
|
|
728
|
+
|
|
729
|
+
## Monitoring and Analytics
|
|
730
|
+
|
|
731
|
+
### Worktree Analytics
|
|
732
|
+
|
|
733
|
+
Usage Analytics:
|
|
734
|
+
```python
|
|
735
|
+
class WorktreeAnalytics:
|
|
736
|
+
def generate_usage_report(self, period: timedelta = timedelta(days=30)) -> UsageReport:
|
|
737
|
+
"""Generate comprehensive usage report."""
|
|
738
|
+
|
|
739
|
+
end_date = datetime.utcnow()
|
|
740
|
+
start_date = end_date - period
|
|
741
|
+
|
|
742
|
+
worktrees = self.list_worktrees()
|
|
743
|
+
|
|
744
|
+
# Calculate metrics
|
|
745
|
+
metrics = {
|
|
746
|
+
'total_worktrees_created': len([
|
|
747
|
+
w for w in worktrees
|
|
748
|
+
if datetime.fromisoformat(w.created_at) >= start_date
|
|
749
|
+
]),
|
|
750
|
+
'average_sync_frequency': self._calculate_average_sync_frequency(worktrees, period),
|
|
751
|
+
'most_active_worktree': self._find_most_active_worktree(worktrees, period),
|
|
752
|
+
'conflict_rate': self._calculate_conflict_rate(worktrees, period),
|
|
753
|
+
'storage_growth': self._calculate_storage_growth(worktrees, period)
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
# Generate recommendations
|
|
757
|
+
recommendations = self._generate_recommendations(metrics, worktrees)
|
|
758
|
+
|
|
759
|
+
return UsageReport(
|
|
760
|
+
period=period,
|
|
761
|
+
metrics=metrics,
|
|
762
|
+
recommendations=recommendations,
|
|
763
|
+
generated_at=end_date
|
|
764
|
+
)
|
|
765
|
+
|
|
766
|
+
def _calculate_average_sync_frequency(self, worktrees: List[WorktreeInfo], period: timedelta) -> float:
|
|
767
|
+
"""Calculate average sync frequency per worktree."""
|
|
768
|
+
|
|
769
|
+
if not worktrees:
|
|
770
|
+
return 0.0
|
|
771
|
+
|
|
772
|
+
total_syncs = sum(w.operations.total_syncs for w in worktrees)
|
|
773
|
+
days_in_period = period.days
|
|
774
|
+
|
|
775
|
+
return total_syncs / (len(worktrees) * days_in_period)
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
---
|
|
779
|
+
|
|
780
|
+
Version: 1.0.0
|
|
781
|
+
Last Updated: 2025-11-29
|
|
782
|
+
Module: Core worktree management architecture with registry, lifecycle, and optimization patterns
|