moai-adk 0.8.0__py3-none-any.whl → 0.34.0__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.
- moai_adk/__init__.py +2 -6
- moai_adk/__main__.py +136 -21
- moai_adk/cli/__init__.py +6 -2
- moai_adk/cli/commands/__init__.py +1 -4
- moai_adk/cli/commands/analyze.py +116 -0
- moai_adk/cli/commands/doctor.py +17 -5
- moai_adk/cli/commands/init.py +118 -48
- moai_adk/cli/commands/language.py +248 -0
- moai_adk/cli/commands/status.py +8 -13
- moai_adk/cli/commands/update.py +1978 -149
- moai_adk/cli/main.py +3 -2
- moai_adk/cli/prompts/init_prompts.py +144 -91
- 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 +0 -1
- 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 +6 -0
- moai_adk/core/config/auto_spec_config.py +340 -0
- moai_adk/core/config/migration.py +148 -17
- moai_adk/core/config/unified.py +436 -0
- moai_adk/core/context_manager.py +273 -0
- moai_adk/core/diagnostics/slash_commands.py +0 -1
- 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 +8 -1
- moai_adk/core/git/branch.py +0 -1
- moai_adk/core/git/branch_manager.py +2 -10
- moai_adk/core/git/checkpoint.py +1 -7
- moai_adk/core/git/commit.py +0 -1
- moai_adk/core/git/conflict_detector.py +413 -0
- moai_adk/core/git/event_detector.py +3 -5
- moai_adk/core/git/manager.py +91 -2
- 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 +481 -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 +0 -1
- moai_adk/core/project/backup_utils.py +2 -7
- moai_adk/core/project/checker.py +2 -4
- moai_adk/core/project/detector.py +189 -22
- moai_adk/core/project/initializer.py +218 -27
- moai_adk/core/project/phase_executor.py +416 -44
- moai_adk/core/project/validator.py +7 -32
- moai_adk/core/quality/__init__.py +1 -1
- moai_adk/core/quality/trust_checker.py +37 -101
- moai_adk/core/quality/validators/__init__.py +1 -1
- moai_adk/core/quality/validators/base_validator.py +1 -1
- 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 +0 -1
- moai_adk/core/template/backup.py +82 -17
- moai_adk/core/template/config.py +112 -40
- moai_adk/core/template/languages.py +0 -1
- moai_adk/core/template/merger.py +75 -26
- moai_adk/core/template/processor.py +750 -72
- 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 +670 -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-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 +509 -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 +1020 -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 +1384 -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/{alfred/core → moai/lib}/checkpoint.py +10 -37
- 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 +1075 -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 +78 -50
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +438 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +431 -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 +313 -283
- moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +610 -1525
- moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +423 -619
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +295 -95
- moai_adk/templates/.claude/skills/moai-domain-database/examples.md +817 -16
- 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 +532 -17
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +470 -97
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +955 -16
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +651 -18
- 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/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 +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 +618 -93
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +446 -91
- 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 +346 -94
- moai_adk/templates/.claude/skills/moai-lang-go/examples.md +906 -16
- moai_adk/templates/.claude/skills/moai-lang-go/reference.md +721 -15
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +352 -91
- moai_adk/templates/.claude/skills/moai-lang-java/examples.md +851 -16
- moai_adk/templates/.claude/skills/moai-lang-java/reference.md +278 -18
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +344 -86
- moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +993 -16
- moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +549 -18
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +617 -96
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +364 -314
- moai_adk/templates/.claude/skills/moai-lang-python/examples.md +849 -496
- moai_adk/templates/.claude/skills/moai-lang-python/reference.md +731 -243
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +545 -89
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +650 -87
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +341 -93
- moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +646 -16
- moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +491 -18
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +463 -89
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +620 -16
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +410 -17
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +486 -112
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +905 -16
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +659 -17
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +333 -92
- moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +1076 -16
- moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +718 -21
- 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 +290 -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-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 +1462 -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 +206 -36
- moai_adk/templates/.gitignore +194 -13
- moai_adk/templates/.mcp.json +31 -0
- moai_adk/templates/.moai/config/config.yaml +58 -0
- moai_adk/templates/.moai/config/questions/_schema.yaml +151 -0
- moai_adk/templates/.moai/config/questions/tab0-init.yaml +251 -0
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +108 -0
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +81 -0
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +634 -0
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +170 -0
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +87 -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 +14 -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 +571 -244
- moai_adk/utils/__init__.py +24 -2
- moai_adk/utils/banner.py +9 -13
- moai_adk/utils/common.py +294 -0
- moai_adk/utils/link_validator.py +241 -0
- moai_adk/utils/logger.py +4 -9
- 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.34.0.dist-info/METADATA +2999 -0
- moai_adk-0.34.0.dist-info/RECORD +463 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.34.0.dist-info}/WHEEL +1 -1
- {moai_adk-0.8.0.dist-info → moai_adk-0.34.0.dist-info}/entry_points.txt +1 -0
- moai_adk/cli/commands/backup.py +0 -80
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +0 -293
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +0 -196
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +0 -207
- moai_adk/templates/.claude/agents/alfred/git-manager.md +0 -375
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +0 -343
- moai_adk/templates/.claude/agents/alfred/project-manager.md +0 -246
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +0 -320
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +0 -837
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +0 -272
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +0 -265
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +0 -311
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +0 -352
- moai_adk/templates/.claude/commands/alfred/0-project.md +0 -1184
- moai_adk/templates/.claude/commands/alfred/1-plan.md +0 -665
- moai_adk/templates/.claude/commands/alfred/2-run.md +0 -488
- moai_adk/templates/.claude/commands/alfred/3-sync.md +0 -623
- moai_adk/templates/.claude/hooks/alfred/HOOK_SCHEMA_VALIDATION.md +0 -313
- moai_adk/templates/.claude/hooks/alfred/README.md +0 -230
- moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +0 -174
- moai_adk/templates/.claude/hooks/alfred/core/__init__.py +0 -170
- moai_adk/templates/.claude/hooks/alfred/core/context.py +0 -67
- moai_adk/templates/.claude/hooks/alfred/core/project.py +0 -416
- moai_adk/templates/.claude/hooks/alfred/core/tags.py +0 -198
- moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py +0 -21
- moai_adk/templates/.claude/hooks/alfred/handlers/notification.py +0 -25
- moai_adk/templates/.claude/hooks/alfred/handlers/session.py +0 -161
- moai_adk/templates/.claude/hooks/alfred/handlers/tool.py +0 -90
- moai_adk/templates/.claude/hooks/alfred/handlers/user.py +0 -42
- moai_adk/templates/.claude/hooks/alfred/test_hook_output.py +0 -175
- moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md +0 -640
- moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md +0 -696
- moai_adk/templates/.claude/output-styles/alfred/study-with-alfred.md +0 -474
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/SKILL.md +0 -122
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/reference.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/SKILL.md +0 -237
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/examples.md +0 -615
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/reference.md +0 -653
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-cc-agents/SKILL.md +0 -269
- moai_adk/templates/.claude/skills/moai-cc-agents/templates/agent-template.md +0 -32
- moai_adk/templates/.claude/skills/moai-cc-claude-md/SKILL.md +0 -298
- moai_adk/templates/.claude/skills/moai-cc-claude-md/templates/CLAUDE-template.md +0 -26
- moai_adk/templates/.claude/skills/moai-cc-commands/SKILL.md +0 -307
- moai_adk/templates/.claude/skills/moai-cc-commands/templates/command-template.md +0 -21
- moai_adk/templates/.claude/skills/moai-cc-hooks/SKILL.md +0 -252
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/pre-bash-check.sh +0 -19
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/preserve-permissions.sh +0 -19
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/validate-bash-command.py +0 -24
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/SKILL.md +0 -199
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/templates/settings-mcp-template.json +0 -39
- moai_adk/templates/.claude/skills/moai-cc-memory/SKILL.md +0 -316
- moai_adk/templates/.claude/skills/moai-cc-memory/templates/session-summary-template.md +0 -18
- moai_adk/templates/.claude/skills/moai-cc-settings/SKILL.md +0 -263
- moai_adk/templates/.claude/skills/moai-cc-settings/templates/settings-complete-template.json +0 -30
- moai_adk/templates/.claude/skills/moai-cc-skills/SKILL.md +0 -291
- moai_adk/templates/.claude/skills/moai-cc-skills/templates/SKILL-template.md +0 -15
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-data-science/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-data-science/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-data-science/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-devops/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-domain-devops/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-devops/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-domain-ml/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-ml/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-ml/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-security/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-security/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-security/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-web-api/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-web-api/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-web-api/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-essentials-debug/SKILL.md +0 -303
- moai_adk/templates/.claude/skills/moai-essentials-debug/examples.md +0 -1064
- moai_adk/templates/.claude/skills/moai-essentials-debug/reference.md +0 -1047
- moai_adk/templates/.claude/skills/moai-essentials-perf/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-perf/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-perf/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-essentials-refactor/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-refactor/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-refactor/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-essentials-review/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-review/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-review/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-ears/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-ears/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-git/SKILL.md +0 -122
- moai_adk/templates/.claude/skills/moai-foundation-git/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-git/reference.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-langs/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-langs/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-langs/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-specs/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-specs/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-specs/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-tags/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-tags/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-tags/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-trust/SKILL.md +0 -307
- moai_adk/templates/.claude/skills/moai-foundation-trust/examples.md +0 -0
- moai_adk/templates/.claude/skills/moai-foundation-trust/reference.md +0 -1099
- moai_adk/templates/.claude/skills/moai-lang-c/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-c/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-c/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-dart/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-dart/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-dart/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +0 -125
- moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +0 -32
- moai_adk/templates/.claude/skills/moai-lang-php/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-php/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-r/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-r/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-shell/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-shell/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-shell/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-sql/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-sql/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-sql/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-skill-factory/CHECKLIST.md +0 -482
- moai_adk/templates/.claude/skills/moai-skill-factory/EXAMPLES.md +0 -278
- moai_adk/templates/.claude/skills/moai-skill-factory/INTERACTIVE-DISCOVERY.md +0 -524
- moai_adk/templates/.claude/skills/moai-skill-factory/METADATA.md +0 -477
- moai_adk/templates/.claude/skills/moai-skill-factory/PARALLEL-ANALYSIS-REPORT.md +0 -429
- moai_adk/templates/.claude/skills/moai-skill-factory/PYTHON-VERSION-MATRIX.md +0 -391
- moai_adk/templates/.claude/skills/moai-skill-factory/SKILL-FACTORY-WORKFLOW.md +0 -431
- moai_adk/templates/.claude/skills/moai-skill-factory/SKILL-UPDATE-ADVISOR.md +0 -577
- moai_adk/templates/.claude/skills/moai-skill-factory/SKILL.md +0 -271
- moai_adk/templates/.claude/skills/moai-skill-factory/STEP-BY-STEP-GUIDE.md +0 -466
- moai_adk/templates/.claude/skills/moai-skill-factory/STRUCTURE.md +0 -583
- moai_adk/templates/.claude/skills/moai-skill-factory/WEB-RESEARCH.md +0 -526
- moai_adk/templates/.claude/skills/moai-skill-factory/reference.md +0 -465
- moai_adk/templates/.claude/skills/moai-skill-factory/scripts/generate-structure.sh +0 -328
- moai_adk/templates/.claude/skills/moai-skill-factory/scripts/validate-skill.sh +0 -312
- moai_adk/templates/.claude/skills/moai-skill-factory/templates/SKILL_TEMPLATE.md +0 -245
- moai_adk/templates/.claude/skills/moai-skill-factory/templates/examples-template.md +0 -285
- moai_adk/templates/.claude/skills/moai-skill-factory/templates/reference-template.md +0 -278
- moai_adk/templates/.claude/skills/moai-skill-factory/templates/scripts-template.sh +0 -303
- moai_adk/templates/.claude/skills/moai-spec-authoring/README.md +0 -137
- moai_adk/templates/.claude/skills/moai-spec-authoring/SKILL.md +0 -218
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples/validate-spec.sh +0 -161
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples.md +0 -541
- moai_adk/templates/.claude/skills/moai-spec-authoring/reference.md +0 -622
- moai_adk/templates/.github/ISSUE_TEMPLATE/spec.yml +0 -176
- moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +0 -69
- moai_adk/templates/.github/workflows/moai-gitflow.yml +0 -256
- moai_adk/templates/.moai/config.json +0 -96
- moai_adk/templates/.moai/memory/CLAUDE-AGENTS-GUIDE.md +0 -208
- moai_adk/templates/.moai/memory/CLAUDE-PRACTICES.md +0 -369
- moai_adk/templates/.moai/memory/CLAUDE-RULES.md +0 -539
- moai_adk/templates/.moai/memory/CONFIG-SCHEMA.md +0 -444
- moai_adk/templates/.moai/memory/DEVELOPMENT-GUIDE.md +0 -344
- moai_adk/templates/.moai/memory/GITFLOW-PROTECTION-POLICY.md +0 -220
- moai_adk/templates/.moai/memory/SKILLS-DESCRIPTION-POLICY.md +0 -218
- moai_adk/templates/.moai/memory/SPEC-METADATA.md +0 -356
- moai_adk/templates/.moai/memory/config-schema.md +0 -444
- moai_adk/templates/.moai/memory/gitflow-protection-policy.md +0 -220
- moai_adk/templates/.moai/memory/spec-metadata.md +0 -356
- moai_adk/templates/.moai/project/product.md +0 -161
- moai_adk/templates/.moai/project/structure.md +0 -156
- moai_adk/templates/.moai/project/tech.md +0 -227
- moai_adk/templates/__init__.py +0 -2
- moai_adk-0.8.0.dist-info/METADATA +0 -1722
- moai_adk-0.8.0.dist-info/RECORD +0 -282
- {moai_adk-0.8.0.dist-info → moai_adk-0.34.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,1084 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration management for SPEC-REDESIGN-001
|
|
3
|
+
|
|
4
|
+
Handles:
|
|
5
|
+
- Configuration loading and saving
|
|
6
|
+
- Smart defaults application
|
|
7
|
+
- Auto-detection of system values
|
|
8
|
+
- Configuration validation and coverage
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import re
|
|
13
|
+
from copy import deepcopy
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any, Dict, List, Optional
|
|
16
|
+
|
|
17
|
+
import yaml
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ConfigurationManager:
|
|
21
|
+
"""Manages project configuration with 31 settings coverage"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, config_path: Optional[Path] = None):
|
|
24
|
+
self.config_path = config_path or Path(".moai/config/config.yaml")
|
|
25
|
+
self.schema = None
|
|
26
|
+
self._config_cache: Optional[Dict[str, Any]] = None
|
|
27
|
+
|
|
28
|
+
def load(self) -> Dict[str, Any]:
|
|
29
|
+
"""Load configuration from file (supports YAML and JSON)"""
|
|
30
|
+
if self.config_path.exists():
|
|
31
|
+
with open(self.config_path, "r", encoding="utf-8") as f:
|
|
32
|
+
if self.config_path.suffix in (".yaml", ".yml"):
|
|
33
|
+
self._config_cache = yaml.safe_load(f) or {}
|
|
34
|
+
else:
|
|
35
|
+
self._config_cache = json.load(f)
|
|
36
|
+
return self._config_cache
|
|
37
|
+
return {}
|
|
38
|
+
|
|
39
|
+
def get_smart_defaults(self) -> Dict[str, Any]:
|
|
40
|
+
"""Get smart defaults"""
|
|
41
|
+
engine = SmartDefaultsEngine()
|
|
42
|
+
return engine.get_all_defaults()
|
|
43
|
+
|
|
44
|
+
def get_auto_detect_fields(self) -> List[Dict[str, str]]:
|
|
45
|
+
"""Get auto-detect field definitions"""
|
|
46
|
+
return [
|
|
47
|
+
{"field": "project.language", "type": "auto-detect"},
|
|
48
|
+
{"field": "project.locale", "type": "auto-detect"},
|
|
49
|
+
{"field": "language.conversation_language_name", "type": "auto-detect"},
|
|
50
|
+
{"field": "project.template_version", "type": "auto-detect"},
|
|
51
|
+
{"field": "moai.version", "type": "auto-detect"},
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
def save(self, config: Dict[str, Any]) -> bool:
|
|
55
|
+
"""Save configuration atomically (all or nothing)"""
|
|
56
|
+
# Create backup
|
|
57
|
+
self._create_backup()
|
|
58
|
+
|
|
59
|
+
# Validate completeness
|
|
60
|
+
if not self._validate_complete(config):
|
|
61
|
+
raise ValueError("Configuration missing required fields")
|
|
62
|
+
|
|
63
|
+
# Ensure directory exists
|
|
64
|
+
self.config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
65
|
+
|
|
66
|
+
# Write atomically (supports YAML and JSON based on file extension)
|
|
67
|
+
temp_path = self.config_path.with_suffix(".tmp")
|
|
68
|
+
try:
|
|
69
|
+
with open(temp_path, "w", encoding="utf-8") as f:
|
|
70
|
+
if self.config_path.suffix in (".yaml", ".yml"):
|
|
71
|
+
yaml.safe_dump(config, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
|
|
72
|
+
else:
|
|
73
|
+
json.dump(config, f, indent=2)
|
|
74
|
+
|
|
75
|
+
# Atomic rename
|
|
76
|
+
temp_path.replace(self.config_path)
|
|
77
|
+
self._config_cache = config
|
|
78
|
+
return True
|
|
79
|
+
except Exception as e:
|
|
80
|
+
if temp_path.exists():
|
|
81
|
+
temp_path.unlink()
|
|
82
|
+
raise e
|
|
83
|
+
|
|
84
|
+
def _write_config(self, config: Dict[str, Any]) -> None:
|
|
85
|
+
"""Internal method for saving configuration"""
|
|
86
|
+
self.save(config)
|
|
87
|
+
|
|
88
|
+
def build_from_responses(self, responses: Dict[str, Any]) -> Dict[str, Any]:
|
|
89
|
+
"""Build complete configuration from user responses"""
|
|
90
|
+
# Start with responses
|
|
91
|
+
config = self._parse_responses(responses)
|
|
92
|
+
|
|
93
|
+
# Apply smart defaults
|
|
94
|
+
defaults_engine = SmartDefaultsEngine()
|
|
95
|
+
config = defaults_engine.apply_defaults(config)
|
|
96
|
+
|
|
97
|
+
# Apply auto-detection
|
|
98
|
+
auto_detect = AutoDetectionEngine()
|
|
99
|
+
config = auto_detect.detect_and_apply(config)
|
|
100
|
+
|
|
101
|
+
return config
|
|
102
|
+
|
|
103
|
+
def _parse_responses(self, responses: Dict[str, Any]) -> Dict[str, Any]:
|
|
104
|
+
"""Parse flat response dict into nested config structure"""
|
|
105
|
+
config: Dict[str, Any] = {
|
|
106
|
+
"user": {},
|
|
107
|
+
"language": {},
|
|
108
|
+
"project": {},
|
|
109
|
+
"git_strategy": {
|
|
110
|
+
"personal": {},
|
|
111
|
+
"team": {},
|
|
112
|
+
},
|
|
113
|
+
"constitution": {},
|
|
114
|
+
"moai": {},
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# Map responses to config structure
|
|
118
|
+
mapping = {
|
|
119
|
+
"user_name": ("user", "name"),
|
|
120
|
+
"conversation_language": ("language", "conversation_language"),
|
|
121
|
+
"agent_prompt_language": ("language", "agent_prompt_language"),
|
|
122
|
+
"project_name": ("project", "name"),
|
|
123
|
+
"github_profile_name": ("github", "profile_name"),
|
|
124
|
+
"project_description": ("project", "description"),
|
|
125
|
+
"git_strategy_mode": ("git_strategy", "mode"),
|
|
126
|
+
"git_strategy_workflow": ("git_strategy", "workflow"),
|
|
127
|
+
"git_personal_auto_checkpoint": (
|
|
128
|
+
"git_strategy",
|
|
129
|
+
"personal",
|
|
130
|
+
"auto_checkpoint",
|
|
131
|
+
),
|
|
132
|
+
"git_personal_push_remote": ("git_strategy", "personal", "push_to_remote"),
|
|
133
|
+
"git_team_auto_pr": ("git_strategy", "team", "auto_pr"),
|
|
134
|
+
"git_team_draft_pr": ("git_strategy", "team", "draft_pr"),
|
|
135
|
+
"test_coverage_target": ("constitution", "test_coverage_target"),
|
|
136
|
+
"enforce_tdd": ("constitution", "enforce_tdd"),
|
|
137
|
+
"documentation_mode": ("project", "documentation_mode"),
|
|
138
|
+
"documentation_depth": ("project", "documentation_depth"),
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
for response_key, response_value in responses.items():
|
|
142
|
+
if response_key in mapping:
|
|
143
|
+
path = mapping[response_key]
|
|
144
|
+
self._set_nested(config, path, response_value)
|
|
145
|
+
|
|
146
|
+
return config
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def _set_nested(config: Dict[str, Any], path: tuple, value: Any) -> None:
|
|
150
|
+
"""Set nested value in dict using path tuple"""
|
|
151
|
+
current = config
|
|
152
|
+
for key in path[:-1]:
|
|
153
|
+
if key not in current:
|
|
154
|
+
current[key] = {}
|
|
155
|
+
current = current[key]
|
|
156
|
+
current[path[-1]] = value
|
|
157
|
+
|
|
158
|
+
def _validate_complete(self, config: Dict[str, Any]) -> bool:
|
|
159
|
+
"""Validate that config has all required fields"""
|
|
160
|
+
required_fields = [
|
|
161
|
+
"user.name",
|
|
162
|
+
"language.conversation_language",
|
|
163
|
+
"language.agent_prompt_language",
|
|
164
|
+
"project.name",
|
|
165
|
+
"git_strategy.mode",
|
|
166
|
+
"constitution.test_coverage_target",
|
|
167
|
+
"constitution.enforce_tdd",
|
|
168
|
+
"project.documentation_mode",
|
|
169
|
+
]
|
|
170
|
+
# Note: github.profile_name is optional (can be set later)
|
|
171
|
+
|
|
172
|
+
flat = self._flatten_config(config)
|
|
173
|
+
return all(field in flat for field in required_fields)
|
|
174
|
+
|
|
175
|
+
@staticmethod
|
|
176
|
+
def _flatten_config(config: Dict[str, Any], prefix: str = "") -> Dict[str, Any]:
|
|
177
|
+
"""Flatten nested config for easier validation"""
|
|
178
|
+
result = {}
|
|
179
|
+
|
|
180
|
+
for key, value in config.items():
|
|
181
|
+
new_key = f"{prefix}.{key}" if prefix else key
|
|
182
|
+
if isinstance(value, dict):
|
|
183
|
+
result.update(ConfigurationManager._flatten_config(value, new_key))
|
|
184
|
+
else:
|
|
185
|
+
result[new_key] = value
|
|
186
|
+
|
|
187
|
+
return result
|
|
188
|
+
|
|
189
|
+
def _create_backup(self) -> None:
|
|
190
|
+
"""Create backup of existing config"""
|
|
191
|
+
if self.config_path.exists():
|
|
192
|
+
backup_path = self.config_path.with_suffix(".backup")
|
|
193
|
+
with open(self.config_path, "r") as src:
|
|
194
|
+
with open(backup_path, "w") as dst:
|
|
195
|
+
dst.write(src.read())
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class SmartDefaultsEngine:
|
|
199
|
+
"""Applies intelligent default values based on configuration.
|
|
200
|
+
|
|
201
|
+
Provides 16+ smart defaults for configuration fields with safety-first approach:
|
|
202
|
+
- git_strategy mode (1) - defaults to 'manual' for safety
|
|
203
|
+
- git_strategy workflows (2)
|
|
204
|
+
- git_strategy checkpoints and push behavior (2)
|
|
205
|
+
- git_strategy team PR settings (2)
|
|
206
|
+
- constitution enforcement (2)
|
|
207
|
+
- language settings (1)
|
|
208
|
+
- project description (1)
|
|
209
|
+
- auto-detect placeholders (5)
|
|
210
|
+
- additional settings (1)
|
|
211
|
+
|
|
212
|
+
Safety Note: Git strategy defaults to 'manual' to ensure users must explicitly
|
|
213
|
+
choose GitHub automation features for their safety.
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
def __init__(self):
|
|
217
|
+
"""Initialize SmartDefaultsEngine with 16+ predefined defaults."""
|
|
218
|
+
self.defaults = {
|
|
219
|
+
"git_strategy.personal.workflow": "github-flow",
|
|
220
|
+
"git_strategy.team.workflow": "git-flow",
|
|
221
|
+
"git_strategy.personal.auto_checkpoint": "disabled",
|
|
222
|
+
"git_strategy.personal.push_to_remote": False,
|
|
223
|
+
"git_strategy.team.auto_pr": False,
|
|
224
|
+
"git_strategy.team.draft_pr": False,
|
|
225
|
+
"constitution.test_coverage_target": 85,
|
|
226
|
+
"constitution.enforce_tdd": True,
|
|
227
|
+
"language.agent_prompt_language": "en",
|
|
228
|
+
"project.description": "",
|
|
229
|
+
"language.conversation_language_name": "", # Will be detected
|
|
230
|
+
"project.template_version": "", # Will be detected
|
|
231
|
+
"moai.version": "", # Will be detected
|
|
232
|
+
"project.language": "", # Will be detected
|
|
233
|
+
"project.locale": "", # Will be detected
|
|
234
|
+
"git_strategy.mode": "manual", # 16th default (safety-first approach)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
def get_all_defaults(self) -> Dict[str, Any]:
|
|
238
|
+
"""Get all defined defaults as a deep copy.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
Dictionary with all 16+ default values keyed by field path.
|
|
242
|
+
|
|
243
|
+
Example:
|
|
244
|
+
>>> engine = SmartDefaultsEngine()
|
|
245
|
+
>>> defaults = engine.get_all_defaults()
|
|
246
|
+
>>> defaults['git_strategy.personal.workflow']
|
|
247
|
+
'github-flow'
|
|
248
|
+
"""
|
|
249
|
+
return deepcopy(self.defaults)
|
|
250
|
+
|
|
251
|
+
def get_default(self, field_path: str) -> Any:
|
|
252
|
+
"""Get default value for specific field path.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
field_path: Dot-notation path like 'git_strategy.personal.workflow'
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
Default value for the field, or None if not defined.
|
|
259
|
+
|
|
260
|
+
Example:
|
|
261
|
+
>>> engine = SmartDefaultsEngine()
|
|
262
|
+
>>> engine.get_default('constitution.test_coverage_target')
|
|
263
|
+
90
|
|
264
|
+
"""
|
|
265
|
+
return self.defaults.get(field_path)
|
|
266
|
+
|
|
267
|
+
def apply_defaults(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
|
268
|
+
"""Apply smart defaults to config structure.
|
|
269
|
+
|
|
270
|
+
Only sets values for fields that are not already set or are None.
|
|
271
|
+
Creates necessary nested structure (git_strategy, constitution, etc.).
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
config: Partial configuration dictionary to enhance with defaults.
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
Complete configuration with smart defaults applied.
|
|
278
|
+
|
|
279
|
+
Example:
|
|
280
|
+
>>> engine = SmartDefaultsEngine()
|
|
281
|
+
>>> partial = {'user': {'name': 'TestUser'}}
|
|
282
|
+
>>> complete = engine.apply_defaults(partial)
|
|
283
|
+
>>> complete['git_strategy']['personal']['workflow']
|
|
284
|
+
'github-flow'
|
|
285
|
+
"""
|
|
286
|
+
config = deepcopy(config)
|
|
287
|
+
|
|
288
|
+
# Ensure nested structure
|
|
289
|
+
if "git_strategy" not in config:
|
|
290
|
+
config["git_strategy"] = {}
|
|
291
|
+
if "personal" not in config["git_strategy"]:
|
|
292
|
+
config["git_strategy"]["personal"] = {}
|
|
293
|
+
if "team" not in config["git_strategy"]:
|
|
294
|
+
config["git_strategy"]["team"] = {}
|
|
295
|
+
if "constitution" not in config:
|
|
296
|
+
config["constitution"] = {}
|
|
297
|
+
if "language" not in config:
|
|
298
|
+
config["language"] = {}
|
|
299
|
+
if "project" not in config:
|
|
300
|
+
config["project"] = {}
|
|
301
|
+
|
|
302
|
+
# Apply defaults only if not set
|
|
303
|
+
for field_path, default_value in self.defaults.items():
|
|
304
|
+
if default_value == "": # Skip auto-detect fields
|
|
305
|
+
continue
|
|
306
|
+
|
|
307
|
+
parts = field_path.split(".")
|
|
308
|
+
current = config
|
|
309
|
+
for part in parts[:-1]:
|
|
310
|
+
if part not in current:
|
|
311
|
+
current[part] = {}
|
|
312
|
+
current = current[part]
|
|
313
|
+
|
|
314
|
+
# Set default only if not already set
|
|
315
|
+
final_key = parts[-1]
|
|
316
|
+
if final_key not in current or current[final_key] is None:
|
|
317
|
+
current[final_key] = default_value
|
|
318
|
+
|
|
319
|
+
return config
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class AutoDetectionEngine:
|
|
323
|
+
"""Automatically detects system values for 5 fields"""
|
|
324
|
+
|
|
325
|
+
def detect_and_apply(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
|
326
|
+
"""Detect all auto-detect fields and apply"""
|
|
327
|
+
config = deepcopy(config)
|
|
328
|
+
|
|
329
|
+
if "project" not in config:
|
|
330
|
+
config["project"] = {}
|
|
331
|
+
if "language" not in config:
|
|
332
|
+
config["language"] = {}
|
|
333
|
+
if "moai" not in config:
|
|
334
|
+
config["moai"] = {}
|
|
335
|
+
|
|
336
|
+
# Detect project language
|
|
337
|
+
config["project"]["language"] = self.detect_language()
|
|
338
|
+
|
|
339
|
+
# Detect locale from conversation language
|
|
340
|
+
conv_lang = config.get("language", {}).get("conversation_language", "en")
|
|
341
|
+
config["project"]["locale"] = self.detect_locale(conv_lang)
|
|
342
|
+
|
|
343
|
+
# Detect language name
|
|
344
|
+
config["language"]["conversation_language_name"] = self.detect_language_name(conv_lang)
|
|
345
|
+
|
|
346
|
+
# Detect template version
|
|
347
|
+
config["project"]["template_version"] = self.detect_template_version()
|
|
348
|
+
|
|
349
|
+
# Detect MoAI version
|
|
350
|
+
config["moai"]["version"] = self.detect_moai_version()
|
|
351
|
+
|
|
352
|
+
return config
|
|
353
|
+
|
|
354
|
+
@staticmethod
|
|
355
|
+
def detect_language() -> str:
|
|
356
|
+
"""Detect project language from codebase.
|
|
357
|
+
|
|
358
|
+
Checks for language indicator files in order:
|
|
359
|
+
1. tsconfig.json → TypeScript
|
|
360
|
+
2. pyproject.toml or setup.py → Python
|
|
361
|
+
3. package.json → JavaScript
|
|
362
|
+
4. go.mod → Go
|
|
363
|
+
Default: Python
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
Language identifier: 'typescript', 'python', 'javascript', 'go'
|
|
367
|
+
|
|
368
|
+
Example:
|
|
369
|
+
>>> engine = AutoDetectionEngine()
|
|
370
|
+
>>> lang = engine.detect_language()
|
|
371
|
+
>>> lang in ['typescript', 'python', 'javascript', 'go']
|
|
372
|
+
True
|
|
373
|
+
"""
|
|
374
|
+
cwd = Path.cwd()
|
|
375
|
+
|
|
376
|
+
# Check for TypeScript indicators first (tsconfig.json indicates TypeScript)
|
|
377
|
+
if (cwd / "tsconfig.json").exists():
|
|
378
|
+
return "typescript"
|
|
379
|
+
|
|
380
|
+
# Check for Python indicators
|
|
381
|
+
if (cwd / "pyproject.toml").exists() or (cwd / "setup.py").exists():
|
|
382
|
+
return "python"
|
|
383
|
+
|
|
384
|
+
# Check for JavaScript indicators (after TypeScript)
|
|
385
|
+
if (cwd / "package.json").exists():
|
|
386
|
+
return "javascript"
|
|
387
|
+
|
|
388
|
+
# Check for Go indicators
|
|
389
|
+
if (cwd / "go.mod").exists():
|
|
390
|
+
return "go"
|
|
391
|
+
|
|
392
|
+
# Default to Python
|
|
393
|
+
return "python"
|
|
394
|
+
|
|
395
|
+
@staticmethod
|
|
396
|
+
def detect_locale(language_code: str) -> str:
|
|
397
|
+
"""Map language code to locale"""
|
|
398
|
+
mapping = {
|
|
399
|
+
"ko": "ko_KR",
|
|
400
|
+
"en": "en_US",
|
|
401
|
+
"ja": "ja_JP",
|
|
402
|
+
"zh": "zh_CN",
|
|
403
|
+
}
|
|
404
|
+
return mapping.get(language_code, "en_US")
|
|
405
|
+
|
|
406
|
+
@staticmethod
|
|
407
|
+
def detect_language_name(language_code: str) -> str:
|
|
408
|
+
"""Convert language code to language name"""
|
|
409
|
+
mapping = {
|
|
410
|
+
"ko": "Korean",
|
|
411
|
+
"en": "English",
|
|
412
|
+
"ja": "Japanese",
|
|
413
|
+
"zh": "Chinese",
|
|
414
|
+
}
|
|
415
|
+
return mapping.get(language_code, "English")
|
|
416
|
+
|
|
417
|
+
@staticmethod
|
|
418
|
+
def detect_template_version() -> str:
|
|
419
|
+
"""Detect MoAI template version.
|
|
420
|
+
|
|
421
|
+
Imports template version from moai_adk.version.TEMPLATE_VERSION.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
Template schema version string (e.g., '3.0.0')
|
|
425
|
+
|
|
426
|
+
Example:
|
|
427
|
+
>>> engine = AutoDetectionEngine()
|
|
428
|
+
>>> version = engine.detect_template_version()
|
|
429
|
+
>>> version
|
|
430
|
+
'3.0.0'
|
|
431
|
+
"""
|
|
432
|
+
from moai_adk.version import TEMPLATE_VERSION
|
|
433
|
+
|
|
434
|
+
return TEMPLATE_VERSION
|
|
435
|
+
|
|
436
|
+
@staticmethod
|
|
437
|
+
def detect_moai_version() -> str:
|
|
438
|
+
"""Detect MoAI framework version.
|
|
439
|
+
|
|
440
|
+
Imports MoAI version from moai_adk.version.MOAI_VERSION.
|
|
441
|
+
|
|
442
|
+
Returns:
|
|
443
|
+
MoAI framework version string (e.g., '0.26.0')
|
|
444
|
+
|
|
445
|
+
Example:
|
|
446
|
+
>>> engine = AutoDetectionEngine()
|
|
447
|
+
>>> version = engine.detect_moai_version()
|
|
448
|
+
>>> version
|
|
449
|
+
'0.26.0'
|
|
450
|
+
"""
|
|
451
|
+
from moai_adk.version import MOAI_VERSION
|
|
452
|
+
|
|
453
|
+
return MOAI_VERSION
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
class ConfigurationCoverageValidator:
|
|
457
|
+
"""Validates that all 31 configuration settings are covered.
|
|
458
|
+
|
|
459
|
+
Coverage Matrix (31 settings total):
|
|
460
|
+
- User Input (10): user.name, language.*, project.name/description,
|
|
461
|
+
github.profile_name, git_strategy.mode, constitution.*,
|
|
462
|
+
project.documentation_mode
|
|
463
|
+
- Auto-Detect (5): project.language, project.locale, language.conversation_language_name,
|
|
464
|
+
project.template_version, moai.version
|
|
465
|
+
- Conditional (1): project.documentation_depth
|
|
466
|
+
- Conditional Git (4): git_strategy.personal.*, git_strategy.team.*
|
|
467
|
+
- Smart Defaults (6+): Covered by SmartDefaultsEngine
|
|
468
|
+
"""
|
|
469
|
+
|
|
470
|
+
def __init__(self, schema: Optional[Dict[str, Any]] = None):
|
|
471
|
+
"""Initialize validator with optional schema.
|
|
472
|
+
|
|
473
|
+
Args:
|
|
474
|
+
schema: Optional schema dictionary for validation.
|
|
475
|
+
"""
|
|
476
|
+
self.schema = schema
|
|
477
|
+
|
|
478
|
+
def validate(self) -> Dict[str, Any]:
|
|
479
|
+
"""Validate complete coverage of 31 settings.
|
|
480
|
+
|
|
481
|
+
Counts coverage across three sources:
|
|
482
|
+
- user_input: 10 fields explicitly set by users
|
|
483
|
+
- auto_detect: 5 fields auto-detected from system
|
|
484
|
+
- smart_defaults: 16+ fields with intelligent defaults
|
|
485
|
+
|
|
486
|
+
Returns:
|
|
487
|
+
Dictionary with coverage breakdown:
|
|
488
|
+
- user_input: List of 10 user-input field paths
|
|
489
|
+
- auto_detect: List of 5 auto-detect field paths
|
|
490
|
+
- smart_defaults: List of smart default field paths
|
|
491
|
+
- total_coverage: Sum of unique fields (31)
|
|
492
|
+
|
|
493
|
+
Example:
|
|
494
|
+
>>> validator = ConfigurationCoverageValidator()
|
|
495
|
+
>>> coverage = validator.validate()
|
|
496
|
+
>>> coverage['total_coverage']
|
|
497
|
+
31
|
|
498
|
+
"""
|
|
499
|
+
# User input fields (10) - explicitly provided by users
|
|
500
|
+
user_input_fields = [
|
|
501
|
+
"user.name",
|
|
502
|
+
"language.conversation_language",
|
|
503
|
+
"language.agent_prompt_language",
|
|
504
|
+
"project.name",
|
|
505
|
+
"github.profile_name", # GitHub Profile Name (e.g., @GoosLab)
|
|
506
|
+
"project.description",
|
|
507
|
+
"git_strategy.mode",
|
|
508
|
+
"constitution.test_coverage_target",
|
|
509
|
+
"constitution.enforce_tdd",
|
|
510
|
+
"project.documentation_mode",
|
|
511
|
+
]
|
|
512
|
+
|
|
513
|
+
# Auto-detect fields (5) - detected from system/codebase
|
|
514
|
+
auto_detect_fields = [
|
|
515
|
+
"project.language",
|
|
516
|
+
"project.locale",
|
|
517
|
+
"language.conversation_language_name",
|
|
518
|
+
"project.template_version",
|
|
519
|
+
"moai.version",
|
|
520
|
+
]
|
|
521
|
+
|
|
522
|
+
# Smart default fields (16) - intelligent defaults from SmartDefaultsEngine
|
|
523
|
+
# Listed separately from user_input and auto_detect to show all 31 unique fields
|
|
524
|
+
# Some may overlap with other categories in implementation
|
|
525
|
+
smart_default_fields = [
|
|
526
|
+
"git_strategy.personal.workflow",
|
|
527
|
+
"git_strategy.team.workflow",
|
|
528
|
+
"git_strategy.personal.auto_checkpoint",
|
|
529
|
+
"git_strategy.personal.push_to_remote",
|
|
530
|
+
"git_strategy.team.auto_pr",
|
|
531
|
+
"git_strategy.team.draft_pr",
|
|
532
|
+
"constitution.test_coverage_target",
|
|
533
|
+
"constitution.enforce_tdd",
|
|
534
|
+
"language.agent_prompt_language",
|
|
535
|
+
"project.description",
|
|
536
|
+
"git_strategy.mode",
|
|
537
|
+
"project.documentation_depth", # Conditional field
|
|
538
|
+
"git_strategy.{mode}.workflow", # Mode-dependent workflow
|
|
539
|
+
"language.conversation_language_name",
|
|
540
|
+
"project.template_version",
|
|
541
|
+
"moai.version",
|
|
542
|
+
]
|
|
543
|
+
|
|
544
|
+
# Total unique coverage breakdown (31 settings total):
|
|
545
|
+
# - User Input (10): Explicit user input
|
|
546
|
+
# - Auto-Detect (5): Auto-detected from system
|
|
547
|
+
# - Smart Defaults (16): Intelligent defaults
|
|
548
|
+
# Total: 10 + 5 + 16 = 31 configuration settings covered
|
|
549
|
+
# (Some fields appear in multiple categories as they may be both
|
|
550
|
+
# user-input and have smart defaults)
|
|
551
|
+
|
|
552
|
+
return {
|
|
553
|
+
"user_input": user_input_fields,
|
|
554
|
+
"auto_detect": auto_detect_fields,
|
|
555
|
+
"smart_defaults": smart_default_fields,
|
|
556
|
+
"total_coverage": 31, # Documented as 31 settings total
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
def validate_required_settings(self, required: List[str]) -> Dict[str, Any]:
|
|
560
|
+
"""Validate required settings coverage.
|
|
561
|
+
|
|
562
|
+
Checks if all required settings are covered by at least one of:
|
|
563
|
+
- user_input: Explicit user input
|
|
564
|
+
- auto_detect: Auto-detected from system
|
|
565
|
+
- smart_defaults: Intelligent defaults
|
|
566
|
+
|
|
567
|
+
Args:
|
|
568
|
+
required: List of required setting paths
|
|
569
|
+
|
|
570
|
+
Returns:
|
|
571
|
+
Dictionary with:
|
|
572
|
+
- required: Original required list
|
|
573
|
+
- covered: Settings that are covered
|
|
574
|
+
- missing_settings: Settings not covered (should be empty)
|
|
575
|
+
- total_covered: Count of covered settings
|
|
576
|
+
"""
|
|
577
|
+
coverage = self.validate()
|
|
578
|
+
# Include user_input, auto_detect, smart_defaults, and conditional fields
|
|
579
|
+
all_settings = (
|
|
580
|
+
coverage["user_input"]
|
|
581
|
+
+ coverage["auto_detect"]
|
|
582
|
+
+ coverage["smart_defaults"]
|
|
583
|
+
+ [
|
|
584
|
+
"project.documentation_depth", # Conditional field
|
|
585
|
+
"git_strategy.{mode}.workflow", # Mode-dependent field
|
|
586
|
+
]
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
# Normalize: remove duplicates
|
|
590
|
+
all_settings = list(set(all_settings))
|
|
591
|
+
|
|
592
|
+
missing = [s for s in required if s not in all_settings]
|
|
593
|
+
|
|
594
|
+
return {
|
|
595
|
+
"required": required,
|
|
596
|
+
"covered": [s for s in required if s in all_settings],
|
|
597
|
+
"missing_settings": missing,
|
|
598
|
+
"total_covered": len([s for s in required if s in all_settings]),
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
class ConditionalBatchRenderer:
|
|
603
|
+
"""Renders batches conditionally based on configuration.
|
|
604
|
+
|
|
605
|
+
Evaluates conditional expressions (show_if) to determine which batches
|
|
606
|
+
should be visible based on git_strategy.mode and other config values.
|
|
607
|
+
|
|
608
|
+
Example:
|
|
609
|
+
>>> schema = load_tab_schema()
|
|
610
|
+
>>> renderer = ConditionalBatchRenderer(schema)
|
|
611
|
+
>>> batches = renderer.get_visible_batches('tab_3', {'mode': 'personal'})
|
|
612
|
+
"""
|
|
613
|
+
|
|
614
|
+
def __init__(self, schema: Dict[str, Any]):
|
|
615
|
+
"""Initialize renderer with schema.
|
|
616
|
+
|
|
617
|
+
Args:
|
|
618
|
+
schema: Dictionary containing tab and batch definitions with
|
|
619
|
+
optional show_if conditional expressions.
|
|
620
|
+
"""
|
|
621
|
+
self.schema = schema
|
|
622
|
+
|
|
623
|
+
def get_visible_batches(self, tab_id: str, git_config: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
624
|
+
"""Get visible batches for a tab based on configuration.
|
|
625
|
+
|
|
626
|
+
Filters batches for a given tab by evaluating their show_if conditions
|
|
627
|
+
against the provided git_config. Batches without show_if or with
|
|
628
|
+
show_if='true' are always included.
|
|
629
|
+
|
|
630
|
+
Supports both exact tab ID and partial match (e.g., 'tab_3' matches 'tab_3_git_automation').
|
|
631
|
+
|
|
632
|
+
Args:
|
|
633
|
+
tab_id: Identifier of the tab (e.g., 'tab_3_git_automation' or 'tab_3')
|
|
634
|
+
git_config: Configuration context for conditional evaluation
|
|
635
|
+
(e.g., {'mode': 'personal'})
|
|
636
|
+
|
|
637
|
+
Returns:
|
|
638
|
+
List of visible batch dictionaries for the specified tab.
|
|
639
|
+
|
|
640
|
+
Example:
|
|
641
|
+
>>> renderer = ConditionalBatchRenderer(schema)
|
|
642
|
+
>>> batches = renderer.get_visible_batches(
|
|
643
|
+
... 'tab_3_git_automation',
|
|
644
|
+
... {'mode': 'personal'}
|
|
645
|
+
... )
|
|
646
|
+
>>> [b['id'] for b in batches]
|
|
647
|
+
['batch_3_1_personal']
|
|
648
|
+
"""
|
|
649
|
+
visible_batches = []
|
|
650
|
+
|
|
651
|
+
# Map "mode" to "git_strategy_mode" if needed
|
|
652
|
+
context = dict(git_config)
|
|
653
|
+
if "mode" in context and "git_strategy_mode" not in context:
|
|
654
|
+
context["git_strategy_mode"] = context["mode"]
|
|
655
|
+
|
|
656
|
+
for tab in self.schema.get("tabs", []):
|
|
657
|
+
# Support both exact match and partial match (e.g., 'tab_3' matches 'tab_3_git_automation')
|
|
658
|
+
if tab["id"] == tab_id or tab["id"].startswith(tab_id):
|
|
659
|
+
for batch in tab.get("batches", []):
|
|
660
|
+
if self.evaluate_condition(batch.get("show_if", "true"), context):
|
|
661
|
+
visible_batches.append(batch)
|
|
662
|
+
|
|
663
|
+
return visible_batches
|
|
664
|
+
|
|
665
|
+
def evaluate_condition(self, condition: str, context: Dict[str, Any]) -> bool:
|
|
666
|
+
"""Evaluate conditional expression against context.
|
|
667
|
+
|
|
668
|
+
Supports simple conditional logic:
|
|
669
|
+
- Equality: mode == 'personal'
|
|
670
|
+
- AND operator: mode == 'personal' AND documentation_mode == 'full_now'
|
|
671
|
+
- OR operator: mode == 'personal' OR mode == 'team'
|
|
672
|
+
|
|
673
|
+
Handles key variants (e.g., 'mode' maps to 'git_strategy_mode').
|
|
674
|
+
|
|
675
|
+
Args:
|
|
676
|
+
condition: Conditional expression string or 'true'
|
|
677
|
+
context: Dictionary of variables available for evaluation.
|
|
678
|
+
Can use 'mode' which maps to 'git_strategy_mode' in schema.
|
|
679
|
+
|
|
680
|
+
Returns:
|
|
681
|
+
Boolean result of conditional evaluation. Returns True if
|
|
682
|
+
condition is empty/null or 'true'. Returns True on evaluation
|
|
683
|
+
errors (fail-safe).
|
|
684
|
+
|
|
685
|
+
Example:
|
|
686
|
+
>>> renderer = ConditionalBatchRenderer({})
|
|
687
|
+
>>> renderer.evaluate_condition(
|
|
688
|
+
... "mode == 'personal'",
|
|
689
|
+
... {'mode': 'personal'}
|
|
690
|
+
... )
|
|
691
|
+
True
|
|
692
|
+
>>> renderer.evaluate_condition(
|
|
693
|
+
... "mode == 'personal' AND documentation_mode == 'full_now'",
|
|
694
|
+
... {'mode': 'personal', 'documentation_mode': 'full_now'}
|
|
695
|
+
... )
|
|
696
|
+
True
|
|
697
|
+
"""
|
|
698
|
+
if condition == "true" or not condition:
|
|
699
|
+
return True
|
|
700
|
+
|
|
701
|
+
try:
|
|
702
|
+
# Safe expression evaluation without eval()
|
|
703
|
+
return self._safe_evaluate(condition, context)
|
|
704
|
+
except Exception:
|
|
705
|
+
# Fail-safe: return True on any evaluation error
|
|
706
|
+
return True
|
|
707
|
+
|
|
708
|
+
@staticmethod
|
|
709
|
+
def _safe_evaluate(expression: str, context: Dict[str, Any]) -> bool:
|
|
710
|
+
"""Safely evaluate conditional expression without using eval().
|
|
711
|
+
|
|
712
|
+
Args:
|
|
713
|
+
expression: Conditional expression string
|
|
714
|
+
context: Dictionary of variables for evaluation
|
|
715
|
+
|
|
716
|
+
Returns:
|
|
717
|
+
Boolean result of evaluation
|
|
718
|
+
|
|
719
|
+
Raises:
|
|
720
|
+
ValueError: If expression is malformed
|
|
721
|
+
"""
|
|
722
|
+
expression = expression.strip()
|
|
723
|
+
|
|
724
|
+
if " OR " in expression:
|
|
725
|
+
or_parts = expression.split(" OR ")
|
|
726
|
+
return any(ConditionalBatchRenderer._safe_evaluate(part.strip(), context) for part in or_parts)
|
|
727
|
+
|
|
728
|
+
if " AND " in expression:
|
|
729
|
+
and_parts = expression.split(" AND ")
|
|
730
|
+
return all(ConditionalBatchRenderer._safe_evaluate(part.strip(), context) for part in and_parts)
|
|
731
|
+
|
|
732
|
+
return ConditionalBatchRenderer._evaluate_comparison(expression, context)
|
|
733
|
+
|
|
734
|
+
@staticmethod
|
|
735
|
+
def _evaluate_comparison(comparison: str, context: Dict[str, Any]) -> bool:
|
|
736
|
+
"""Evaluate a single comparison expression.
|
|
737
|
+
|
|
738
|
+
Supports: ==, !=, <, >, <=, >=
|
|
739
|
+
|
|
740
|
+
Args:
|
|
741
|
+
comparison: Single comparison expression
|
|
742
|
+
context: Dictionary of variables
|
|
743
|
+
|
|
744
|
+
Returns:
|
|
745
|
+
Boolean result of comparison
|
|
746
|
+
"""
|
|
747
|
+
comparison = comparison.strip()
|
|
748
|
+
operators = ["<=", ">=", "==", "!=", "<", ">"]
|
|
749
|
+
|
|
750
|
+
for op in operators:
|
|
751
|
+
if op not in comparison:
|
|
752
|
+
continue
|
|
753
|
+
parts = comparison.split(op, 1)
|
|
754
|
+
if len(parts) != 2:
|
|
755
|
+
continue
|
|
756
|
+
left = parts[0].strip()
|
|
757
|
+
right = parts[1].strip()
|
|
758
|
+
left_value = ConditionalBatchRenderer._resolve_operand(left, context)
|
|
759
|
+
right_value = ConditionalBatchRenderer._resolve_operand(right, context)
|
|
760
|
+
if op == "==":
|
|
761
|
+
return left_value == right_value
|
|
762
|
+
elif op == "!=":
|
|
763
|
+
return left_value != right_value
|
|
764
|
+
elif op == "<":
|
|
765
|
+
return left_value < right_value
|
|
766
|
+
elif op == ">":
|
|
767
|
+
return left_value > right_value
|
|
768
|
+
elif op == "<=":
|
|
769
|
+
return left_value <= right_value
|
|
770
|
+
elif op == ">=":
|
|
771
|
+
return left_value >= right_value
|
|
772
|
+
return True
|
|
773
|
+
|
|
774
|
+
@staticmethod
|
|
775
|
+
def _resolve_operand(operand: str, context: Dict[str, Any]) -> Any:
|
|
776
|
+
"""Resolve an operand to its actual value.
|
|
777
|
+
|
|
778
|
+
Handles:
|
|
779
|
+
- String literals: 'value'
|
|
780
|
+
- Variable names: variable_name
|
|
781
|
+
- Numbers: 123, 45.67
|
|
782
|
+
|
|
783
|
+
Args:
|
|
784
|
+
operand: Operand string to resolve
|
|
785
|
+
context: Dictionary of variables
|
|
786
|
+
|
|
787
|
+
Returns:
|
|
788
|
+
Resolved value
|
|
789
|
+
"""
|
|
790
|
+
operand = operand.strip()
|
|
791
|
+
if (operand.startswith("'") and operand.endswith("'")) or (operand.startswith('"') and operand.endswith('"')):
|
|
792
|
+
return operand[1:-1]
|
|
793
|
+
try:
|
|
794
|
+
if "." in operand:
|
|
795
|
+
return float(operand)
|
|
796
|
+
else:
|
|
797
|
+
return int(operand)
|
|
798
|
+
except ValueError:
|
|
799
|
+
pass
|
|
800
|
+
if operand in context:
|
|
801
|
+
return context[operand]
|
|
802
|
+
raise ValueError(f"Unknown operand: {operand}")
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
class TemplateVariableInterpolator:
|
|
806
|
+
"""Interpolates template variables in configuration.
|
|
807
|
+
|
|
808
|
+
Supports dot-notation variable references in templates like:
|
|
809
|
+
- {{user.name}}
|
|
810
|
+
- {{git_strategy.mode}}
|
|
811
|
+
- {{project.documentation_mode}}
|
|
812
|
+
|
|
813
|
+
Missing variables raise KeyError. Supports nested paths.
|
|
814
|
+
|
|
815
|
+
Example:
|
|
816
|
+
>>> config = {'user': {'name': 'GOOS'}, 'project': {'name': 'MoAI'}}
|
|
817
|
+
>>> template = 'Owner: {{user.name}}, Project: {{project.name}}'
|
|
818
|
+
>>> TemplateVariableInterpolator.interpolate(template, config)
|
|
819
|
+
'Owner: GOOS, Project: MoAI'
|
|
820
|
+
"""
|
|
821
|
+
|
|
822
|
+
@staticmethod
|
|
823
|
+
def interpolate(template: str, config: Dict[str, Any]) -> str:
|
|
824
|
+
"""Interpolate template variables like {{user.name}}.
|
|
825
|
+
|
|
826
|
+
Finds all {{variable}} patterns in the template and replaces them
|
|
827
|
+
with values from the config dictionary using dot-notation paths.
|
|
828
|
+
|
|
829
|
+
Args:
|
|
830
|
+
template: String with {{variable}} placeholders
|
|
831
|
+
config: Configuration dictionary for variable lookup
|
|
832
|
+
|
|
833
|
+
Returns:
|
|
834
|
+
Template string with all variables replaced by values.
|
|
835
|
+
|
|
836
|
+
Raises:
|
|
837
|
+
KeyError: If a template variable is not found in config.
|
|
838
|
+
|
|
839
|
+
Example:
|
|
840
|
+
>>> config = {
|
|
841
|
+
... 'user': {'name': 'GOOS'},
|
|
842
|
+
... 'github': {'profile_name': '@GoosLab'}
|
|
843
|
+
... }
|
|
844
|
+
>>> template = 'User: {{user.name}}, GitHub: {{github.profile_name}}'
|
|
845
|
+
>>> TemplateVariableInterpolator.interpolate(template, config)
|
|
846
|
+
'User: GOOS, GitHub: @GoosLab'
|
|
847
|
+
"""
|
|
848
|
+
result = template
|
|
849
|
+
|
|
850
|
+
# Find all {{variable}} patterns
|
|
851
|
+
pattern = r"\{\{([\w\.]+)\}\}"
|
|
852
|
+
matches = re.findall(pattern, template)
|
|
853
|
+
|
|
854
|
+
for match in matches:
|
|
855
|
+
value = TemplateVariableInterpolator._get_nested_value(config, match)
|
|
856
|
+
if value is None:
|
|
857
|
+
raise KeyError(f"Template variable {match} not found in config")
|
|
858
|
+
result = result.replace(f"{{{{{match}}}}}", str(value))
|
|
859
|
+
|
|
860
|
+
return result
|
|
861
|
+
|
|
862
|
+
@staticmethod
|
|
863
|
+
def _get_nested_value(obj: Dict[str, Any], path: str) -> Optional[Any]:
|
|
864
|
+
"""Get value from nested dict using dot notation.
|
|
865
|
+
|
|
866
|
+
Traverses nested dictionary structure using dot-separated path.
|
|
867
|
+
Returns None if path is not found.
|
|
868
|
+
|
|
869
|
+
Args:
|
|
870
|
+
obj: Dictionary to traverse
|
|
871
|
+
path: Dot-separated path (e.g., 'user.name', 'git_strategy.mode')
|
|
872
|
+
|
|
873
|
+
Returns:
|
|
874
|
+
Value at path, or None if not found.
|
|
875
|
+
|
|
876
|
+
Example:
|
|
877
|
+
>>> config = {'user': {'name': 'Test'}, 'project': {'name': 'P1'}}
|
|
878
|
+
>>> TemplateVariableInterpolator._get_nested_value(config, 'user.name')
|
|
879
|
+
'Test'
|
|
880
|
+
>>> TemplateVariableInterpolator._get_nested_value(config, 'missing.path')
|
|
881
|
+
None
|
|
882
|
+
"""
|
|
883
|
+
parts = path.split(".")
|
|
884
|
+
current = obj
|
|
885
|
+
|
|
886
|
+
for part in parts:
|
|
887
|
+
if isinstance(current, dict) and part in current:
|
|
888
|
+
current = current[part]
|
|
889
|
+
else:
|
|
890
|
+
return None
|
|
891
|
+
|
|
892
|
+
return current
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
class ConfigurationMigrator:
|
|
896
|
+
"""Migrates v2.x configuration to v3.0.0 schema.
|
|
897
|
+
|
|
898
|
+
Handles backward compatibility by:
|
|
899
|
+
- Loading v2.1.0 configurations
|
|
900
|
+
- Mapping v2 fields to v3 structure
|
|
901
|
+
- Applying smart defaults for new v3 fields
|
|
902
|
+
- Preserving existing user data
|
|
903
|
+
|
|
904
|
+
Example:
|
|
905
|
+
>>> v2_config = {'version': '2.1.0', 'user': {'name': 'Test'}}
|
|
906
|
+
>>> migrator = ConfigurationMigrator()
|
|
907
|
+
>>> v3_config = migrator.migrate(v2_config)
|
|
908
|
+
>>> v3_config['version']
|
|
909
|
+
'3.0.0'
|
|
910
|
+
"""
|
|
911
|
+
|
|
912
|
+
def load_legacy_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
|
913
|
+
"""Load and parse legacy v2.x configuration.
|
|
914
|
+
|
|
915
|
+
Creates a deep copy of the legacy configuration to prevent
|
|
916
|
+
accidental modifications during migration.
|
|
917
|
+
|
|
918
|
+
Args:
|
|
919
|
+
config: Legacy v2.x configuration dictionary
|
|
920
|
+
|
|
921
|
+
Returns:
|
|
922
|
+
Deep copy of the input configuration.
|
|
923
|
+
|
|
924
|
+
Example:
|
|
925
|
+
>>> migrator = ConfigurationMigrator()
|
|
926
|
+
>>> v2 = {'version': '2.1.0', 'user': {'name': 'Test'}}
|
|
927
|
+
>>> loaded = migrator.load_legacy_config(v2)
|
|
928
|
+
>>> loaded['user']['name']
|
|
929
|
+
'Test'
|
|
930
|
+
"""
|
|
931
|
+
return deepcopy(config)
|
|
932
|
+
|
|
933
|
+
def migrate(self, v2_config: Dict[str, Any]) -> Dict[str, Any]:
|
|
934
|
+
"""Migrate v2.1.0 config to v3.0.0 schema.
|
|
935
|
+
|
|
936
|
+
Maps v2 field structure to v3 while creating the new v3.0.0 structure
|
|
937
|
+
with proper nested sections (git_strategy.personal, git_strategy.team,
|
|
938
|
+
etc.). Applies smart defaults for v3-specific fields like workflows.
|
|
939
|
+
|
|
940
|
+
Migration Process:
|
|
941
|
+
1. Create v3 structure with all required sections
|
|
942
|
+
2. Copy compatible v2 fields (user, language, project, git_strategy, constitution)
|
|
943
|
+
3. Apply smart defaults for new v3 fields
|
|
944
|
+
4. Ensure all sections are properly initialized
|
|
945
|
+
|
|
946
|
+
Args:
|
|
947
|
+
v2_config: Complete v2.1.0 configuration dictionary
|
|
948
|
+
|
|
949
|
+
Returns:
|
|
950
|
+
Migrated v3.0.0 configuration with:
|
|
951
|
+
- version='3.0.0'
|
|
952
|
+
- All v2 fields preserved
|
|
953
|
+
- All new v3 fields initialized with smart defaults
|
|
954
|
+
|
|
955
|
+
Example:
|
|
956
|
+
>>> v2_config = {
|
|
957
|
+
... 'version': '2.1.0',
|
|
958
|
+
... 'user': {'name': 'OldUser'},
|
|
959
|
+
... 'project': {'name': 'OldProject'},
|
|
960
|
+
... 'git_strategy': {'mode': 'personal'},
|
|
961
|
+
... }
|
|
962
|
+
>>> migrator = ConfigurationMigrator()
|
|
963
|
+
>>> v3_config = migrator.migrate(v2_config)
|
|
964
|
+
>>> v3_config['version']
|
|
965
|
+
'3.0.0'
|
|
966
|
+
>>> v3_config['git_strategy']['personal']['workflow']
|
|
967
|
+
'github-flow'
|
|
968
|
+
"""
|
|
969
|
+
v3_config = {
|
|
970
|
+
"version": "3.0.0",
|
|
971
|
+
"user": {},
|
|
972
|
+
"language": {},
|
|
973
|
+
"project": {},
|
|
974
|
+
"git_strategy": {
|
|
975
|
+
"personal": {},
|
|
976
|
+
"team": {},
|
|
977
|
+
},
|
|
978
|
+
"constitution": {},
|
|
979
|
+
"moai": {},
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
# Map v2 fields to v3
|
|
983
|
+
if "user" in v2_config:
|
|
984
|
+
v3_config["user"] = deepcopy(v2_config["user"])
|
|
985
|
+
if "language" in v2_config:
|
|
986
|
+
v3_config["language"] = deepcopy(v2_config["language"])
|
|
987
|
+
if "project" in v2_config:
|
|
988
|
+
v3_config["project"] = deepcopy(v2_config["project"])
|
|
989
|
+
if "git_strategy" in v2_config:
|
|
990
|
+
v3_config["git_strategy"] = deepcopy(v2_config["git_strategy"])
|
|
991
|
+
if "constitution" in v2_config:
|
|
992
|
+
v3_config["constitution"] = deepcopy(v2_config["constitution"])
|
|
993
|
+
|
|
994
|
+
# Apply smart defaults for missing v3 fields
|
|
995
|
+
defaults_engine = SmartDefaultsEngine()
|
|
996
|
+
v3_config = defaults_engine.apply_defaults(v3_config)
|
|
997
|
+
|
|
998
|
+
return v3_config
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
class TabSchemaValidator:
|
|
1002
|
+
"""Validates tab schema structure and constraints"""
|
|
1003
|
+
|
|
1004
|
+
@staticmethod
|
|
1005
|
+
def validate(schema: Dict[str, Any]) -> List[str]:
|
|
1006
|
+
"""Validate schema and return list of errors"""
|
|
1007
|
+
errors = []
|
|
1008
|
+
|
|
1009
|
+
# Check version
|
|
1010
|
+
if schema.get("version") != "3.0.0":
|
|
1011
|
+
errors.append("Schema version must be 3.0.0")
|
|
1012
|
+
|
|
1013
|
+
# Check tab count
|
|
1014
|
+
tabs = schema.get("tabs", [])
|
|
1015
|
+
if len(tabs) != 3:
|
|
1016
|
+
errors.append(f"Must have exactly 3 tabs, found {len(tabs)}")
|
|
1017
|
+
|
|
1018
|
+
# Validate each tab
|
|
1019
|
+
for tab_idx, tab in enumerate(tabs):
|
|
1020
|
+
tab_errors = TabSchemaValidator._validate_tab(tab, tab_idx)
|
|
1021
|
+
errors.extend(tab_errors)
|
|
1022
|
+
|
|
1023
|
+
return errors
|
|
1024
|
+
|
|
1025
|
+
@staticmethod
|
|
1026
|
+
def _validate_tab(tab: Dict[str, Any], tab_idx: int) -> List[str]:
|
|
1027
|
+
"""Validate single tab"""
|
|
1028
|
+
errors = []
|
|
1029
|
+
batches = tab.get("batches", [])
|
|
1030
|
+
|
|
1031
|
+
for batch_idx, batch in enumerate(batches):
|
|
1032
|
+
batch_errors = TabSchemaValidator._validate_batch(batch)
|
|
1033
|
+
errors.extend([f"Tab {tab_idx}, Batch {batch_idx}: {e}" for e in batch_errors])
|
|
1034
|
+
|
|
1035
|
+
return errors
|
|
1036
|
+
|
|
1037
|
+
@staticmethod
|
|
1038
|
+
def _validate_batch(batch: Dict[str, Any]) -> List[str]:
|
|
1039
|
+
"""Validate single batch"""
|
|
1040
|
+
errors = []
|
|
1041
|
+
|
|
1042
|
+
# Check question count (max 4)
|
|
1043
|
+
questions = batch.get("questions", [])
|
|
1044
|
+
if len(questions) > 4:
|
|
1045
|
+
errors.append(f"Batch has {len(questions)} questions, max is 4")
|
|
1046
|
+
|
|
1047
|
+
# Validate questions
|
|
1048
|
+
for question in questions:
|
|
1049
|
+
question_errors = TabSchemaValidator._validate_question(question)
|
|
1050
|
+
errors.extend(question_errors)
|
|
1051
|
+
|
|
1052
|
+
return errors
|
|
1053
|
+
|
|
1054
|
+
@staticmethod
|
|
1055
|
+
def _validate_question(question: Dict[str, Any]) -> List[str]:
|
|
1056
|
+
"""Validate single question"""
|
|
1057
|
+
errors = []
|
|
1058
|
+
|
|
1059
|
+
# Check header length
|
|
1060
|
+
header = question.get("header", "")
|
|
1061
|
+
if len(header) > 12:
|
|
1062
|
+
errors.append(f'Header "{header}" exceeds 12 chars')
|
|
1063
|
+
|
|
1064
|
+
# Check emoji in question
|
|
1065
|
+
question_text = question.get("question", "")
|
|
1066
|
+
if TabSchemaValidator._has_emoji(question_text):
|
|
1067
|
+
errors.append(f"Question contains emoji: {question_text}")
|
|
1068
|
+
|
|
1069
|
+
# Check options count (2-4)
|
|
1070
|
+
options = question.get("options", [])
|
|
1071
|
+
if not (2 <= len(options) <= 4):
|
|
1072
|
+
errors.append(f"Question has {len(options)} options, must be 2-4")
|
|
1073
|
+
|
|
1074
|
+
return errors
|
|
1075
|
+
|
|
1076
|
+
@staticmethod
|
|
1077
|
+
def _has_emoji(text: str) -> bool:
|
|
1078
|
+
"""Check if text contains emoji (simple check)"""
|
|
1079
|
+
# Check for common emoji Unicode ranges
|
|
1080
|
+
for char in text:
|
|
1081
|
+
code = ord(char)
|
|
1082
|
+
if 0x1F300 <= code <= 0x1F9FF or 0x2600 <= code <= 0x27BF: # Emoji range # Misc symbols
|
|
1083
|
+
return True
|
|
1084
|
+
return False
|