moai-adk 0.8.0__py3-none-any.whl → 1.1.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 +267 -21
- moai_adk/astgrep/__init__.py +37 -0
- moai_adk/astgrep/analyzer.py +522 -0
- moai_adk/astgrep/models.py +124 -0
- moai_adk/astgrep/rules.py +179 -0
- moai_adk/cli/__init__.py +6 -2
- moai_adk/cli/commands/__init__.py +1 -4
- moai_adk/cli/commands/analyze.py +125 -0
- moai_adk/cli/commands/doctor.py +24 -6
- moai_adk/cli/commands/init.py +437 -57
- moai_adk/cli/commands/language.py +254 -0
- moai_adk/cli/commands/rank.py +449 -0
- moai_adk/cli/commands/status.py +15 -14
- moai_adk/cli/commands/switch.py +325 -0
- moai_adk/cli/commands/update.py +2195 -93
- moai_adk/cli/main.py +3 -2
- moai_adk/cli/prompts/init_prompts.py +457 -108
- moai_adk/cli/prompts/translations/__init__.py +573 -0
- moai_adk/cli/spec_status.py +263 -0
- moai_adk/cli/ui/__init__.py +44 -0
- moai_adk/cli/ui/progress.py +422 -0
- moai_adk/cli/ui/prompts.py +448 -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 +788 -0
- moai_adk/cli/worktree/exceptions.py +89 -0
- moai_adk/cli/worktree/manager.py +648 -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/migration.py +148 -17
- moai_adk/core/config/unified.py +617 -0
- moai_adk/core/context_manager.py +273 -0
- moai_adk/core/credentials.py +264 -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 +1920 -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 +422 -0
- moai_adk/core/git/event_detector.py +16 -7
- moai_adk/core/git/manager.py +91 -2
- 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 +578 -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 +666 -0
- moai_adk/core/migration/__init__.py +18 -0
- moai_adk/core/migration/alfred_to_moai_migrator.py +389 -0
- moai_adk/core/migration/backup_manager.py +327 -0
- moai_adk/core/migration/custom_element_scanner.py +358 -0
- moai_adk/core/migration/file_migrator.py +381 -0
- moai_adk/core/migration/interactive_checkbox_ui.py +499 -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 +243 -0
- moai_adk/core/migration/version_migrator.py +263 -0
- moai_adk/core/model_allocator.py +241 -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 +13 -8
- moai_adk/core/project/checker.py +2 -4
- moai_adk/core/project/detector.py +189 -22
- moai_adk/core/project/initializer.py +177 -29
- moai_adk/core/project/phase_executor.py +482 -48
- moai_adk/core/project/validator.py +22 -32
- moai_adk/core/quality/__init__.py +1 -1
- moai_adk/core/quality/trust_checker.py +66 -110
- 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 +953 -0
- moai_adk/core/session_manager.py +651 -0
- moai_adk/core/skill_loading_system.py +579 -0
- moai_adk/core/spec_status_manager.py +478 -0
- moai_adk/core/template/__init__.py +0 -1
- moai_adk/core/template/backup.py +168 -21
- moai_adk/core/template/config.py +141 -45
- moai_adk/core/template/languages.py +0 -1
- moai_adk/core/template/merger.py +107 -32
- moai_adk/core/template/processor.py +1075 -74
- moai_adk/core/template_engine.py +319 -0
- moai_adk/core/template_variable_synchronizer.py +431 -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 +477 -0
- moai_adk/foundation/__init__.py +37 -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/__init__.py +376 -0
- moai_adk/foundation/git/commit_templates.py +557 -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/loop/__init__.py +54 -0
- moai_adk/loop/controller.py +305 -0
- moai_adk/loop/feedback.py +230 -0
- moai_adk/loop/state.py +209 -0
- moai_adk/loop/storage.py +220 -0
- moai_adk/lsp/__init__.py +70 -0
- moai_adk/lsp/client.py +320 -0
- moai_adk/lsp/models.py +261 -0
- moai_adk/lsp/protocol.py +404 -0
- moai_adk/lsp/server_manager.py +248 -0
- moai_adk/project/__init__.py +0 -0
- moai_adk/project/configuration.py +1091 -0
- moai_adk/project/documentation.py +566 -0
- moai_adk/project/schema.py +447 -0
- moai_adk/py.typed +0 -0
- moai_adk/ralph/__init__.py +37 -0
- moai_adk/ralph/engine.py +307 -0
- moai_adk/rank/__init__.py +21 -0
- moai_adk/rank/auth.py +425 -0
- moai_adk/rank/client.py +557 -0
- moai_adk/rank/config.py +147 -0
- moai_adk/rank/hook.py +1503 -0
- moai_adk/rank/py.typed +0 -0
- moai_adk/statusline/__init__.py +41 -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 +341 -0
- moai_adk/statusline/memory_collector.py +268 -0
- moai_adk/statusline/metrics_tracker.py +78 -0
- moai_adk/statusline/renderer.py +359 -0
- moai_adk/statusline/update_checker.py +129 -0
- moai_adk/statusline/version_reader.py +741 -0
- moai_adk/tag_system/__init__.py +48 -0
- moai_adk/tag_system/atomic_ops.py +117 -0
- moai_adk/tag_system/linkage.py +335 -0
- moai_adk/tag_system/parser.py +176 -0
- moai_adk/tag_system/validator.py +200 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +490 -0
- moai_adk/templates/.claude/agents/moai/builder-command.md +1218 -0
- moai_adk/templates/.claude/agents/moai/builder-plugin.md +763 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +682 -0
- moai_adk/templates/.claude/agents/moai/expert-backend.md +963 -0
- moai_adk/templates/.claude/agents/moai/expert-debug.md +407 -0
- moai_adk/templates/.claude/agents/moai/expert-devops.md +722 -0
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +748 -0
- moai_adk/templates/.claude/agents/moai/expert-performance.md +661 -0
- moai_adk/templates/.claude/agents/moai/expert-refactoring.md +228 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +525 -0
- moai_adk/templates/.claude/agents/moai/expert-testing.md +737 -0
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +438 -0
- moai_adk/templates/.claude/agents/moai/manager-docs.md +578 -0
- moai_adk/templates/.claude/agents/moai/manager-git.md +1092 -0
- moai_adk/templates/.claude/agents/moai/manager-project.md +971 -0
- moai_adk/templates/.claude/agents/moai/manager-quality.md +641 -0
- moai_adk/templates/.claude/agents/moai/manager-spec.md +815 -0
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +811 -0
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +797 -0
- moai_adk/templates/.claude/commands/moai/0-project.md +438 -0
- moai_adk/templates/.claude/commands/moai/1-plan.md +1447 -0
- moai_adk/templates/.claude/commands/moai/2-run.md +850 -0
- moai_adk/templates/.claude/commands/moai/3-sync.md +1398 -0
- moai_adk/templates/.claude/commands/moai/9-feedback.md +330 -0
- moai_adk/templates/.claude/commands/moai/alfred.md +339 -0
- moai_adk/templates/.claude/commands/moai/cancel-loop.md +163 -0
- moai_adk/templates/.claude/commands/moai/fix.md +264 -0
- moai_adk/templates/.claude/commands/moai/loop.md +363 -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/README.md +143 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +41 -0
- moai_adk/templates/.claude/hooks/moai/lib/alfred_detector.py +105 -0
- moai_adk/templates/.claude/hooks/moai/lib/atomic_write.py +122 -0
- moai_adk/templates/.claude/hooks/{alfred/core → moai/lib}/checkpoint.py +13 -37
- moai_adk/templates/.claude/hooks/moai/lib/common.py +161 -0
- moai_adk/templates/.claude/hooks/moai/lib/config.py +376 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +442 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
- moai_adk/templates/.claude/hooks/moai/lib/enhanced_output_style_detector.py +372 -0
- moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
- moai_adk/templates/.claude/hooks/moai/lib/exceptions.py +171 -0
- moai_adk/templates/.claude/hooks/moai/lib/file_utils.py +95 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_collector.py +190 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +592 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_detector.py +298 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +417 -0
- moai_adk/templates/.claude/hooks/moai/lib/main.py +341 -0
- moai_adk/templates/.claude/hooks/moai/lib/memory_collector.py +268 -0
- moai_adk/templates/.claude/hooks/moai/lib/metrics_tracker.py +78 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +104 -0
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +219 -0
- moai_adk/templates/.claude/hooks/moai/lib/project.py +777 -0
- moai_adk/templates/.claude/hooks/moai/lib/renderer.py +359 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_linkage.py +333 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_parser.py +176 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_validator.py +200 -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/tool_registry.py +896 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +542 -0
- moai_adk/templates/.claude/hooks/moai/lib/update_checker.py +129 -0
- moai_adk/templates/.claude/hooks/moai/lib/version_reader.py +741 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__ast_grep_scan.py +276 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__code_formatter.py +255 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__coverage_guard.py +325 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__linter.py +315 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__lsp_diagnostic.py +508 -0
- moai_adk/templates/.claude/hooks/moai/pre_commit__tag_validator.py +287 -0
- moai_adk/templates/.claude/hooks/moai/pre_tool__security_guard.py +268 -0
- moai_adk/templates/.claude/hooks/moai/pre_tool__tdd_enforcer.py +208 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +894 -0
- moai_adk/templates/.claude/hooks/moai/session_end__rank_submit.py +69 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +1170 -0
- moai_adk/templates/.claude/hooks/moai/shared/utils/announcement_translator.py +206 -0
- moai_adk/templates/.claude/hooks/moai/stop__loop_controller.py +621 -0
- moai_adk/templates/.claude/output-styles/moai/alfred.md +758 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +643 -0
- moai_adk/templates/.claude/output-styles/moai/yoda.md +359 -0
- moai_adk/templates/.claude/settings.json +177 -72
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +303 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +252 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +56 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +120 -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 +185 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +207 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +234 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +132 -281
- 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 +133 -77
- 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 +91 -78
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +955 -16
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/component-architecture.md +723 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/nextjs16-patterns.md +713 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/performance-optimization.md +694 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/react19-patterns.md +591 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/state-management.md +680 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/vue35-patterns.md +802 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +651 -18
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +234 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +189 -0
- moai_adk/templates/.claude/skills/moai-formats-data/examples.md +804 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +327 -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 +225 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/examples.md +732 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/advanced-agent-patterns.md +370 -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-cli-reference-official.md +420 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +739 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-devcontainers-official.md +381 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-discover-plugins-official.md +379 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-headless-official.md +378 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +670 -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-plugin-marketplaces-official.md +308 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugins-official.md +640 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sandboxing-official.md +282 -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 +467 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-statusline-official.md +293 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +420 -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 +221 -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 +242 -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-advanced.md +279 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-implementation.md +267 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +228 -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/patterns.md +22 -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-ears-format.md +200 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +171 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-tdd-implementation.md +275 -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 +239 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-implementation.md +244 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-validation.md +219 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/reference.md +478 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +311 -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 +180 -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-framework-electron/SKILL.md +288 -0
- moai_adk/templates/.claude/skills/moai-framework-electron/examples.md +2082 -0
- moai_adk/templates/.claude/skills/moai-framework-electron/reference.md +1649 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +96 -77
- moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +1226 -16
- moai_adk/templates/.claude/skills/moai-lang-cpp/modules/advanced-patterns.md +401 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +1119 -14
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +80 -79
- moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +572 -16
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/aspnet-core.md +627 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/blazor-components.md +767 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/cqrs-validation.md +626 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/csharp12-features.md +580 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/efcore-patterns.md +622 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +388 -15
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +135 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/examples.md +1171 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/modules/advanced-patterns.md +531 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/reference.md +889 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +104 -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 +153 -80
- 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 +117 -80
- 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-javascript/SKILL.md +133 -79
- moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +960 -16
- moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +1528 -17
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +100 -79
- 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 +135 -76
- moai_adk/templates/.claude/skills/moai-lang-php/examples.md +1595 -16
- moai_adk/templates/.claude/skills/moai-lang-php/modules/advanced-patterns.md +538 -0
- moai_adk/templates/.claude/skills/moai-lang-php/reference.md +1309 -16
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +141 -341
- 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 +134 -76
- moai_adk/templates/.claude/skills/moai-lang-r/examples.md +1141 -16
- moai_adk/templates/.claude/skills/moai-lang-r/modules/advanced-patterns.md +489 -0
- moai_adk/templates/.claude/skills/moai-lang-r/reference.md +1074 -17
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +136 -77
- moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +1093 -16
- moai_adk/templates/.claude/skills/moai-lang-ruby/modules/advanced-patterns.md +309 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/modules/testing-patterns.md +306 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +1010 -17
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +112 -78
- 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 +113 -75
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +620 -16
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/akka-actors.md +479 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/cats-effect.md +489 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/functional-programming.md +460 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/spark-data.md +498 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/zio-patterns.md +541 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +410 -17
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +88 -83
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +905 -16
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/combine-reactive.md +256 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/concurrency.md +270 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/swift6-features.md +265 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/swiftui-patterns.md +314 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +659 -17
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +115 -82
- 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 +145 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/modules/advanced-patterns.md +465 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/modules/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 +143 -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 +336 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +350 -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/modules/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 +175 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +284 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/examples.md +2446 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/adaptive-mfa.md +233 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/akamai-integration.md +214 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/application-credentials.md +280 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-log-events.md +224 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-overview.md +140 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/bot-detection.md +144 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/breached-password-detection.md +187 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/brute-force-protection.md +189 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/certifications.md +282 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/compliance-overview.md +263 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/continuous-session-protection.md +307 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/customize-mfa.md +177 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/dpop-implementation.md +283 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/fapi-implementation.md +259 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/gdpr-compliance.md +313 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/guardian-configuration.md +269 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/highly-regulated-identity.md +272 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/jwt-fundamentals.md +248 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mdl-verification.md +210 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-api-management.md +278 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-factors.md +226 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-overview.md +174 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mtls-sender-constraining.md +316 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/ropg-flow-mfa.md +216 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-center.md +325 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-guidance.md +277 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/state-parameters.md +177 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/step-up-authentication.md +251 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/suspicious-ip-throttling.md +240 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/tenant-access-control.md +179 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/webauthn-fido.md +235 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/reference.md +224 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +135 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/examples.md +1426 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/modules/advanced-patterns.md +417 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/reference.md +273 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +158 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/examples.md +506 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/auth-integration.md +421 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/file-storage.md +474 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/reactive-queries.md +302 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/server-functions.md +452 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/reference.md +385 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +166 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/examples.md +514 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/custom-claims.md +374 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/phone-auth.md +372 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/social-auth.md +339 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/reference.md +382 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +127 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/examples.md +445 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/offline-cache.md +392 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/realtime-listeners.md +441 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/security-rules.md +352 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/transactions.md +452 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/reference.md +322 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +156 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/examples.md +470 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/auto-scaling.md +349 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/branching-workflows.md +354 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/connection-pooling.md +412 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/pitr-backups.md +458 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/reference.md +272 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +146 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/examples.md +539 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/docker-deployment.md +261 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/multi-service.md +291 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/networking-domains.md +338 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/volumes-storage.md +353 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/reference.md +374 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +141 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/examples.md +502 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/auth-integration.md +384 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/edge-functions.md +371 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/postgresql-pgvector.md +231 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/realtime-presence.md +354 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/row-level-security.md +286 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/storage-cdn.md +319 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/typescript-patterns.md +453 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/reference.md +284 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +132 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/examples.md +502 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/analytics-speed.md +348 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/deployment-config.md +344 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/edge-functions.md +222 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/isr-caching.md +306 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/kv-storage.md +399 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/reference.md +360 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/SKILL.md +193 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/examples.md +1099 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/language-specific.md +307 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/pattern-syntax.md +237 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/refactoring-patterns.md +260 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/security-rules.md +239 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/reference.md +288 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/go.yml +90 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/python.yml +101 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/typescript.yml +83 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/complexity-check.yml +94 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/deprecated-apis.yml +84 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/secrets-detection.yml +89 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/sql-injection.yml +45 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/xss-prevention.yml +50 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/sgconfig.yml +54 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +251 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/examples.md +544 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/modules/advanced-patterns.md +379 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/modules/optimization.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/reference.md +307 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/SKILL.md +197 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/examples.md +1063 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/reference.md +1414 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +287 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples.md +547 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/reference.md +275 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1434 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +92 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +337 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/examples.md +900 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/modules/advanced-patterns.md +237 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/reference.md +704 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +270 -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 +269 -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 +269 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/advanced-patterns.md +576 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +302 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/context7-integration.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/review-workflows.md +500 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/relevance-analysis.md +154 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/safety-analysis.md +148 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/scoring-algorithms.md +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/timeliness-analysis.md +168 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/truthfulness-analysis.md +136 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/usability-analysis.md +153 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework.md +257 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +263 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/analysis-patterns.md +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/core-classes.md +299 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/tool-integration.md +380 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/debugging-workflows.md +451 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/error-analysis.md +442 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/optimization.md +505 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/optimization-patterns.md +473 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/profiling-techniques.md +481 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/ai-optimization.md +241 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/bottleneck-detection.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/optimization-plan.md +315 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/profiler-core.md +277 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/real-time-monitoring.md +187 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +327 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/quality-metrics.md +415 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/ai-workflows.md +620 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/patterns.md +692 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/security-analysis.md +429 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +313 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/static-analysis.md +438 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd/core-classes.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/advanced-features.md +494 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/red-green-refactor.md +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-generation.md +471 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-patterns.md +371 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +265 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/trust5-validation.md +428 -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-workflow-worktree/SKILL.md +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/examples.md +606 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/integration-patterns.md +149 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/moai-adk-integration.md +245 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-advanced.md +310 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-development.md +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-workflows.md +302 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/registry-architecture.md +271 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/resource-optimization.md +300 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/tools-integration.md +280 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/troubleshooting.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-commands.md +296 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-management.md +217 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/reference.md +357 -0
- moai_adk/templates/.git-hooks/pre-commit +128 -0
- moai_adk/templates/.git-hooks/pre-push +468 -0
- moai_adk/templates/.github/workflows/ci-universal.yml +1314 -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 +152 -13
- moai_adk/templates/.lsp.json +152 -0
- moai_adk/templates/.mcp.json +13 -0
- moai_adk/templates/.moai/announcements/en.json +18 -0
- moai_adk/templates/.moai/announcements/ja.json +18 -0
- moai_adk/templates/.moai/announcements/ko.json +18 -0
- moai_adk/templates/.moai/announcements/zh.json +18 -0
- moai_adk/templates/.moai/config/config.yaml +64 -0
- moai_adk/templates/.moai/config/multilingual-triggers.yaml +213 -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/llm.yaml +41 -0
- moai_adk/templates/.moai/config/sections/pricing.yaml +30 -0
- moai_adk/templates/.moai/config/sections/project.yaml +13 -0
- moai_adk/templates/.moai/config/sections/quality.yaml +55 -0
- moai_adk/templates/.moai/config/sections/ralph.yaml +55 -0
- moai_adk/templates/.moai/config/sections/system.yaml +59 -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/llm-configs/glm.json +22 -0
- moai_adk/templates/CLAUDE.ja.md +343 -0
- moai_adk/templates/CLAUDE.ko.md +343 -0
- moai_adk/templates/CLAUDE.md +274 -246
- moai_adk/templates/CLAUDE.zh.md +343 -0
- moai_adk/utils/__init__.py +24 -2
- moai_adk/utils/banner.py +9 -13
- moai_adk/utils/common.py +331 -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-1.1.0.dist-info/METADATA +2443 -0
- moai_adk-1.1.0.dist-info/RECORD +701 -0
- {moai_adk-0.8.0.dist-info → moai_adk-1.1.0.dist-info}/WHEEL +1 -1
- moai_adk-1.1.0.dist-info/entry_points.txt +5 -0
- moai_adk-1.1.0.dist-info/licenses/LICENSE +99 -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-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-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/entry_points.txt +0 -2
- moai_adk-0.8.0.dist-info/licenses/LICENSE +0 -21
|
@@ -1,85 +1,577 @@
|
|
|
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 = [
|
|
23
85
|
".moai/specs/", # User SPEC documents
|
|
24
86
|
".moai/reports/", # User reports
|
|
25
87
|
".moai/project/", # User project documents (product/structure/tech.md)
|
|
26
|
-
#
|
|
27
|
-
#
|
|
88
|
+
".moai/config/sections/", # User configuration section files (YAML)
|
|
89
|
+
# config.json/config.yaml is now FORCE OVERWRITTEN (backup in .moai-backups/)
|
|
90
|
+
# Merge via /moai:0-project when optimized=false
|
|
28
91
|
]
|
|
29
92
|
|
|
30
93
|
# Paths excluded from backups
|
|
31
94
|
BACKUP_EXCLUDE = PROTECTED_PATHS
|
|
32
95
|
|
|
33
|
-
|
|
34
|
-
|
|
96
|
+
# Common template variables with validation hints
|
|
97
|
+
COMMON_TEMPLATE_VARIABLES = {
|
|
98
|
+
"PROJECT_DIR": "Cross-platform project path (run /moai:0-project to set)",
|
|
99
|
+
"PROJECT_NAME": "Project name (run /moai:0-project to set)",
|
|
100
|
+
"AUTHOR": "Project author (run /moai:0-project to set)",
|
|
101
|
+
"CONVERSATION_LANGUAGE": "Interface language (run /moai:0-project to set)",
|
|
102
|
+
"MOAI_VERSION": "MoAI-ADK version (should be set automatically)",
|
|
103
|
+
"MOAI_VERSION_SHORT": "Short MoAI-ADK version (without 'v' prefix)",
|
|
104
|
+
"MOAI_VERSION_DISPLAY": "Display version with proper formatting",
|
|
105
|
+
"MOAI_VERSION_TRIMMED": "Trimmed version for UI displays",
|
|
106
|
+
"MOAI_VERSION_SEMVER": "Semantic version format (major.minor.patch)",
|
|
107
|
+
"MOAI_VERSION_VALID": "Version validation status",
|
|
108
|
+
"MOAI_VERSION_SOURCE": "Version source information",
|
|
109
|
+
"MOAI_VERSION_CACHE_AGE": "Cache age for debugging",
|
|
110
|
+
"CREATION_TIMESTAMP": "Project creation timestamp",
|
|
111
|
+
"STATUSLINE_COMMAND": "Cross-platform statusline command (OS-specific)",
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
def __init__(self, target_path: Path, config: Optional[TemplateProcessorConfig] = None) -> None:
|
|
115
|
+
"""Initialize the processor with enhanced configuration.
|
|
35
116
|
|
|
36
117
|
Args:
|
|
37
118
|
target_path: Project path.
|
|
119
|
+
config: Optional configuration for processor behavior.
|
|
38
120
|
"""
|
|
39
121
|
self.target_path = target_path.resolve()
|
|
40
122
|
self.template_root = self._get_template_root()
|
|
41
123
|
self.backup = TemplateBackup(self.target_path)
|
|
42
124
|
self.merger = TemplateMerger(self.target_path)
|
|
43
125
|
self.context: dict[str, str] = {} # Template variable substitution context
|
|
126
|
+
self._version_reader: VersionReader | None = None
|
|
127
|
+
self.config = config or TemplateProcessorConfig()
|
|
128
|
+
self._substitution_cache: Dict[
|
|
129
|
+
int, tuple[str, list[str]]
|
|
130
|
+
] = {} # Cache for substitution results (key: hash, value: (content, warnings))
|
|
131
|
+
self._variable_validation_cache: Dict[str, bool] = {} # Cache for variable validation
|
|
132
|
+
self.logger = logging.getLogger(__name__)
|
|
44
133
|
|
|
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"
|
|
134
|
+
if self.config.verbose_logging:
|
|
135
|
+
self.logger.info(f"TemplateProcessor initialized with config: {self.config}")
|
|
51
136
|
|
|
52
137
|
def set_context(self, context: dict[str, str]) -> None:
|
|
53
|
-
"""Set variable substitution context.
|
|
138
|
+
"""Set variable substitution context with enhanced validation.
|
|
54
139
|
|
|
55
140
|
Args:
|
|
56
141
|
context: Dictionary of template variables.
|
|
57
142
|
"""
|
|
58
143
|
self.context = context
|
|
144
|
+
self._substitution_cache.clear() # Clear cache when context changes
|
|
145
|
+
self._variable_validation_cache.clear()
|
|
146
|
+
|
|
147
|
+
if self.config.verbose_logging:
|
|
148
|
+
self.logger.debug(f"Context set with {len(context)} variables")
|
|
149
|
+
|
|
150
|
+
# Validate template variables if enabled
|
|
151
|
+
if self.config.validate_template_variables:
|
|
152
|
+
self._validate_template_variables(context)
|
|
153
|
+
|
|
154
|
+
# Add deprecation mapping for HOOK_PROJECT_DIR
|
|
155
|
+
if "PROJECT_DIR" in self.context and "HOOK_PROJECT_DIR" not in self.context:
|
|
156
|
+
self.context["HOOK_PROJECT_DIR"] = self.context["PROJECT_DIR"]
|
|
157
|
+
|
|
158
|
+
def _get_version_reader(self) -> VersionReader:
|
|
159
|
+
"""
|
|
160
|
+
Get or create version reader instance with enhanced configuration.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
VersionReader instance
|
|
164
|
+
"""
|
|
165
|
+
if self._version_reader is None:
|
|
166
|
+
version_config = VersionConfig(
|
|
167
|
+
cache_ttl_seconds=self.config.version_cache_ttl_seconds,
|
|
168
|
+
fallback_version=self.config.version_fallback,
|
|
169
|
+
version_format_regex=self.config.version_format_regex,
|
|
170
|
+
debug_mode=self.config.verbose_logging,
|
|
171
|
+
)
|
|
172
|
+
self._version_reader = VersionReader(version_config)
|
|
173
|
+
|
|
174
|
+
if self.config.verbose_logging:
|
|
175
|
+
self.logger.info("VersionReader created with enhanced configuration")
|
|
176
|
+
return self._version_reader
|
|
177
|
+
|
|
178
|
+
def _get_current_version(self) -> Optional[str]:
|
|
179
|
+
"""
|
|
180
|
+
Get the current MoAI-ADK package version.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
Current version string, or None if version cannot be determined
|
|
184
|
+
"""
|
|
185
|
+
try:
|
|
186
|
+
version_reader = self._get_version_reader()
|
|
187
|
+
version = version_reader.get_version()
|
|
188
|
+
if version and version != "unknown":
|
|
189
|
+
return version
|
|
190
|
+
except Exception as e:
|
|
191
|
+
self.logger.warning(f"Failed to get current version: {e}")
|
|
192
|
+
|
|
193
|
+
# Fallback: try direct import
|
|
194
|
+
try:
|
|
195
|
+
from moai_adk import __version__
|
|
196
|
+
|
|
197
|
+
return __version__
|
|
198
|
+
except ImportError:
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
return None
|
|
202
|
+
|
|
203
|
+
def _validate_template_variables(self, context: Dict[str, str]) -> None:
|
|
204
|
+
"""
|
|
205
|
+
Validate template variables with comprehensive checking.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
context: Dictionary of template variables to validate
|
|
209
|
+
"""
|
|
210
|
+
import re
|
|
211
|
+
|
|
212
|
+
if not self.config.validate_template_variables:
|
|
213
|
+
return
|
|
214
|
+
|
|
215
|
+
validation_errors: List[str] = []
|
|
216
|
+
warning_messages: List[str] = []
|
|
217
|
+
|
|
218
|
+
# Check variable names against pattern
|
|
219
|
+
variable_pattern = re.compile(self.config.allowed_variable_pattern)
|
|
220
|
+
|
|
221
|
+
for var_name, var_value in context.items():
|
|
222
|
+
# Check variable name format
|
|
223
|
+
if not variable_pattern.match(var_name):
|
|
224
|
+
validation_errors.append(f"Invalid variable name format: '{var_name}'")
|
|
225
|
+
continue
|
|
226
|
+
|
|
227
|
+
# Check variable length
|
|
228
|
+
if len(var_name) > self.config.max_variable_length:
|
|
229
|
+
warning_messages.append(f"Variable name '{var_name}' exceeds maximum length")
|
|
230
|
+
|
|
231
|
+
# Check variable value length
|
|
232
|
+
if len(var_value) > self.config.max_variable_length * 2:
|
|
233
|
+
warning_messages.append(f"Variable value '{var_value[:20]}...' is very long")
|
|
234
|
+
|
|
235
|
+
# Check for potentially dangerous values
|
|
236
|
+
if "{{" in var_value or "}}" in var_value:
|
|
237
|
+
warning_messages.append(f"Variable '{var_name}' contains placeholder patterns")
|
|
238
|
+
|
|
239
|
+
# Check for common variables that should be present
|
|
240
|
+
missing_common_vars = []
|
|
241
|
+
for common_var in self.COMMON_TEMPLATE_VARIABLES:
|
|
242
|
+
if common_var not in context:
|
|
243
|
+
missing_common_vars.append(common_var)
|
|
244
|
+
|
|
245
|
+
if missing_common_vars and self.config.enable_substitution_warnings:
|
|
246
|
+
warning_messages.append(f"Common variables missing: {', '.join(missing_common_vars[:3])}")
|
|
247
|
+
|
|
248
|
+
# Report validation results
|
|
249
|
+
if validation_errors and not self.config.graceful_degradation:
|
|
250
|
+
raise ValueError(f"Template variable validation failed: {validation_errors}")
|
|
251
|
+
|
|
252
|
+
if validation_errors and self.config.graceful_degradation:
|
|
253
|
+
self.logger.warning(f"Template variable validation warnings: {validation_errors}")
|
|
254
|
+
|
|
255
|
+
if warning_messages and self.config.enable_substitution_warnings:
|
|
256
|
+
self.logger.warning(f"Template variable warnings: {warning_messages}")
|
|
257
|
+
|
|
258
|
+
if self.config.verbose_logging:
|
|
259
|
+
self.logger.debug(f"Template variables validated: {len(context)} variables checked")
|
|
260
|
+
|
|
261
|
+
def get_enhanced_version_context(self) -> dict[str, str]:
|
|
262
|
+
"""
|
|
263
|
+
Get enhanced version context with proper error handling and caching.
|
|
264
|
+
|
|
265
|
+
Returns comprehensive version information including multiple format options
|
|
266
|
+
and debugging information.
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
Dictionary containing enhanced version-related template variables
|
|
270
|
+
"""
|
|
271
|
+
version_context = {}
|
|
272
|
+
logger = logging.getLogger(__name__)
|
|
273
|
+
|
|
274
|
+
try:
|
|
275
|
+
version_reader = self._get_version_reader()
|
|
276
|
+
moai_version = version_reader.get_version()
|
|
277
|
+
|
|
278
|
+
# Basic version information
|
|
279
|
+
version_context["MOAI_VERSION"] = moai_version
|
|
280
|
+
version_context["MOAI_VERSION_SHORT"] = self._format_short_version(moai_version)
|
|
281
|
+
version_context["MOAI_VERSION_DISPLAY"] = self._format_display_version(moai_version)
|
|
282
|
+
|
|
283
|
+
# Enhanced formatting options
|
|
284
|
+
version_context["MOAI_VERSION_TRIMMED"] = self._format_trimmed_version(moai_version, max_length=10)
|
|
285
|
+
version_context["MOAI_VERSION_SEMVER"] = self._format_semver_version(moai_version)
|
|
286
|
+
|
|
287
|
+
# Validation and source information
|
|
288
|
+
version_context["MOAI_VERSION_VALID"] = "true" if moai_version != "unknown" else "false"
|
|
289
|
+
version_context["MOAI_VERSION_SOURCE"] = self._get_version_source(version_reader)
|
|
290
|
+
|
|
291
|
+
# Performance metrics
|
|
292
|
+
cache_age = version_reader.get_cache_age_seconds()
|
|
293
|
+
if cache_age is not None:
|
|
294
|
+
version_context["MOAI_VERSION_CACHE_AGE"] = f"{cache_age:.2f}s"
|
|
295
|
+
else:
|
|
296
|
+
version_context["MOAI_VERSION_CACHE_AGE"] = "uncached"
|
|
297
|
+
|
|
298
|
+
# Additional metadata
|
|
299
|
+
if self.config.enable_version_validation:
|
|
300
|
+
is_valid = self._is_valid_version_format(moai_version)
|
|
301
|
+
version_context["MOAI_VERSION_FORMAT_VALID"] = "true" if is_valid else "false"
|
|
302
|
+
|
|
303
|
+
if self.config.verbose_logging:
|
|
304
|
+
logger.debug(f"Enhanced version context generated: {version_context}")
|
|
305
|
+
|
|
306
|
+
except Exception as e:
|
|
307
|
+
logger.warning(f"Failed to read version for template context: {e}")
|
|
308
|
+
# Use fallback version with comprehensive formatting
|
|
309
|
+
fallback_version = self.config.version_fallback
|
|
310
|
+
version_context["MOAI_VERSION"] = fallback_version
|
|
311
|
+
version_context["MOAI_VERSION_SHORT"] = self._format_short_version(fallback_version)
|
|
312
|
+
version_context["MOAI_VERSION_DISPLAY"] = self._format_display_version(fallback_version)
|
|
313
|
+
version_context["MOAI_VERSION_TRIMMED"] = self._format_trimmed_version(fallback_version, max_length=10)
|
|
314
|
+
version_context["MOAI_VERSION_SEMVER"] = self._format_semver_version(fallback_version)
|
|
315
|
+
version_context["MOAI_VERSION_VALID"] = "false" if fallback_version == "unknown" else "true"
|
|
316
|
+
version_context["MOAI_VERSION_SOURCE"] = "fallback_config"
|
|
317
|
+
version_context["MOAI_VERSION_CACHE_AGE"] = "unavailable"
|
|
318
|
+
version_context["MOAI_VERSION_FORMAT_VALID"] = "false"
|
|
319
|
+
|
|
320
|
+
return version_context
|
|
321
|
+
|
|
322
|
+
def _is_valid_version_format(self, version: str) -> bool:
|
|
323
|
+
"""
|
|
324
|
+
Validate version format using configured regex pattern.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
version: Version string to validate
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
True if version format is valid
|
|
331
|
+
"""
|
|
332
|
+
import re
|
|
333
|
+
|
|
334
|
+
try:
|
|
335
|
+
pattern = re.compile(self.config.version_format_regex)
|
|
336
|
+
return bool(pattern.match(version))
|
|
337
|
+
except re.error:
|
|
338
|
+
# Fallback to default pattern if custom one is invalid
|
|
339
|
+
default_pattern = re.compile(r"^v?(\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)$")
|
|
340
|
+
return bool(default_pattern.match(version))
|
|
341
|
+
|
|
342
|
+
def _format_short_version(self, version: str) -> str:
|
|
343
|
+
"""
|
|
344
|
+
Format short version by removing 'v' prefix if present.
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
version: Version string
|
|
348
|
+
|
|
349
|
+
Returns:
|
|
350
|
+
Short version string
|
|
351
|
+
"""
|
|
352
|
+
return version[1:] if version.startswith("v") else version
|
|
353
|
+
|
|
354
|
+
def _format_display_version(self, version: str) -> str:
|
|
355
|
+
"""
|
|
356
|
+
Format display version with proper formatting.
|
|
357
|
+
|
|
358
|
+
Args:
|
|
359
|
+
version: Version string
|
|
360
|
+
|
|
361
|
+
Returns:
|
|
362
|
+
Display version string
|
|
363
|
+
"""
|
|
364
|
+
if version == "unknown":
|
|
365
|
+
return "MoAI-ADK unknown version"
|
|
366
|
+
elif version.startswith("v"):
|
|
367
|
+
return f"MoAI-ADK {version}"
|
|
368
|
+
else:
|
|
369
|
+
return f"MoAI-ADK v{version}"
|
|
370
|
+
|
|
371
|
+
def _format_trimmed_version(self, version: str, max_length: int = 10) -> str:
|
|
372
|
+
"""
|
|
373
|
+
Format version with maximum length, suitable for UI displays.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
version: Version string
|
|
377
|
+
max_length: Maximum allowed length for the version string
|
|
378
|
+
|
|
379
|
+
Returns:
|
|
380
|
+
Trimmed version string
|
|
381
|
+
"""
|
|
382
|
+
if version == "unknown":
|
|
383
|
+
return "unknown"
|
|
384
|
+
|
|
385
|
+
# Remove 'v' prefix for trimming
|
|
386
|
+
clean_version = version[1:] if version.startswith("v") else version
|
|
387
|
+
|
|
388
|
+
# Trim if necessary
|
|
389
|
+
if len(clean_version) > max_length:
|
|
390
|
+
return clean_version[:max_length]
|
|
391
|
+
return clean_version
|
|
392
|
+
|
|
393
|
+
def _format_semver_version(self, version: str) -> str:
|
|
394
|
+
"""
|
|
395
|
+
Format version as semantic version with major.minor.patch structure.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
version: Version string
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
Semantic version string
|
|
402
|
+
"""
|
|
403
|
+
if version == "unknown":
|
|
404
|
+
return "0.0.0"
|
|
405
|
+
|
|
406
|
+
# Remove 'v' prefix and extract semantic version
|
|
407
|
+
clean_version = version[1:] if version.startswith("v") else version
|
|
408
|
+
|
|
409
|
+
# Extract core semantic version (remove pre-release and build metadata)
|
|
410
|
+
import re
|
|
411
|
+
|
|
412
|
+
semver_match = re.match(r"^(\d+\.\d+\.\d+)", clean_version)
|
|
413
|
+
if semver_match:
|
|
414
|
+
return semver_match.group(1)
|
|
415
|
+
return "0.0.0"
|
|
416
|
+
|
|
417
|
+
def _get_version_source(self, version_reader: VersionReader) -> str:
|
|
418
|
+
"""
|
|
419
|
+
Determine the source of the version information.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
version_reader: VersionReader instance
|
|
423
|
+
|
|
424
|
+
Returns:
|
|
425
|
+
String indicating version source
|
|
426
|
+
"""
|
|
427
|
+
config = version_reader.get_config()
|
|
428
|
+
cache_age = version_reader.get_cache_age_seconds()
|
|
429
|
+
|
|
430
|
+
if cache_age is not None and cache_age < config.cache_ttl_seconds:
|
|
431
|
+
return "config_cached"
|
|
432
|
+
elif cache_age is not None:
|
|
433
|
+
return "config_stale"
|
|
434
|
+
else:
|
|
435
|
+
return config.fallback_source.value
|
|
436
|
+
|
|
437
|
+
def _get_template_root(self) -> Path:
|
|
438
|
+
"""Return the template root path."""
|
|
439
|
+
# src/moai_adk/core/template/processor.py → src/moai_adk/templates/
|
|
440
|
+
current_file = Path(__file__).resolve()
|
|
441
|
+
package_root = current_file.parent.parent.parent
|
|
442
|
+
return package_root / "templates"
|
|
59
443
|
|
|
60
444
|
def _substitute_variables(self, content: str) -> tuple[str, list[str]]:
|
|
61
|
-
"""
|
|
445
|
+
"""
|
|
446
|
+
Substitute template variables in content with enhanced validation and caching.
|
|
447
|
+
|
|
448
|
+
Args:
|
|
449
|
+
content: Content to substitute variables in
|
|
62
450
|
|
|
63
451
|
Returns:
|
|
64
452
|
Tuple of (substituted_content, warnings_list)
|
|
65
453
|
"""
|
|
66
454
|
warnings = []
|
|
67
|
-
|
|
68
|
-
|
|
455
|
+
logger = logging.getLogger(__name__)
|
|
456
|
+
|
|
457
|
+
# Check cache first if enabled
|
|
458
|
+
cache_key = hash((frozenset(self.context.items()), content[:1000]))
|
|
459
|
+
if self.config.enable_caching and cache_key in self._substitution_cache:
|
|
460
|
+
cached_result = self._substitution_cache[cache_key]
|
|
461
|
+
if self.config.verbose_logging:
|
|
462
|
+
logger.debug("Using cached substitution result")
|
|
463
|
+
return cached_result
|
|
464
|
+
|
|
465
|
+
# Enhanced variable substitution with validation
|
|
466
|
+
substitution_count = 0
|
|
69
467
|
for key, value in self.context.items():
|
|
70
468
|
placeholder = f"{{{{{key}}}}}" # {{KEY}}
|
|
71
469
|
if placeholder in content:
|
|
470
|
+
if self.config.validate_template_variables:
|
|
471
|
+
# Validate variable before substitution
|
|
472
|
+
if not self._is_valid_template_variable(key, value):
|
|
473
|
+
warnings.append(f"Invalid variable {key} - skipped substitution")
|
|
474
|
+
continue
|
|
475
|
+
|
|
72
476
|
safe_value = self._sanitize_value(value)
|
|
73
477
|
content = content.replace(placeholder, safe_value)
|
|
478
|
+
substitution_count += 1
|
|
74
479
|
|
|
75
|
-
|
|
76
|
-
|
|
480
|
+
if self.config.verbose_logging:
|
|
481
|
+
logger.debug(f"Substituted {key}: {safe_value[:50]}...")
|
|
482
|
+
|
|
483
|
+
# Detect unsubstituted variables with enhanced error messages
|
|
484
|
+
remaining = re.findall(r"\{\{([A-Z_]+)\}\}", content)
|
|
77
485
|
if remaining:
|
|
78
486
|
unique_remaining = sorted(set(remaining))
|
|
79
|
-
|
|
487
|
+
|
|
488
|
+
# Build detailed warning message with enhanced suggestions
|
|
489
|
+
warning_parts = []
|
|
490
|
+
for var in unique_remaining:
|
|
491
|
+
if var in self.COMMON_TEMPLATE_VARIABLES:
|
|
492
|
+
suggestion = self.COMMON_TEMPLATE_VARIABLES[var]
|
|
493
|
+
warning_parts.append(f"{{{{{var}}}}} → {suggestion}")
|
|
494
|
+
else:
|
|
495
|
+
warning_parts.append(f"{{{{{var}}}}} → Unknown variable (check template)")
|
|
496
|
+
|
|
497
|
+
warnings.append("Template variables not substituted:")
|
|
498
|
+
warnings.extend(f" • {part}" for part in warning_parts)
|
|
499
|
+
|
|
500
|
+
if self.config.enable_substitution_warnings:
|
|
501
|
+
warnings.append("💡 Run 'uv run moai-adk update' to fix template variables")
|
|
502
|
+
|
|
503
|
+
# Add performance information if verbose logging is enabled
|
|
504
|
+
if self.config.verbose_logging:
|
|
505
|
+
warnings.append(f" 📊 Substituted {substitution_count} variables")
|
|
506
|
+
|
|
507
|
+
# Cache the result if enabled
|
|
508
|
+
if self.config.enable_caching:
|
|
509
|
+
result = (content, warnings)
|
|
510
|
+
self._substitution_cache[cache_key] = result
|
|
511
|
+
|
|
512
|
+
# Manage cache size
|
|
513
|
+
if len(self._substitution_cache) > self.config.cache_size:
|
|
514
|
+
# Remove oldest entry (simple FIFO)
|
|
515
|
+
oldest_key = next(iter(self._substitution_cache))
|
|
516
|
+
del self._substitution_cache[oldest_key]
|
|
517
|
+
if self.config.verbose_logging:
|
|
518
|
+
logger.debug("Cache size limit reached, removed oldest entry")
|
|
80
519
|
|
|
81
520
|
return content, warnings
|
|
82
521
|
|
|
522
|
+
def _is_valid_template_variable(self, key: str, value: str) -> bool:
|
|
523
|
+
"""
|
|
524
|
+
Validate a template variable before substitution.
|
|
525
|
+
|
|
526
|
+
Args:
|
|
527
|
+
key: Variable name
|
|
528
|
+
value: Variable value
|
|
529
|
+
|
|
530
|
+
Returns:
|
|
531
|
+
True if variable is valid
|
|
532
|
+
"""
|
|
533
|
+
import re
|
|
534
|
+
|
|
535
|
+
# Check variable name format
|
|
536
|
+
if not re.match(self.config.allowed_variable_pattern, key):
|
|
537
|
+
return False
|
|
538
|
+
|
|
539
|
+
# Check variable length
|
|
540
|
+
if len(key) > self.config.max_variable_length:
|
|
541
|
+
return False
|
|
542
|
+
|
|
543
|
+
# Check value length
|
|
544
|
+
if len(value) > self.config.max_variable_length * 2:
|
|
545
|
+
return False
|
|
546
|
+
|
|
547
|
+
# Note: {{ }} patterns are handled by sanitization, not validation
|
|
548
|
+
|
|
549
|
+
# Check for empty values
|
|
550
|
+
if not value.strip():
|
|
551
|
+
return False
|
|
552
|
+
|
|
553
|
+
return True
|
|
554
|
+
|
|
555
|
+
def clear_substitution_cache(self) -> None:
|
|
556
|
+
"""Clear the substitution cache."""
|
|
557
|
+
self._substitution_cache.clear()
|
|
558
|
+
if self.config.verbose_logging:
|
|
559
|
+
self.logger.debug("Substitution cache cleared")
|
|
560
|
+
|
|
561
|
+
def get_cache_stats(self) -> Dict[str, Any]:
|
|
562
|
+
"""
|
|
563
|
+
Get cache statistics.
|
|
564
|
+
|
|
565
|
+
Returns:
|
|
566
|
+
Dictionary containing cache statistics
|
|
567
|
+
"""
|
|
568
|
+
return {
|
|
569
|
+
"cache_size": len(self._substitution_cache),
|
|
570
|
+
"max_cache_size": self.config.cache_size,
|
|
571
|
+
"cache_enabled": self.config.enable_caching,
|
|
572
|
+
"cache_hit_ratio": 0.0, # Would need to track hits to implement this
|
|
573
|
+
}
|
|
574
|
+
|
|
83
575
|
def _sanitize_value(self, value: str) -> str:
|
|
84
576
|
"""Sanitize value to prevent recursive substitution and control characters.
|
|
85
577
|
|
|
@@ -90,9 +582,9 @@ class TemplateProcessor:
|
|
|
90
582
|
Sanitized value.
|
|
91
583
|
"""
|
|
92
584
|
# Remove control characters (keep printable and whitespace)
|
|
93
|
-
value =
|
|
585
|
+
value = "".join(c for c in value if c.isprintable() or c in "\n\r\t")
|
|
94
586
|
# Prevent recursive substitution by removing placeholder patterns
|
|
95
|
-
value = value.replace(
|
|
587
|
+
value = value.replace("{{", "").replace("}}", "")
|
|
96
588
|
return value
|
|
97
589
|
|
|
98
590
|
def _is_text_file(self, file_path: Path) -> bool:
|
|
@@ -105,8 +597,18 @@ class TemplateProcessor:
|
|
|
105
597
|
True if file is text-based.
|
|
106
598
|
"""
|
|
107
599
|
text_extensions = {
|
|
108
|
-
|
|
109
|
-
|
|
600
|
+
".md",
|
|
601
|
+
".json",
|
|
602
|
+
".txt",
|
|
603
|
+
".py",
|
|
604
|
+
".ts",
|
|
605
|
+
".js",
|
|
606
|
+
".yaml",
|
|
607
|
+
".yml",
|
|
608
|
+
".toml",
|
|
609
|
+
".xml",
|
|
610
|
+
".sh",
|
|
611
|
+
".bash",
|
|
110
612
|
}
|
|
111
613
|
return file_path.suffix.lower() in text_extensions
|
|
112
614
|
|
|
@@ -127,10 +629,10 @@ class TemplateProcessor:
|
|
|
127
629
|
Returns:
|
|
128
630
|
Content with localized descriptions.
|
|
129
631
|
"""
|
|
130
|
-
import yaml
|
|
632
|
+
import yaml # type: ignore[import-untyped]
|
|
131
633
|
|
|
132
634
|
# Pattern to match YAML frontmatter
|
|
133
|
-
frontmatter_pattern = r
|
|
635
|
+
frontmatter_pattern = r"^---\n(.*?)\n---"
|
|
134
636
|
match = re.match(frontmatter_pattern, content, re.DOTALL)
|
|
135
637
|
|
|
136
638
|
if not match:
|
|
@@ -141,18 +643,18 @@ class TemplateProcessor:
|
|
|
141
643
|
yaml_data = yaml.safe_load(yaml_content)
|
|
142
644
|
|
|
143
645
|
# Check if description is a dict (multilingual)
|
|
144
|
-
if isinstance(yaml_data.get(
|
|
646
|
+
if isinstance(yaml_data.get("description"), dict):
|
|
145
647
|
# Select language (fallback to English)
|
|
146
|
-
descriptions = yaml_data[
|
|
147
|
-
selected_desc = descriptions.get(language, descriptions.get(
|
|
648
|
+
descriptions = yaml_data["description"]
|
|
649
|
+
selected_desc = descriptions.get(language, descriptions.get("en", ""))
|
|
148
650
|
|
|
149
651
|
# Replace description with selected language
|
|
150
|
-
yaml_data[
|
|
652
|
+
yaml_data["description"] = selected_desc
|
|
151
653
|
|
|
152
654
|
# Reconstruct frontmatter
|
|
153
655
|
new_yaml = yaml.dump(yaml_data, allow_unicode=True, sort_keys=False)
|
|
154
656
|
# Preserve the rest of the content
|
|
155
|
-
rest_content = content[match.end():]
|
|
657
|
+
rest_content = content[match.end() :]
|
|
156
658
|
return f"---\n{new_yaml}---{rest_content}"
|
|
157
659
|
|
|
158
660
|
except Exception:
|
|
@@ -171,22 +673,22 @@ class TemplateProcessor:
|
|
|
171
673
|
Returns:
|
|
172
674
|
List of warnings.
|
|
173
675
|
"""
|
|
676
|
+
import stat
|
|
677
|
+
|
|
174
678
|
warnings = []
|
|
175
679
|
|
|
176
680
|
# Text files: read, substitute, write
|
|
177
681
|
if self._is_text_file(src) and self.context:
|
|
178
682
|
try:
|
|
179
|
-
content = src.read_text(encoding=
|
|
683
|
+
content = src.read_text(encoding="utf-8")
|
|
180
684
|
content, file_warnings = self._substitute_variables(content)
|
|
181
685
|
|
|
182
686
|
# Apply description localization for command/output-style files
|
|
183
|
-
if src.suffix ==
|
|
184
|
-
|
|
185
|
-
):
|
|
186
|
-
lang = self.context.get('CONVERSATION_LANGUAGE', 'en')
|
|
687
|
+
if src.suffix == ".md" and ("commands/alfred" in str(src) or "output-styles/alfred" in str(src)):
|
|
688
|
+
lang = self.context.get("CONVERSATION_LANGUAGE", "en")
|
|
187
689
|
content = self._localize_yaml_description(content, lang)
|
|
188
690
|
|
|
189
|
-
dst.write_text(content, encoding=
|
|
691
|
+
dst.write_text(content, encoding="utf-8")
|
|
190
692
|
warnings.extend(file_warnings)
|
|
191
693
|
except UnicodeDecodeError:
|
|
192
694
|
# Binary file fallback
|
|
@@ -195,6 +697,12 @@ class TemplateProcessor:
|
|
|
195
697
|
# Binary file or no context: simple copy
|
|
196
698
|
shutil.copy2(src, dst)
|
|
197
699
|
|
|
700
|
+
# Ensure executable permission for shell scripts
|
|
701
|
+
if src.suffix == ".sh":
|
|
702
|
+
# Always make shell scripts executable regardless of source permissions
|
|
703
|
+
dst_mode = dst.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
|
|
704
|
+
dst.chmod(dst_mode)
|
|
705
|
+
|
|
198
706
|
return warnings
|
|
199
707
|
|
|
200
708
|
def _copy_dir_with_substitution(self, src: Path, dst: Path) -> None:
|
|
@@ -237,9 +745,11 @@ class TemplateProcessor:
|
|
|
237
745
|
|
|
238
746
|
self._copy_claude(silent)
|
|
239
747
|
self._copy_moai(silent)
|
|
748
|
+
self._sync_new_section_files(silent) # Add new section files from template
|
|
240
749
|
self._copy_github(silent)
|
|
241
750
|
self._copy_claude_md(silent)
|
|
242
751
|
self._copy_gitignore(silent)
|
|
752
|
+
self._copy_mcp_json(silent)
|
|
243
753
|
|
|
244
754
|
if not silent:
|
|
245
755
|
console.print("✅ Templates copied successfully")
|
|
@@ -290,9 +800,6 @@ class TemplateProcessor:
|
|
|
290
800
|
def _copy_claude(self, silent: bool = False) -> None:
|
|
291
801
|
""".claude/ directory copy with variable substitution (selective with alfred folder overwrite).
|
|
292
802
|
|
|
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
803
|
|
|
297
804
|
Strategy:
|
|
298
805
|
- Alfred folders (commands/agents/hooks/output-styles/alfred) → copy wholesale (delete & overwrite)
|
|
@@ -311,18 +818,21 @@ class TemplateProcessor:
|
|
|
311
818
|
# Create .claude directory if not exists
|
|
312
819
|
dst.mkdir(parents=True, exist_ok=True)
|
|
313
820
|
|
|
314
|
-
#
|
|
315
|
-
#
|
|
316
|
-
|
|
317
|
-
alfred_folders = [
|
|
821
|
+
# Alfred and Moai folders to copy wholesale (overwrite)
|
|
822
|
+
# Including both legacy alfred/ and new moai/ structure
|
|
823
|
+
alfred_moai_folders = [
|
|
318
824
|
"hooks/alfred",
|
|
825
|
+
"hooks/moai",
|
|
319
826
|
"commands/alfred", # Contains 0-project.md, 1-plan.md, 2-run.md, 3-sync.md
|
|
320
|
-
"
|
|
827
|
+
"commands/moai",
|
|
828
|
+
"output-styles/moai",
|
|
321
829
|
"agents/alfred",
|
|
830
|
+
"agents/moai",
|
|
831
|
+
# NOTE: "skills" handled by _sync_skills_selective() to preserve custom skills
|
|
322
832
|
]
|
|
323
833
|
|
|
324
|
-
# 1. Copy Alfred folders wholesale (backup before delete & overwrite)
|
|
325
|
-
for folder in
|
|
834
|
+
# 1. Copy Alfred and Moai folders wholesale (backup before delete & overwrite)
|
|
835
|
+
for folder in alfred_moai_folders:
|
|
326
836
|
src_folder = src / folder
|
|
327
837
|
dst_folder = dst / folder
|
|
328
838
|
|
|
@@ -337,22 +847,71 @@ class TemplateProcessor:
|
|
|
337
847
|
if not silent:
|
|
338
848
|
console.print(f" ✅ .claude/{folder}/ overwritten")
|
|
339
849
|
|
|
340
|
-
#
|
|
850
|
+
# 1.5 Copy other subdirectories in parent folders (e.g., output-styles/moai, hooks/shared)
|
|
851
|
+
# This ensures non-alfred subdirectories are also copied
|
|
852
|
+
parent_folders_with_subdirs = ["output-styles", "hooks", "commands", "agents"]
|
|
853
|
+
for parent_name in parent_folders_with_subdirs:
|
|
854
|
+
src_parent = src / parent_name
|
|
855
|
+
if not src_parent.exists():
|
|
856
|
+
continue
|
|
857
|
+
|
|
858
|
+
for subdir in src_parent.iterdir():
|
|
859
|
+
if not subdir.is_dir():
|
|
860
|
+
continue
|
|
861
|
+
|
|
862
|
+
# Skip alfred subdirectories (already handled above)
|
|
863
|
+
if subdir.name == "alfred":
|
|
864
|
+
continue
|
|
865
|
+
|
|
866
|
+
rel_subdir = f"{parent_name}/{subdir.name}"
|
|
867
|
+
dst_subdir = dst / parent_name / subdir.name
|
|
868
|
+
|
|
869
|
+
if dst_subdir.exists():
|
|
870
|
+
# For non-alfred directories, overwrite with merge if necessary
|
|
871
|
+
shutil.rmtree(dst_subdir)
|
|
872
|
+
|
|
873
|
+
# Copy the subdirectory
|
|
874
|
+
shutil.copytree(subdir, dst_subdir)
|
|
875
|
+
if not silent:
|
|
876
|
+
console.print(f" ✅ .claude/{rel_subdir}/ copied")
|
|
877
|
+
|
|
878
|
+
# 1.6 Sync skills selectively (preserve custom skills, update moai-* skills)
|
|
879
|
+
self._sync_skills_selective(src, dst, silent)
|
|
880
|
+
|
|
881
|
+
# 2. Copy other files/folders individually (smart merge for settings.json and config.json)
|
|
341
882
|
all_warnings = []
|
|
342
883
|
for item in src.iterdir():
|
|
343
884
|
rel_path = item.relative_to(src)
|
|
344
885
|
dst_item = dst / rel_path
|
|
345
886
|
|
|
346
887
|
# Skip Alfred parent folders (already handled above)
|
|
347
|
-
|
|
888
|
+
# Also skip "skills" - handled by _sync_skills_selective()
|
|
889
|
+
if item.is_dir() and item.name in [
|
|
890
|
+
"hooks",
|
|
891
|
+
"commands",
|
|
892
|
+
"output-styles",
|
|
893
|
+
"agents",
|
|
894
|
+
"skills", # Handled by _sync_skills_selective() to preserve custom skills
|
|
895
|
+
]:
|
|
348
896
|
continue
|
|
349
897
|
|
|
350
898
|
if item.is_file():
|
|
351
899
|
# Smart merge for settings.json
|
|
352
900
|
if item.name == "settings.json":
|
|
353
901
|
self._merge_settings_json(item, dst_item)
|
|
902
|
+
# Apply variable substitution to merged settings.json (for cross-platform Hook paths)
|
|
903
|
+
if self.context:
|
|
904
|
+
content = dst_item.read_text(encoding="utf-8")
|
|
905
|
+
content, file_warnings = self._substitute_variables(content)
|
|
906
|
+
dst_item.write_text(content, encoding="utf-8")
|
|
907
|
+
all_warnings.extend(file_warnings)
|
|
908
|
+
if not silent:
|
|
909
|
+
console.print(" 🔄 settings.json merged (Hook paths configured for your OS)")
|
|
910
|
+
# Smart merge for config.json
|
|
911
|
+
elif item.name == "config.json":
|
|
912
|
+
self._merge_config_json(item, dst_item)
|
|
354
913
|
if not silent:
|
|
355
|
-
console.print(" 🔄
|
|
914
|
+
console.print(" 🔄 config.json merged (user preferences preserved)")
|
|
356
915
|
else:
|
|
357
916
|
# FORCE OVERWRITE: Always copy other files (no skip)
|
|
358
917
|
warnings = self._copy_file_with_substitution(item, dst_item)
|
|
@@ -370,6 +929,54 @@ class TemplateProcessor:
|
|
|
370
929
|
if not silent:
|
|
371
930
|
console.print(" ✅ .claude/ copy complete (variables substituted)")
|
|
372
931
|
|
|
932
|
+
def _sync_skills_selective(self, src: Path, dst: Path, silent: bool = False) -> None:
|
|
933
|
+
"""Sync only moai-* template skills, preserve custom skills.
|
|
934
|
+
|
|
935
|
+
This method ensures that:
|
|
936
|
+
- Template skills (moai-* prefix) are updated from source
|
|
937
|
+
- Custom skills (any other prefix) are preserved untouched
|
|
938
|
+
|
|
939
|
+
Args:
|
|
940
|
+
src: Source .claude directory from template
|
|
941
|
+
dst: Destination .claude directory in project
|
|
942
|
+
silent: Suppress console output if True
|
|
943
|
+
"""
|
|
944
|
+
skills_src = src / "skills"
|
|
945
|
+
skills_dst = dst / "skills"
|
|
946
|
+
|
|
947
|
+
if not skills_src.exists():
|
|
948
|
+
return
|
|
949
|
+
|
|
950
|
+
skills_dst.mkdir(parents=True, exist_ok=True)
|
|
951
|
+
|
|
952
|
+
# Step 1: Identify template skills in source (moai-* prefix)
|
|
953
|
+
template_skills = {d.name for d in skills_src.iterdir() if d.is_dir() and d.name.startswith("moai-")}
|
|
954
|
+
|
|
955
|
+
# Step 2: Delete only template skills in destination
|
|
956
|
+
if skills_dst.exists():
|
|
957
|
+
for skill_dir in list(skills_dst.iterdir()):
|
|
958
|
+
if skill_dir.is_dir() and skill_dir.name.startswith("moai-"):
|
|
959
|
+
shutil.rmtree(skill_dir)
|
|
960
|
+
if not silent:
|
|
961
|
+
console.print(f" [dim]Updating template skill: {skill_dir.name}[/dim]")
|
|
962
|
+
|
|
963
|
+
# Step 3: Copy template skills from source
|
|
964
|
+
for skill_name in sorted(template_skills):
|
|
965
|
+
src_skill = skills_src / skill_name
|
|
966
|
+
dst_skill = skills_dst / skill_name
|
|
967
|
+
shutil.copytree(src_skill, dst_skill)
|
|
968
|
+
|
|
969
|
+
if not silent and template_skills:
|
|
970
|
+
console.print(f" ✅ Synced {len(template_skills)} template skill(s)")
|
|
971
|
+
|
|
972
|
+
# Step 4: Report preserved custom skills
|
|
973
|
+
if skills_dst.exists():
|
|
974
|
+
custom_skills = [d.name for d in skills_dst.iterdir() if d.is_dir() and not d.name.startswith("moai-")]
|
|
975
|
+
if custom_skills and not silent:
|
|
976
|
+
preview = ", ".join(sorted(custom_skills)[:3])
|
|
977
|
+
suffix = "..." if len(custom_skills) > 3 else ""
|
|
978
|
+
console.print(f" ✅ Preserved {len(custom_skills)} custom skill(s): {preview}{suffix}")
|
|
979
|
+
|
|
373
980
|
def _copy_moai(self, silent: bool = False) -> None:
|
|
374
981
|
""".moai/ directory copy with variable substitution (excludes protected paths)."""
|
|
375
982
|
src = self.template_root / ".moai"
|
|
@@ -380,10 +987,11 @@ class TemplateProcessor:
|
|
|
380
987
|
console.print("⚠️ .moai/ template not found")
|
|
381
988
|
return
|
|
382
989
|
|
|
383
|
-
# Paths excluded from template copying (specs/, reports/)
|
|
990
|
+
# Paths excluded from template copying (specs/, reports/, sections/)
|
|
384
991
|
template_protected_paths = [
|
|
385
992
|
"specs",
|
|
386
993
|
"reports",
|
|
994
|
+
"config/sections", # User section YAML files
|
|
387
995
|
]
|
|
388
996
|
|
|
389
997
|
all_warnings = []
|
|
@@ -416,8 +1024,134 @@ class TemplateProcessor:
|
|
|
416
1024
|
if not silent:
|
|
417
1025
|
console.print(" ✅ .moai/ copy complete (variables substituted)")
|
|
418
1026
|
|
|
1027
|
+
def _deep_merge_dicts(self, base: dict, overlay: dict) -> tuple[dict, list[str]]:
|
|
1028
|
+
"""Deep merge two dictionaries, preserving base values and adding new keys from overlay.
|
|
1029
|
+
|
|
1030
|
+
Args:
|
|
1031
|
+
base: User's existing configuration (values to preserve)
|
|
1032
|
+
overlay: Template configuration (new keys to add)
|
|
1033
|
+
|
|
1034
|
+
Returns:
|
|
1035
|
+
Tuple of (merged dict, list of new keys added)
|
|
1036
|
+
"""
|
|
1037
|
+
result = base.copy()
|
|
1038
|
+
new_keys = []
|
|
1039
|
+
|
|
1040
|
+
for key, value in overlay.items():
|
|
1041
|
+
if key not in result:
|
|
1042
|
+
# New key: add from template
|
|
1043
|
+
result[key] = value
|
|
1044
|
+
new_keys.append(key)
|
|
1045
|
+
elif isinstance(value, dict) and isinstance(result.get(key), dict):
|
|
1046
|
+
# Both are dicts: recurse
|
|
1047
|
+
merged, nested_new = self._deep_merge_dicts(result[key], value)
|
|
1048
|
+
result[key] = merged
|
|
1049
|
+
new_keys.extend([f"{key}.{k}" for k in nested_new])
|
|
1050
|
+
# else: key exists in base, preserve user's value
|
|
1051
|
+
|
|
1052
|
+
return result, new_keys
|
|
1053
|
+
|
|
1054
|
+
def _sync_new_section_files(self, silent: bool = False) -> None:
|
|
1055
|
+
"""Sync section files from template to project with smart merge.
|
|
1056
|
+
|
|
1057
|
+
This method handles section file synchronization with the following logic:
|
|
1058
|
+
- New files (template has, project doesn't): Copy from template
|
|
1059
|
+
- Existing files: Smart merge (preserve user values, add new fields)
|
|
1060
|
+
- system.yaml: Always update moai.version to current package version
|
|
1061
|
+
|
|
1062
|
+
Smart Merge Behavior:
|
|
1063
|
+
- User values are NEVER overwritten
|
|
1064
|
+
- Only new keys/fields from template are added
|
|
1065
|
+
- Nested structures are recursively merged
|
|
1066
|
+
"""
|
|
1067
|
+
template_sections = self.template_root / ".moai" / "config" / "sections"
|
|
1068
|
+
project_sections = self.target_path / ".moai" / "config" / "sections"
|
|
1069
|
+
|
|
1070
|
+
if not template_sections.exists():
|
|
1071
|
+
return
|
|
1072
|
+
|
|
1073
|
+
# Ensure project sections directory exists
|
|
1074
|
+
project_sections.mkdir(parents=True, exist_ok=True)
|
|
1075
|
+
|
|
1076
|
+
# Get current package version
|
|
1077
|
+
try:
|
|
1078
|
+
from moai_adk import __version__
|
|
1079
|
+
|
|
1080
|
+
current_version = __version__
|
|
1081
|
+
except ImportError:
|
|
1082
|
+
current_version = None
|
|
1083
|
+
|
|
1084
|
+
new_files_added = []
|
|
1085
|
+
files_updated = []
|
|
1086
|
+
|
|
1087
|
+
import yaml
|
|
1088
|
+
|
|
1089
|
+
for template_file in template_sections.glob("*.yaml"):
|
|
1090
|
+
project_file = project_sections / template_file.name
|
|
1091
|
+
|
|
1092
|
+
if not project_file.exists():
|
|
1093
|
+
# New file: copy with variable substitution
|
|
1094
|
+
self._copy_file_with_substitution(template_file, project_file)
|
|
1095
|
+
new_files_added.append(template_file.name)
|
|
1096
|
+
else:
|
|
1097
|
+
# Existing file: smart merge (add new fields only)
|
|
1098
|
+
try:
|
|
1099
|
+
# Load template data
|
|
1100
|
+
template_content = template_file.read_text(encoding="utf-8")
|
|
1101
|
+
template_data = yaml.safe_load(template_content) or {}
|
|
1102
|
+
|
|
1103
|
+
# Load project data (user's current values)
|
|
1104
|
+
project_content = project_file.read_text(encoding="utf-8")
|
|
1105
|
+
project_data = yaml.safe_load(project_content) or {}
|
|
1106
|
+
|
|
1107
|
+
# Deep merge: preserve user values, add new template keys
|
|
1108
|
+
merged_data, new_keys = self._deep_merge_dicts(project_data, template_data)
|
|
1109
|
+
|
|
1110
|
+
if new_keys:
|
|
1111
|
+
# Write merged data back
|
|
1112
|
+
with open(project_file, "w", encoding="utf-8") as f:
|
|
1113
|
+
yaml.dump(
|
|
1114
|
+
merged_data,
|
|
1115
|
+
f,
|
|
1116
|
+
default_flow_style=False,
|
|
1117
|
+
allow_unicode=True,
|
|
1118
|
+
sort_keys=False,
|
|
1119
|
+
)
|
|
1120
|
+
files_updated.append(f"{template_file.name} (+{len(new_keys)} fields)")
|
|
1121
|
+
|
|
1122
|
+
except Exception:
|
|
1123
|
+
pass # Silently ignore yaml errors for individual files
|
|
1124
|
+
|
|
1125
|
+
# Update system.yaml version (special case: always update version)
|
|
1126
|
+
system_yaml = project_sections / "system.yaml"
|
|
1127
|
+
if system_yaml.exists() and current_version:
|
|
1128
|
+
try:
|
|
1129
|
+
content = system_yaml.read_text(encoding="utf-8")
|
|
1130
|
+
data = yaml.safe_load(content) or {}
|
|
1131
|
+
|
|
1132
|
+
# Update moai.version
|
|
1133
|
+
if "moai" not in data:
|
|
1134
|
+
data["moai"] = {}
|
|
1135
|
+
if data.get("moai", {}).get("version") != current_version:
|
|
1136
|
+
data["moai"]["version"] = current_version
|
|
1137
|
+
|
|
1138
|
+
# Write back
|
|
1139
|
+
with open(system_yaml, "w", encoding="utf-8") as f:
|
|
1140
|
+
yaml.dump(data, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
|
|
1141
|
+
|
|
1142
|
+
if not silent:
|
|
1143
|
+
console.print(f" 🔄 system.yaml version updated to {current_version}")
|
|
1144
|
+
except Exception:
|
|
1145
|
+
pass # Silently ignore yaml errors
|
|
1146
|
+
|
|
1147
|
+
if new_files_added and not silent:
|
|
1148
|
+
console.print(f" ✨ New section files added: {', '.join(new_files_added)}")
|
|
1149
|
+
|
|
1150
|
+
if files_updated and not silent:
|
|
1151
|
+
console.print(f" 🔀 Section files updated: {', '.join(files_updated)}")
|
|
1152
|
+
|
|
419
1153
|
def _copy_github(self, silent: bool = False) -> None:
|
|
420
|
-
""".github/ directory copy with
|
|
1154
|
+
""".github/ directory copy with smart merge (preserves user workflows)."""
|
|
421
1155
|
src = self.template_root / ".github"
|
|
422
1156
|
dst = self.target_path / ".github"
|
|
423
1157
|
|
|
@@ -426,17 +1160,39 @@ class TemplateProcessor:
|
|
|
426
1160
|
console.print("⚠️ .github/ template not found")
|
|
427
1161
|
return
|
|
428
1162
|
|
|
1163
|
+
# Smart merge: preserve existing user workflows
|
|
429
1164
|
if dst.exists():
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
1165
|
+
self._merge_github_workflows(src, dst)
|
|
1166
|
+
else:
|
|
1167
|
+
# First time: just copy
|
|
1168
|
+
self._copy_dir_with_substitution(src, dst)
|
|
433
1169
|
|
|
434
1170
|
if not silent:
|
|
435
|
-
console.print("
|
|
1171
|
+
console.print(" 🔄 .github/ merged (user workflows preserved, variables substituted)")
|
|
436
1172
|
|
|
437
1173
|
def _copy_claude_md(self, silent: bool = False) -> None:
|
|
438
|
-
"""Copy CLAUDE.md with
|
|
439
|
-
|
|
1174
|
+
"""Copy CLAUDE.md with complete replacement (no merge).
|
|
1175
|
+
|
|
1176
|
+
Selects language-specific CLAUDE.md based on conversation_language setting:
|
|
1177
|
+
- CLAUDE.ko.md for Korean
|
|
1178
|
+
- CLAUDE.ja.md for Japanese
|
|
1179
|
+
- CLAUDE.zh.md for Chinese
|
|
1180
|
+
- CLAUDE.md for English (default)
|
|
1181
|
+
"""
|
|
1182
|
+
# Get language from context (set by set_context())
|
|
1183
|
+
language = self.context.get("CONVERSATION_LANGUAGE", "en") if self.context else "en"
|
|
1184
|
+
|
|
1185
|
+
# Select language-specific file
|
|
1186
|
+
if language and language != "en":
|
|
1187
|
+
lang_specific_src = self.template_root / f"CLAUDE.{language}.md"
|
|
1188
|
+
if lang_specific_src.exists():
|
|
1189
|
+
src = lang_specific_src
|
|
1190
|
+
else:
|
|
1191
|
+
# Fallback to English if language-specific file doesn't exist
|
|
1192
|
+
src = self.template_root / "CLAUDE.md"
|
|
1193
|
+
else:
|
|
1194
|
+
src = self.template_root / "CLAUDE.md"
|
|
1195
|
+
|
|
440
1196
|
dst = self.target_path / "CLAUDE.md"
|
|
441
1197
|
|
|
442
1198
|
if not src.exists():
|
|
@@ -444,16 +1200,11 @@ class TemplateProcessor:
|
|
|
444
1200
|
console.print("⚠️ CLAUDE.md template not found")
|
|
445
1201
|
return
|
|
446
1202
|
|
|
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")
|
|
1203
|
+
# Simple copy with substitution (no merge)
|
|
1204
|
+
self._copy_file_with_substitution(src, dst)
|
|
1205
|
+
|
|
1206
|
+
if not silent:
|
|
1207
|
+
console.print(" ✅ CLAUDE.md replaced (use CLAUDE.local.md for personal instructions)")
|
|
457
1208
|
|
|
458
1209
|
def _merge_claude_md(self, src: Path, dst: Path) -> None:
|
|
459
1210
|
"""Delegate the smart merge for CLAUDE.md.
|
|
@@ -464,6 +1215,15 @@ class TemplateProcessor:
|
|
|
464
1215
|
"""
|
|
465
1216
|
self.merger.merge_claude_md(src, dst)
|
|
466
1217
|
|
|
1218
|
+
def _merge_github_workflows(self, src: Path, dst: Path) -> None:
|
|
1219
|
+
"""Delegate the smart merge for .github/workflows/.
|
|
1220
|
+
|
|
1221
|
+
Args:
|
|
1222
|
+
src: Template .github directory.
|
|
1223
|
+
dst: Project .github directory.
|
|
1224
|
+
"""
|
|
1225
|
+
self.merger.merge_github_workflows(src, dst)
|
|
1226
|
+
|
|
467
1227
|
def _merge_settings_json(self, src: Path, dst: Path) -> None:
|
|
468
1228
|
"""Delegate the smart merge for settings.json.
|
|
469
1229
|
|
|
@@ -473,15 +1233,215 @@ class TemplateProcessor:
|
|
|
473
1233
|
"""
|
|
474
1234
|
# Find the latest backup for user settings extraction
|
|
475
1235
|
backup_path = None
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
backup_path = backup_settings
|
|
1236
|
+
latest_backup = self.backup.get_latest_backup()
|
|
1237
|
+
if latest_backup:
|
|
1238
|
+
backup_settings = latest_backup / ".claude" / "settings.json"
|
|
1239
|
+
if backup_settings.exists():
|
|
1240
|
+
backup_path = backup_settings
|
|
482
1241
|
|
|
483
1242
|
self.merger.merge_settings_json(src, dst, backup_path)
|
|
484
1243
|
|
|
1244
|
+
def _merge_config_json(self, src: Path, dst: Path) -> None:
|
|
1245
|
+
"""Smart merge for config using section YAML files with JSON fallback.
|
|
1246
|
+
|
|
1247
|
+
Supports both new section-based YAML files and legacy config.json.
|
|
1248
|
+
Priority: Section YAML files > config.json fallback
|
|
1249
|
+
|
|
1250
|
+
Args:
|
|
1251
|
+
src: Template config file (config.json for legacy projects).
|
|
1252
|
+
dst: Project config file destination.
|
|
1253
|
+
"""
|
|
1254
|
+
import json
|
|
1255
|
+
import os
|
|
1256
|
+
|
|
1257
|
+
try:
|
|
1258
|
+
import yaml # noqa: F401 # pyright: ignore[reportUnusedImport]
|
|
1259
|
+
|
|
1260
|
+
yaml_available = True
|
|
1261
|
+
except ImportError:
|
|
1262
|
+
yaml_available = False
|
|
1263
|
+
|
|
1264
|
+
# Check for section-based YAML configuration (new approach)
|
|
1265
|
+
sections_dir = self.target_path / ".moai" / "config" / "sections"
|
|
1266
|
+
|
|
1267
|
+
if yaml_available and sections_dir.exists() and sections_dir.is_dir():
|
|
1268
|
+
# Use section YAML files - merge each section individually
|
|
1269
|
+
self._merge_section_yaml_files(sections_dir)
|
|
1270
|
+
return
|
|
1271
|
+
|
|
1272
|
+
# Fallback to legacy config.json merging
|
|
1273
|
+
# Load template config
|
|
1274
|
+
try:
|
|
1275
|
+
template_config = json.loads(src.read_text(encoding="utf-8"))
|
|
1276
|
+
except (json.JSONDecodeError, FileNotFoundError) as e:
|
|
1277
|
+
console.print(f"⚠️ Warning: Could not read template config.json: {e}")
|
|
1278
|
+
return
|
|
1279
|
+
|
|
1280
|
+
# Find latest backup config.json
|
|
1281
|
+
latest_backup = self.backup.get_latest_backup()
|
|
1282
|
+
if latest_backup:
|
|
1283
|
+
backup_config_path = latest_backup / ".moai" / "config" / "config.json"
|
|
1284
|
+
if backup_config_path.exists():
|
|
1285
|
+
try:
|
|
1286
|
+
json.loads(backup_config_path.read_text(encoding="utf-8"))
|
|
1287
|
+
except json.JSONDecodeError as e:
|
|
1288
|
+
console.print(f"⚠️ Warning: Could not read backup config.json: {e}")
|
|
1289
|
+
|
|
1290
|
+
# Load existing project config.json
|
|
1291
|
+
existing_config = {}
|
|
1292
|
+
if dst.exists():
|
|
1293
|
+
try:
|
|
1294
|
+
existing_config = json.loads(dst.read_text(encoding="utf-8"))
|
|
1295
|
+
except json.JSONDecodeError as e:
|
|
1296
|
+
console.print(f"⚠️ Warning: Could not read existing config.json: {e}")
|
|
1297
|
+
|
|
1298
|
+
# Merge with priority system: Environment > Existing User > Template
|
|
1299
|
+
# We'll use LanguageConfigResolver to handle this properly
|
|
1300
|
+
try:
|
|
1301
|
+
# Import LanguageConfigResolver for priority-based merging
|
|
1302
|
+
from moai_adk.core.language_config_resolver import LanguageConfigResolver
|
|
1303
|
+
|
|
1304
|
+
# Create temporary resolver to handle merging
|
|
1305
|
+
temp_project_path = self.target_path / ".moai" / "config"
|
|
1306
|
+
temp_project_path.mkdir(parents=True, exist_ok=True)
|
|
1307
|
+
|
|
1308
|
+
# Start with template config as base
|
|
1309
|
+
merged_config = template_config.copy()
|
|
1310
|
+
|
|
1311
|
+
# Apply existing user config (higher priority than template)
|
|
1312
|
+
for key, value in existing_config.items():
|
|
1313
|
+
if key not in ["config_source"]: # Skip metadata
|
|
1314
|
+
if key in merged_config and isinstance(merged_config[key], dict) and isinstance(value, dict):
|
|
1315
|
+
# Deep merge for nested objects
|
|
1316
|
+
merged_config[key].update(value)
|
|
1317
|
+
else:
|
|
1318
|
+
merged_config[key] = value
|
|
1319
|
+
|
|
1320
|
+
# Apply environment variables (highest priority)
|
|
1321
|
+
env_mappings = {
|
|
1322
|
+
"MOAI_USER_NAME": ("user", "name"),
|
|
1323
|
+
"MOAI_CONVERSATION_LANG": ("language", "conversation_language"),
|
|
1324
|
+
"MOAI_AGENT_PROMPT_LANG": ("language", "agent_prompt_language"),
|
|
1325
|
+
"MOAI_CONVERSATION_LANG_NAME": (
|
|
1326
|
+
"language",
|
|
1327
|
+
"conversation_language_name",
|
|
1328
|
+
),
|
|
1329
|
+
"MOAI_GIT_COMMIT_MESSAGES_LANG": ("language", "git_commit_messages"),
|
|
1330
|
+
"MOAI_CODE_COMMENTS_LANG": ("language", "code_comments"),
|
|
1331
|
+
"MOAI_DOCUMENTATION_LANG": ("language", "documentation"),
|
|
1332
|
+
"MOAI_ERROR_MESSAGES_LANG": ("language", "error_messages"),
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
for env_var, (section, key) in env_mappings.items():
|
|
1336
|
+
env_value = os.getenv(env_var)
|
|
1337
|
+
if env_value:
|
|
1338
|
+
if section not in merged_config:
|
|
1339
|
+
merged_config[section] = {}
|
|
1340
|
+
merged_config[section][key] = env_value
|
|
1341
|
+
|
|
1342
|
+
# Ensure consistency
|
|
1343
|
+
resolver = LanguageConfigResolver(str(self.target_path))
|
|
1344
|
+
merged_config = resolver._ensure_consistency(merged_config)
|
|
1345
|
+
|
|
1346
|
+
# Write merged config
|
|
1347
|
+
dst.write_text(
|
|
1348
|
+
json.dumps(merged_config, indent=2, ensure_ascii=False) + "\n",
|
|
1349
|
+
encoding="utf-8",
|
|
1350
|
+
)
|
|
1351
|
+
|
|
1352
|
+
except ImportError:
|
|
1353
|
+
# Fallback: simple merge without LanguageConfigResolver
|
|
1354
|
+
merged_config = template_config.copy()
|
|
1355
|
+
|
|
1356
|
+
# Apply existing config
|
|
1357
|
+
for key, value in existing_config.items():
|
|
1358
|
+
if key not in ["config_source"]:
|
|
1359
|
+
merged_config[key] = value
|
|
1360
|
+
|
|
1361
|
+
dst.write_text(
|
|
1362
|
+
json.dumps(merged_config, indent=2, ensure_ascii=False) + "\n",
|
|
1363
|
+
encoding="utf-8",
|
|
1364
|
+
)
|
|
1365
|
+
console.print(" ⚠️ Warning: Using simple merge (LanguageConfigResolver not available)")
|
|
1366
|
+
|
|
1367
|
+
def _merge_section_yaml_files(self, sections_dir: Path) -> None:
|
|
1368
|
+
"""Merge section YAML files with user-specific values preserved.
|
|
1369
|
+
|
|
1370
|
+
Args:
|
|
1371
|
+
sections_dir: Path to sections directory (.moai/config/sections/)
|
|
1372
|
+
"""
|
|
1373
|
+
import os
|
|
1374
|
+
|
|
1375
|
+
try:
|
|
1376
|
+
import yaml
|
|
1377
|
+
except ImportError:
|
|
1378
|
+
console.print("⚠️ Warning: PyYAML not available, skipping section merge")
|
|
1379
|
+
return
|
|
1380
|
+
|
|
1381
|
+
# Get current package version for system.yaml update
|
|
1382
|
+
current_version = self._get_current_version()
|
|
1383
|
+
|
|
1384
|
+
# Environment variable mappings for each section
|
|
1385
|
+
env_mappings = {
|
|
1386
|
+
"language.yaml": {
|
|
1387
|
+
"MOAI_CONVERSATION_LANG": ["language", "conversation_language"],
|
|
1388
|
+
"MOAI_AGENT_PROMPT_LANG": ["language", "agent_prompt_language"],
|
|
1389
|
+
"MOAI_CONVERSATION_LANG_NAME": ["language", "conversation_language_name"],
|
|
1390
|
+
"MOAI_GIT_COMMIT_MESSAGES_LANG": ["language", "git_commit_messages"],
|
|
1391
|
+
"MOAI_CODE_COMMENTS_LANG": ["language", "code_comments"],
|
|
1392
|
+
"MOAI_DOCUMENTATION_LANG": ["language", "documentation"],
|
|
1393
|
+
"MOAI_ERROR_MESSAGES_LANG": ["language", "error_messages"],
|
|
1394
|
+
},
|
|
1395
|
+
"user.yaml": {
|
|
1396
|
+
"MOAI_USER_NAME": ["user", "name"],
|
|
1397
|
+
},
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
for section_file in sections_dir.glob("*.yaml"):
|
|
1401
|
+
try:
|
|
1402
|
+
# Read existing section content
|
|
1403
|
+
with open(section_file, "r", encoding="utf-8") as f:
|
|
1404
|
+
section_data = yaml.safe_load(f) or {}
|
|
1405
|
+
|
|
1406
|
+
modified = False
|
|
1407
|
+
|
|
1408
|
+
# Update system.yaml version to current package version
|
|
1409
|
+
if section_file.name == "system.yaml" and current_version:
|
|
1410
|
+
if "moai" not in section_data:
|
|
1411
|
+
section_data["moai"] = {}
|
|
1412
|
+
if section_data.get("moai", {}).get("version") != current_version:
|
|
1413
|
+
section_data["moai"]["version"] = current_version
|
|
1414
|
+
modified = True
|
|
1415
|
+
|
|
1416
|
+
# Apply environment variable overrides if applicable
|
|
1417
|
+
if section_file.name in env_mappings:
|
|
1418
|
+
for env_var, path in env_mappings[section_file.name].items():
|
|
1419
|
+
env_value = os.getenv(env_var)
|
|
1420
|
+
if env_value:
|
|
1421
|
+
# Navigate to the correct nested location
|
|
1422
|
+
current = section_data
|
|
1423
|
+
for key in path[:-1]:
|
|
1424
|
+
if key not in current:
|
|
1425
|
+
current[key] = {}
|
|
1426
|
+
current = current[key]
|
|
1427
|
+
if current.get(path[-1]) != env_value:
|
|
1428
|
+
current[path[-1]] = env_value
|
|
1429
|
+
modified = True
|
|
1430
|
+
|
|
1431
|
+
# Write back only if modifications were made
|
|
1432
|
+
if modified or section_file.name in env_mappings:
|
|
1433
|
+
with open(section_file, "w", encoding="utf-8") as f:
|
|
1434
|
+
yaml.safe_dump(
|
|
1435
|
+
section_data,
|
|
1436
|
+
f,
|
|
1437
|
+
default_flow_style=False,
|
|
1438
|
+
allow_unicode=True,
|
|
1439
|
+
sort_keys=False,
|
|
1440
|
+
)
|
|
1441
|
+
|
|
1442
|
+
except Exception as e:
|
|
1443
|
+
console.print(f"⚠️ Warning: Failed to merge {section_file.name}: {e}")
|
|
1444
|
+
|
|
485
1445
|
def _copy_gitignore(self, silent: bool = False) -> None:
|
|
486
1446
|
""".gitignore copy (optional)."""
|
|
487
1447
|
src = self.template_root / ".gitignore"
|
|
@@ -509,6 +1469,47 @@ class TemplateProcessor:
|
|
|
509
1469
|
"""
|
|
510
1470
|
self.merger.merge_gitignore(src, dst)
|
|
511
1471
|
|
|
1472
|
+
def _copy_mcp_json(self, silent: bool = False) -> None:
|
|
1473
|
+
""".mcp.json copy (smart merge with existing MCP server configuration)."""
|
|
1474
|
+
src = self.template_root / ".mcp.json"
|
|
1475
|
+
dst = self.target_path / ".mcp.json"
|
|
1476
|
+
|
|
1477
|
+
if not src.exists():
|
|
1478
|
+
return
|
|
1479
|
+
|
|
1480
|
+
# Merge with existing .mcp.json when present (preserve user-added MCP servers)
|
|
1481
|
+
if dst.exists():
|
|
1482
|
+
self._merge_mcp_json(src, dst)
|
|
1483
|
+
if not silent:
|
|
1484
|
+
console.print(" 🔄 .mcp.json merged (user MCP servers preserved)")
|
|
1485
|
+
else:
|
|
1486
|
+
shutil.copy2(src, dst)
|
|
1487
|
+
if not silent:
|
|
1488
|
+
console.print(" ✅ .mcp.json copy complete")
|
|
1489
|
+
|
|
1490
|
+
def _merge_mcp_json(self, src: Path, dst: Path) -> None:
|
|
1491
|
+
"""Smart merge for .mcp.json (preserve user-added MCP servers).
|
|
1492
|
+
|
|
1493
|
+
Args:
|
|
1494
|
+
src: Template .mcp.json.
|
|
1495
|
+
dst: Project .mcp.json.
|
|
1496
|
+
"""
|
|
1497
|
+
try:
|
|
1498
|
+
src_data = json.loads(src.read_text(encoding="utf-8"))
|
|
1499
|
+
dst_data = json.loads(dst.read_text(encoding="utf-8"))
|
|
1500
|
+
|
|
1501
|
+
# Merge mcpServers: preserve user servers, update template servers
|
|
1502
|
+
if "mcpServers" in src_data:
|
|
1503
|
+
if "mcpServers" not in dst_data:
|
|
1504
|
+
dst_data["mcpServers"] = {}
|
|
1505
|
+
# Update with template servers (preserves existing user servers)
|
|
1506
|
+
dst_data["mcpServers"].update(src_data["mcpServers"])
|
|
1507
|
+
|
|
1508
|
+
# Write merged result back
|
|
1509
|
+
dst.write_text(json.dumps(dst_data, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
1510
|
+
except json.JSONDecodeError as e:
|
|
1511
|
+
console.print(f"[yellow]⚠️ Failed to merge .mcp.json: {e}[/yellow]")
|
|
1512
|
+
|
|
512
1513
|
def merge_config(self, detected_language: str | None = None) -> dict[str, str]:
|
|
513
1514
|
"""Delegate the smart merge for config.json.
|
|
514
1515
|
|