moai-adk 0.4.5__py3-none-any.whl → 0.20.1__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 +1 -1
- moai_adk/__main__.py +74 -1
- moai_adk/cli/commands/__init__.py +1 -1
- moai_adk/cli/commands/analyze.py +119 -0
- moai_adk/cli/commands/backup.py +25 -1
- moai_adk/cli/commands/doctor.py +31 -5
- moai_adk/cli/commands/improve_user_experience.py +307 -0
- moai_adk/cli/commands/init.py +111 -10
- moai_adk/cli/commands/status.py +33 -3
- moai_adk/cli/commands/update.py +921 -130
- moai_adk/cli/commands/validate_links.py +120 -0
- moai_adk/cli/prompts/init_prompts.py +22 -87
- moai_adk/core/analysis/__init__.py +9 -0
- moai_adk/core/analysis/session_analyzer.py +388 -0
- moai_adk/core/analysis/tag_chain_analyzer.py +344 -0
- moai_adk/core/analysis/tag_chain_repair.py +879 -0
- moai_adk/core/config/__init__.py +19 -0
- moai_adk/core/config/migration.py +235 -0
- moai_adk/core/git/__init__.py +1 -1
- moai_adk/core/git/branch.py +1 -1
- moai_adk/core/git/commit.py +1 -1
- moai_adk/core/git/manager.py +1 -1
- moai_adk/core/issue_creator.py +313 -0
- moai_adk/core/mcp/setup.py +56 -0
- moai_adk/core/mcp/setup_old.py +296 -0
- moai_adk/core/project/backup_utils.py +1 -1
- moai_adk/core/project/checker.py +2 -2
- moai_adk/core/project/detector.py +211 -12
- moai_adk/core/project/initializer.py +85 -15
- moai_adk/core/project/phase_executor.py +76 -13
- moai_adk/core/project/validator.py +13 -13
- moai_adk/core/quality/__init__.py +1 -1
- moai_adk/core/quality/trust_checker.py +1 -1
- moai_adk/core/quality/validators/__init__.py +1 -1
- moai_adk/core/quality/validators/base_validator.py +1 -1
- moai_adk/core/tags/__init__.py +86 -0
- moai_adk/core/tags/auto_corrector.py +693 -0
- moai_adk/core/tags/ci_validator.py +463 -0
- moai_adk/core/tags/cli.py +283 -0
- moai_adk/core/tags/generator.py +109 -0
- moai_adk/core/tags/inserter.py +99 -0
- moai_adk/core/tags/mapper.py +126 -0
- moai_adk/core/tags/parser.py +76 -0
- moai_adk/core/tags/policy_validator.py +580 -0
- moai_adk/core/tags/pre_commit_validator.py +421 -0
- moai_adk/core/tags/reporter.py +956 -0
- moai_adk/core/tags/rollback_manager.py +525 -0
- moai_adk/core/tags/tags.py +149 -0
- moai_adk/core/tags/validator.py +897 -0
- moai_adk/core/template/__init__.py +1 -1
- moai_adk/core/template/backup.py +1 -1
- moai_adk/core/template/merger.py +50 -1
- moai_adk/core/template/processor.py +119 -13
- moai_adk/core/template_engine.py +268 -0
- moai_adk/templates/.claude/agents/alfred/backend-expert.md +348 -0
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +209 -944
- moai_adk/templates/.claude/agents/alfred/database-expert.md +352 -0
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +34 -5
- moai_adk/templates/.claude/agents/alfred/devops-expert.md +464 -0
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +38 -8
- moai_adk/templates/.claude/agents/alfred/format-expert.md +469 -0
- moai_adk/templates/.claude/agents/alfred/frontend-expert.md +357 -0
- moai_adk/templates/.claude/agents/alfred/git-manager.md +128 -9
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +104 -6
- moai_adk/templates/.claude/agents/alfred/project-manager.md +88 -16
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +36 -9
- moai_adk/templates/.claude/agents/alfred/security-expert.md +270 -0
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +865 -0
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +214 -43
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +111 -9
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +309 -160
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +36 -7
- moai_adk/templates/.claude/agents/alfred/ui-ux-expert.md +605 -0
- moai_adk/templates/.claude/commands/alfred/0-project.md +393 -966
- moai_adk/templates/.claude/commands/alfred/1-plan.md +651 -367
- moai_adk/templates/.claude/commands/alfred/2-run.md +388 -241
- moai_adk/templates/.claude/commands/alfred/3-sync.md +1921 -410
- moai_adk/templates/.claude/commands/alfred/9-feedback.md +153 -0
- moai_adk/templates/.claude/commands/alfred/release-new.md +3604 -0
- moai_adk/templates/.claude/hooks/alfred/core/project.py +484 -20
- moai_adk/templates/.claude/hooks/alfred/core/timeout.py +136 -0
- moai_adk/templates/.claude/hooks/alfred/core/ttl_cache.py +108 -0
- moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py +14 -6
- moai_adk/templates/.claude/hooks/alfred/post_tool__enable_streaming_ui.py +50 -0
- moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +93 -0
- moai_adk/templates/.claude/hooks/alfred/post_tool__tag_auto_corrector.py +407 -0
- moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +99 -0
- moai_adk/templates/.claude/hooks/alfred/pre_tool__realtime_tag_monitor.py +335 -0
- moai_adk/templates/.claude/hooks/alfred/pre_tool__tag_policy_validator.py +325 -0
- moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +93 -0
- moai_adk/templates/.claude/hooks/alfred/session_start__auto_cleanup.py +580 -0
- moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +298 -0
- moai_adk/templates/.claude/hooks/alfred/shared/core/__init__.py +170 -0
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/checkpoint.py +3 -3
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/context.py +5 -5
- moai_adk/templates/.claude/hooks/alfred/shared/core/project.py +749 -0
- moai_adk/templates/.claude/hooks/alfred/shared/core/tags.py +230 -0
- moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/__init__.py +21 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/daily_analysis.py +351 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/notification.py +154 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/session.py +174 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/tool.py +87 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/user.py +61 -0
- moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +111 -0
- moai_adk/templates/.claude/hooks/alfred/utils/__init__.py +1 -0
- moai_adk/templates/.claude/hooks/alfred/utils/hook_config.py +94 -0
- moai_adk/templates/.claude/hooks/alfred/utils/timeout.py +161 -0
- moai_adk/templates/.claude/output-styles/alfred/alfred-moai-adk-beginner.md +267 -0
- moai_adk/templates/.claude/output-styles/alfred/keating-personal-tutor.md +440 -0
- moai_adk/templates/.claude/output-styles/alfred/r2d2-agentic-coding.md +583 -0
- moai_adk/templates/.claude/settings.json +96 -14
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/SKILL.md +70 -0
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/examples.md +62 -0
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/reference.md +242 -0
- moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/SKILL.md +237 -0
- moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/examples.md +871 -0
- moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/reference.md +653 -0
- moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/README.md +162 -0
- moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/SKILL.md +227 -0
- moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/examples.md +354 -0
- moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/reference.md +158 -0
- moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/SKILL.md +179 -79
- moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/examples.md +117 -0
- moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/scripts/pre-review-check.sh +62 -0
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/SKILL.md +132 -0
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/examples.md +28 -0
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/reference.md +444 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/SKILL.md +62 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/examples.md +28 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/reference.md +405 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/SKILL.md +51 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/examples.md +355 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/reference.md +239 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/SKILL.md +323 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/examples.md +286 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/reference.md +126 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/SKILL.md +229 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/reference.md +150 -0
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/SKILL.md +87 -73
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/reference.md +28 -0
- moai_adk/templates/.claude/skills/moai-alfred-personas/README.md +42 -0
- moai_adk/templates/.claude/skills/moai-alfred-personas/SKILL.md +429 -0
- moai_adk/templates/.claude/skills/moai-alfred-personas/examples.md +520 -0
- moai_adk/templates/.claude/skills/moai-alfred-personas/reference.md +405 -0
- moai_adk/templates/.claude/skills/moai-alfred-practices/SKILL.md +89 -0
- moai_adk/templates/.claude/skills/moai-alfred-practices/examples.md +122 -0
- moai_adk/templates/.claude/skills/moai-alfred-practices/reference.md +369 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/SKILL.md +508 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/examples.md +481 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/reference.md +100 -0
- moai_adk/templates/.claude/skills/moai-alfred-rules/SKILL.md +77 -0
- moai_adk/templates/.claude/skills/moai-alfred-rules/examples.md +265 -0
- moai_adk/templates/.claude/skills/moai-alfred-rules/reference.md +539 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/SKILL.md +320 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/reference.md +84 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/README.md +137 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/SKILL.md +219 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples/validate-spec.sh +161 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples.md +541 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/reference.md +622 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/reference.md +211 -0
- moai_adk/templates/.claude/skills/moai-alfred-workflow/SKILL.md +288 -0
- moai_adk/templates/.claude/skills/moai-cc-agents/SKILL.md +269 -0
- moai_adk/templates/.claude/skills/moai-cc-agents/templates/agent-template.md +32 -0
- moai_adk/templates/.claude/skills/moai-cc-claude-md/SKILL.md +298 -0
- moai_adk/templates/.claude/skills/moai-cc-claude-md/templates/CLAUDE-template.md +26 -0
- moai_adk/templates/.claude/skills/moai-cc-commands/SKILL.md +307 -0
- moai_adk/templates/.claude/skills/moai-cc-commands/templates/command-template.md +21 -0
- moai_adk/templates/.claude/skills/moai-cc-hooks/SKILL.md +252 -0
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/pre-bash-check.sh +19 -0
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/preserve-permissions.sh +19 -0
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/validate-bash-command.py +24 -0
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/SKILL.md +199 -0
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/templates/settings-mcp-template.json +39 -0
- moai_adk/templates/.claude/skills/moai-cc-memory/SKILL.md +316 -0
- moai_adk/templates/.claude/skills/moai-cc-memory/templates/session-summary-template.md +18 -0
- moai_adk/templates/.claude/skills/moai-cc-settings/SKILL.md +263 -0
- moai_adk/templates/.claude/skills/moai-cc-settings/templates/settings-complete-template.json +30 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/CHECKLIST.md +482 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/EXAMPLES.md +303 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/INTERACTIVE-DISCOVERY.md +524 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/METADATA.md +477 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/PARALLEL-ANALYSIS-REPORT.md +429 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/PYTHON-VERSION-MATRIX.md +391 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-FACTORY-WORKFLOW.md +431 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-UPDATE-ADVISOR.md +577 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL.md +273 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/STEP-BY-STEP-GUIDE.md +466 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/STRUCTURE.md +583 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/WEB-RESEARCH.md +526 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/reference.md +608 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/generate-structure.sh +328 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/validate-skill.sh +312 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/SKILL_TEMPLATE.md +245 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/examples-template.md +285 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/reference-template.md +278 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/scripts-template.sh +303 -0
- moai_adk/templates/.claude/skills/moai-cc-skills/SKILL.md +291 -0
- moai_adk/templates/.claude/skills/moai-cc-skills/templates/SKILL-template.md +15 -0
- moai_adk/templates/.claude/skills/moai-change-logger/SKILL.md +563 -0
- moai_adk/templates/.claude/skills/moai-design-systems/SKILL.md +802 -0
- moai_adk/templates/.claude/skills/moai-design-systems/examples.md +1238 -0
- moai_adk/templates/.claude/skills/moai-design-systems/reference.md +673 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +234 -43
- moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +1633 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +660 -0
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/SKILL.md +97 -69
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-domain-data-science/SKILL.md +97 -72
- moai_adk/templates/.claude/skills/moai-domain-data-science/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-data-science/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +97 -74
- moai_adk/templates/.claude/skills/moai-domain-database/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-database/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-domain-devops/SKILL.md +98 -74
- moai_adk/templates/.claude/skills/moai-domain-devops/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-devops/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +102 -73
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-domain-ml/SKILL.md +97 -73
- moai_adk/templates/.claude/skills/moai-domain-ml/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-ml/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/SKILL.md +97 -67
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-domain-security/SKILL.md +97 -79
- moai_adk/templates/.claude/skills/moai-domain-security/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-security/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-domain-web-api/SKILL.md +97 -71
- moai_adk/templates/.claude/skills/moai-domain-web-api/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-domain-web-api/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-essentials-debug/SKILL.md +265 -64
- moai_adk/templates/.claude/skills/moai-essentials-debug/examples.md +1064 -0
- moai_adk/templates/.claude/skills/moai-essentials-debug/reference.md +1047 -0
- moai_adk/templates/.claude/skills/moai-essentials-perf/SKILL.md +87 -78
- moai_adk/templates/.claude/skills/moai-essentials-perf/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-essentials-perf/reference.md +28 -0
- moai_adk/templates/.claude/skills/moai-essentials-refactor/SKILL.md +87 -70
- moai_adk/templates/.claude/skills/moai-essentials-refactor/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-essentials-refactor/reference.md +28 -0
- moai_adk/templates/.claude/skills/moai-essentials-review/SKILL.md +87 -86
- moai_adk/templates/.claude/skills/moai-essentials-review/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-essentials-review/reference.md +28 -0
- moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +80 -62
- moai_adk/templates/.claude/skills/moai-foundation-ears/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-foundation-ears/reference.md +28 -0
- moai_adk/templates/.claude/skills/moai-foundation-git/SKILL.md +207 -50
- moai_adk/templates/.claude/skills/moai-foundation-git/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-foundation-git/reference.md +29 -0
- moai_adk/templates/.claude/skills/moai-foundation-langs/SKILL.md +90 -71
- moai_adk/templates/.claude/skills/moai-foundation-langs/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-foundation-langs/reference.md +28 -0
- moai_adk/templates/.claude/skills/moai-foundation-specs/SKILL.md +78 -58
- moai_adk/templates/.claude/skills/moai-foundation-specs/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-foundation-specs/reference.md +28 -0
- moai_adk/templates/.claude/skills/moai-foundation-tags/SKILL.md +78 -51
- moai_adk/templates/.claude/skills/moai-foundation-tags/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-foundation-tags/reference.md +28 -0
- moai_adk/templates/.claude/skills/moai-foundation-trust/.!11330!examples.md +0 -0
- moai_adk/templates/.claude/skills/moai-foundation-trust/SKILL.md +253 -32
- moai_adk/templates/.claude/skills/moai-foundation-trust/examples.md +0 -0
- moai_adk/templates/.claude/skills/moai-foundation-trust/reference.md +1099 -0
- moai_adk/templates/.claude/skills/moai-jit-docs-enhanced/SKILL.md +460 -0
- moai_adk/templates/.claude/skills/moai-lang-c/SKILL.md +98 -74
- moai_adk/templates/.claude/skills/moai-lang-c/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-c/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +98 -76
- moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +2358 -70
- moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-lang-dart/SKILL.md +2962 -68
- moai_adk/templates/.claude/skills/moai-lang-dart/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-dart/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +1898 -70
- moai_adk/templates/.claude/skills/moai-lang-go/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-go/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +1465 -68
- moai_adk/templates/.claude/skills/moai-lang-java/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-java/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +2364 -66
- moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +32 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +1630 -69
- moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +89 -61
- moai_adk/templates/.claude/skills/moai-lang-php/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-php/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +735 -66
- moai_adk/templates/.claude/skills/moai-lang-python/examples.md +624 -0
- moai_adk/templates/.claude/skills/moai-lang-python/reference.md +316 -0
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +97 -73
- moai_adk/templates/.claude/skills/moai-lang-r/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-r/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +98 -73
- moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +1834 -70
- moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +99 -74
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-lang-shell/SKILL.md +97 -74
- moai_adk/templates/.claude/skills/moai-lang-shell/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-shell/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-lang-sql/SKILL.md +98 -74
- moai_adk/templates/.claude/skills/moai-lang-sql/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-sql/reference.md +31 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +1959 -69
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +30 -0
- moai_adk/templates/.claude/skills/moai-lang-template/SKILL.md +348 -0
- moai_adk/templates/.claude/skills/moai-lang-template/VARIABLES.md +98 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +1230 -66
- moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +29 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +34 -0
- moai_adk/templates/.claude/skills/moai-learning-optimizer/SKILL.md +575 -0
- moai_adk/templates/.claude/skills/moai-project-batch-questions/README.md +50 -0
- moai_adk/templates/.claude/skills/moai-project-batch-questions/SKILL.md +304 -0
- moai_adk/templates/.claude/skills/moai-project-batch-questions/examples.md +417 -0
- moai_adk/templates/.claude/skills/moai-project-batch-questions/reference.md +704 -0
- moai_adk/templates/.claude/skills/moai-project-config-manager/README.md +87 -0
- moai_adk/templates/.claude/skills/moai-project-config-manager/SKILL.md +552 -0
- moai_adk/templates/.claude/skills/moai-project-config-manager/examples.md +1109 -0
- moai_adk/templates/.claude/skills/moai-project-config-manager/reference.md +514 -0
- moai_adk/templates/.claude/skills/moai-project-config-manager/validate.py +106 -0
- moai_adk/templates/.claude/skills/moai-project-documentation/README.md +11 -0
- moai_adk/templates/.claude/skills/moai-project-documentation/SKILL.md +622 -0
- moai_adk/templates/.claude/skills/moai-project-documentation/examples.md +20 -0
- moai_adk/templates/.claude/skills/moai-project-documentation/reference.md +12 -0
- moai_adk/templates/.claude/skills/moai-project-language-initializer/README.md +152 -0
- moai_adk/templates/.claude/skills/moai-project-language-initializer/SKILL.md +285 -0
- moai_adk/templates/.claude/skills/moai-project-language-initializer/examples.md +333 -0
- moai_adk/templates/.claude/skills/moai-project-language-initializer/reference.md +386 -0
- moai_adk/templates/.claude/skills/moai-project-template-optimizer/README.md +49 -0
- moai_adk/templates/.claude/skills/moai-project-template-optimizer/SKILL.md +319 -0
- moai_adk/templates/.claude/skills/moai-project-template-optimizer/examples.md +58 -0
- moai_adk/templates/.claude/skills/moai-project-template-optimizer/reference.md +123 -0
- moai_adk/templates/.claude/skills/moai-session-info/SKILL.md +314 -0
- moai_adk/templates/.claude/skills/moai-streaming-ui/SKILL.md +552 -0
- moai_adk/templates/.claude/skills/moai-tag-policy-validator/SKILL.md +570 -0
- moai_adk/templates/.git-hooks/pre-commit +66 -0
- moai_adk/templates/.git-hooks/pre-push +255 -0
- moai_adk/templates/.github/workflows/c-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/cpp-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/csharp-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/dart-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/go-tag-validation.yml +130 -0
- moai_adk/templates/.github/workflows/java-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/javascript-tag-validation.yml +135 -0
- moai_adk/templates/.github/workflows/kotlin-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/moai-gitflow.yml +166 -3
- moai_adk/templates/.github/workflows/moai-release-create.yml +100 -0
- moai_adk/templates/.github/workflows/moai-release-pipeline.yml +188 -0
- moai_adk/templates/.github/workflows/php-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/python-tag-validation.yml +118 -0
- moai_adk/templates/.github/workflows/release.yml +118 -0
- moai_adk/templates/.github/workflows/ruby-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/rust-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/shell-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +338 -0
- moai_adk/templates/.github/workflows/swift-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/tag-report.yml +269 -0
- moai_adk/templates/.github/workflows/tag-validation.yml +186 -0
- moai_adk/templates/.github/workflows/typescript-tag-validation.yml +154 -0
- moai_adk/templates/.mcp.json +31 -0
- moai_adk/templates/.moai/config.json +80 -7
- moai_adk/templates/CLAUDE.md +562 -546
- moai_adk/utils/banner.py +5 -5
- moai_adk/utils/common.py +294 -0
- moai_adk/utils/link_validator.py +235 -0
- moai_adk/utils/logger.py +8 -8
- moai_adk/utils/user_experience.py +451 -0
- moai_adk-0.20.1.dist-info/METADATA +233 -0
- moai_adk-0.20.1.dist-info/RECORD +404 -0
- moai_adk/templates/.claude/hooks/alfred/README.md +0 -230
- moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +0 -156
- moai_adk/templates/.claude/hooks/alfred/core/__init__.py +0 -85
- moai_adk/templates/.claude/hooks/alfred/handlers/notification.py +0 -25
- moai_adk/templates/.claude/hooks/alfred/handlers/session.py +0 -92
- moai_adk/templates/.claude/hooks/alfred/handlers/tool.py +0 -70
- moai_adk/templates/.claude/hooks/alfred/handlers/user.py +0 -41
- moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md +0 -636
- moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md +0 -692
- moai_adk/templates/.claude/output-styles/alfred/study-with-alfred.md +0 -470
- moai_adk/templates/.claude/skills/moai-alfred-debugger-pro/SKILL.md +0 -103
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/SKILL.md +0 -103
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/SKILL.md +0 -95
- moai_adk/templates/.claude/skills/moai-alfred-performance-optimizer/SKILL.md +0 -105
- moai_adk/templates/.claude/skills/moai-alfred-refactoring-coach/SKILL.md +0 -97
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/SKILL.md +0 -97
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/SKILL.md +0 -90
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/SKILL.md +0 -99
- moai_adk/templates/.claude/skills/moai-alfred-tui-survey/SKILL.md +0 -87
- moai_adk/templates/.claude/skills/moai-alfred-tui-survey/examples.md +0 -62
- moai_adk/templates/.claude/skills/moai-claude-code/SKILL.md +0 -94
- moai_adk/templates/.claude/skills/moai-claude-code/examples.md +0 -513
- moai_adk/templates/.claude/skills/moai-claude-code/reference.md +0 -433
- moai_adk/templates/.claude/skills/moai-claude-code/templates/agent-full.md +0 -332
- moai_adk/templates/.claude/skills/moai-claude-code/templates/command-full.md +0 -384
- moai_adk/templates/.claude/skills/moai-claude-code/templates/plugin-full.json +0 -363
- moai_adk/templates/.claude/skills/moai-claude-code/templates/settings-full.json +0 -595
- moai_adk/templates/.claude/skills/moai-claude-code/templates/skill-full.md +0 -496
- moai_adk/templates/.claude/skills/moai-lang-clojure/SKILL.md +0 -100
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +0 -99
- moai_adk/templates/.claude/skills/moai-lang-haskell/SKILL.md +0 -100
- moai_adk/templates/.claude/skills/moai-lang-julia/SKILL.md +0 -98
- moai_adk/templates/.claude/skills/moai-lang-lua/SKILL.md +0 -98
- moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +0 -69
- 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/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.4.5.dist-info/METADATA +0 -369
- moai_adk-0.4.5.dist-info/RECORD +0 -152
- {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/WHEEL +0 -0
- {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/entry_points.txt +0 -0
- {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/licenses/LICENSE +0 -0
moai_adk/core/template/backup.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @CODE:TEMPLATE-001 | SPEC: SPEC-INIT-003/spec.md | Chain: TEMPLATE-001
|
|
1
|
+
# @CODE:TEMPLATE-BACKUP-001 | SPEC: SPEC-INIT-003/spec.md | Chain: TEMPLATE-001
|
|
2
2
|
"""Template backup manager (SPEC-INIT-003 v0.3.0).
|
|
3
3
|
|
|
4
4
|
Creates and manages backups to protect user data during template updates.
|
moai_adk/core/template/merger.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @CODE:TEMPLATE-001 | SPEC: SPEC-INIT-003/spec.md | Chain: TEMPLATE-001
|
|
1
|
+
# @CODE:TEMPLATE-MERGER-001 | SPEC: SPEC-INIT-003/spec.md | Chain: TEMPLATE-001
|
|
2
2
|
"""Template file merger (SPEC-INIT-003 v0.3.0).
|
|
3
3
|
|
|
4
4
|
Intelligently merges existing user files with new templates.
|
|
@@ -182,3 +182,52 @@ class TemplateMerger:
|
|
|
182
182
|
json.dumps(merged, indent=2, ensure_ascii=False) + "\n",
|
|
183
183
|
encoding="utf-8"
|
|
184
184
|
)
|
|
185
|
+
|
|
186
|
+
def merge_github_workflows(self, template_dir: Path, existing_dir: Path) -> None:
|
|
187
|
+
"""Smart merge for .github/workflows/ directory.
|
|
188
|
+
|
|
189
|
+
Rules:
|
|
190
|
+
- Preserve existing user workflows (never delete)
|
|
191
|
+
- Add/update only MoAI-ADK managed workflows (moai-*.yml)
|
|
192
|
+
- Copy other template directories (ISSUE_TEMPLATE/, PULL_REQUEST_TEMPLATE.md)
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
template_dir: Template .github directory.
|
|
196
|
+
existing_dir: Existing .github directory.
|
|
197
|
+
"""
|
|
198
|
+
import shutil
|
|
199
|
+
|
|
200
|
+
# Ensure workflows directory exists
|
|
201
|
+
workflows_dir = existing_dir / "workflows"
|
|
202
|
+
workflows_dir.mkdir(exist_ok=True)
|
|
203
|
+
|
|
204
|
+
# Track existing user workflows for preservation
|
|
205
|
+
user_workflows = set()
|
|
206
|
+
if workflows_dir.exists():
|
|
207
|
+
for workflow_file in workflows_dir.glob("*.yml"):
|
|
208
|
+
user_workflows.add(workflow_file.name)
|
|
209
|
+
|
|
210
|
+
# Copy template contents with smart merge for workflows
|
|
211
|
+
for item in template_dir.rglob("*"):
|
|
212
|
+
if item.is_file():
|
|
213
|
+
rel_path = item.relative_to(template_dir)
|
|
214
|
+
dst_item = existing_dir / rel_path
|
|
215
|
+
|
|
216
|
+
# Handle workflow files specially
|
|
217
|
+
if rel_path.parent.name == "workflows" and rel_path.name.endswith(".yml"):
|
|
218
|
+
# Only update MoAI-ADK managed workflows (moai-*.yml)
|
|
219
|
+
if rel_path.name.startswith("moai-"):
|
|
220
|
+
dst_item.parent.mkdir(parents=True, exist_ok=True)
|
|
221
|
+
shutil.copy2(item, dst_item)
|
|
222
|
+
# Skip non-moai workflows to preserve user custom workflows
|
|
223
|
+
continue
|
|
224
|
+
|
|
225
|
+
# Copy non-workflow files normally
|
|
226
|
+
dst_item.parent.mkdir(parents=True, exist_ok=True)
|
|
227
|
+
shutil.copy2(item, dst_item)
|
|
228
|
+
|
|
229
|
+
elif item.is_dir():
|
|
230
|
+
# Create directories as needed
|
|
231
|
+
rel_path = item.relative_to(template_dir)
|
|
232
|
+
dst_item = existing_dir / rel_path
|
|
233
|
+
dst_item.mkdir(parents=True, exist_ok=True)
|
|
@@ -65,6 +65,15 @@ class TemplateProcessor:
|
|
|
65
65
|
"""
|
|
66
66
|
warnings = []
|
|
67
67
|
|
|
68
|
+
# Detect common template variables and provide helpful suggestions
|
|
69
|
+
common_variables = {
|
|
70
|
+
"HOOK_PROJECT_DIR": "Cross-platform hook path (update moai-adk to fix)",
|
|
71
|
+
"PROJECT_NAME": "Project name (run /alfred:0-project to set)",
|
|
72
|
+
"AUTHOR": "Project author (run /alfred:0-project to set)",
|
|
73
|
+
"CONVERSATION_LANGUAGE": "Interface language (run /alfred:0-project to set)",
|
|
74
|
+
"MOAI_VERSION": "MoAI-ADK version (should be set automatically)",
|
|
75
|
+
}
|
|
76
|
+
|
|
68
77
|
# Perform variable substitution
|
|
69
78
|
for key, value in self.context.items():
|
|
70
79
|
placeholder = f"{{{{{key}}}}}" # {{KEY}}
|
|
@@ -72,11 +81,23 @@ class TemplateProcessor:
|
|
|
72
81
|
safe_value = self._sanitize_value(value)
|
|
73
82
|
content = content.replace(placeholder, safe_value)
|
|
74
83
|
|
|
75
|
-
# Detect unsubstituted variables
|
|
84
|
+
# Detect unsubstituted variables with enhanced error messages
|
|
76
85
|
remaining = re.findall(r'\{\{([A-Z_]+)\}\}', content)
|
|
77
86
|
if remaining:
|
|
78
87
|
unique_remaining = sorted(set(remaining))
|
|
79
|
-
|
|
88
|
+
|
|
89
|
+
# Build detailed warning message
|
|
90
|
+
warning_parts = []
|
|
91
|
+
for var in unique_remaining:
|
|
92
|
+
if var in common_variables:
|
|
93
|
+
suggestion = common_variables[var]
|
|
94
|
+
warning_parts.append(f"{{{{{var}}}}} → {suggestion}")
|
|
95
|
+
else:
|
|
96
|
+
warning_parts.append(f"{{{{{var}}}}} → Unknown variable (check template)")
|
|
97
|
+
|
|
98
|
+
warnings.append("Template variables not substituted:")
|
|
99
|
+
warnings.extend(f" • {part}" for part in warning_parts)
|
|
100
|
+
warnings.append("💡 Run 'uv run moai-adk update' to fix template variables")
|
|
80
101
|
|
|
81
102
|
return content, warnings
|
|
82
103
|
|
|
@@ -110,8 +131,59 @@ class TemplateProcessor:
|
|
|
110
131
|
}
|
|
111
132
|
return file_path.suffix.lower() in text_extensions
|
|
112
133
|
|
|
134
|
+
def _localize_yaml_description(self, content: str, language: str = "en") -> str:
|
|
135
|
+
"""Localize multilingual YAML description field.
|
|
136
|
+
|
|
137
|
+
Converts multilingual description maps to single-language strings:
|
|
138
|
+
description:
|
|
139
|
+
en: "English text"
|
|
140
|
+
ko: "Korean text"
|
|
141
|
+
→
|
|
142
|
+
description: "Korean text" (if language="ko")
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
content: File content.
|
|
146
|
+
language: Target language code (en, ko, ja, zh).
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Content with localized descriptions.
|
|
150
|
+
"""
|
|
151
|
+
import yaml
|
|
152
|
+
|
|
153
|
+
# Pattern to match YAML frontmatter
|
|
154
|
+
frontmatter_pattern = r'^---\n(.*?)\n---'
|
|
155
|
+
match = re.match(frontmatter_pattern, content, re.DOTALL)
|
|
156
|
+
|
|
157
|
+
if not match:
|
|
158
|
+
return content
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
yaml_content = match.group(1)
|
|
162
|
+
yaml_data = yaml.safe_load(yaml_content)
|
|
163
|
+
|
|
164
|
+
# Check if description is a dict (multilingual)
|
|
165
|
+
if isinstance(yaml_data.get('description'), dict):
|
|
166
|
+
# Select language (fallback to English)
|
|
167
|
+
descriptions = yaml_data['description']
|
|
168
|
+
selected_desc = descriptions.get(language, descriptions.get('en', ''))
|
|
169
|
+
|
|
170
|
+
# Replace description with selected language
|
|
171
|
+
yaml_data['description'] = selected_desc
|
|
172
|
+
|
|
173
|
+
# Reconstruct frontmatter
|
|
174
|
+
new_yaml = yaml.dump(yaml_data, allow_unicode=True, sort_keys=False)
|
|
175
|
+
# Preserve the rest of the content
|
|
176
|
+
rest_content = content[match.end():]
|
|
177
|
+
return f"---\n{new_yaml}---{rest_content}"
|
|
178
|
+
|
|
179
|
+
except Exception:
|
|
180
|
+
# If YAML parsing fails, return original content
|
|
181
|
+
pass
|
|
182
|
+
|
|
183
|
+
return content
|
|
184
|
+
|
|
113
185
|
def _copy_file_with_substitution(self, src: Path, dst: Path) -> list[str]:
|
|
114
|
-
"""Copy file with variable substitution for text files.
|
|
186
|
+
"""Copy file with variable substitution and description localization for text files.
|
|
115
187
|
|
|
116
188
|
Args:
|
|
117
189
|
src: Source file path.
|
|
@@ -127,6 +199,14 @@ class TemplateProcessor:
|
|
|
127
199
|
try:
|
|
128
200
|
content = src.read_text(encoding='utf-8')
|
|
129
201
|
content, file_warnings = self._substitute_variables(content)
|
|
202
|
+
|
|
203
|
+
# Apply description localization for command/output-style files
|
|
204
|
+
if src.suffix == '.md' and (
|
|
205
|
+
'commands/alfred' in str(src) or 'output-styles/alfred' in str(src)
|
|
206
|
+
):
|
|
207
|
+
lang = self.context.get('CONVERSATION_LANGUAGE', 'en')
|
|
208
|
+
content = self._localize_yaml_description(content, lang)
|
|
209
|
+
|
|
130
210
|
dst.write_text(content, encoding='utf-8')
|
|
131
211
|
warnings.extend(file_warnings)
|
|
132
212
|
except UnicodeDecodeError:
|
|
@@ -231,7 +311,7 @@ class TemplateProcessor:
|
|
|
231
311
|
def _copy_claude(self, silent: bool = False) -> None:
|
|
232
312
|
""".claude/ directory copy with variable substitution (selective with alfred folder overwrite).
|
|
233
313
|
|
|
234
|
-
@CODE:INIT-
|
|
314
|
+
@CODE:INIT-TEMPLATE-001:ALFRED-001 | Copy all 4 Alfred command files from templates
|
|
235
315
|
@REQ:COMMAND-GENERATION-001 | SPEC-INIT-004: Automatic generation of Alfred command files
|
|
236
316
|
@SPEC:TEMPLATE-PROCESSING-001 | Template processor integration for Alfred command files
|
|
237
317
|
|
|
@@ -252,8 +332,8 @@ class TemplateProcessor:
|
|
|
252
332
|
# Create .claude directory if not exists
|
|
253
333
|
dst.mkdir(parents=True, exist_ok=True)
|
|
254
334
|
|
|
255
|
-
# @CODE:INIT-
|
|
256
|
-
# @CODE:INIT-
|
|
335
|
+
# @CODE:INIT-ALFRED-002 | Alfred command files must always be overwritten
|
|
336
|
+
# @CODE:INIT-COMMAND-003 | Copy all 4 Alfred command files from templates
|
|
257
337
|
# Alfred folders to copy wholesale (overwrite)
|
|
258
338
|
alfred_folders = [
|
|
259
339
|
"hooks/alfred",
|
|
@@ -292,8 +372,14 @@ class TemplateProcessor:
|
|
|
292
372
|
# Smart merge for settings.json
|
|
293
373
|
if item.name == "settings.json":
|
|
294
374
|
self._merge_settings_json(item, dst_item)
|
|
375
|
+
# Apply variable substitution to merged settings.json (for cross-platform Hook paths)
|
|
376
|
+
if self.context:
|
|
377
|
+
content = dst_item.read_text(encoding='utf-8')
|
|
378
|
+
content, file_warnings = self._substitute_variables(content)
|
|
379
|
+
dst_item.write_text(content, encoding='utf-8')
|
|
380
|
+
all_warnings.extend(file_warnings)
|
|
295
381
|
if not silent:
|
|
296
|
-
console.print(" 🔄 settings.json merged (
|
|
382
|
+
console.print(" 🔄 settings.json merged (Hook paths configured for your OS)")
|
|
297
383
|
else:
|
|
298
384
|
# FORCE OVERWRITE: Always copy other files (no skip)
|
|
299
385
|
warnings = self._copy_file_with_substitution(item, dst_item)
|
|
@@ -358,7 +444,7 @@ class TemplateProcessor:
|
|
|
358
444
|
console.print(" ✅ .moai/ copy complete (variables substituted)")
|
|
359
445
|
|
|
360
446
|
def _copy_github(self, silent: bool = False) -> None:
|
|
361
|
-
""".github/ directory copy with
|
|
447
|
+
""".github/ directory copy with smart merge (preserves user workflows)."""
|
|
362
448
|
src = self.template_root / ".github"
|
|
363
449
|
dst = self.target_path / ".github"
|
|
364
450
|
|
|
@@ -367,13 +453,15 @@ class TemplateProcessor:
|
|
|
367
453
|
console.print("⚠️ .github/ template not found")
|
|
368
454
|
return
|
|
369
455
|
|
|
456
|
+
# Smart merge: preserve existing user workflows
|
|
370
457
|
if dst.exists():
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
458
|
+
self._merge_github_workflows(src, dst)
|
|
459
|
+
else:
|
|
460
|
+
# First time: just copy
|
|
461
|
+
self._copy_dir_with_substitution(src, dst)
|
|
374
462
|
|
|
375
463
|
if not silent:
|
|
376
|
-
console.print("
|
|
464
|
+
console.print(" 🔄 .github/ merged (user workflows preserved, variables substituted)")
|
|
377
465
|
|
|
378
466
|
def _copy_claude_md(self, silent: bool = False) -> None:
|
|
379
467
|
"""Copy CLAUDE.md with smart merge (preserves \"## Project Information\" section)."""
|
|
@@ -388,8 +476,17 @@ class TemplateProcessor:
|
|
|
388
476
|
# Smart merge: preserve existing "## Project Information" section
|
|
389
477
|
if dst.exists():
|
|
390
478
|
self._merge_claude_md(src, dst)
|
|
479
|
+
# Substitute variables in the merged content
|
|
480
|
+
if self.context:
|
|
481
|
+
content = dst.read_text(encoding='utf-8')
|
|
482
|
+
content, warnings = self._substitute_variables(content)
|
|
483
|
+
dst.write_text(content, encoding='utf-8')
|
|
484
|
+
if warnings and not silent:
|
|
485
|
+
console.print("[yellow]⚠️ Template warnings:[/yellow]")
|
|
486
|
+
for warning in set(warnings):
|
|
487
|
+
console.print(f" {warning}")
|
|
391
488
|
if not silent:
|
|
392
|
-
console.print(" 🔄 CLAUDE.md merged (project information preserved)")
|
|
489
|
+
console.print(" 🔄 CLAUDE.md merged (project information preserved, variables substituted)")
|
|
393
490
|
else:
|
|
394
491
|
# First time: just copy
|
|
395
492
|
self._copy_file_with_substitution(src, dst)
|
|
@@ -405,6 +502,15 @@ class TemplateProcessor:
|
|
|
405
502
|
"""
|
|
406
503
|
self.merger.merge_claude_md(src, dst)
|
|
407
504
|
|
|
505
|
+
def _merge_github_workflows(self, src: Path, dst: Path) -> None:
|
|
506
|
+
"""Delegate the smart merge for .github/workflows/.
|
|
507
|
+
|
|
508
|
+
Args:
|
|
509
|
+
src: Template .github directory.
|
|
510
|
+
dst: Project .github directory.
|
|
511
|
+
"""
|
|
512
|
+
self.merger.merge_github_workflows(src, dst)
|
|
513
|
+
|
|
408
514
|
def _merge_settings_json(self, src: Path, dst: Path) -> None:
|
|
409
515
|
"""Delegate the smart merge for settings.json.
|
|
410
516
|
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Template engine for parameterizing GitHub templates and other configuration files.
|
|
3
|
+
|
|
4
|
+
Supports Jinja2-style templating with variable substitution and conditional sections.
|
|
5
|
+
Enables users to customize MoAI-ADK templates for their own projects.
|
|
6
|
+
|
|
7
|
+
@TAG:TEMPLATE-ENGINE-001 - Template variable substitution system
|
|
8
|
+
@TAG:GITHUB-CUSTOMIZATION-001 - GitHub template parameterization
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any, Dict, Optional
|
|
13
|
+
|
|
14
|
+
from jinja2 import (
|
|
15
|
+
Environment,
|
|
16
|
+
FileSystemLoader,
|
|
17
|
+
StrictUndefined,
|
|
18
|
+
TemplateNotFound,
|
|
19
|
+
TemplateRuntimeError,
|
|
20
|
+
TemplateSyntaxError,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class TemplateEngine:
|
|
25
|
+
"""
|
|
26
|
+
Jinja2-based template engine for MoAI-ADK configuration and GitHub templates.
|
|
27
|
+
|
|
28
|
+
Supports:
|
|
29
|
+
- Variable substitution: {{PROJECT_NAME}}, {{SPEC_DIR}}, etc.
|
|
30
|
+
- Conditional sections: {{#ENABLE_TRUST_5}}...{{/ENABLE_TRUST_5}}
|
|
31
|
+
- File-based and string-based template rendering
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(self, strict_undefined: bool = True):
|
|
35
|
+
"""
|
|
36
|
+
Initialize the template engine.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
strict_undefined: If True, raise error on undefined variables (default: True).
|
|
40
|
+
If False, render undefined variables as empty strings.
|
|
41
|
+
|
|
42
|
+
Note:
|
|
43
|
+
Changed to strict_undefined=True (v0.10.2+) for safer template rendering.
|
|
44
|
+
Variables must be explicitly provided to avoid silent template failures.
|
|
45
|
+
"""
|
|
46
|
+
self.strict_undefined = strict_undefined
|
|
47
|
+
self.undefined_behavior = StrictUndefined if strict_undefined else None
|
|
48
|
+
|
|
49
|
+
def render_string(
|
|
50
|
+
self,
|
|
51
|
+
template_string: str,
|
|
52
|
+
variables: Dict[str, Any]
|
|
53
|
+
) -> str:
|
|
54
|
+
"""
|
|
55
|
+
Render a Jinja2 template string with provided variables.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
template_string: The template content as a string
|
|
59
|
+
variables: Dictionary of variables to substitute
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
Rendered template string
|
|
63
|
+
|
|
64
|
+
Raises:
|
|
65
|
+
TemplateSyntaxError: If template syntax is invalid
|
|
66
|
+
TemplateRuntimeError: If variable substitution fails in strict mode
|
|
67
|
+
"""
|
|
68
|
+
try:
|
|
69
|
+
env = Environment(
|
|
70
|
+
undefined=self.undefined_behavior,
|
|
71
|
+
trim_blocks=False,
|
|
72
|
+
lstrip_blocks=False
|
|
73
|
+
)
|
|
74
|
+
template = env.from_string(template_string)
|
|
75
|
+
return template.render(**variables)
|
|
76
|
+
except (TemplateSyntaxError, TemplateRuntimeError) as e:
|
|
77
|
+
raise RuntimeError(f"Template rendering error: {e}")
|
|
78
|
+
|
|
79
|
+
def render_file(
|
|
80
|
+
self,
|
|
81
|
+
template_path: Path,
|
|
82
|
+
variables: Dict[str, Any],
|
|
83
|
+
output_path: Optional[Path] = None
|
|
84
|
+
) -> str:
|
|
85
|
+
"""
|
|
86
|
+
Render a Jinja2 template file with provided variables.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
template_path: Path to the template file
|
|
90
|
+
variables: Dictionary of variables to substitute
|
|
91
|
+
output_path: If provided, write rendered content to this path
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Rendered template content
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
FileNotFoundError: If template file doesn't exist
|
|
98
|
+
TemplateSyntaxError: If template syntax is invalid
|
|
99
|
+
TemplateRuntimeError: If variable substitution fails in strict mode
|
|
100
|
+
"""
|
|
101
|
+
if not template_path.exists():
|
|
102
|
+
raise FileNotFoundError(f"Template file not found: {template_path}")
|
|
103
|
+
|
|
104
|
+
template_dir = template_path.parent
|
|
105
|
+
template_name = template_path.name
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
env = Environment(
|
|
109
|
+
loader=FileSystemLoader(str(template_dir)),
|
|
110
|
+
undefined=self.undefined_behavior,
|
|
111
|
+
trim_blocks=False,
|
|
112
|
+
lstrip_blocks=False
|
|
113
|
+
)
|
|
114
|
+
template = env.get_template(template_name)
|
|
115
|
+
rendered = template.render(**variables)
|
|
116
|
+
|
|
117
|
+
if output_path:
|
|
118
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
119
|
+
output_path.write_text(rendered, encoding='utf-8')
|
|
120
|
+
|
|
121
|
+
return rendered
|
|
122
|
+
except TemplateNotFound:
|
|
123
|
+
raise FileNotFoundError(f"Template not found in {template_dir}: {template_name}")
|
|
124
|
+
except (TemplateSyntaxError, TemplateRuntimeError) as e:
|
|
125
|
+
raise RuntimeError(f"Template rendering error in {template_path}: {e}")
|
|
126
|
+
|
|
127
|
+
def render_directory(
|
|
128
|
+
self,
|
|
129
|
+
template_dir: Path,
|
|
130
|
+
output_dir: Path,
|
|
131
|
+
variables: Dict[str, Any],
|
|
132
|
+
pattern: str = "**/*.{md,yml,yaml,json}"
|
|
133
|
+
) -> Dict[str, str]:
|
|
134
|
+
"""
|
|
135
|
+
Render all template files in a directory.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
template_dir: Source directory containing templates
|
|
139
|
+
output_dir: Destination directory for rendered files
|
|
140
|
+
variables: Dictionary of variables to substitute
|
|
141
|
+
pattern: Glob pattern for files to process (default: template files)
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Dictionary mapping input paths to rendered content
|
|
145
|
+
|
|
146
|
+
Raises:
|
|
147
|
+
FileNotFoundError: If template directory doesn't exist
|
|
148
|
+
"""
|
|
149
|
+
if not template_dir.exists():
|
|
150
|
+
raise FileNotFoundError(f"Template directory not found: {template_dir}")
|
|
151
|
+
|
|
152
|
+
results = {}
|
|
153
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
154
|
+
|
|
155
|
+
for template_file in template_dir.glob(pattern):
|
|
156
|
+
if template_file.is_file():
|
|
157
|
+
relative_path = template_file.relative_to(template_dir)
|
|
158
|
+
output_file = output_dir / relative_path
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
rendered = self.render_file(template_file, variables, output_file)
|
|
162
|
+
results[str(relative_path)] = rendered
|
|
163
|
+
except Exception as e:
|
|
164
|
+
raise RuntimeError(f"Error rendering {relative_path}: {e}")
|
|
165
|
+
|
|
166
|
+
return results
|
|
167
|
+
|
|
168
|
+
@staticmethod
|
|
169
|
+
def get_default_variables(config: Dict[str, Any]) -> Dict[str, Any]:
|
|
170
|
+
"""
|
|
171
|
+
Extract template variables from project configuration.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
config: Project configuration dictionary (from .moai/config.json)
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Dictionary of template variables
|
|
178
|
+
"""
|
|
179
|
+
github_config = config.get("github", {}).get("templates", {})
|
|
180
|
+
project_config = config.get("project", {})
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
# Project information
|
|
184
|
+
"PROJECT_NAME": project_config.get("name", "MyProject"),
|
|
185
|
+
"PROJECT_DESCRIPTION": project_config.get("description", ""),
|
|
186
|
+
"PROJECT_MODE": project_config.get("mode", "team"), # team or personal
|
|
187
|
+
|
|
188
|
+
# Directory structure
|
|
189
|
+
"SPEC_DIR": github_config.get("spec_directory", ".moai/specs"),
|
|
190
|
+
"DOCS_DIR": github_config.get("docs_directory", ".moai/docs"),
|
|
191
|
+
"TEST_DIR": github_config.get("test_directory", "tests"),
|
|
192
|
+
|
|
193
|
+
# Feature flags
|
|
194
|
+
"ENABLE_TRUST_5": github_config.get("enable_trust_5", True),
|
|
195
|
+
"ENABLE_TAG_SYSTEM": github_config.get("enable_tag_system", True),
|
|
196
|
+
"ENABLE_ALFRED_COMMANDS": github_config.get("enable_alfred_commands", True),
|
|
197
|
+
|
|
198
|
+
# Language configuration
|
|
199
|
+
"CONVERSATION_LANGUAGE": project_config.get("conversation_language", "en"),
|
|
200
|
+
"CONVERSATION_LANGUAGE_NAME": project_config.get("conversation_language_name", "English"),
|
|
201
|
+
|
|
202
|
+
# Additional metadata
|
|
203
|
+
"MOAI_VERSION": config.get("moai", {}).get("version", "0.7.0"),
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class TemplateVariableValidator:
|
|
208
|
+
"""
|
|
209
|
+
Validates template variables for completeness and correctness.
|
|
210
|
+
Ensures all required variables are present before rendering.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
REQUIRED_VARIABLES = {
|
|
214
|
+
"PROJECT_NAME": str,
|
|
215
|
+
"SPEC_DIR": str,
|
|
216
|
+
"DOCS_DIR": str,
|
|
217
|
+
"TEST_DIR": str,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
OPTIONAL_VARIABLES = {
|
|
221
|
+
"PROJECT_DESCRIPTION": (str, type(None)),
|
|
222
|
+
"PROJECT_MODE": str,
|
|
223
|
+
"ENABLE_TRUST_5": bool,
|
|
224
|
+
"ENABLE_TAG_SYSTEM": bool,
|
|
225
|
+
"ENABLE_ALFRED_COMMANDS": bool,
|
|
226
|
+
"CONVERSATION_LANGUAGE": str,
|
|
227
|
+
"CONVERSATION_LANGUAGE_NAME": str,
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
@classmethod
|
|
231
|
+
def validate(cls, variables: Dict[str, Any]) -> tuple[bool, list[str]]:
|
|
232
|
+
"""
|
|
233
|
+
Validate template variables.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
variables: Dictionary of variables to validate
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
Tuple of (is_valid, list_of_errors)
|
|
240
|
+
"""
|
|
241
|
+
errors = []
|
|
242
|
+
|
|
243
|
+
# Check required variables
|
|
244
|
+
for var_name, var_type in cls.REQUIRED_VARIABLES.items():
|
|
245
|
+
if var_name not in variables:
|
|
246
|
+
errors.append(f"Missing required variable: {var_name}")
|
|
247
|
+
elif not isinstance(variables[var_name], var_type):
|
|
248
|
+
actual_type = type(variables[var_name]).__name__
|
|
249
|
+
errors.append(
|
|
250
|
+
f"Invalid type for {var_name}: "
|
|
251
|
+
f"expected {var_type.__name__}, got {actual_type}"
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
# Check optional variables (if present)
|
|
255
|
+
for var_name, var_type in cls.OPTIONAL_VARIABLES.items():
|
|
256
|
+
if var_name in variables:
|
|
257
|
+
if not isinstance(variables[var_name], var_type):
|
|
258
|
+
if isinstance(var_type, tuple):
|
|
259
|
+
type_names = " or ".join(t.__name__ for t in var_type)
|
|
260
|
+
else:
|
|
261
|
+
type_names = var_type.__name__
|
|
262
|
+
actual_type = type(variables[var_name]).__name__
|
|
263
|
+
errors.append(
|
|
264
|
+
f"Invalid type for {var_name}: "
|
|
265
|
+
f"expected {type_names}, got {actual_type}"
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
return len(errors) == 0, errors
|