moai-adk 0.25.4__py3-none-any.whl → 0.32.8__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 +2 -5
- moai_adk/__main__.py +114 -82
- moai_adk/cli/__init__.py +6 -1
- moai_adk/cli/commands/__init__.py +1 -3
- moai_adk/cli/commands/analyze.py +5 -16
- moai_adk/cli/commands/doctor.py +6 -18
- moai_adk/cli/commands/init.py +56 -125
- moai_adk/cli/commands/language.py +14 -35
- moai_adk/cli/commands/status.py +9 -15
- moai_adk/cli/commands/update.py +1555 -190
- moai_adk/cli/prompts/init_prompts.py +112 -56
- 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 +672 -0
- moai_adk/cli/worktree/exceptions.py +89 -0
- moai_adk/cli/worktree/manager.py +490 -0
- moai_adk/cli/worktree/models.py +65 -0
- moai_adk/cli/worktree/registry.py +128 -0
- moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
- moai_adk/core/analysis/session_analyzer.py +17 -56
- moai_adk/core/claude_integration.py +26 -54
- moai_adk/core/command_helpers.py +10 -10
- moai_adk/core/comprehensive_monitoring_system.py +1183 -0
- moai_adk/core/config/auto_spec_config.py +5 -11
- moai_adk/core/config/migration.py +19 -9
- moai_adk/core/config/unified.py +436 -0
- moai_adk/core/context_manager.py +6 -12
- moai_adk/core/enterprise_features.py +1404 -0
- moai_adk/core/error_recovery_system.py +725 -112
- moai_adk/core/event_driven_hook_system.py +1371 -0
- moai_adk/core/git/__init__.py +8 -0
- moai_adk/core/git/branch_manager.py +3 -11
- moai_adk/core/git/checkpoint.py +1 -3
- moai_adk/core/git/conflict_detector.py +413 -0
- moai_adk/core/git/manager.py +91 -1
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +56 -80
- moai_adk/core/input_validation_middleware.py +1006 -0
- moai_adk/core/integration/engine.py +6 -18
- moai_adk/core/integration/integration_tester.py +10 -9
- moai_adk/core/integration/utils.py +1 -1
- moai_adk/core/issue_creator.py +10 -28
- moai_adk/core/jit_context_loader.py +956 -0
- moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
- moai_adk/core/language_config_resolver.py +485 -0
- moai_adk/core/language_validator.py +28 -41
- moai_adk/core/mcp/setup.py +15 -12
- moai_adk/core/merge/__init__.py +9 -0
- moai_adk/core/merge/analyzer.py +481 -0
- moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
- moai_adk/core/migration/backup_manager.py +78 -9
- moai_adk/core/migration/custom_element_scanner.py +358 -0
- moai_adk/core/migration/file_migrator.py +8 -17
- 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 +6 -10
- moai_adk/core/migration/version_migrator.py +3 -3
- moai_adk/core/performance/cache_system.py +8 -10
- moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
- moai_adk/core/project/checker.py +2 -4
- moai_adk/core/project/detector.py +1 -3
- moai_adk/core/project/initializer.py +135 -23
- moai_adk/core/project/phase_executor.py +54 -81
- moai_adk/core/project/validator.py +6 -12
- moai_adk/core/quality/trust_checker.py +9 -27
- moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
- moai_adk/core/robust_json_parser.py +611 -0
- moai_adk/core/rollback_manager.py +73 -148
- moai_adk/core/session_manager.py +10 -26
- moai_adk/core/skill_loading_system.py +579 -0
- moai_adk/core/spec/confidence_scoring.py +31 -100
- moai_adk/core/spec/ears_template_engine.py +351 -286
- moai_adk/core/spec/quality_validator.py +35 -69
- moai_adk/core/spec_status_manager.py +64 -74
- moai_adk/core/template/backup.py +45 -20
- moai_adk/core/template/config.py +112 -39
- moai_adk/core/template/merger.py +11 -19
- moai_adk/core/template/processor.py +253 -149
- moai_adk/core/template_engine.py +73 -40
- 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 +4 -12
- 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 +23 -72
- moai_adk/foundation/trust/validation_checklist.py +57 -162
- 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/alfred_detector.py +1 -3
- moai_adk/statusline/config.py +13 -4
- moai_adk/statusline/enhanced_output_style_detector.py +23 -15
- moai_adk/statusline/main.py +51 -15
- moai_adk/statusline/renderer.py +104 -48
- moai_adk/statusline/update_checker.py +3 -9
- moai_adk/statusline/version_reader.py +140 -46
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +549 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +445 -0
- moai_adk/templates/.claude/agents/moai/builder-command.md +1132 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +601 -0
- moai_adk/templates/.claude/agents/moai/expert-backend.md +831 -0
- moai_adk/templates/.claude/agents/moai/expert-database.md +774 -0
- moai_adk/templates/.claude/agents/moai/expert-debug.md +396 -0
- moai_adk/templates/.claude/agents/moai/expert-devops.md +711 -0
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +666 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +474 -0
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +1038 -0
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +429 -0
- moai_adk/templates/.claude/agents/moai/manager-docs.md +570 -0
- moai_adk/templates/.claude/agents/moai/manager-git.md +937 -0
- moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
- moai_adk/templates/.claude/agents/moai/manager-quality.md +598 -0
- moai_adk/templates/.claude/agents/moai/manager-spec.md +713 -0
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +600 -0
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +603 -0
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +369 -0
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +1567 -0
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +749 -0
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +427 -0
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +994 -0
- moai_adk/templates/.claude/commands/moai/0-project.md +1143 -0
- moai_adk/templates/.claude/commands/moai/1-plan.md +1435 -0
- moai_adk/templates/.claude/commands/moai/2-run.md +883 -0
- moai_adk/templates/.claude/commands/moai/3-sync.md +993 -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 +921 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +380 -0
- moai_adk/templates/.claude/output-styles/moai/yoda.md +338 -0
- moai_adk/templates/.claude/settings.json +172 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +247 -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-domain-backend/SKILL.md +319 -0
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +320 -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-frontend/SKILL.md +496 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +453 -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/design-system-tokens.md +405 -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 +491 -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-foundation-claude/SKILL.md +201 -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-context/SKILL.md +438 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +515 -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 +346 -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-quality/SKILL.md +362 -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-integration-mcp/SKILL.md +352 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/README.md +52 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/error-handling.md +334 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/integration-patterns.md +310 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/security-authentication.md +256 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/server-architecture.md +253 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/README.md +133 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/SKILL.md +296 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/examples.md +1269 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/reference.md +331 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +298 -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 +316 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -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-shadcn/SKILL.md +370 -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-platform-baas/README.md +186 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/SKILL.md +290 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/examples.md +1225 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/reference.md +567 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/scripts/provider-selector.py +323 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/templates/stack-config.yaml +204 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +446 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +387 -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 +135 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -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/schemas/config-schema.json +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1362 -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 +71 -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-templates/SKILL.md +374 -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-testing/LICENSE.txt +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +453 -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/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/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 +410 -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 +103 -41
- moai_adk/templates/.git-hooks/pre-push +116 -21
- moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
- moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
- moai_adk/templates/.gitignore +184 -44
- moai_adk/templates/.mcp.json +7 -9
- moai_adk/templates/.moai/cache/personalization.json +10 -0
- moai_adk/templates/.moai/config/config.yaml +344 -0
- moai_adk/templates/.moai/config/presets/manual.yaml +28 -0
- moai_adk/templates/.moai/config/presets/personal.yaml +30 -0
- moai_adk/templates/.moai/config/presets/team.yaml +33 -0
- moai_adk/templates/.moai/config/questions/_schema.yaml +79 -0
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +108 -0
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +122 -0
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +542 -0
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +167 -0
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +152 -0
- moai_adk/templates/.moai/config/sections/git-strategy.yaml +40 -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 +15 -0
- moai_adk/templates/.moai/config/sections/system.yaml +14 -0
- moai_adk/templates/.moai/config/sections/user.yaml +5 -0
- moai_adk/templates/.moai/config/statusline-config.yaml +86 -0
- moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
- moai_adk/templates/CLAUDE.md +382 -501
- moai_adk/utils/__init__.py +24 -1
- moai_adk/utils/banner.py +7 -10
- moai_adk/utils/common.py +16 -30
- moai_adk/utils/link_validator.py +4 -12
- moai_adk/utils/safe_file_reader.py +2 -6
- moai_adk/utils/timeout.py +160 -0
- moai_adk/utils/toon_utils.py +256 -0
- moai_adk/version.py +22 -0
- moai_adk-0.32.8.dist-info/METADATA +2478 -0
- moai_adk-0.32.8.dist-info/RECORD +396 -0
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/WHEEL +1 -1
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/entry_points.txt +1 -0
- moai_adk/cli/commands/backup.py +0 -82
- moai_adk/cli/commands/improve_user_experience.py +0 -348
- moai_adk/cli/commands/migrate.py +0 -158
- moai_adk/cli/commands/validate_links.py +0 -118
- moai_adk/templates/.github/workflows/moai-gitflow.yml +0 -413
- moai_adk/templates/.github/workflows/moai-release-create.yml +0 -100
- moai_adk/templates/.github/workflows/moai-release-pipeline.yml +0 -188
- moai_adk/utils/user_experience.py +0 -531
- moai_adk-0.25.4.dist-info/METADATA +0 -2279
- moai_adk-0.25.4.dist-info/RECORD +0 -112
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"timeout_manager": {
|
|
4
|
+
"global_timeout_ms": 5000,
|
|
5
|
+
"default_retry_count": 1,
|
|
6
|
+
"default_retry_delay_ms": 200,
|
|
7
|
+
"graceful_degradation": true
|
|
8
|
+
},
|
|
9
|
+
"hook_configs": {
|
|
10
|
+
"session_start": {
|
|
11
|
+
"policy": "normal",
|
|
12
|
+
"timeout_ms": 5000,
|
|
13
|
+
"retry_count": 1,
|
|
14
|
+
"retry_delay_ms": 200,
|
|
15
|
+
"graceful_degradation": true,
|
|
16
|
+
"memory_limit_mb": 100
|
|
17
|
+
},
|
|
18
|
+
"session_end": {
|
|
19
|
+
"policy": "normal",
|
|
20
|
+
"timeout_ms": 5000,
|
|
21
|
+
"retry_count": 1,
|
|
22
|
+
"retry_delay_ms": 500,
|
|
23
|
+
"graceful_degradation": true,
|
|
24
|
+
"memory_limit_mb": 150
|
|
25
|
+
},
|
|
26
|
+
"pre_tool": {
|
|
27
|
+
"policy": "fast",
|
|
28
|
+
"timeout_ms": 2000,
|
|
29
|
+
"retry_count": 1,
|
|
30
|
+
"retry_delay_ms": 100,
|
|
31
|
+
"graceful_degradation": true,
|
|
32
|
+
"memory_limit_mb": 50
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"resources": {
|
|
36
|
+
"memory_limits": {
|
|
37
|
+
"default_mb": 100,
|
|
38
|
+
"max_mb": 1000
|
|
39
|
+
},
|
|
40
|
+
"workers": {
|
|
41
|
+
"default_max_workers": 4,
|
|
42
|
+
"max_max_workers": 8
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"performance": {
|
|
46
|
+
"cache": {
|
|
47
|
+
"size_limit": 100,
|
|
48
|
+
"ttl_seconds": 300
|
|
49
|
+
},
|
|
50
|
+
"monitoring": {
|
|
51
|
+
"enabled": true,
|
|
52
|
+
"log_performance": false
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"document_management": {
|
|
57
|
+
"enabled": true,
|
|
58
|
+
"validation": {
|
|
59
|
+
"block_violations": false
|
|
60
|
+
},
|
|
61
|
+
"root_whitelist": [
|
|
62
|
+
"README.md",
|
|
63
|
+
"LICENSE",
|
|
64
|
+
".gitignore",
|
|
65
|
+
".claude",
|
|
66
|
+
".moai",
|
|
67
|
+
"pyproject.toml",
|
|
68
|
+
"src"
|
|
69
|
+
],
|
|
70
|
+
"directories": {
|
|
71
|
+
"temp": {
|
|
72
|
+
"base": ".moai/temp/"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"base": ".moai/scripts/"
|
|
76
|
+
},
|
|
77
|
+
"work": {
|
|
78
|
+
"base": ".moai/temp/work/"
|
|
79
|
+
},
|
|
80
|
+
"dev": {
|
|
81
|
+
"base": ".moai/scripts/dev/"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"file_patterns": {
|
|
85
|
+
"temp": {
|
|
86
|
+
"work": ["*.tmp", "*.temp", "*.bak", "*.log"],
|
|
87
|
+
"cache": ["*.cache", "*.cache.*"]
|
|
88
|
+
},
|
|
89
|
+
"scripts": {
|
|
90
|
+
"dev": ["*.sh", "*.py", "*.js", "*.ts"],
|
|
91
|
+
"utils": ["*.py", "*.sh"]
|
|
92
|
+
},
|
|
93
|
+
"work": {
|
|
94
|
+
"drafts": ["*.md", "*.txt"],
|
|
95
|
+
"notes": ["*.md", "*.txt", "*.rst"]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"auto_cleanup": {
|
|
100
|
+
"enabled": true,
|
|
101
|
+
"cleanup_days": 7,
|
|
102
|
+
"max_cache_size_mb": 100
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Optimized Git Operations Manager
|
|
3
|
+
|
|
4
|
+
Provides efficient, thread-safe Git operations with connection pooling,
|
|
5
|
+
caching, and error handling to prevent performance bottlenecks and race conditions.
|
|
6
|
+
|
|
7
|
+
Features:
|
|
8
|
+
- Connection pooling for Git commands
|
|
9
|
+
- Intelligent caching with TTL
|
|
10
|
+
- Parallel execution with semaphore control
|
|
11
|
+
- Retry mechanisms for transient failures
|
|
12
|
+
- Comprehensive error handling and logging
|
|
13
|
+
- Cross-platform compatibility
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import hashlib
|
|
17
|
+
import logging
|
|
18
|
+
import subprocess
|
|
19
|
+
import threading
|
|
20
|
+
import time
|
|
21
|
+
from concurrent.futures import Future, ThreadPoolExecutor
|
|
22
|
+
from contextlib import contextmanager
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from datetime import datetime, timedelta
|
|
25
|
+
from enum import Enum
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
from queue import Empty, Queue
|
|
28
|
+
from typing import Any, Callable, Dict, List, Optional, Union
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class GitOperationType(Enum):
|
|
32
|
+
"""Types of Git operations for caching and optimization"""
|
|
33
|
+
|
|
34
|
+
BRANCH = "branch"
|
|
35
|
+
COMMIT = "commit"
|
|
36
|
+
STATUS = "status"
|
|
37
|
+
LOG = "log"
|
|
38
|
+
DIFF = "diff"
|
|
39
|
+
REMOTE = "remote"
|
|
40
|
+
CONFIG = "config"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class GitCommand:
|
|
45
|
+
"""Git command specification"""
|
|
46
|
+
|
|
47
|
+
operation_type: GitOperationType
|
|
48
|
+
args: List[str]
|
|
49
|
+
cache_ttl_seconds: int = 60
|
|
50
|
+
retry_count: int = 2
|
|
51
|
+
timeout_seconds: int = 10
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@dataclass
|
|
55
|
+
class GitResult:
|
|
56
|
+
"""Result of Git operation with metadata"""
|
|
57
|
+
|
|
58
|
+
success: bool
|
|
59
|
+
stdout: str = ""
|
|
60
|
+
stderr: str = ""
|
|
61
|
+
return_code: int = -1
|
|
62
|
+
execution_time: float = 0.0
|
|
63
|
+
cached: bool = False
|
|
64
|
+
cache_hit: bool = False
|
|
65
|
+
operation_type: Optional[GitOperationType] = None
|
|
66
|
+
command: List[str] = field(default_factory=list)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass
|
|
70
|
+
class CacheEntry:
|
|
71
|
+
"""Cache entry for Git results"""
|
|
72
|
+
|
|
73
|
+
result: GitResult
|
|
74
|
+
timestamp: datetime
|
|
75
|
+
ttl: timedelta
|
|
76
|
+
hit_count: int = 0
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class GitOperationError(Exception):
|
|
80
|
+
"""Enhanced Git operation error with context"""
|
|
81
|
+
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
message: str,
|
|
85
|
+
command: List[str] = None,
|
|
86
|
+
return_code: int = -1,
|
|
87
|
+
stderr: str = "",
|
|
88
|
+
execution_time: float = 0.0,
|
|
89
|
+
):
|
|
90
|
+
super().__init__(message)
|
|
91
|
+
self.command = command or []
|
|
92
|
+
self.return_code = return_code
|
|
93
|
+
self.stderr = stderr
|
|
94
|
+
self.execution_time = execution_time
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class GitOperationsManager:
|
|
98
|
+
"""Optimized Git operations manager with connection pooling and caching
|
|
99
|
+
|
|
100
|
+
Features:
|
|
101
|
+
- Thread-safe execution with semaphore control
|
|
102
|
+
- Intelligent caching based on operation type
|
|
103
|
+
- Connection pooling to prevent resource contention
|
|
104
|
+
- Retry mechanisms for transient failures
|
|
105
|
+
- Performance monitoring and logging
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
def __init__(self, max_workers: int = 4, cache_size_limit: int = 100):
|
|
109
|
+
self._logger = logging.getLogger(__name__)
|
|
110
|
+
|
|
111
|
+
# Thread pool for parallel Git operations
|
|
112
|
+
self._executor = ThreadPoolExecutor(max_workers=max_workers, thread_name_prefix="git_ops")
|
|
113
|
+
self._semaphore = threading.Semaphore(max_workers) # Limit concurrent Git operations
|
|
114
|
+
|
|
115
|
+
# Cache management
|
|
116
|
+
self._cache: Dict[str, CacheEntry] = {}
|
|
117
|
+
self._cache_lock = threading.RLock()
|
|
118
|
+
self._cache_size_limit = cache_size_limit
|
|
119
|
+
|
|
120
|
+
# Performance tracking
|
|
121
|
+
self._operation_stats = {
|
|
122
|
+
"total_operations": 0,
|
|
123
|
+
"cache_hits": 0,
|
|
124
|
+
"cache_misses": 0,
|
|
125
|
+
"errors": 0,
|
|
126
|
+
"total_time": 0.0,
|
|
127
|
+
}
|
|
128
|
+
self._stats_lock = threading.Lock()
|
|
129
|
+
|
|
130
|
+
# Git command queue for sequential operations when needed
|
|
131
|
+
self._command_queue: "Queue[Any]" = Queue()
|
|
132
|
+
self._queue_processor_thread: Optional[threading.Thread] = None
|
|
133
|
+
self._queue_active = True
|
|
134
|
+
|
|
135
|
+
# Start queue processor thread
|
|
136
|
+
self._start_queue_processor()
|
|
137
|
+
|
|
138
|
+
self._logger.info(f"GitOperationsManager initialized with max_workers={max_workers}")
|
|
139
|
+
|
|
140
|
+
def _start_queue_processor(self) -> None:
|
|
141
|
+
"""Start background thread to process queued commands"""
|
|
142
|
+
|
|
143
|
+
def process_queue():
|
|
144
|
+
while self._queue_active:
|
|
145
|
+
try:
|
|
146
|
+
# Wait for command with timeout
|
|
147
|
+
future: Future = self._command_queue.get(timeout=1.0)
|
|
148
|
+
try:
|
|
149
|
+
# Execute the command
|
|
150
|
+
command, callback = future
|
|
151
|
+
result = self._execute_git_command_unsafe(command)
|
|
152
|
+
if callback:
|
|
153
|
+
callback(result)
|
|
154
|
+
except Exception as e:
|
|
155
|
+
self._logger.error(f"Error processing queued command: {e}")
|
|
156
|
+
finally:
|
|
157
|
+
self._command_queue.task_done()
|
|
158
|
+
except Empty:
|
|
159
|
+
continue
|
|
160
|
+
except Exception as e:
|
|
161
|
+
self._logger.error(f"Queue processor error: {e}")
|
|
162
|
+
|
|
163
|
+
self._queue_processor_thread = threading.Thread(target=process_queue, daemon=True)
|
|
164
|
+
self._queue_processor_thread.start()
|
|
165
|
+
|
|
166
|
+
def _generate_cache_key(self, operation_type: GitOperationType, args: List[str]) -> str:
|
|
167
|
+
"""Generate cache key for Git operation"""
|
|
168
|
+
# Include current working directory and branch for context-aware caching
|
|
169
|
+
try:
|
|
170
|
+
cwd = str(Path.cwd())
|
|
171
|
+
# Simple branch detection for cache key
|
|
172
|
+
branch_info = ""
|
|
173
|
+
if operation_type in [GitOperationType.STATUS, GitOperationType.DIFF]:
|
|
174
|
+
try:
|
|
175
|
+
result = subprocess.run(
|
|
176
|
+
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
177
|
+
capture_output=True,
|
|
178
|
+
text=True,
|
|
179
|
+
timeout=2,
|
|
180
|
+
)
|
|
181
|
+
if result.returncode == 0:
|
|
182
|
+
branch_info = result.stdout.strip()
|
|
183
|
+
except Exception:
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
key_data = f"{operation_type.value}:{args}:{cwd}:{branch_info}"
|
|
187
|
+
except Exception:
|
|
188
|
+
# Fallback to simple key
|
|
189
|
+
key_data = f"{operation_type.value}:{args}"
|
|
190
|
+
|
|
191
|
+
return hashlib.md5(key_data.encode(), usedforsecurity=False).hexdigest()
|
|
192
|
+
|
|
193
|
+
def _is_cache_valid(self, entry: CacheEntry) -> bool:
|
|
194
|
+
"""Check if cache entry is still valid"""
|
|
195
|
+
return datetime.now() - entry.timestamp < entry.ttl
|
|
196
|
+
|
|
197
|
+
def _cleanup_cache(self) -> int:
|
|
198
|
+
"""Clean up expired cache entries and enforce size limit"""
|
|
199
|
+
with self._cache_lock:
|
|
200
|
+
# Remove expired entries
|
|
201
|
+
expired_keys = [key for key, entry in self._cache.items() if not self._is_cache_valid(entry)]
|
|
202
|
+
for key in expired_keys:
|
|
203
|
+
del self._cache[key]
|
|
204
|
+
|
|
205
|
+
# Enforce size limit (remove least recently used)
|
|
206
|
+
if len(self._cache) > self._cache_size_limit:
|
|
207
|
+
# Sort by last access time (hit count as proxy)
|
|
208
|
+
sorted_items = sorted(self._cache.items(), key=lambda x: (x[1].hit_count, x[1].timestamp))
|
|
209
|
+
items_to_remove = len(self._cache) - self._cache_size_limit
|
|
210
|
+
for key, _ in sorted_items[:items_to_remove]:
|
|
211
|
+
del self._cache[key]
|
|
212
|
+
|
|
213
|
+
return len(expired_keys)
|
|
214
|
+
|
|
215
|
+
def _get_from_cache(self, cache_key: str) -> Optional[GitResult]:
|
|
216
|
+
"""Get result from cache if valid"""
|
|
217
|
+
with self._cache_lock:
|
|
218
|
+
if cache_key in self._cache:
|
|
219
|
+
entry = self._cache[cache_key]
|
|
220
|
+
if self._is_cache_valid(entry):
|
|
221
|
+
entry.hit_count += 1
|
|
222
|
+
# Return a copy of the result
|
|
223
|
+
result = GitResult(
|
|
224
|
+
success=entry.result.success,
|
|
225
|
+
stdout=entry.result.stdout,
|
|
226
|
+
stderr=entry.result.stderr,
|
|
227
|
+
return_code=entry.result.return_code,
|
|
228
|
+
execution_time=entry.result.execution_time,
|
|
229
|
+
cached=True,
|
|
230
|
+
cache_hit=True,
|
|
231
|
+
operation_type=entry.result.operation_type,
|
|
232
|
+
command=entry.result.command.copy(),
|
|
233
|
+
)
|
|
234
|
+
return result
|
|
235
|
+
else:
|
|
236
|
+
# Remove expired entry
|
|
237
|
+
del self._cache[cache_key]
|
|
238
|
+
|
|
239
|
+
return None
|
|
240
|
+
|
|
241
|
+
def _store_in_cache(self, cache_key: str, result: GitResult, ttl: int) -> None:
|
|
242
|
+
"""Store result in cache with TTL"""
|
|
243
|
+
with self._cache_lock:
|
|
244
|
+
self._cache[cache_key] = CacheEntry(result=result, timestamp=datetime.now(), ttl=timedelta(seconds=ttl))
|
|
245
|
+
|
|
246
|
+
# Cleanup if cache is getting large
|
|
247
|
+
if len(self._cache) > self._cache_size_limit * 0.8:
|
|
248
|
+
self._cleanup_cache()
|
|
249
|
+
|
|
250
|
+
def _execute_git_command_unsafe(self, command: GitCommand) -> GitResult:
|
|
251
|
+
"""Execute Git command without semaphore control (internal use)"""
|
|
252
|
+
start_time = time.time()
|
|
253
|
+
full_command = ["git"] + command.args
|
|
254
|
+
|
|
255
|
+
try:
|
|
256
|
+
# Execute Git command
|
|
257
|
+
result = subprocess.run(
|
|
258
|
+
full_command,
|
|
259
|
+
capture_output=True,
|
|
260
|
+
text=True,
|
|
261
|
+
timeout=command.timeout_seconds,
|
|
262
|
+
cwd=Path.cwd(),
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
execution_time = time.time() - start_time
|
|
266
|
+
|
|
267
|
+
git_result = GitResult(
|
|
268
|
+
success=result.returncode == 0,
|
|
269
|
+
stdout=result.stdout.strip(),
|
|
270
|
+
stderr=result.stderr.strip(),
|
|
271
|
+
return_code=result.returncode,
|
|
272
|
+
execution_time=execution_time,
|
|
273
|
+
cached=False,
|
|
274
|
+
cache_hit=False,
|
|
275
|
+
operation_type=command.operation_type,
|
|
276
|
+
command=full_command.copy(),
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
# Update statistics
|
|
280
|
+
with self._stats_lock:
|
|
281
|
+
self._operation_stats["total_operations"] += 1
|
|
282
|
+
self._operation_stats["total_time"] += execution_time
|
|
283
|
+
|
|
284
|
+
if result.returncode != 0:
|
|
285
|
+
self._operation_stats["errors"] += 1
|
|
286
|
+
|
|
287
|
+
return git_result
|
|
288
|
+
|
|
289
|
+
except subprocess.TimeoutExpired:
|
|
290
|
+
execution_time = time.time() - start_time
|
|
291
|
+
error_msg = f"Git command timed out after {command.timeout_seconds}s: {' '.join(full_command)}"
|
|
292
|
+
self._logger.error(error_msg)
|
|
293
|
+
|
|
294
|
+
with self._stats_lock:
|
|
295
|
+
self._operation_stats["total_operations"] += 1
|
|
296
|
+
self._operation_stats["errors"] += 1
|
|
297
|
+
|
|
298
|
+
return GitResult(
|
|
299
|
+
success=False,
|
|
300
|
+
stderr=error_msg,
|
|
301
|
+
execution_time=execution_time,
|
|
302
|
+
operation_type=command.operation_type,
|
|
303
|
+
command=full_command.copy(),
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
except Exception as e:
|
|
307
|
+
execution_time = time.time() - start_time
|
|
308
|
+
error_msg = f"Git command failed: {e}"
|
|
309
|
+
self._logger.error(error_msg)
|
|
310
|
+
|
|
311
|
+
with self._stats_lock:
|
|
312
|
+
self._operation_stats["total_operations"] += 1
|
|
313
|
+
self._operation_stats["errors"] += 1
|
|
314
|
+
|
|
315
|
+
return GitResult(
|
|
316
|
+
success=False,
|
|
317
|
+
stderr=error_msg,
|
|
318
|
+
execution_time=execution_time,
|
|
319
|
+
operation_type=command.operation_type,
|
|
320
|
+
command=full_command.copy(),
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
def execute_git_command(self, command: Union[GitCommand, str], *args) -> GitResult:
|
|
324
|
+
"""Execute Git command with caching and retry logic"""
|
|
325
|
+
# Convert string command to GitCommand
|
|
326
|
+
if isinstance(command, str):
|
|
327
|
+
command = GitCommand(
|
|
328
|
+
operation_type=GitOperationType.CONFIG, # Default
|
|
329
|
+
args=[command] + list(args),
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
# Check cache first
|
|
333
|
+
cache_key = self._generate_cache_key(command.operation_type, command.args)
|
|
334
|
+
cached_result = self._get_from_cache(cache_key)
|
|
335
|
+
if cached_result:
|
|
336
|
+
with self._stats_lock:
|
|
337
|
+
self._operation_stats["cache_hits"] += 1
|
|
338
|
+
return cached_result
|
|
339
|
+
|
|
340
|
+
with self._stats_lock:
|
|
341
|
+
self._operation_stats["cache_misses"] += 1
|
|
342
|
+
|
|
343
|
+
# Execute with retry logic
|
|
344
|
+
last_result = None
|
|
345
|
+
for attempt in range(command.retry_count + 1):
|
|
346
|
+
try:
|
|
347
|
+
with self._semaphore: # Limit concurrent Git operations
|
|
348
|
+
result = self._execute_git_command_unsafe(command)
|
|
349
|
+
|
|
350
|
+
if result.success:
|
|
351
|
+
# Cache successful result
|
|
352
|
+
self._store_in_cache(cache_key, result, command.cache_ttl_seconds)
|
|
353
|
+
return result
|
|
354
|
+
else:
|
|
355
|
+
last_result = result
|
|
356
|
+
if attempt < command.retry_count:
|
|
357
|
+
self._logger.warning(
|
|
358
|
+
f"Git command failed, retrying ({attempt + 1}/{command.retry_count}): {result.stderr}"
|
|
359
|
+
)
|
|
360
|
+
time.sleep(0.1 * (attempt + 1)) # Exponential backoff
|
|
361
|
+
else:
|
|
362
|
+
self._logger.error(f"Git command failed after retries: {result.stderr}")
|
|
363
|
+
|
|
364
|
+
except Exception as e:
|
|
365
|
+
self._logger.error(f"Git command exception (attempt {attempt + 1}): {e}")
|
|
366
|
+
if attempt == command.retry_count:
|
|
367
|
+
return GitResult(
|
|
368
|
+
success=False,
|
|
369
|
+
stderr=str(e),
|
|
370
|
+
operation_type=command.operation_type,
|
|
371
|
+
command=["git"] + command.args,
|
|
372
|
+
)
|
|
373
|
+
time.sleep(0.1 * (attempt + 1))
|
|
374
|
+
|
|
375
|
+
return last_result or GitResult(success=False, stderr="Unknown error")
|
|
376
|
+
|
|
377
|
+
def execute_parallel(self, commands: List[GitCommand]) -> List[GitResult]:
|
|
378
|
+
"""Execute multiple Git commands in parallel with controlled concurrency"""
|
|
379
|
+
futures = []
|
|
380
|
+
results = []
|
|
381
|
+
|
|
382
|
+
# Submit all commands
|
|
383
|
+
for command in commands:
|
|
384
|
+
future = self._executor.submit(self.execute_git_command, command)
|
|
385
|
+
futures.append((future, command))
|
|
386
|
+
|
|
387
|
+
# Collect results as they complete
|
|
388
|
+
for future, command in futures:
|
|
389
|
+
try:
|
|
390
|
+
result = future.result(timeout=command.timeout_seconds + 5) # Extra buffer
|
|
391
|
+
results.append(result)
|
|
392
|
+
except Exception as e:
|
|
393
|
+
self._logger.error(f"Parallel Git command failed: {e}")
|
|
394
|
+
results.append(
|
|
395
|
+
GitResult(
|
|
396
|
+
success=False,
|
|
397
|
+
stderr=str(e),
|
|
398
|
+
operation_type=command.operation_type,
|
|
399
|
+
command=["git"] + command.args,
|
|
400
|
+
)
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
return results
|
|
404
|
+
|
|
405
|
+
def get_project_info(self, use_cache: bool = True) -> Dict[str, Any]:
|
|
406
|
+
"""Get comprehensive project information efficiently"""
|
|
407
|
+
commands = [
|
|
408
|
+
GitCommand(
|
|
409
|
+
operation_type=GitOperationType.BRANCH,
|
|
410
|
+
args=["branch", "--show-current"],
|
|
411
|
+
cache_ttl_seconds=30,
|
|
412
|
+
timeout_seconds=5,
|
|
413
|
+
),
|
|
414
|
+
GitCommand(
|
|
415
|
+
operation_type=GitOperationType.LOG,
|
|
416
|
+
args=["log", "--pretty=format:%h %s", "-1"],
|
|
417
|
+
cache_ttl_seconds=10,
|
|
418
|
+
timeout_seconds=5,
|
|
419
|
+
),
|
|
420
|
+
GitCommand(
|
|
421
|
+
operation_type=GitOperationType.LOG,
|
|
422
|
+
args=["log", "--pretty=format:%ar", "-1"],
|
|
423
|
+
cache_ttl_seconds=10,
|
|
424
|
+
timeout_seconds=5,
|
|
425
|
+
),
|
|
426
|
+
GitCommand(
|
|
427
|
+
operation_type=GitOperationType.STATUS,
|
|
428
|
+
args=["status", "--porcelain"],
|
|
429
|
+
cache_ttl_seconds=5, # Short TTL for status
|
|
430
|
+
timeout_seconds=5,
|
|
431
|
+
),
|
|
432
|
+
]
|
|
433
|
+
|
|
434
|
+
# If cache disabled, clear relevant entries
|
|
435
|
+
if not use_cache:
|
|
436
|
+
with self._cache_lock:
|
|
437
|
+
for command in commands:
|
|
438
|
+
cache_key = self._generate_cache_key(command.operation_type, command.args)
|
|
439
|
+
self._cache.pop(cache_key, None)
|
|
440
|
+
|
|
441
|
+
# Execute commands in parallel
|
|
442
|
+
results = self.execute_parallel(commands)
|
|
443
|
+
|
|
444
|
+
# Process results
|
|
445
|
+
project_info = {
|
|
446
|
+
"branch": "unknown",
|
|
447
|
+
"last_commit": "unknown",
|
|
448
|
+
"commit_time": "unknown",
|
|
449
|
+
"changes": 0,
|
|
450
|
+
"fetch_time": datetime.now().isoformat(),
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
if len(results) >= 4:
|
|
454
|
+
if results[0].success:
|
|
455
|
+
project_info["branch"] = results[0].stdout or "unknown"
|
|
456
|
+
if results[1].success:
|
|
457
|
+
project_info["last_commit"] = results[1].stdout or "unknown"
|
|
458
|
+
if results[2].success:
|
|
459
|
+
project_info["commit_time"] = results[2].stdout or "unknown"
|
|
460
|
+
if results[3].success:
|
|
461
|
+
changes_text = results[3].stdout.strip()
|
|
462
|
+
project_info["changes"] = len(changes_text.splitlines()) if changes_text else 0
|
|
463
|
+
|
|
464
|
+
return project_info
|
|
465
|
+
|
|
466
|
+
def queue_command(
|
|
467
|
+
self,
|
|
468
|
+
command: GitCommand,
|
|
469
|
+
callback: Optional[Callable[[GitResult], None]] = None,
|
|
470
|
+
) -> None:
|
|
471
|
+
"""Queue a Git command for background execution"""
|
|
472
|
+
try:
|
|
473
|
+
future = (command, callback)
|
|
474
|
+
self._command_queue.put(future, timeout=1.0)
|
|
475
|
+
except Exception as e:
|
|
476
|
+
self._logger.error(f"Failed to queue Git command: {e}")
|
|
477
|
+
|
|
478
|
+
def get_statistics(self) -> Dict[str, Any]:
|
|
479
|
+
"""Get performance and cache statistics"""
|
|
480
|
+
with self._stats_lock, self._cache_lock:
|
|
481
|
+
return {
|
|
482
|
+
"operations": {
|
|
483
|
+
"total": self._operation_stats["total_operations"],
|
|
484
|
+
"cache_hits": self._operation_stats["cache_hits"],
|
|
485
|
+
"cache_misses": self._operation_stats["cache_misses"],
|
|
486
|
+
"cache_hit_rate": (
|
|
487
|
+
self._operation_stats["cache_hits"]
|
|
488
|
+
/ (self._operation_stats["cache_hits"] + self._operation_stats["cache_misses"])
|
|
489
|
+
if (self._operation_stats["cache_hits"] + self._operation_stats["cache_misses"]) > 0
|
|
490
|
+
else 0
|
|
491
|
+
),
|
|
492
|
+
"errors": self._operation_stats["errors"],
|
|
493
|
+
"average_execution_time": (
|
|
494
|
+
self._operation_stats["total_time"] / self._operation_stats["total_operations"]
|
|
495
|
+
if self._operation_stats["total_operations"] > 0
|
|
496
|
+
else 0
|
|
497
|
+
),
|
|
498
|
+
},
|
|
499
|
+
"cache": {
|
|
500
|
+
"size": len(self._cache),
|
|
501
|
+
"size_limit": self._cache_size_limit,
|
|
502
|
+
"utilization": len(self._cache) / self._cache_size_limit,
|
|
503
|
+
},
|
|
504
|
+
"queue": {"pending": self._command_queue.qsize()},
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
def clear_cache(self, operation_type: Optional[GitOperationType] = None) -> int:
|
|
508
|
+
"""Clear cache entries, optionally filtered by operation type"""
|
|
509
|
+
with self._cache_lock:
|
|
510
|
+
if operation_type is None:
|
|
511
|
+
# Clear all cache
|
|
512
|
+
count = len(self._cache)
|
|
513
|
+
self._cache.clear()
|
|
514
|
+
else:
|
|
515
|
+
# Clear specific operation type
|
|
516
|
+
keys_to_remove = [
|
|
517
|
+
key for key, entry in self._cache.items() if entry.result.operation_type == operation_type
|
|
518
|
+
]
|
|
519
|
+
for key in keys_to_remove:
|
|
520
|
+
del self._cache[key]
|
|
521
|
+
count = len(keys_to_remove)
|
|
522
|
+
|
|
523
|
+
return count
|
|
524
|
+
|
|
525
|
+
def shutdown(self) -> None:
|
|
526
|
+
"""Shutdown the Git operations manager"""
|
|
527
|
+
self._logger.info("Shutting down GitOperationsManager")
|
|
528
|
+
|
|
529
|
+
# Stop queue processor
|
|
530
|
+
self._queue_active = False
|
|
531
|
+
if self._queue_processor_thread and self._queue_processor_thread.is_alive():
|
|
532
|
+
self._queue_processor_thread.join(timeout=2.0)
|
|
533
|
+
|
|
534
|
+
# Shutdown thread pool
|
|
535
|
+
self._executor.shutdown(wait=True)
|
|
536
|
+
|
|
537
|
+
# Clear cache
|
|
538
|
+
with self._cache_lock:
|
|
539
|
+
self._cache.clear()
|
|
540
|
+
|
|
541
|
+
self._logger.info("GitOperationsManager shutdown complete")
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
# Global instance
|
|
545
|
+
_git_manager = None
|
|
546
|
+
_git_manager_lock = threading.Lock()
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
def get_git_manager() -> GitOperationsManager:
|
|
550
|
+
"""Get the global Git operations manager instance"""
|
|
551
|
+
global _git_manager
|
|
552
|
+
if _git_manager is None:
|
|
553
|
+
with _git_manager_lock:
|
|
554
|
+
if _git_manager is None:
|
|
555
|
+
_git_manager = GitOperationsManager()
|
|
556
|
+
return _git_manager
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
@contextmanager
|
|
560
|
+
def git_operation_context(max_workers: int = 4):
|
|
561
|
+
"""Context manager for Git operations with temporary manager"""
|
|
562
|
+
manager = GitOperationsManager(max_workers=max_workers)
|
|
563
|
+
try:
|
|
564
|
+
yield manager
|
|
565
|
+
finally:
|
|
566
|
+
manager.shutdown()
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
# Convenience functions for common operations
|
|
570
|
+
def get_git_info(use_cache: bool = True) -> Dict[str, Any]:
|
|
571
|
+
"""Convenience function to get Git project information"""
|
|
572
|
+
manager = get_git_manager()
|
|
573
|
+
return manager.get_project_info(use_cache=use_cache)
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def run_git_command(
|
|
577
|
+
operation_type: GitOperationType,
|
|
578
|
+
args: List[str],
|
|
579
|
+
cache_ttl: int = 60,
|
|
580
|
+
timeout: int = 10,
|
|
581
|
+
) -> GitResult:
|
|
582
|
+
"""Convenience function to run a single Git command"""
|
|
583
|
+
command = GitCommand(
|
|
584
|
+
operation_type=operation_type,
|
|
585
|
+
args=args,
|
|
586
|
+
cache_ttl_seconds=cache_ttl,
|
|
587
|
+
timeout_seconds=timeout,
|
|
588
|
+
)
|
|
589
|
+
manager = get_git_manager()
|
|
590
|
+
return manager.execute_git_command(command)
|