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
|
@@ -1,22 +1,84 @@
|
|
|
1
|
-
#
|
|
2
|
-
"""Template copy and backup processor
|
|
1
|
+
# # REMOVED_ORPHAN_CODE:TEMPLATE-001 | SPEC: SPEC-INIT-003/spec.md | Chain: TEMPLATE-001
|
|
2
|
+
"""Enhanced Template copy and backup processor with improved version handling and validation.
|
|
3
|
+
|
|
4
|
+
SPEC-INIT-003 v0.3.0: preserve user content
|
|
5
|
+
Enhanced with:
|
|
6
|
+
- Comprehensive version field management
|
|
7
|
+
- Template substitution validation
|
|
8
|
+
- Performance optimization
|
|
9
|
+
- Error handling improvements
|
|
10
|
+
- Configuration-driven behavior
|
|
11
|
+
"""
|
|
3
12
|
|
|
4
13
|
from __future__ import annotations
|
|
5
14
|
|
|
15
|
+
import json
|
|
16
|
+
import logging
|
|
6
17
|
import re
|
|
7
18
|
import shutil
|
|
19
|
+
from dataclasses import dataclass
|
|
8
20
|
from pathlib import Path
|
|
21
|
+
from typing import Any, Dict, List, Optional
|
|
9
22
|
|
|
10
23
|
from rich.console import Console
|
|
11
24
|
|
|
12
25
|
from moai_adk.core.template.backup import TemplateBackup
|
|
13
26
|
from moai_adk.core.template.merger import TemplateMerger
|
|
27
|
+
from moai_adk.statusline.version_reader import VersionConfig, VersionReader
|
|
14
28
|
|
|
15
29
|
console = Console()
|
|
16
30
|
|
|
17
31
|
|
|
32
|
+
@dataclass
|
|
33
|
+
class TemplateProcessorConfig:
|
|
34
|
+
"""Configuration for TemplateProcessor behavior."""
|
|
35
|
+
|
|
36
|
+
# Version handling configuration
|
|
37
|
+
version_cache_ttl_seconds: int = 120
|
|
38
|
+
version_fallback: str = "unknown"
|
|
39
|
+
version_format_regex: str = r"^v?(\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)$"
|
|
40
|
+
enable_version_validation: bool = True
|
|
41
|
+
preserve_user_version: bool = True
|
|
42
|
+
|
|
43
|
+
# Template substitution configuration
|
|
44
|
+
validate_template_variables: bool = True
|
|
45
|
+
max_variable_length: int = 50
|
|
46
|
+
allowed_variable_pattern: str = r"^[A-Z_]+$"
|
|
47
|
+
enable_substitution_warnings: bool = True
|
|
48
|
+
|
|
49
|
+
# Performance configuration
|
|
50
|
+
enable_caching: bool = True
|
|
51
|
+
cache_size: int = 100
|
|
52
|
+
async_operations: bool = False
|
|
53
|
+
|
|
54
|
+
# Error handling configuration
|
|
55
|
+
graceful_degradation: bool = True
|
|
56
|
+
verbose_logging: bool = False
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def from_dict(cls, config_dict: Dict[str, Any]) -> "TemplateProcessorConfig":
|
|
60
|
+
"""Create config from dictionary."""
|
|
61
|
+
config_dict = config_dict or {}
|
|
62
|
+
return cls(
|
|
63
|
+
version_cache_ttl_seconds=config_dict.get("version_cache_ttl_seconds", 120),
|
|
64
|
+
version_fallback=config_dict.get("version_fallback", "unknown"),
|
|
65
|
+
version_format_regex=config_dict.get("version_format_regex", r"^v?(\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)$"),
|
|
66
|
+
enable_version_validation=config_dict.get("enable_version_validation", True),
|
|
67
|
+
preserve_user_version=config_dict.get("preserve_user_version", True),
|
|
68
|
+
validate_template_variables=config_dict.get("validate_template_variables", True),
|
|
69
|
+
max_variable_length=config_dict.get("max_variable_length", 50),
|
|
70
|
+
allowed_variable_pattern=config_dict.get("allowed_variable_pattern", r"^[A-Z_]+$"),
|
|
71
|
+
enable_substitution_warnings=config_dict.get("enable_substitution_warnings", True),
|
|
72
|
+
enable_caching=config_dict.get("enable_caching", True),
|
|
73
|
+
cache_size=config_dict.get("cache_size", 100),
|
|
74
|
+
async_operations=config_dict.get("async_operations", False),
|
|
75
|
+
graceful_degradation=config_dict.get("graceful_degradation", True),
|
|
76
|
+
verbose_logging=config_dict.get("verbose_logging", False),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
18
80
|
class TemplateProcessor:
|
|
19
|
-
"""Orchestrate template copying and backups."""
|
|
81
|
+
"""Orchestrate template copying and backups with enhanced version handling and validation."""
|
|
20
82
|
|
|
21
83
|
# User data protection paths (never touch) - SPEC-INIT-003 v0.3.0
|
|
22
84
|
PROTECTED_PATHS = [
|
|
@@ -24,62 +86,465 @@ class TemplateProcessor:
|
|
|
24
86
|
".moai/reports/", # User reports
|
|
25
87
|
".moai/project/", # User project documents (product/structure/tech.md)
|
|
26
88
|
# config.json is now FORCE OVERWRITTEN (backup in .moai-backups/)
|
|
27
|
-
# Merge via /
|
|
89
|
+
# Merge via /moai:0-project when optimized=false
|
|
28
90
|
]
|
|
29
91
|
|
|
30
92
|
# Paths excluded from backups
|
|
31
93
|
BACKUP_EXCLUDE = PROTECTED_PATHS
|
|
32
94
|
|
|
33
|
-
|
|
34
|
-
|
|
95
|
+
# Common template variables with validation hints
|
|
96
|
+
COMMON_TEMPLATE_VARIABLES = {
|
|
97
|
+
"PROJECT_DIR": "Cross-platform project path (run /moai:0-project to set)",
|
|
98
|
+
"PROJECT_NAME": "Project name (run /moai:0-project to set)",
|
|
99
|
+
"AUTHOR": "Project author (run /moai:0-project to set)",
|
|
100
|
+
"CONVERSATION_LANGUAGE": "Interface language (run /moai:0-project to set)",
|
|
101
|
+
"MOAI_VERSION": "MoAI-ADK version (should be set automatically)",
|
|
102
|
+
"MOAI_VERSION_SHORT": "Short MoAI-ADK version (without 'v' prefix)",
|
|
103
|
+
"MOAI_VERSION_DISPLAY": "Display version with proper formatting",
|
|
104
|
+
"MOAI_VERSION_TRIMMED": "Trimmed version for UI displays",
|
|
105
|
+
"MOAI_VERSION_SEMVER": "Semantic version format (major.minor.patch)",
|
|
106
|
+
"MOAI_VERSION_VALID": "Version validation status",
|
|
107
|
+
"MOAI_VERSION_SOURCE": "Version source information",
|
|
108
|
+
"MOAI_VERSION_CACHE_AGE": "Cache age for debugging",
|
|
109
|
+
"CREATION_TIMESTAMP": "Project creation timestamp",
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
def __init__(self, target_path: Path, config: Optional[TemplateProcessorConfig] = None) -> None:
|
|
113
|
+
"""Initialize the processor with enhanced configuration.
|
|
35
114
|
|
|
36
115
|
Args:
|
|
37
116
|
target_path: Project path.
|
|
117
|
+
config: Optional configuration for processor behavior.
|
|
38
118
|
"""
|
|
39
119
|
self.target_path = target_path.resolve()
|
|
40
120
|
self.template_root = self._get_template_root()
|
|
41
121
|
self.backup = TemplateBackup(self.target_path)
|
|
42
122
|
self.merger = TemplateMerger(self.target_path)
|
|
43
123
|
self.context: dict[str, str] = {} # Template variable substitution context
|
|
124
|
+
self._version_reader: VersionReader | None = None
|
|
125
|
+
self.config = config or TemplateProcessorConfig()
|
|
126
|
+
self._substitution_cache: Dict[
|
|
127
|
+
int, tuple[str, list[str]]
|
|
128
|
+
] = {} # Cache for substitution results (key: hash, value: (content, warnings))
|
|
129
|
+
self._variable_validation_cache: Dict[str, bool] = {} # Cache for variable validation
|
|
130
|
+
self.logger = logging.getLogger(__name__)
|
|
44
131
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
# src/moai_adk/core/template/processor.py → src/moai_adk/templates/
|
|
48
|
-
current_file = Path(__file__).resolve()
|
|
49
|
-
package_root = current_file.parent.parent.parent
|
|
50
|
-
return package_root / "templates"
|
|
132
|
+
if self.config.verbose_logging:
|
|
133
|
+
self.logger.info(f"TemplateProcessor initialized with config: {self.config}")
|
|
51
134
|
|
|
52
135
|
def set_context(self, context: dict[str, str]) -> None:
|
|
53
|
-
"""Set variable substitution context.
|
|
136
|
+
"""Set variable substitution context with enhanced validation.
|
|
54
137
|
|
|
55
138
|
Args:
|
|
56
139
|
context: Dictionary of template variables.
|
|
57
140
|
"""
|
|
58
141
|
self.context = context
|
|
142
|
+
self._substitution_cache.clear() # Clear cache when context changes
|
|
143
|
+
self._variable_validation_cache.clear()
|
|
144
|
+
|
|
145
|
+
if self.config.verbose_logging:
|
|
146
|
+
self.logger.debug(f"Context set with {len(context)} variables")
|
|
147
|
+
|
|
148
|
+
# Validate template variables if enabled
|
|
149
|
+
if self.config.validate_template_variables:
|
|
150
|
+
self._validate_template_variables(context)
|
|
151
|
+
|
|
152
|
+
# Add deprecation mapping for HOOK_PROJECT_DIR
|
|
153
|
+
if "PROJECT_DIR" in self.context and "HOOK_PROJECT_DIR" not in self.context:
|
|
154
|
+
self.context["HOOK_PROJECT_DIR"] = self.context["PROJECT_DIR"]
|
|
155
|
+
|
|
156
|
+
def _get_version_reader(self) -> VersionReader:
|
|
157
|
+
"""
|
|
158
|
+
Get or create version reader instance with enhanced configuration.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
VersionReader instance
|
|
162
|
+
"""
|
|
163
|
+
if self._version_reader is None:
|
|
164
|
+
version_config = VersionConfig(
|
|
165
|
+
cache_ttl_seconds=self.config.version_cache_ttl_seconds,
|
|
166
|
+
fallback_version=self.config.version_fallback,
|
|
167
|
+
version_format_regex=self.config.version_format_regex,
|
|
168
|
+
debug_mode=self.config.verbose_logging,
|
|
169
|
+
)
|
|
170
|
+
self._version_reader = VersionReader(version_config)
|
|
171
|
+
|
|
172
|
+
if self.config.verbose_logging:
|
|
173
|
+
self.logger.info("VersionReader created with enhanced configuration")
|
|
174
|
+
return self._version_reader
|
|
175
|
+
|
|
176
|
+
def _validate_template_variables(self, context: Dict[str, str]) -> None:
|
|
177
|
+
"""
|
|
178
|
+
Validate template variables with comprehensive checking.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
context: Dictionary of template variables to validate
|
|
182
|
+
"""
|
|
183
|
+
import re
|
|
184
|
+
|
|
185
|
+
if not self.config.validate_template_variables:
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
validation_errors: List[str] = []
|
|
189
|
+
warning_messages: List[str] = []
|
|
190
|
+
|
|
191
|
+
# Check variable names against pattern
|
|
192
|
+
variable_pattern = re.compile(self.config.allowed_variable_pattern)
|
|
193
|
+
|
|
194
|
+
for var_name, var_value in context.items():
|
|
195
|
+
# Check variable name format
|
|
196
|
+
if not variable_pattern.match(var_name):
|
|
197
|
+
validation_errors.append(f"Invalid variable name format: '{var_name}'")
|
|
198
|
+
continue
|
|
199
|
+
|
|
200
|
+
# Check variable length
|
|
201
|
+
if len(var_name) > self.config.max_variable_length:
|
|
202
|
+
warning_messages.append(f"Variable name '{var_name}' exceeds maximum length")
|
|
203
|
+
|
|
204
|
+
# Check variable value length
|
|
205
|
+
if len(var_value) > self.config.max_variable_length * 2:
|
|
206
|
+
warning_messages.append(f"Variable value '{var_value[:20]}...' is very long")
|
|
207
|
+
|
|
208
|
+
# Check for potentially dangerous values
|
|
209
|
+
if "{{" in var_value or "}}" in var_value:
|
|
210
|
+
warning_messages.append(f"Variable '{var_name}' contains placeholder patterns")
|
|
211
|
+
|
|
212
|
+
# Check for common variables that should be present
|
|
213
|
+
missing_common_vars = []
|
|
214
|
+
for common_var in self.COMMON_TEMPLATE_VARIABLES:
|
|
215
|
+
if common_var not in context:
|
|
216
|
+
missing_common_vars.append(common_var)
|
|
217
|
+
|
|
218
|
+
if missing_common_vars and self.config.enable_substitution_warnings:
|
|
219
|
+
warning_messages.append(f"Common variables missing: {', '.join(missing_common_vars[:3])}")
|
|
220
|
+
|
|
221
|
+
# Report validation results
|
|
222
|
+
if validation_errors and not self.config.graceful_degradation:
|
|
223
|
+
raise ValueError(f"Template variable validation failed: {validation_errors}")
|
|
224
|
+
|
|
225
|
+
if validation_errors and self.config.graceful_degradation:
|
|
226
|
+
self.logger.warning(f"Template variable validation warnings: {validation_errors}")
|
|
227
|
+
|
|
228
|
+
if warning_messages and self.config.enable_substitution_warnings:
|
|
229
|
+
self.logger.warning(f"Template variable warnings: {warning_messages}")
|
|
230
|
+
|
|
231
|
+
if self.config.verbose_logging:
|
|
232
|
+
self.logger.debug(f"Template variables validated: {len(context)} variables checked")
|
|
233
|
+
|
|
234
|
+
def get_enhanced_version_context(self) -> dict[str, str]:
|
|
235
|
+
"""
|
|
236
|
+
Get enhanced version context with proper error handling and caching.
|
|
237
|
+
|
|
238
|
+
Returns comprehensive version information including multiple format options
|
|
239
|
+
and debugging information.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Dictionary containing enhanced version-related template variables
|
|
243
|
+
"""
|
|
244
|
+
version_context = {}
|
|
245
|
+
logger = logging.getLogger(__name__)
|
|
246
|
+
|
|
247
|
+
try:
|
|
248
|
+
version_reader = self._get_version_reader()
|
|
249
|
+
moai_version = version_reader.get_version()
|
|
250
|
+
|
|
251
|
+
# Basic version information
|
|
252
|
+
version_context["MOAI_VERSION"] = moai_version
|
|
253
|
+
version_context["MOAI_VERSION_SHORT"] = self._format_short_version(moai_version)
|
|
254
|
+
version_context["MOAI_VERSION_DISPLAY"] = self._format_display_version(moai_version)
|
|
255
|
+
|
|
256
|
+
# Enhanced formatting options
|
|
257
|
+
version_context["MOAI_VERSION_TRIMMED"] = self._format_trimmed_version(moai_version, max_length=10)
|
|
258
|
+
version_context["MOAI_VERSION_SEMVER"] = self._format_semver_version(moai_version)
|
|
259
|
+
|
|
260
|
+
# Validation and source information
|
|
261
|
+
version_context["MOAI_VERSION_VALID"] = "true" if moai_version != "unknown" else "false"
|
|
262
|
+
version_context["MOAI_VERSION_SOURCE"] = self._get_version_source(version_reader)
|
|
263
|
+
|
|
264
|
+
# Performance metrics
|
|
265
|
+
cache_age = version_reader.get_cache_age_seconds()
|
|
266
|
+
if cache_age is not None:
|
|
267
|
+
version_context["MOAI_VERSION_CACHE_AGE"] = f"{cache_age:.2f}s"
|
|
268
|
+
else:
|
|
269
|
+
version_context["MOAI_VERSION_CACHE_AGE"] = "uncached"
|
|
270
|
+
|
|
271
|
+
# Additional metadata
|
|
272
|
+
if self.config.enable_version_validation:
|
|
273
|
+
is_valid = self._is_valid_version_format(moai_version)
|
|
274
|
+
version_context["MOAI_VERSION_FORMAT_VALID"] = "true" if is_valid else "false"
|
|
275
|
+
|
|
276
|
+
if self.config.verbose_logging:
|
|
277
|
+
logger.debug(f"Enhanced version context generated: {version_context}")
|
|
278
|
+
|
|
279
|
+
except Exception as e:
|
|
280
|
+
logger.warning(f"Failed to read version for template context: {e}")
|
|
281
|
+
# Use fallback version with comprehensive formatting
|
|
282
|
+
fallback_version = self.config.version_fallback
|
|
283
|
+
version_context["MOAI_VERSION"] = fallback_version
|
|
284
|
+
version_context["MOAI_VERSION_SHORT"] = self._format_short_version(fallback_version)
|
|
285
|
+
version_context["MOAI_VERSION_DISPLAY"] = self._format_display_version(fallback_version)
|
|
286
|
+
version_context["MOAI_VERSION_TRIMMED"] = self._format_trimmed_version(fallback_version, max_length=10)
|
|
287
|
+
version_context["MOAI_VERSION_SEMVER"] = self._format_semver_version(fallback_version)
|
|
288
|
+
version_context["MOAI_VERSION_VALID"] = "false" if fallback_version == "unknown" else "true"
|
|
289
|
+
version_context["MOAI_VERSION_SOURCE"] = "fallback_config"
|
|
290
|
+
version_context["MOAI_VERSION_CACHE_AGE"] = "unavailable"
|
|
291
|
+
version_context["MOAI_VERSION_FORMAT_VALID"] = "false"
|
|
292
|
+
|
|
293
|
+
return version_context
|
|
294
|
+
|
|
295
|
+
def _is_valid_version_format(self, version: str) -> bool:
|
|
296
|
+
"""
|
|
297
|
+
Validate version format using configured regex pattern.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
version: Version string to validate
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
True if version format is valid
|
|
304
|
+
"""
|
|
305
|
+
import re
|
|
306
|
+
|
|
307
|
+
try:
|
|
308
|
+
pattern = re.compile(self.config.version_format_regex)
|
|
309
|
+
return bool(pattern.match(version))
|
|
310
|
+
except re.error:
|
|
311
|
+
# Fallback to default pattern if custom one is invalid
|
|
312
|
+
default_pattern = re.compile(r"^v?(\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)$")
|
|
313
|
+
return bool(default_pattern.match(version))
|
|
314
|
+
|
|
315
|
+
def _format_short_version(self, version: str) -> str:
|
|
316
|
+
"""
|
|
317
|
+
Format short version by removing 'v' prefix if present.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
version: Version string
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
Short version string
|
|
324
|
+
"""
|
|
325
|
+
return version[1:] if version.startswith("v") else version
|
|
326
|
+
|
|
327
|
+
def _format_display_version(self, version: str) -> str:
|
|
328
|
+
"""
|
|
329
|
+
Format display version with proper formatting.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
version: Version string
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
Display version string
|
|
336
|
+
"""
|
|
337
|
+
if version == "unknown":
|
|
338
|
+
return "MoAI-ADK unknown version"
|
|
339
|
+
elif version.startswith("v"):
|
|
340
|
+
return f"MoAI-ADK {version}"
|
|
341
|
+
else:
|
|
342
|
+
return f"MoAI-ADK v{version}"
|
|
343
|
+
|
|
344
|
+
def _format_trimmed_version(self, version: str, max_length: int = 10) -> str:
|
|
345
|
+
"""
|
|
346
|
+
Format version with maximum length, suitable for UI displays.
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
version: Version string
|
|
350
|
+
max_length: Maximum allowed length for the version string
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
Trimmed version string
|
|
354
|
+
"""
|
|
355
|
+
if version == "unknown":
|
|
356
|
+
return "unknown"
|
|
357
|
+
|
|
358
|
+
# Remove 'v' prefix for trimming
|
|
359
|
+
clean_version = version[1:] if version.startswith("v") else version
|
|
360
|
+
|
|
361
|
+
# Trim if necessary
|
|
362
|
+
if len(clean_version) > max_length:
|
|
363
|
+
return clean_version[:max_length]
|
|
364
|
+
return clean_version
|
|
365
|
+
|
|
366
|
+
def _format_semver_version(self, version: str) -> str:
|
|
367
|
+
"""
|
|
368
|
+
Format version as semantic version with major.minor.patch structure.
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
version: Version string
|
|
372
|
+
|
|
373
|
+
Returns:
|
|
374
|
+
Semantic version string
|
|
375
|
+
"""
|
|
376
|
+
if version == "unknown":
|
|
377
|
+
return "0.0.0"
|
|
378
|
+
|
|
379
|
+
# Remove 'v' prefix and extract semantic version
|
|
380
|
+
clean_version = version[1:] if version.startswith("v") else version
|
|
381
|
+
|
|
382
|
+
# Extract core semantic version (remove pre-release and build metadata)
|
|
383
|
+
import re
|
|
384
|
+
|
|
385
|
+
semver_match = re.match(r"^(\d+\.\d+\.\d+)", clean_version)
|
|
386
|
+
if semver_match:
|
|
387
|
+
return semver_match.group(1)
|
|
388
|
+
return "0.0.0"
|
|
389
|
+
|
|
390
|
+
def _get_version_source(self, version_reader: VersionReader) -> str:
|
|
391
|
+
"""
|
|
392
|
+
Determine the source of the version information.
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
version_reader: VersionReader instance
|
|
396
|
+
|
|
397
|
+
Returns:
|
|
398
|
+
String indicating version source
|
|
399
|
+
"""
|
|
400
|
+
config = version_reader.get_config()
|
|
401
|
+
cache_age = version_reader.get_cache_age_seconds()
|
|
402
|
+
|
|
403
|
+
if cache_age is not None and cache_age < config.cache_ttl_seconds:
|
|
404
|
+
return "config_cached"
|
|
405
|
+
elif cache_age is not None:
|
|
406
|
+
return "config_stale"
|
|
407
|
+
else:
|
|
408
|
+
return config.fallback_source.value
|
|
409
|
+
|
|
410
|
+
def _get_template_root(self) -> Path:
|
|
411
|
+
"""Return the template root path."""
|
|
412
|
+
# src/moai_adk/core/template/processor.py → src/moai_adk/templates/
|
|
413
|
+
current_file = Path(__file__).resolve()
|
|
414
|
+
package_root = current_file.parent.parent.parent
|
|
415
|
+
return package_root / "templates"
|
|
59
416
|
|
|
60
417
|
def _substitute_variables(self, content: str) -> tuple[str, list[str]]:
|
|
61
|
-
"""
|
|
418
|
+
"""
|
|
419
|
+
Substitute template variables in content with enhanced validation and caching.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
content: Content to substitute variables in
|
|
62
423
|
|
|
63
424
|
Returns:
|
|
64
425
|
Tuple of (substituted_content, warnings_list)
|
|
65
426
|
"""
|
|
66
427
|
warnings = []
|
|
67
|
-
|
|
68
|
-
|
|
428
|
+
logger = logging.getLogger(__name__)
|
|
429
|
+
|
|
430
|
+
# Check cache first if enabled
|
|
431
|
+
cache_key = hash((frozenset(self.context.items()), content[:1000]))
|
|
432
|
+
if self.config.enable_caching and cache_key in self._substitution_cache:
|
|
433
|
+
cached_result = self._substitution_cache[cache_key]
|
|
434
|
+
if self.config.verbose_logging:
|
|
435
|
+
logger.debug("Using cached substitution result")
|
|
436
|
+
return cached_result
|
|
437
|
+
|
|
438
|
+
# Enhanced variable substitution with validation
|
|
439
|
+
substitution_count = 0
|
|
69
440
|
for key, value in self.context.items():
|
|
70
441
|
placeholder = f"{{{{{key}}}}}" # {{KEY}}
|
|
71
442
|
if placeholder in content:
|
|
443
|
+
if self.config.validate_template_variables:
|
|
444
|
+
# Validate variable before substitution
|
|
445
|
+
if not self._is_valid_template_variable(key, value):
|
|
446
|
+
warnings.append(f"Invalid variable {key} - skipped substitution")
|
|
447
|
+
continue
|
|
448
|
+
|
|
72
449
|
safe_value = self._sanitize_value(value)
|
|
73
450
|
content = content.replace(placeholder, safe_value)
|
|
451
|
+
substitution_count += 1
|
|
452
|
+
|
|
453
|
+
if self.config.verbose_logging:
|
|
454
|
+
logger.debug(f"Substituted {key}: {safe_value[:50]}...")
|
|
74
455
|
|
|
75
|
-
# Detect unsubstituted variables
|
|
76
|
-
remaining = re.findall(r
|
|
456
|
+
# Detect unsubstituted variables with enhanced error messages
|
|
457
|
+
remaining = re.findall(r"\{\{([A-Z_]+)\}\}", content)
|
|
77
458
|
if remaining:
|
|
78
459
|
unique_remaining = sorted(set(remaining))
|
|
79
|
-
|
|
460
|
+
|
|
461
|
+
# Build detailed warning message with enhanced suggestions
|
|
462
|
+
warning_parts = []
|
|
463
|
+
for var in unique_remaining:
|
|
464
|
+
if var in self.COMMON_TEMPLATE_VARIABLES:
|
|
465
|
+
suggestion = self.COMMON_TEMPLATE_VARIABLES[var]
|
|
466
|
+
warning_parts.append(f"{{{{{var}}}}} → {suggestion}")
|
|
467
|
+
else:
|
|
468
|
+
warning_parts.append(f"{{{{{var}}}}} → Unknown variable (check template)")
|
|
469
|
+
|
|
470
|
+
warnings.append("Template variables not substituted:")
|
|
471
|
+
warnings.extend(f" • {part}" for part in warning_parts)
|
|
472
|
+
|
|
473
|
+
if self.config.enable_substitution_warnings:
|
|
474
|
+
warnings.append("💡 Run 'uv run moai-adk update' to fix template variables")
|
|
475
|
+
|
|
476
|
+
# Add performance information if verbose logging is enabled
|
|
477
|
+
if self.config.verbose_logging:
|
|
478
|
+
warnings.append(f" 📊 Substituted {substitution_count} variables")
|
|
479
|
+
|
|
480
|
+
# Cache the result if enabled
|
|
481
|
+
if self.config.enable_caching:
|
|
482
|
+
result = (content, warnings)
|
|
483
|
+
self._substitution_cache[cache_key] = result
|
|
484
|
+
|
|
485
|
+
# Manage cache size
|
|
486
|
+
if len(self._substitution_cache) > self.config.cache_size:
|
|
487
|
+
# Remove oldest entry (simple FIFO)
|
|
488
|
+
oldest_key = next(iter(self._substitution_cache))
|
|
489
|
+
del self._substitution_cache[oldest_key]
|
|
490
|
+
if self.config.verbose_logging:
|
|
491
|
+
logger.debug("Cache size limit reached, removed oldest entry")
|
|
80
492
|
|
|
81
493
|
return content, warnings
|
|
82
494
|
|
|
495
|
+
def _is_valid_template_variable(self, key: str, value: str) -> bool:
|
|
496
|
+
"""
|
|
497
|
+
Validate a template variable before substitution.
|
|
498
|
+
|
|
499
|
+
Args:
|
|
500
|
+
key: Variable name
|
|
501
|
+
value: Variable value
|
|
502
|
+
|
|
503
|
+
Returns:
|
|
504
|
+
True if variable is valid
|
|
505
|
+
"""
|
|
506
|
+
import re
|
|
507
|
+
|
|
508
|
+
# Check variable name format
|
|
509
|
+
if not re.match(self.config.allowed_variable_pattern, key):
|
|
510
|
+
return False
|
|
511
|
+
|
|
512
|
+
# Check variable length
|
|
513
|
+
if len(key) > self.config.max_variable_length:
|
|
514
|
+
return False
|
|
515
|
+
|
|
516
|
+
# Check value length
|
|
517
|
+
if len(value) > self.config.max_variable_length * 2:
|
|
518
|
+
return False
|
|
519
|
+
|
|
520
|
+
# Note: {{ }} patterns are handled by sanitization, not validation
|
|
521
|
+
|
|
522
|
+
# Check for empty values
|
|
523
|
+
if not value.strip():
|
|
524
|
+
return False
|
|
525
|
+
|
|
526
|
+
return True
|
|
527
|
+
|
|
528
|
+
def clear_substitution_cache(self) -> None:
|
|
529
|
+
"""Clear the substitution cache."""
|
|
530
|
+
self._substitution_cache.clear()
|
|
531
|
+
if self.config.verbose_logging:
|
|
532
|
+
self.logger.debug("Substitution cache cleared")
|
|
533
|
+
|
|
534
|
+
def get_cache_stats(self) -> Dict[str, Any]:
|
|
535
|
+
"""
|
|
536
|
+
Get cache statistics.
|
|
537
|
+
|
|
538
|
+
Returns:
|
|
539
|
+
Dictionary containing cache statistics
|
|
540
|
+
"""
|
|
541
|
+
return {
|
|
542
|
+
"cache_size": len(self._substitution_cache),
|
|
543
|
+
"max_cache_size": self.config.cache_size,
|
|
544
|
+
"cache_enabled": self.config.enable_caching,
|
|
545
|
+
"cache_hit_ratio": 0.0, # Would need to track hits to implement this
|
|
546
|
+
}
|
|
547
|
+
|
|
83
548
|
def _sanitize_value(self, value: str) -> str:
|
|
84
549
|
"""Sanitize value to prevent recursive substitution and control characters.
|
|
85
550
|
|
|
@@ -90,9 +555,9 @@ class TemplateProcessor:
|
|
|
90
555
|
Sanitized value.
|
|
91
556
|
"""
|
|
92
557
|
# Remove control characters (keep printable and whitespace)
|
|
93
|
-
value =
|
|
558
|
+
value = "".join(c for c in value if c.isprintable() or c in "\n\r\t")
|
|
94
559
|
# Prevent recursive substitution by removing placeholder patterns
|
|
95
|
-
value = value.replace(
|
|
560
|
+
value = value.replace("{{", "").replace("}}", "")
|
|
96
561
|
return value
|
|
97
562
|
|
|
98
563
|
def _is_text_file(self, file_path: Path) -> bool:
|
|
@@ -105,8 +570,18 @@ class TemplateProcessor:
|
|
|
105
570
|
True if file is text-based.
|
|
106
571
|
"""
|
|
107
572
|
text_extensions = {
|
|
108
|
-
|
|
109
|
-
|
|
573
|
+
".md",
|
|
574
|
+
".json",
|
|
575
|
+
".txt",
|
|
576
|
+
".py",
|
|
577
|
+
".ts",
|
|
578
|
+
".js",
|
|
579
|
+
".yaml",
|
|
580
|
+
".yml",
|
|
581
|
+
".toml",
|
|
582
|
+
".xml",
|
|
583
|
+
".sh",
|
|
584
|
+
".bash",
|
|
110
585
|
}
|
|
111
586
|
return file_path.suffix.lower() in text_extensions
|
|
112
587
|
|
|
@@ -127,10 +602,10 @@ class TemplateProcessor:
|
|
|
127
602
|
Returns:
|
|
128
603
|
Content with localized descriptions.
|
|
129
604
|
"""
|
|
130
|
-
import yaml
|
|
605
|
+
import yaml # type: ignore[import-untyped]
|
|
131
606
|
|
|
132
607
|
# Pattern to match YAML frontmatter
|
|
133
|
-
frontmatter_pattern = r
|
|
608
|
+
frontmatter_pattern = r"^---\n(.*?)\n---"
|
|
134
609
|
match = re.match(frontmatter_pattern, content, re.DOTALL)
|
|
135
610
|
|
|
136
611
|
if not match:
|
|
@@ -141,18 +616,18 @@ class TemplateProcessor:
|
|
|
141
616
|
yaml_data = yaml.safe_load(yaml_content)
|
|
142
617
|
|
|
143
618
|
# Check if description is a dict (multilingual)
|
|
144
|
-
if isinstance(yaml_data.get(
|
|
619
|
+
if isinstance(yaml_data.get("description"), dict):
|
|
145
620
|
# Select language (fallback to English)
|
|
146
|
-
descriptions = yaml_data[
|
|
147
|
-
selected_desc = descriptions.get(language, descriptions.get(
|
|
621
|
+
descriptions = yaml_data["description"]
|
|
622
|
+
selected_desc = descriptions.get(language, descriptions.get("en", ""))
|
|
148
623
|
|
|
149
624
|
# Replace description with selected language
|
|
150
|
-
yaml_data[
|
|
625
|
+
yaml_data["description"] = selected_desc
|
|
151
626
|
|
|
152
627
|
# Reconstruct frontmatter
|
|
153
628
|
new_yaml = yaml.dump(yaml_data, allow_unicode=True, sort_keys=False)
|
|
154
629
|
# Preserve the rest of the content
|
|
155
|
-
rest_content = content[match.end():]
|
|
630
|
+
rest_content = content[match.end() :]
|
|
156
631
|
return f"---\n{new_yaml}---{rest_content}"
|
|
157
632
|
|
|
158
633
|
except Exception:
|
|
@@ -171,22 +646,22 @@ class TemplateProcessor:
|
|
|
171
646
|
Returns:
|
|
172
647
|
List of warnings.
|
|
173
648
|
"""
|
|
649
|
+
import stat
|
|
650
|
+
|
|
174
651
|
warnings = []
|
|
175
652
|
|
|
176
653
|
# Text files: read, substitute, write
|
|
177
654
|
if self._is_text_file(src) and self.context:
|
|
178
655
|
try:
|
|
179
|
-
content = src.read_text(encoding=
|
|
656
|
+
content = src.read_text(encoding="utf-8")
|
|
180
657
|
content, file_warnings = self._substitute_variables(content)
|
|
181
658
|
|
|
182
659
|
# Apply description localization for command/output-style files
|
|
183
|
-
if src.suffix ==
|
|
184
|
-
|
|
185
|
-
):
|
|
186
|
-
lang = self.context.get('CONVERSATION_LANGUAGE', 'en')
|
|
660
|
+
if src.suffix == ".md" and ("commands/alfred" in str(src) or "output-styles/alfred" in str(src)):
|
|
661
|
+
lang = self.context.get("CONVERSATION_LANGUAGE", "en")
|
|
187
662
|
content = self._localize_yaml_description(content, lang)
|
|
188
663
|
|
|
189
|
-
dst.write_text(content, encoding=
|
|
664
|
+
dst.write_text(content, encoding="utf-8")
|
|
190
665
|
warnings.extend(file_warnings)
|
|
191
666
|
except UnicodeDecodeError:
|
|
192
667
|
# Binary file fallback
|
|
@@ -195,6 +670,12 @@ class TemplateProcessor:
|
|
|
195
670
|
# Binary file or no context: simple copy
|
|
196
671
|
shutil.copy2(src, dst)
|
|
197
672
|
|
|
673
|
+
# Ensure executable permission for shell scripts
|
|
674
|
+
if src.suffix == ".sh":
|
|
675
|
+
# Always make shell scripts executable regardless of source permissions
|
|
676
|
+
dst_mode = dst.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
|
|
677
|
+
dst.chmod(dst_mode)
|
|
678
|
+
|
|
198
679
|
return warnings
|
|
199
680
|
|
|
200
681
|
def _copy_dir_with_substitution(self, src: Path, dst: Path) -> None:
|
|
@@ -240,6 +721,7 @@ class TemplateProcessor:
|
|
|
240
721
|
self._copy_github(silent)
|
|
241
722
|
self._copy_claude_md(silent)
|
|
242
723
|
self._copy_gitignore(silent)
|
|
724
|
+
self._copy_mcp_json(silent)
|
|
243
725
|
|
|
244
726
|
if not silent:
|
|
245
727
|
console.print("✅ Templates copied successfully")
|
|
@@ -290,9 +772,6 @@ class TemplateProcessor:
|
|
|
290
772
|
def _copy_claude(self, silent: bool = False) -> None:
|
|
291
773
|
""".claude/ directory copy with variable substitution (selective with alfred folder overwrite).
|
|
292
774
|
|
|
293
|
-
@CODE:INIT-004:ALFRED-001 | Copy all 4 Alfred command files from templates
|
|
294
|
-
@REQ:COMMAND-GENERATION-001 | SPEC-INIT-004: Automatic generation of Alfred command files
|
|
295
|
-
@SPEC:TEMPLATE-PROCESSING-001 | Template processor integration for Alfred command files
|
|
296
775
|
|
|
297
776
|
Strategy:
|
|
298
777
|
- Alfred folders (commands/agents/hooks/output-styles/alfred) → copy wholesale (delete & overwrite)
|
|
@@ -311,18 +790,21 @@ class TemplateProcessor:
|
|
|
311
790
|
# Create .claude directory if not exists
|
|
312
791
|
dst.mkdir(parents=True, exist_ok=True)
|
|
313
792
|
|
|
314
|
-
#
|
|
315
|
-
#
|
|
316
|
-
|
|
317
|
-
alfred_folders = [
|
|
793
|
+
# Alfred and Moai folders to copy wholesale (overwrite)
|
|
794
|
+
# Including both legacy alfred/ and new moai/ structure
|
|
795
|
+
alfred_moai_folders = [
|
|
318
796
|
"hooks/alfred",
|
|
797
|
+
"hooks/moai",
|
|
319
798
|
"commands/alfred", # Contains 0-project.md, 1-plan.md, 2-run.md, 3-sync.md
|
|
320
|
-
"
|
|
799
|
+
"commands/moai",
|
|
800
|
+
"output-styles/moai",
|
|
321
801
|
"agents/alfred",
|
|
802
|
+
"agents/moai",
|
|
803
|
+
"skills", # NEW: Complete replacement for skills folder
|
|
322
804
|
]
|
|
323
805
|
|
|
324
|
-
# 1. Copy Alfred folders wholesale (backup before delete & overwrite)
|
|
325
|
-
for folder in
|
|
806
|
+
# 1. Copy Alfred and Moai folders wholesale (backup before delete & overwrite)
|
|
807
|
+
for folder in alfred_moai_folders:
|
|
326
808
|
src_folder = src / folder
|
|
327
809
|
dst_folder = dst / folder
|
|
328
810
|
|
|
@@ -337,22 +819,66 @@ class TemplateProcessor:
|
|
|
337
819
|
if not silent:
|
|
338
820
|
console.print(f" ✅ .claude/{folder}/ overwritten")
|
|
339
821
|
|
|
340
|
-
#
|
|
822
|
+
# 1.5 Copy other subdirectories in parent folders (e.g., output-styles/moai, hooks/shared)
|
|
823
|
+
# This ensures non-alfred subdirectories are also copied
|
|
824
|
+
parent_folders_with_subdirs = ["output-styles", "hooks", "commands", "agents"]
|
|
825
|
+
for parent_name in parent_folders_with_subdirs:
|
|
826
|
+
src_parent = src / parent_name
|
|
827
|
+
if not src_parent.exists():
|
|
828
|
+
continue
|
|
829
|
+
|
|
830
|
+
for subdir in src_parent.iterdir():
|
|
831
|
+
if not subdir.is_dir():
|
|
832
|
+
continue
|
|
833
|
+
|
|
834
|
+
# Skip alfred subdirectories (already handled above)
|
|
835
|
+
if subdir.name == "alfred":
|
|
836
|
+
continue
|
|
837
|
+
|
|
838
|
+
rel_subdir = f"{parent_name}/{subdir.name}"
|
|
839
|
+
dst_subdir = dst / parent_name / subdir.name
|
|
840
|
+
|
|
841
|
+
if dst_subdir.exists():
|
|
842
|
+
# For non-alfred directories, overwrite with merge if necessary
|
|
843
|
+
shutil.rmtree(dst_subdir)
|
|
844
|
+
|
|
845
|
+
# Copy the subdirectory
|
|
846
|
+
shutil.copytree(subdir, dst_subdir)
|
|
847
|
+
if not silent:
|
|
848
|
+
console.print(f" ✅ .claude/{rel_subdir}/ copied")
|
|
849
|
+
|
|
850
|
+
# 2. Copy other files/folders individually (smart merge for settings.json and config.json)
|
|
341
851
|
all_warnings = []
|
|
342
852
|
for item in src.iterdir():
|
|
343
853
|
rel_path = item.relative_to(src)
|
|
344
854
|
dst_item = dst / rel_path
|
|
345
855
|
|
|
346
856
|
# Skip Alfred parent folders (already handled above)
|
|
347
|
-
if item.is_dir() and item.name in [
|
|
857
|
+
if item.is_dir() and item.name in [
|
|
858
|
+
"hooks",
|
|
859
|
+
"commands",
|
|
860
|
+
"output-styles",
|
|
861
|
+
"agents",
|
|
862
|
+
]:
|
|
348
863
|
continue
|
|
349
864
|
|
|
350
865
|
if item.is_file():
|
|
351
866
|
# Smart merge for settings.json
|
|
352
867
|
if item.name == "settings.json":
|
|
353
868
|
self._merge_settings_json(item, dst_item)
|
|
869
|
+
# Apply variable substitution to merged settings.json (for cross-platform Hook paths)
|
|
870
|
+
if self.context:
|
|
871
|
+
content = dst_item.read_text(encoding="utf-8")
|
|
872
|
+
content, file_warnings = self._substitute_variables(content)
|
|
873
|
+
dst_item.write_text(content, encoding="utf-8")
|
|
874
|
+
all_warnings.extend(file_warnings)
|
|
875
|
+
if not silent:
|
|
876
|
+
console.print(" 🔄 settings.json merged (Hook paths configured for your OS)")
|
|
877
|
+
# Smart merge for config.json
|
|
878
|
+
elif item.name == "config.json":
|
|
879
|
+
self._merge_config_json(item, dst_item)
|
|
354
880
|
if not silent:
|
|
355
|
-
console.print(" 🔄
|
|
881
|
+
console.print(" 🔄 config.json merged (user preferences preserved)")
|
|
356
882
|
else:
|
|
357
883
|
# FORCE OVERWRITE: Always copy other files (no skip)
|
|
358
884
|
warnings = self._copy_file_with_substitution(item, dst_item)
|
|
@@ -380,10 +906,11 @@ class TemplateProcessor:
|
|
|
380
906
|
console.print("⚠️ .moai/ template not found")
|
|
381
907
|
return
|
|
382
908
|
|
|
383
|
-
# Paths excluded from template copying (specs/, reports/)
|
|
909
|
+
# Paths excluded from template copying (specs/, reports/, .moai/config/config.json)
|
|
384
910
|
template_protected_paths = [
|
|
385
911
|
"specs",
|
|
386
912
|
"reports",
|
|
913
|
+
".moai/config/config.json",
|
|
387
914
|
]
|
|
388
915
|
|
|
389
916
|
all_warnings = []
|
|
@@ -417,7 +944,7 @@ class TemplateProcessor:
|
|
|
417
944
|
console.print(" ✅ .moai/ copy complete (variables substituted)")
|
|
418
945
|
|
|
419
946
|
def _copy_github(self, silent: bool = False) -> None:
|
|
420
|
-
""".github/ directory copy with
|
|
947
|
+
""".github/ directory copy with smart merge (preserves user workflows)."""
|
|
421
948
|
src = self.template_root / ".github"
|
|
422
949
|
dst = self.target_path / ".github"
|
|
423
950
|
|
|
@@ -426,16 +953,18 @@ class TemplateProcessor:
|
|
|
426
953
|
console.print("⚠️ .github/ template not found")
|
|
427
954
|
return
|
|
428
955
|
|
|
956
|
+
# Smart merge: preserve existing user workflows
|
|
429
957
|
if dst.exists():
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
958
|
+
self._merge_github_workflows(src, dst)
|
|
959
|
+
else:
|
|
960
|
+
# First time: just copy
|
|
961
|
+
self._copy_dir_with_substitution(src, dst)
|
|
433
962
|
|
|
434
963
|
if not silent:
|
|
435
|
-
console.print("
|
|
964
|
+
console.print(" 🔄 .github/ merged (user workflows preserved, variables substituted)")
|
|
436
965
|
|
|
437
966
|
def _copy_claude_md(self, silent: bool = False) -> None:
|
|
438
|
-
"""Copy CLAUDE.md with
|
|
967
|
+
"""Copy CLAUDE.md with complete replacement (no merge)."""
|
|
439
968
|
src = self.template_root / "CLAUDE.md"
|
|
440
969
|
dst = self.target_path / "CLAUDE.md"
|
|
441
970
|
|
|
@@ -444,16 +973,11 @@ class TemplateProcessor:
|
|
|
444
973
|
console.print("⚠️ CLAUDE.md template not found")
|
|
445
974
|
return
|
|
446
975
|
|
|
447
|
-
#
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
else:
|
|
453
|
-
# First time: just copy
|
|
454
|
-
self._copy_file_with_substitution(src, dst)
|
|
455
|
-
if not silent:
|
|
456
|
-
console.print(" ✅ CLAUDE.md created")
|
|
976
|
+
# Simple copy with substitution (no merge)
|
|
977
|
+
self._copy_file_with_substitution(src, dst)
|
|
978
|
+
|
|
979
|
+
if not silent:
|
|
980
|
+
console.print(" ✅ CLAUDE.md replaced (use CLAUDE.local.md for personal instructions)")
|
|
457
981
|
|
|
458
982
|
def _merge_claude_md(self, src: Path, dst: Path) -> None:
|
|
459
983
|
"""Delegate the smart merge for CLAUDE.md.
|
|
@@ -464,6 +988,15 @@ class TemplateProcessor:
|
|
|
464
988
|
"""
|
|
465
989
|
self.merger.merge_claude_md(src, dst)
|
|
466
990
|
|
|
991
|
+
def _merge_github_workflows(self, src: Path, dst: Path) -> None:
|
|
992
|
+
"""Delegate the smart merge for .github/workflows/.
|
|
993
|
+
|
|
994
|
+
Args:
|
|
995
|
+
src: Template .github directory.
|
|
996
|
+
dst: Project .github directory.
|
|
997
|
+
"""
|
|
998
|
+
self.merger.merge_github_workflows(src, dst)
|
|
999
|
+
|
|
467
1000
|
def _merge_settings_json(self, src: Path, dst: Path) -> None:
|
|
468
1001
|
"""Delegate the smart merge for settings.json.
|
|
469
1002
|
|
|
@@ -473,15 +1006,119 @@ class TemplateProcessor:
|
|
|
473
1006
|
"""
|
|
474
1007
|
# Find the latest backup for user settings extraction
|
|
475
1008
|
backup_path = None
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
backup_path = backup_settings
|
|
1009
|
+
latest_backup = self.backup.get_latest_backup()
|
|
1010
|
+
if latest_backup:
|
|
1011
|
+
backup_settings = latest_backup / ".claude" / "settings.json"
|
|
1012
|
+
if backup_settings.exists():
|
|
1013
|
+
backup_path = backup_settings
|
|
482
1014
|
|
|
483
1015
|
self.merger.merge_settings_json(src, dst, backup_path)
|
|
484
1016
|
|
|
1017
|
+
def _merge_config_json(self, src: Path, dst: Path) -> None:
|
|
1018
|
+
"""Smart merge for config.json using LanguageConfigResolver priority system.
|
|
1019
|
+
|
|
1020
|
+
Args:
|
|
1021
|
+
src: Template config.json.
|
|
1022
|
+
dst: Project config.json.
|
|
1023
|
+
"""
|
|
1024
|
+
import json
|
|
1025
|
+
|
|
1026
|
+
# Load template config
|
|
1027
|
+
try:
|
|
1028
|
+
template_config = json.loads(src.read_text(encoding="utf-8"))
|
|
1029
|
+
except (json.JSONDecodeError, FileNotFoundError) as e:
|
|
1030
|
+
console.print(f"⚠️ Warning: Could not read template config.json: {e}")
|
|
1031
|
+
return
|
|
1032
|
+
|
|
1033
|
+
# Find latest backup config.json
|
|
1034
|
+
latest_backup = self.backup.get_latest_backup()
|
|
1035
|
+
if latest_backup:
|
|
1036
|
+
backup_config_path = latest_backup / ".moai" / "config" / "config.json"
|
|
1037
|
+
if backup_config_path.exists():
|
|
1038
|
+
try:
|
|
1039
|
+
json.loads(backup_config_path.read_text(encoding="utf-8"))
|
|
1040
|
+
except json.JSONDecodeError as e:
|
|
1041
|
+
console.print(f"⚠️ Warning: Could not read backup config.json: {e}")
|
|
1042
|
+
|
|
1043
|
+
# Load existing project config.json
|
|
1044
|
+
existing_config = {}
|
|
1045
|
+
if dst.exists():
|
|
1046
|
+
try:
|
|
1047
|
+
existing_config = json.loads(dst.read_text(encoding="utf-8"))
|
|
1048
|
+
except json.JSONDecodeError as e:
|
|
1049
|
+
console.print(f"⚠️ Warning: Could not read existing config.json: {e}")
|
|
1050
|
+
|
|
1051
|
+
# Merge with priority system: Environment > Existing User > Template
|
|
1052
|
+
# We'll use LanguageConfigResolver to handle this properly
|
|
1053
|
+
try:
|
|
1054
|
+
# Import LanguageConfigResolver for priority-based merging
|
|
1055
|
+
from moai_adk.core.language_config_resolver import LanguageConfigResolver
|
|
1056
|
+
|
|
1057
|
+
# Create temporary resolver to handle merging
|
|
1058
|
+
temp_project_path = self.target_path / ".moai" / "config"
|
|
1059
|
+
temp_project_path.mkdir(parents=True, exist_ok=True)
|
|
1060
|
+
|
|
1061
|
+
# Start with template config as base
|
|
1062
|
+
merged_config = template_config.copy()
|
|
1063
|
+
|
|
1064
|
+
# Apply existing user config (higher priority than template)
|
|
1065
|
+
for key, value in existing_config.items():
|
|
1066
|
+
if key not in ["config_source"]: # Skip metadata
|
|
1067
|
+
if key in merged_config and isinstance(merged_config[key], dict) and isinstance(value, dict):
|
|
1068
|
+
# Deep merge for nested objects
|
|
1069
|
+
merged_config[key].update(value)
|
|
1070
|
+
else:
|
|
1071
|
+
merged_config[key] = value
|
|
1072
|
+
|
|
1073
|
+
# Apply environment variables (highest priority)
|
|
1074
|
+
import os
|
|
1075
|
+
|
|
1076
|
+
env_mappings = {
|
|
1077
|
+
"MOAI_USER_NAME": ("user", "name"),
|
|
1078
|
+
"MOAI_CONVERSATION_LANG": ("language", "conversation_language"),
|
|
1079
|
+
"MOAI_AGENT_PROMPT_LANG": ("language", "agent_prompt_language"),
|
|
1080
|
+
"MOAI_CONVERSATION_LANG_NAME": (
|
|
1081
|
+
"language",
|
|
1082
|
+
"conversation_language_name",
|
|
1083
|
+
),
|
|
1084
|
+
"MOAI_GIT_COMMIT_MESSAGES_LANG": ("language", "git_commit_messages"),
|
|
1085
|
+
"MOAI_CODE_COMMENTS_LANG": ("language", "code_comments"),
|
|
1086
|
+
"MOAI_DOCUMENTATION_LANG": ("language", "documentation"),
|
|
1087
|
+
"MOAI_ERROR_MESSAGES_LANG": ("language", "error_messages"),
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
for env_var, (section, key) in env_mappings.items():
|
|
1091
|
+
env_value = os.getenv(env_var)
|
|
1092
|
+
if env_value:
|
|
1093
|
+
if section not in merged_config:
|
|
1094
|
+
merged_config[section] = {}
|
|
1095
|
+
merged_config[section][key] = env_value
|
|
1096
|
+
|
|
1097
|
+
# Ensure consistency
|
|
1098
|
+
resolver = LanguageConfigResolver(str(self.target_path))
|
|
1099
|
+
merged_config = resolver._ensure_consistency(merged_config)
|
|
1100
|
+
|
|
1101
|
+
# Write merged config
|
|
1102
|
+
dst.write_text(
|
|
1103
|
+
json.dumps(merged_config, indent=2, ensure_ascii=False) + "\n",
|
|
1104
|
+
encoding="utf-8",
|
|
1105
|
+
)
|
|
1106
|
+
|
|
1107
|
+
except ImportError:
|
|
1108
|
+
# Fallback: simple merge without LanguageConfigResolver
|
|
1109
|
+
merged_config = template_config.copy()
|
|
1110
|
+
|
|
1111
|
+
# Apply existing config
|
|
1112
|
+
for key, value in existing_config.items():
|
|
1113
|
+
if key not in ["config_source"]:
|
|
1114
|
+
merged_config[key] = value
|
|
1115
|
+
|
|
1116
|
+
dst.write_text(
|
|
1117
|
+
json.dumps(merged_config, indent=2, ensure_ascii=False) + "\n",
|
|
1118
|
+
encoding="utf-8",
|
|
1119
|
+
)
|
|
1120
|
+
console.print(" ⚠️ Warning: Using simple merge (LanguageConfigResolver not available)")
|
|
1121
|
+
|
|
485
1122
|
def _copy_gitignore(self, silent: bool = False) -> None:
|
|
486
1123
|
""".gitignore copy (optional)."""
|
|
487
1124
|
src = self.template_root / ".gitignore"
|
|
@@ -509,6 +1146,47 @@ class TemplateProcessor:
|
|
|
509
1146
|
"""
|
|
510
1147
|
self.merger.merge_gitignore(src, dst)
|
|
511
1148
|
|
|
1149
|
+
def _copy_mcp_json(self, silent: bool = False) -> None:
|
|
1150
|
+
""".mcp.json copy (smart merge with existing MCP server configuration)."""
|
|
1151
|
+
src = self.template_root / ".mcp.json"
|
|
1152
|
+
dst = self.target_path / ".mcp.json"
|
|
1153
|
+
|
|
1154
|
+
if not src.exists():
|
|
1155
|
+
return
|
|
1156
|
+
|
|
1157
|
+
# Merge with existing .mcp.json when present (preserve user-added MCP servers)
|
|
1158
|
+
if dst.exists():
|
|
1159
|
+
self._merge_mcp_json(src, dst)
|
|
1160
|
+
if not silent:
|
|
1161
|
+
console.print(" 🔄 .mcp.json merged (user MCP servers preserved)")
|
|
1162
|
+
else:
|
|
1163
|
+
shutil.copy2(src, dst)
|
|
1164
|
+
if not silent:
|
|
1165
|
+
console.print(" ✅ .mcp.json copy complete")
|
|
1166
|
+
|
|
1167
|
+
def _merge_mcp_json(self, src: Path, dst: Path) -> None:
|
|
1168
|
+
"""Smart merge for .mcp.json (preserve user-added MCP servers).
|
|
1169
|
+
|
|
1170
|
+
Args:
|
|
1171
|
+
src: Template .mcp.json.
|
|
1172
|
+
dst: Project .mcp.json.
|
|
1173
|
+
"""
|
|
1174
|
+
try:
|
|
1175
|
+
src_data = json.loads(src.read_text(encoding="utf-8"))
|
|
1176
|
+
dst_data = json.loads(dst.read_text(encoding="utf-8"))
|
|
1177
|
+
|
|
1178
|
+
# Merge mcpServers: preserve user servers, update template servers
|
|
1179
|
+
if "mcpServers" in src_data:
|
|
1180
|
+
if "mcpServers" not in dst_data:
|
|
1181
|
+
dst_data["mcpServers"] = {}
|
|
1182
|
+
# Update with template servers (preserves existing user servers)
|
|
1183
|
+
dst_data["mcpServers"].update(src_data["mcpServers"])
|
|
1184
|
+
|
|
1185
|
+
# Write merged result back
|
|
1186
|
+
dst.write_text(json.dumps(dst_data, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
1187
|
+
except json.JSONDecodeError as e:
|
|
1188
|
+
console.print(f"[yellow]⚠️ Failed to merge .mcp.json: {e}[/yellow]")
|
|
1189
|
+
|
|
512
1190
|
def merge_config(self, detected_language: str | None = None) -> dict[str, str]:
|
|
513
1191
|
"""Delegate the smart merge for config.json.
|
|
514
1192
|
|