moai-adk 0.25.4__py3-none-any.whl → 0.32.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/__init__.py +2 -5
- moai_adk/__main__.py +114 -82
- moai_adk/cli/__init__.py +6 -1
- moai_adk/cli/commands/__init__.py +1 -3
- moai_adk/cli/commands/analyze.py +5 -16
- moai_adk/cli/commands/doctor.py +6 -18
- moai_adk/cli/commands/init.py +56 -125
- moai_adk/cli/commands/language.py +14 -35
- moai_adk/cli/commands/status.py +9 -15
- moai_adk/cli/commands/update.py +1555 -190
- moai_adk/cli/prompts/init_prompts.py +112 -56
- moai_adk/cli/spec_status.py +263 -0
- moai_adk/cli/ui/__init__.py +44 -0
- moai_adk/cli/ui/progress.py +422 -0
- moai_adk/cli/ui/prompts.py +389 -0
- moai_adk/cli/ui/theme.py +129 -0
- moai_adk/cli/worktree/__init__.py +27 -0
- moai_adk/cli/worktree/__main__.py +31 -0
- moai_adk/cli/worktree/cli.py +672 -0
- moai_adk/cli/worktree/exceptions.py +89 -0
- moai_adk/cli/worktree/manager.py +490 -0
- moai_adk/cli/worktree/models.py +65 -0
- moai_adk/cli/worktree/registry.py +128 -0
- moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
- moai_adk/core/analysis/session_analyzer.py +17 -56
- moai_adk/core/claude_integration.py +26 -54
- moai_adk/core/command_helpers.py +10 -10
- moai_adk/core/comprehensive_monitoring_system.py +1183 -0
- moai_adk/core/config/auto_spec_config.py +5 -11
- moai_adk/core/config/migration.py +19 -9
- moai_adk/core/config/unified.py +436 -0
- moai_adk/core/context_manager.py +6 -12
- moai_adk/core/enterprise_features.py +1404 -0
- moai_adk/core/error_recovery_system.py +725 -112
- moai_adk/core/event_driven_hook_system.py +1371 -0
- moai_adk/core/git/__init__.py +8 -0
- moai_adk/core/git/branch_manager.py +3 -11
- moai_adk/core/git/checkpoint.py +1 -3
- moai_adk/core/git/conflict_detector.py +413 -0
- moai_adk/core/git/manager.py +91 -1
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +56 -80
- moai_adk/core/input_validation_middleware.py +1006 -0
- moai_adk/core/integration/engine.py +6 -18
- moai_adk/core/integration/integration_tester.py +10 -9
- moai_adk/core/integration/utils.py +1 -1
- moai_adk/core/issue_creator.py +10 -28
- moai_adk/core/jit_context_loader.py +956 -0
- moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
- moai_adk/core/language_config_resolver.py +485 -0
- moai_adk/core/language_validator.py +28 -41
- moai_adk/core/mcp/setup.py +15 -12
- moai_adk/core/merge/__init__.py +9 -0
- moai_adk/core/merge/analyzer.py +481 -0
- moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
- moai_adk/core/migration/backup_manager.py +78 -9
- moai_adk/core/migration/custom_element_scanner.py +358 -0
- moai_adk/core/migration/file_migrator.py +8 -17
- moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
- moai_adk/core/migration/selective_restorer.py +470 -0
- moai_adk/core/migration/template_utils.py +74 -0
- moai_adk/core/migration/user_selection_ui.py +338 -0
- moai_adk/core/migration/version_detector.py +6 -10
- moai_adk/core/migration/version_migrator.py +3 -3
- moai_adk/core/performance/cache_system.py +8 -10
- moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
- moai_adk/core/project/checker.py +2 -4
- moai_adk/core/project/detector.py +1 -3
- moai_adk/core/project/initializer.py +135 -23
- moai_adk/core/project/phase_executor.py +54 -81
- moai_adk/core/project/validator.py +6 -12
- moai_adk/core/quality/trust_checker.py +9 -27
- moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
- moai_adk/core/robust_json_parser.py +611 -0
- moai_adk/core/rollback_manager.py +73 -148
- moai_adk/core/session_manager.py +10 -26
- moai_adk/core/skill_loading_system.py +579 -0
- moai_adk/core/spec/confidence_scoring.py +31 -100
- moai_adk/core/spec/ears_template_engine.py +351 -286
- moai_adk/core/spec/quality_validator.py +35 -69
- moai_adk/core/spec_status_manager.py +64 -74
- moai_adk/core/template/backup.py +45 -20
- moai_adk/core/template/config.py +112 -39
- moai_adk/core/template/merger.py +11 -19
- moai_adk/core/template/processor.py +253 -149
- moai_adk/core/template_engine.py +73 -40
- moai_adk/core/template_variable_synchronizer.py +417 -0
- moai_adk/core/unified_permission_manager.py +745 -0
- moai_adk/core/user_behavior_analytics.py +851 -0
- moai_adk/core/version_sync.py +429 -0
- moai_adk/foundation/__init__.py +56 -0
- moai_adk/foundation/backend.py +1027 -0
- moai_adk/foundation/database.py +1115 -0
- moai_adk/foundation/devops.py +1585 -0
- moai_adk/foundation/ears.py +431 -0
- moai_adk/foundation/frontend.py +870 -0
- moai_adk/foundation/git/commit_templates.py +4 -12
- moai_adk/foundation/git.py +376 -0
- moai_adk/foundation/langs.py +484 -0
- moai_adk/foundation/ml_ops.py +1162 -0
- moai_adk/foundation/testing.py +1524 -0
- moai_adk/foundation/trust/trust_principles.py +23 -72
- moai_adk/foundation/trust/validation_checklist.py +57 -162
- moai_adk/project/__init__.py +0 -0
- moai_adk/project/configuration.py +1084 -0
- moai_adk/project/documentation.py +566 -0
- moai_adk/project/schema.py +447 -0
- moai_adk/statusline/alfred_detector.py +1 -3
- moai_adk/statusline/config.py +13 -4
- moai_adk/statusline/enhanced_output_style_detector.py +23 -15
- moai_adk/statusline/main.py +51 -15
- moai_adk/statusline/renderer.py +104 -48
- moai_adk/statusline/update_checker.py +3 -9
- moai_adk/statusline/version_reader.py +140 -46
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +549 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +445 -0
- moai_adk/templates/.claude/agents/moai/builder-command.md +1132 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +601 -0
- moai_adk/templates/.claude/agents/moai/expert-backend.md +831 -0
- moai_adk/templates/.claude/agents/moai/expert-database.md +774 -0
- moai_adk/templates/.claude/agents/moai/expert-debug.md +396 -0
- moai_adk/templates/.claude/agents/moai/expert-devops.md +711 -0
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +666 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +474 -0
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +1038 -0
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +429 -0
- moai_adk/templates/.claude/agents/moai/manager-docs.md +570 -0
- moai_adk/templates/.claude/agents/moai/manager-git.md +937 -0
- moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
- moai_adk/templates/.claude/agents/moai/manager-quality.md +598 -0
- moai_adk/templates/.claude/agents/moai/manager-spec.md +713 -0
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +600 -0
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +603 -0
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +369 -0
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +1567 -0
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +749 -0
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +427 -0
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +994 -0
- moai_adk/templates/.claude/commands/moai/0-project.md +1143 -0
- moai_adk/templates/.claude/commands/moai/1-plan.md +1435 -0
- moai_adk/templates/.claude/commands/moai/2-run.md +883 -0
- moai_adk/templates/.claude/commands/moai/3-sync.md +993 -0
- moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
- moai_adk/templates/.claude/hooks/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
- moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
- moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
- moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
- moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +921 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +380 -0
- moai_adk/templates/.claude/output-styles/moai/yoda.md +338 -0
- moai_adk/templates/.claude/settings.json +172 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +247 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +319 -0
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +320 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +496 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +453 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/design-system-tokens.md +405 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +491 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +201 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +438 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +515 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +346 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +362 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/SKILL.md +352 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/README.md +52 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/error-handling.md +334 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/integration-patterns.md +310 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/security-authentication.md +256 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/server-architecture.md +253 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/README.md +133 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/SKILL.md +296 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/examples.md +1269 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/reference.md +331 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +298 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +316 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +370 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/README.md +186 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/SKILL.md +290 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/examples.md +1225 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/reference.md +567 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/scripts/provider-selector.py +323 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/templates/stack-config.yaml +204 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +446 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +387 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +135 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1362 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +374 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +453 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +410 -0
- moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
- moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
- moai_adk/templates/.git-hooks/pre-commit +103 -41
- moai_adk/templates/.git-hooks/pre-push +116 -21
- moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
- moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
- moai_adk/templates/.gitignore +184 -44
- moai_adk/templates/.mcp.json +7 -9
- moai_adk/templates/.moai/cache/personalization.json +10 -0
- moai_adk/templates/.moai/config/config.yaml +344 -0
- moai_adk/templates/.moai/config/presets/manual.yaml +28 -0
- moai_adk/templates/.moai/config/presets/personal.yaml +30 -0
- moai_adk/templates/.moai/config/presets/team.yaml +33 -0
- moai_adk/templates/.moai/config/questions/_schema.yaml +79 -0
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +108 -0
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +122 -0
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +542 -0
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +167 -0
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +152 -0
- moai_adk/templates/.moai/config/sections/git-strategy.yaml +40 -0
- moai_adk/templates/.moai/config/sections/language.yaml +11 -0
- moai_adk/templates/.moai/config/sections/project.yaml +13 -0
- moai_adk/templates/.moai/config/sections/quality.yaml +15 -0
- moai_adk/templates/.moai/config/sections/system.yaml +14 -0
- moai_adk/templates/.moai/config/sections/user.yaml +5 -0
- moai_adk/templates/.moai/config/statusline-config.yaml +86 -0
- moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
- moai_adk/templates/CLAUDE.md +382 -501
- moai_adk/utils/__init__.py +24 -1
- moai_adk/utils/banner.py +7 -10
- moai_adk/utils/common.py +16 -30
- moai_adk/utils/link_validator.py +4 -12
- moai_adk/utils/safe_file_reader.py +2 -6
- moai_adk/utils/timeout.py +160 -0
- moai_adk/utils/toon_utils.py +256 -0
- moai_adk/version.py +22 -0
- moai_adk-0.32.8.dist-info/METADATA +2478 -0
- moai_adk-0.32.8.dist-info/RECORD +396 -0
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/WHEEL +1 -1
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/entry_points.txt +1 -0
- moai_adk/cli/commands/backup.py +0 -82
- moai_adk/cli/commands/improve_user_experience.py +0 -348
- moai_adk/cli/commands/migrate.py +0 -158
- moai_adk/cli/commands/validate_links.py +0 -118
- moai_adk/templates/.github/workflows/moai-gitflow.yml +0 -413
- moai_adk/templates/.github/workflows/moai-release-create.yml +0 -100
- moai_adk/templates/.github/workflows/moai-release-pipeline.yml +0 -188
- moai_adk/utils/user_experience.py +0 -531
- moai_adk-0.25.4.dist-info/METADATA +0 -2279
- moai_adk-0.25.4.dist-info/RECORD +0 -112
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/licenses/LICENSE +0 -0
moai_adk/core/template_engine.py
CHANGED
|
@@ -4,8 +4,11 @@ Template engine for parameterizing GitHub templates and other configuration file
|
|
|
4
4
|
Supports Jinja2-style templating with variable substitution and conditional sections.
|
|
5
5
|
Enables users to customize MoAI-ADK templates for their own projects.
|
|
6
6
|
|
|
7
|
+
Performance: Jinja2 Environment instances are cached to avoid recreation overhead
|
|
8
|
+
(40-60ms per render → ~1ms after caching).
|
|
7
9
|
"""
|
|
8
10
|
|
|
11
|
+
from functools import lru_cache
|
|
9
12
|
from pathlib import Path
|
|
10
13
|
from typing import Any, Dict, Optional
|
|
11
14
|
|
|
@@ -20,6 +23,49 @@ from jinja2 import (
|
|
|
20
23
|
)
|
|
21
24
|
|
|
22
25
|
|
|
26
|
+
# Module-level cached Environment factory functions
|
|
27
|
+
@lru_cache(maxsize=2)
|
|
28
|
+
def _get_string_environment(strict: bool) -> Environment:
|
|
29
|
+
"""
|
|
30
|
+
Get cached Jinja2 Environment for string rendering.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
strict: If True, raise error on undefined variables
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Cached Environment instance
|
|
37
|
+
|
|
38
|
+
Performance: Cached to avoid Environment recreation overhead
|
|
39
|
+
"""
|
|
40
|
+
return Environment(
|
|
41
|
+
undefined=StrictUndefined if strict else Undefined,
|
|
42
|
+
trim_blocks=False,
|
|
43
|
+
lstrip_blocks=False,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@lru_cache(maxsize=8)
|
|
48
|
+
def _get_file_environment(template_dir: str, strict: bool) -> Environment:
|
|
49
|
+
"""
|
|
50
|
+
Get cached Jinja2 Environment for file rendering.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
template_dir: Template directory path (string for hashability)
|
|
54
|
+
strict: If True, raise error on undefined variables
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Cached Environment instance with FileSystemLoader
|
|
58
|
+
|
|
59
|
+
Performance: Cached to avoid Environment recreation overhead
|
|
60
|
+
"""
|
|
61
|
+
return Environment(
|
|
62
|
+
loader=FileSystemLoader(template_dir),
|
|
63
|
+
undefined=StrictUndefined if strict else Undefined,
|
|
64
|
+
trim_blocks=False,
|
|
65
|
+
lstrip_blocks=False,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
23
69
|
class TemplateEngine:
|
|
24
70
|
"""
|
|
25
71
|
Jinja2-based template engine for MoAI-ADK configuration and GitHub templates.
|
|
@@ -59,13 +105,12 @@ class TemplateEngine:
|
|
|
59
105
|
Raises:
|
|
60
106
|
TemplateSyntaxError: If template syntax is invalid
|
|
61
107
|
TemplateRuntimeError: If variable substitution fails in strict mode
|
|
108
|
+
|
|
109
|
+
Performance: Uses cached Environment instance (40-60ms → ~1ms)
|
|
62
110
|
"""
|
|
63
111
|
try:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
trim_blocks=False,
|
|
67
|
-
lstrip_blocks=False,
|
|
68
|
-
)
|
|
112
|
+
# Use cached Environment instead of creating new one
|
|
113
|
+
env = _get_string_environment(strict=self.strict_undefined)
|
|
69
114
|
template = env.from_string(template_string)
|
|
70
115
|
return template.render(**variables)
|
|
71
116
|
except (TemplateSyntaxError, TemplateRuntimeError) as e:
|
|
@@ -92,6 +137,8 @@ class TemplateEngine:
|
|
|
92
137
|
FileNotFoundError: If template file doesn't exist
|
|
93
138
|
TemplateSyntaxError: If template syntax is invalid
|
|
94
139
|
TemplateRuntimeError: If variable substitution fails in strict mode
|
|
140
|
+
|
|
141
|
+
Performance: Uses cached Environment instance (40-60ms → ~1ms)
|
|
95
142
|
"""
|
|
96
143
|
if not template_path.exists():
|
|
97
144
|
raise FileNotFoundError(f"Template file not found: {template_path}")
|
|
@@ -100,12 +147,8 @@ class TemplateEngine:
|
|
|
100
147
|
template_name = template_path.name
|
|
101
148
|
|
|
102
149
|
try:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
undefined=self.undefined_behavior,
|
|
106
|
-
trim_blocks=False,
|
|
107
|
-
lstrip_blocks=False,
|
|
108
|
-
)
|
|
150
|
+
# Use cached Environment instead of creating new one
|
|
151
|
+
env = _get_file_environment(template_dir=str(template_dir), strict=self.strict_undefined)
|
|
109
152
|
template = env.get_template(template_name)
|
|
110
153
|
rendered = template.render(**variables)
|
|
111
154
|
|
|
@@ -115,9 +158,7 @@ class TemplateEngine:
|
|
|
115
158
|
|
|
116
159
|
return rendered
|
|
117
160
|
except TemplateNotFound:
|
|
118
|
-
raise FileNotFoundError(
|
|
119
|
-
f"Template not found in {template_dir}: {template_name}"
|
|
120
|
-
)
|
|
161
|
+
raise FileNotFoundError(f"Template not found in {template_dir}: {template_name}")
|
|
121
162
|
except (TemplateSyntaxError, TemplateRuntimeError) as e:
|
|
122
163
|
raise RuntimeError(f"Template rendering error in {template_path}: {e}")
|
|
123
164
|
|
|
@@ -173,7 +214,8 @@ class TemplateEngine:
|
|
|
173
214
|
Returns:
|
|
174
215
|
Dictionary of template variables
|
|
175
216
|
"""
|
|
176
|
-
|
|
217
|
+
github_templates_config = config.get("github", {}).get("templates", {})
|
|
218
|
+
github_config = config.get("github", {})
|
|
177
219
|
project_config = config.get("project", {})
|
|
178
220
|
user_config = config.get("user", {})
|
|
179
221
|
|
|
@@ -181,28 +223,23 @@ class TemplateEngine:
|
|
|
181
223
|
# Project information
|
|
182
224
|
"PROJECT_NAME": project_config.get("name", "MyProject"),
|
|
183
225
|
"PROJECT_DESCRIPTION": project_config.get("description", ""),
|
|
184
|
-
"PROJECT_OWNER": project_config.get("owner", ""),
|
|
226
|
+
"PROJECT_OWNER": project_config.get("owner", ""), # GitHub username (project owner)
|
|
227
|
+
"GITHUB_PROFILE_NAME": github_config.get("profile_name", ""),
|
|
185
228
|
"PROJECT_MODE": project_config.get("mode", "team"), # team or personal
|
|
186
229
|
"CODEBASE_LANGUAGE": project_config.get("codebase_language", "python"),
|
|
187
230
|
# User information
|
|
188
231
|
"USER_NAME": user_config.get("name", ""),
|
|
189
232
|
# Directory structure
|
|
190
|
-
"SPEC_DIR":
|
|
191
|
-
"DOCS_DIR":
|
|
192
|
-
"TEST_DIR":
|
|
233
|
+
"SPEC_DIR": github_templates_config.get("spec_directory", ".moai/specs"),
|
|
234
|
+
"DOCS_DIR": github_templates_config.get("docs_directory", ".moai/docs"),
|
|
235
|
+
"TEST_DIR": github_templates_config.get("test_directory", "tests"),
|
|
193
236
|
# Feature flags
|
|
194
237
|
"ENABLE_TRUST_5": github_config.get("enable_trust_5", True),
|
|
195
|
-
"ENABLE_ALFRED_COMMANDS":
|
|
238
|
+
"ENABLE_ALFRED_COMMANDS": github_templates_config.get("enable_alfred_commands", True),
|
|
196
239
|
# Language configuration
|
|
197
|
-
"CONVERSATION_LANGUAGE": config.get("language", {}).get(
|
|
198
|
-
|
|
199
|
-
),
|
|
200
|
-
"CONVERSATION_LANGUAGE_NAME": config.get("language", {}).get(
|
|
201
|
-
"conversation_language_name", "English"
|
|
202
|
-
),
|
|
203
|
-
"AGENT_PROMPT_LANGUAGE": config.get("language", {}).get(
|
|
204
|
-
"agent_prompt_language", "english"
|
|
205
|
-
),
|
|
240
|
+
"CONVERSATION_LANGUAGE": config.get("language", {}).get("conversation_language", "en"),
|
|
241
|
+
"CONVERSATION_LANGUAGE_NAME": config.get("language", {}).get("conversation_language_name", "English"),
|
|
242
|
+
"AGENT_PROMPT_LANGUAGE": config.get("language", {}).get("agent_prompt_language", "english"),
|
|
206
243
|
# Additional metadata
|
|
207
244
|
"MOAI_VERSION": config.get("moai", {}).get("version", "0.7.0"),
|
|
208
245
|
}
|
|
@@ -253,25 +290,21 @@ class TemplateVariableValidator:
|
|
|
253
290
|
errors.append(f"Missing required variable: {var_name}")
|
|
254
291
|
elif not isinstance(variables[var_name], var_type):
|
|
255
292
|
actual_type = type(variables[var_name]).__name__
|
|
256
|
-
errors.append(
|
|
257
|
-
f"Invalid type for {var_name}: "
|
|
258
|
-
f"expected {var_type.__name__}, got {actual_type}"
|
|
259
|
-
)
|
|
293
|
+
errors.append(f"Invalid type for {var_name}: expected {var_type.__name__}, got {actual_type}")
|
|
260
294
|
|
|
261
295
|
# Check optional variables (if present)
|
|
262
296
|
for var_name, var_type in cls.OPTIONAL_VARIABLES.items():
|
|
263
297
|
if var_name in variables:
|
|
264
298
|
if not isinstance(variables[var_name], var_type):
|
|
265
299
|
if isinstance(var_type, tuple):
|
|
266
|
-
type_names =
|
|
267
|
-
getattr(t, "__name__", str(t)) for t in var_type
|
|
268
|
-
|
|
300
|
+
type_names = (
|
|
301
|
+
" or ".join(getattr(t, "__name__", str(t)) for t in var_type)
|
|
302
|
+
if var_type is not None
|
|
303
|
+
else "unknown"
|
|
304
|
+
) # type: ignore[union-attr]
|
|
269
305
|
else:
|
|
270
306
|
type_names = getattr(var_type, "__name__", str(var_type))
|
|
271
307
|
actual_type = type(variables[var_name]).__name__
|
|
272
|
-
errors.append(
|
|
273
|
-
f"Invalid type for {var_name}: "
|
|
274
|
-
f"expected {type_names}, got {actual_type}"
|
|
275
|
-
)
|
|
308
|
+
errors.append(f"Invalid type for {var_name}: expected {type_names}, got {actual_type}")
|
|
276
309
|
|
|
277
310
|
return len(errors) == 0, errors
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Template Variable Synchronizer for MoAI-ADK
|
|
3
|
+
|
|
4
|
+
Handles synchronization of template variables when configuration is updated
|
|
5
|
+
through /moai:0-project command or other configuration management operations.
|
|
6
|
+
|
|
7
|
+
This module ensures that when language or user settings change, all template
|
|
8
|
+
variables in the system are properly updated to reflect the new configuration.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import re
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any, Dict, List, Optional
|
|
15
|
+
|
|
16
|
+
from .language_config_resolver import get_resolver
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TemplateVariableSynchronizer:
|
|
20
|
+
"""
|
|
21
|
+
Synchronizes template variables across the MoAI-ADK system when configuration changes.
|
|
22
|
+
|
|
23
|
+
Responsible for:
|
|
24
|
+
- Detecting template variables that need updating
|
|
25
|
+
- Re-substituting variables in affected files
|
|
26
|
+
- Maintaining consistency between config and template files
|
|
27
|
+
- Tracking template variable usage across the project
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
# Template variable patterns to track and synchronize
|
|
31
|
+
TEMPLATE_PATTERNS = {
|
|
32
|
+
r"\{\{CONVERSATION_LANGUAGE\}\}",
|
|
33
|
+
r"\{\{CONVERSATION_LANGUAGE_NAME\}\}",
|
|
34
|
+
r"\{\{AGENT_PROMPT_LANGUAGE\}\}",
|
|
35
|
+
r"\{\{USER_NAME\}\}",
|
|
36
|
+
r"\{\{PERSONALIZED_GREETING\}\}",
|
|
37
|
+
r"\{\{LANGUAGE_CONFIG_SOURCE\}\}",
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Files that typically contain template variables
|
|
41
|
+
TEMPLATE_TRACKING_PATTERNS = [
|
|
42
|
+
".claude/settings.json",
|
|
43
|
+
".claude/settings.local.json",
|
|
44
|
+
".moai/config/config.json",
|
|
45
|
+
".claude/output-styles/**/*.md",
|
|
46
|
+
".claude/hooks/**/*.py",
|
|
47
|
+
".claude/commands/**/*.md",
|
|
48
|
+
".claude/skills/**/*.md",
|
|
49
|
+
"CLAUDE.md",
|
|
50
|
+
"README.md",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
def __init__(self, project_root: str):
|
|
54
|
+
"""
|
|
55
|
+
Initialize the synchronizer.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
project_root: Root directory of the MoAI-ADK project
|
|
59
|
+
"""
|
|
60
|
+
self.project_root = Path(project_root)
|
|
61
|
+
self.language_resolver = get_resolver(project_root)
|
|
62
|
+
|
|
63
|
+
def synchronize_after_config_change(self, changed_config_path: Optional[Path] = None) -> Dict[str, Any]:
|
|
64
|
+
"""
|
|
65
|
+
Synchronize template variables after configuration changes.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
changed_config_path: Path to the configuration file that was changed
|
|
69
|
+
(None if unknown or multiple files changed)
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Dictionary containing synchronization results
|
|
73
|
+
"""
|
|
74
|
+
results: Dict[str, Any] = {
|
|
75
|
+
"files_updated": 0,
|
|
76
|
+
"variables_updated": [],
|
|
77
|
+
"errors": [],
|
|
78
|
+
"sync_status": "completed",
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
# Get current resolved configuration
|
|
83
|
+
current_config = self.language_resolver.resolve_config(force_refresh=True)
|
|
84
|
+
template_vars = self.language_resolver.export_template_variables(current_config)
|
|
85
|
+
|
|
86
|
+
# Find files that need updating
|
|
87
|
+
files_to_update = self._find_files_with_template_variables(changed_config_path)
|
|
88
|
+
|
|
89
|
+
# Update each file
|
|
90
|
+
for file_path in files_to_update:
|
|
91
|
+
try:
|
|
92
|
+
updated_vars = self._update_file_template_variables(file_path, template_vars)
|
|
93
|
+
if updated_vars:
|
|
94
|
+
files_updated: int = results["files_updated"] # type: ignore[assignment]
|
|
95
|
+
results["files_updated"] = files_updated + 1
|
|
96
|
+
variables_updated: List[str] = results["variables_updated"] # type: ignore[assignment]
|
|
97
|
+
variables_updated.extend(updated_vars)
|
|
98
|
+
|
|
99
|
+
except Exception as e:
|
|
100
|
+
error_msg = f"Failed to update {file_path}: {str(e)}"
|
|
101
|
+
errors: List[str] = results["errors"] # type: ignore[assignment]
|
|
102
|
+
errors.append(error_msg)
|
|
103
|
+
|
|
104
|
+
# Special handling for certain file types
|
|
105
|
+
self._handle_special_file_updates(template_vars, results)
|
|
106
|
+
|
|
107
|
+
except Exception as e:
|
|
108
|
+
results["sync_status"] = "failed"
|
|
109
|
+
errors_list: List[str] = results["errors"] # type: ignore[assignment]
|
|
110
|
+
errors_list.append(f"Synchronization failed: {str(e)}")
|
|
111
|
+
|
|
112
|
+
return results
|
|
113
|
+
|
|
114
|
+
def _find_files_with_template_variables(self, changed_config_path: Optional[Path]) -> List[Path]:
|
|
115
|
+
"""
|
|
116
|
+
Find files that contain template variables and might need updating.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
changed_config_path: Specific config file that changed, if known
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
List of file paths that contain template variables
|
|
123
|
+
"""
|
|
124
|
+
files_with_variables = []
|
|
125
|
+
|
|
126
|
+
# If a specific config file changed, prioritize files that depend on it
|
|
127
|
+
if changed_config_path:
|
|
128
|
+
dependency_map = {
|
|
129
|
+
".moai/config/config.json": [
|
|
130
|
+
".claude/settings.json",
|
|
131
|
+
".claude/settings.local.json",
|
|
132
|
+
".claude/output-styles",
|
|
133
|
+
".claude/hooks",
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
config_key = str(changed_config_path.relative_to(self.project_root))
|
|
138
|
+
if config_key in dependency_map:
|
|
139
|
+
for pattern in dependency_map[config_key]:
|
|
140
|
+
files_with_variables.extend(self._glob_files(pattern))
|
|
141
|
+
|
|
142
|
+
# Always check common template files
|
|
143
|
+
common_patterns = [
|
|
144
|
+
".claude/settings.json",
|
|
145
|
+
".claude/settings.local.json",
|
|
146
|
+
".claude/output-styles/**/*.md",
|
|
147
|
+
"CLAUDE.md",
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
for pattern in common_patterns:
|
|
151
|
+
files_with_variables.extend(self._glob_files(pattern))
|
|
152
|
+
|
|
153
|
+
# Remove duplicates and sort
|
|
154
|
+
files_with_variables = list(set(files_with_variables))
|
|
155
|
+
files_with_variables.sort()
|
|
156
|
+
|
|
157
|
+
return [f for f in files_with_variables if f.exists() and f.is_file()]
|
|
158
|
+
|
|
159
|
+
def _glob_files(self, pattern: str) -> List[Path]:
|
|
160
|
+
"""
|
|
161
|
+
Glob files matching a pattern.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
pattern: Glob pattern (supports ** for recursive matching)
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
List of matching file paths
|
|
168
|
+
"""
|
|
169
|
+
try:
|
|
170
|
+
return list(self.project_root.glob(pattern))
|
|
171
|
+
except (OSError, ValueError):
|
|
172
|
+
return []
|
|
173
|
+
|
|
174
|
+
def _update_file_template_variables(self, file_path: Path, template_vars: Dict[str, str]) -> List[str]:
|
|
175
|
+
"""
|
|
176
|
+
Update template variables in a specific file.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
file_path: Path to the file to update
|
|
180
|
+
template_vars: Dictionary of template variables to substitute
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
List of variable names that were updated in this file
|
|
184
|
+
"""
|
|
185
|
+
if not file_path.exists():
|
|
186
|
+
return []
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
content = file_path.read_text(encoding="utf-8")
|
|
190
|
+
original_content = content
|
|
191
|
+
|
|
192
|
+
# Track which variables were updated
|
|
193
|
+
updated_vars = []
|
|
194
|
+
|
|
195
|
+
# Apply each template variable substitution
|
|
196
|
+
for var_name, var_value in template_vars.items():
|
|
197
|
+
# Look for {{VARIABLE_NAME}} pattern
|
|
198
|
+
pattern = re.compile(r"\{\{" + re.escape(var_name) + r"\}\}")
|
|
199
|
+
|
|
200
|
+
if pattern.search(content):
|
|
201
|
+
content = pattern.sub(var_value, content)
|
|
202
|
+
updated_vars.append(var_name)
|
|
203
|
+
|
|
204
|
+
# Only write if content changed
|
|
205
|
+
if content != original_content:
|
|
206
|
+
file_path.write_text(content, encoding="utf-8")
|
|
207
|
+
|
|
208
|
+
return updated_vars
|
|
209
|
+
|
|
210
|
+
except (OSError, UnicodeDecodeError, UnicodeEncodeError):
|
|
211
|
+
# File read/write errors - skip this file
|
|
212
|
+
return []
|
|
213
|
+
|
|
214
|
+
def _handle_special_file_updates(self, template_vars: Dict[str, str], results: Dict[str, Any]) -> None:
|
|
215
|
+
"""
|
|
216
|
+
Handle special cases for certain file types.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
template_vars: Dictionary of template variables
|
|
220
|
+
results: Results dictionary to update
|
|
221
|
+
"""
|
|
222
|
+
# Handle settings.json environment variables section
|
|
223
|
+
settings_file = self.project_root / ".claude" / "settings.json"
|
|
224
|
+
if settings_file.exists():
|
|
225
|
+
try:
|
|
226
|
+
self._update_settings_env_vars(settings_file, template_vars, results)
|
|
227
|
+
except Exception as e:
|
|
228
|
+
results["errors"].append(f"Failed to update settings.json env vars: {str(e)}")
|
|
229
|
+
|
|
230
|
+
def _update_settings_env_vars(
|
|
231
|
+
self,
|
|
232
|
+
settings_file: Path,
|
|
233
|
+
template_vars: Dict[str, str],
|
|
234
|
+
results: Dict[str, Any],
|
|
235
|
+
) -> None:
|
|
236
|
+
"""
|
|
237
|
+
Update the environment variables section in settings.json.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
settings_file: Path to settings.json
|
|
241
|
+
template_vars: Template variables to use for env values
|
|
242
|
+
results: Results dictionary to update
|
|
243
|
+
"""
|
|
244
|
+
try:
|
|
245
|
+
settings_data = json.loads(settings_file.read_text(encoding="utf-8"))
|
|
246
|
+
|
|
247
|
+
# Define environment variable mappings
|
|
248
|
+
env_mappings = {
|
|
249
|
+
"CONVERSATION_LANGUAGE": "MOAI_CONVERSATION_LANG",
|
|
250
|
+
"AGENT_PROMPT_LANGUAGE": "MOAI_AGENT_PROMPT_LANG",
|
|
251
|
+
"CONVERSATION_LANGUAGE_NAME": "MOAI_CONVERSATION_LANG_NAME",
|
|
252
|
+
"USER_NAME": "MOAI_USER_NAME",
|
|
253
|
+
"LANGUAGE_CONFIG_SOURCE": "MOAI_CONFIG_SOURCE",
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
# Update or create env section
|
|
257
|
+
if "env" not in settings_data:
|
|
258
|
+
settings_data["env"] = {}
|
|
259
|
+
|
|
260
|
+
updated_vars = []
|
|
261
|
+
for template_var, env_var in env_mappings.items():
|
|
262
|
+
if template_var in template_vars:
|
|
263
|
+
old_value = settings_data["env"].get(env_var)
|
|
264
|
+
new_value = template_vars[template_var]
|
|
265
|
+
|
|
266
|
+
if old_value != new_value:
|
|
267
|
+
settings_data["env"][env_var] = new_value
|
|
268
|
+
updated_vars.append(f"{env_var}: {old_value} → {new_value}")
|
|
269
|
+
|
|
270
|
+
# Write back if changed
|
|
271
|
+
if updated_vars:
|
|
272
|
+
settings_file.write_text(
|
|
273
|
+
json.dumps(settings_data, indent=2, ensure_ascii=False) + "\n",
|
|
274
|
+
encoding="utf-8",
|
|
275
|
+
)
|
|
276
|
+
results["files_updated"] += 1
|
|
277
|
+
results["variables_updated"].extend(updated_vars)
|
|
278
|
+
|
|
279
|
+
except (json.JSONDecodeError, OSError, UnicodeDecodeError, UnicodeEncodeError):
|
|
280
|
+
# Skip if settings.json is malformed or can't be accessed
|
|
281
|
+
pass
|
|
282
|
+
|
|
283
|
+
def validate_template_variable_consistency(self) -> Dict[str, Any]:
|
|
284
|
+
"""
|
|
285
|
+
Validate that template variables are consistent across the project.
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
Dictionary containing validation results
|
|
289
|
+
"""
|
|
290
|
+
validation_results = {
|
|
291
|
+
"status": "passed",
|
|
292
|
+
"inconsistencies": [],
|
|
293
|
+
"total_files_checked": 0,
|
|
294
|
+
"files_with_variables": 0,
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
try:
|
|
298
|
+
# Get current template variables
|
|
299
|
+
current_config = self.language_resolver.resolve_config()
|
|
300
|
+
current_vars = self.language_resolver.export_template_variables(current_config)
|
|
301
|
+
|
|
302
|
+
# Check files for template variable consistency
|
|
303
|
+
files_with_variables = self._find_files_with_template_variables(None)
|
|
304
|
+
validation_results["total_files_checked"] = len(files_with_variables)
|
|
305
|
+
|
|
306
|
+
for file_path in files_with_variables:
|
|
307
|
+
try:
|
|
308
|
+
content = file_path.read_text(encoding="utf-8")
|
|
309
|
+
file_inconsistencies: List[str] = []
|
|
310
|
+
|
|
311
|
+
# Check each template variable
|
|
312
|
+
for var_name, expected_value in current_vars.items():
|
|
313
|
+
pattern = re.compile(r"\{\{" + re.escape(var_name) + r"\}\}")
|
|
314
|
+
|
|
315
|
+
if pattern.search(content):
|
|
316
|
+
files_with_vars: int = validation_results["files_with_variables"] # type: ignore[assignment]
|
|
317
|
+
validation_results["files_with_variables"] = files_with_vars + 1
|
|
318
|
+
# Variable found but not substituted - this might be expected
|
|
319
|
+
# Only report as inconsistency if we expect it to be substituted
|
|
320
|
+
pass
|
|
321
|
+
|
|
322
|
+
if file_inconsistencies:
|
|
323
|
+
inconsistencies: List[Dict[str, Any]] = validation_results["inconsistencies"] # type: ignore[assignment]
|
|
324
|
+
inconsistencies.append(
|
|
325
|
+
{
|
|
326
|
+
"file": str(file_path.relative_to(self.project_root)),
|
|
327
|
+
"issues": file_inconsistencies,
|
|
328
|
+
}
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
except (OSError, UnicodeDecodeError):
|
|
332
|
+
# Skip files that can't be read
|
|
333
|
+
continue
|
|
334
|
+
|
|
335
|
+
if validation_results["inconsistencies"]:
|
|
336
|
+
validation_results["status"] = "warning"
|
|
337
|
+
|
|
338
|
+
except Exception as e:
|
|
339
|
+
validation_results["status"] = "failed"
|
|
340
|
+
validation_results["error"] = str(e)
|
|
341
|
+
|
|
342
|
+
return validation_results
|
|
343
|
+
|
|
344
|
+
def get_template_variable_usage_report(self) -> Dict[str, Any]:
|
|
345
|
+
"""
|
|
346
|
+
Generate a report of template variable usage across the project.
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
Dictionary containing template variable usage statistics
|
|
350
|
+
"""
|
|
351
|
+
usage_report = {
|
|
352
|
+
"total_files_with_variables": 0,
|
|
353
|
+
"variable_usage": {},
|
|
354
|
+
"files_by_variable": {},
|
|
355
|
+
"unsubstituted_variables": [],
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
try:
|
|
359
|
+
files_with_variables = self._find_files_with_template_variables(None)
|
|
360
|
+
usage_report["total_files_with_variables"] = len(files_with_variables)
|
|
361
|
+
|
|
362
|
+
for file_path in files_with_variables:
|
|
363
|
+
try:
|
|
364
|
+
content = file_path.read_text(encoding="utf-8")
|
|
365
|
+
relative_path = str(file_path.relative_to(self.project_root))
|
|
366
|
+
|
|
367
|
+
# Check for each template variable pattern
|
|
368
|
+
for pattern_str in self.TEMPLATE_PATTERNS:
|
|
369
|
+
pattern = re.compile(pattern_str)
|
|
370
|
+
matches = pattern.findall(content)
|
|
371
|
+
|
|
372
|
+
if matches:
|
|
373
|
+
var_name = pattern_str.strip(r"{}")
|
|
374
|
+
variable_usage: Dict[str, int] = usage_report["variable_usage"] # type: ignore[assignment]
|
|
375
|
+
files_by_variable: Dict[str, List[str]] = usage_report["files_by_variable"] # type: ignore[assignment]
|
|
376
|
+
unsubstituted_variables: List[Dict[str, Any]] = usage_report["unsubstituted_variables"] # type: ignore[assignment]
|
|
377
|
+
|
|
378
|
+
if var_name not in variable_usage:
|
|
379
|
+
variable_usage[var_name] = 0
|
|
380
|
+
files_by_variable[var_name] = []
|
|
381
|
+
|
|
382
|
+
variable_usage[var_name] += len(matches)
|
|
383
|
+
files_by_variable[var_name].append(relative_path)
|
|
384
|
+
|
|
385
|
+
# Track unsubstituted variables
|
|
386
|
+
unsubstituted_variables.append(
|
|
387
|
+
{
|
|
388
|
+
"file": relative_path,
|
|
389
|
+
"variable": var_name,
|
|
390
|
+
"count": len(matches),
|
|
391
|
+
}
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
except (OSError, UnicodeDecodeError):
|
|
395
|
+
continue
|
|
396
|
+
|
|
397
|
+
except Exception as e:
|
|
398
|
+
usage_report["error"] = str(e)
|
|
399
|
+
|
|
400
|
+
return usage_report
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def synchronize_template_variables(project_root: str, changed_config_path: Optional[str] = None) -> Dict[str, Any]:
|
|
404
|
+
"""
|
|
405
|
+
Convenience function to synchronize template variables.
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
project_root: Root directory of the project
|
|
409
|
+
changed_config_path: Path to configuration file that changed
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
Synchronization results
|
|
413
|
+
"""
|
|
414
|
+
synchronizer = TemplateVariableSynchronizer(project_root)
|
|
415
|
+
|
|
416
|
+
config_path = Path(changed_config_path) if changed_config_path else None
|
|
417
|
+
return synchronizer.synchronize_after_config_change(config_path)
|