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
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# @CODE:DOC-TAG-004 | Component 1: Pre-commit TAG validator
|
|
3
|
+
"""Pre-commit TAG validation module
|
|
4
|
+
|
|
5
|
+
This module provides validation functionality for TAG annotations:
|
|
6
|
+
- Format validation (@DOC:DOMAIN-TYPE-NNN)
|
|
7
|
+
- Duplicate TAG detection across files
|
|
8
|
+
- Orphan TAG detection (CODE without TEST, etc.)
|
|
9
|
+
- Git staged file scanning
|
|
10
|
+
|
|
11
|
+
Used by pre-commit hooks to ensure TAG quality.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import re
|
|
15
|
+
import subprocess
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Dict, List, Optional, Tuple
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class ValidationError:
|
|
23
|
+
"""Validation error with file location information"""
|
|
24
|
+
message: str
|
|
25
|
+
tag: str
|
|
26
|
+
locations: List[Tuple[str, int]] = field(default_factory=list)
|
|
27
|
+
|
|
28
|
+
def __str__(self) -> str:
|
|
29
|
+
loc_str = ", ".join([f"{f}:{line}" for f, line in self.locations])
|
|
30
|
+
return f"{self.message}: {self.tag} at {loc_str}"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class ValidationWarning:
|
|
35
|
+
"""Validation warning with file location"""
|
|
36
|
+
message: str
|
|
37
|
+
tag: str
|
|
38
|
+
location: Tuple[str, int]
|
|
39
|
+
|
|
40
|
+
def __str__(self) -> str:
|
|
41
|
+
return f"{self.message}: {self.tag} at {self.location[0]}:{self.location[1]}"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class ValidationResult:
|
|
46
|
+
"""Complete validation result"""
|
|
47
|
+
is_valid: bool
|
|
48
|
+
errors: List[ValidationError] = field(default_factory=list)
|
|
49
|
+
warnings: List[ValidationWarning] = field(default_factory=list)
|
|
50
|
+
|
|
51
|
+
def format(self) -> str:
|
|
52
|
+
"""Format result for display"""
|
|
53
|
+
lines = []
|
|
54
|
+
|
|
55
|
+
if self.errors:
|
|
56
|
+
lines.append("Errors:")
|
|
57
|
+
for error in self.errors:
|
|
58
|
+
lines.append(f" - {error}")
|
|
59
|
+
|
|
60
|
+
if self.warnings:
|
|
61
|
+
lines.append("\nWarnings:")
|
|
62
|
+
for warning in self.warnings:
|
|
63
|
+
lines.append(f" - {warning}")
|
|
64
|
+
|
|
65
|
+
if not self.errors and not self.warnings:
|
|
66
|
+
lines.append("No issues found.")
|
|
67
|
+
|
|
68
|
+
return "\n".join(lines)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class PreCommitValidator:
|
|
72
|
+
"""Pre-commit TAG validator
|
|
73
|
+
|
|
74
|
+
Validates TAG annotations in files:
|
|
75
|
+
- Format: @DOC:DOMAIN-TYPE-NNN
|
|
76
|
+
- No duplicates
|
|
77
|
+
- No orphans (CODE without TEST)
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
strict_mode: Treat warnings as errors
|
|
81
|
+
check_orphans: Enable orphan TAG detection
|
|
82
|
+
tag_pattern: Custom TAG regex pattern
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
# Default TAG pattern: @(SPEC|CODE|TEST|DOC):DOMAIN-NNN or DOMAIN-TYPE-NNN
|
|
86
|
+
# Matches formats like:
|
|
87
|
+
# - @CODE:AUTH-API-001 (domain-type-number)
|
|
88
|
+
# - @CODE:SPEC-001 (domain-number)
|
|
89
|
+
# - @TEST:USER-REG-001 (domain-type-number)
|
|
90
|
+
DEFAULT_TAG_PATTERN = r"@(SPEC|CODE|TEST|DOC):([A-Z]+(?:-[A-Z]+)*-\d{3})"
|
|
91
|
+
|
|
92
|
+
def __init__(
|
|
93
|
+
self,
|
|
94
|
+
strict_mode: bool = False,
|
|
95
|
+
check_orphans: bool = True,
|
|
96
|
+
tag_pattern: Optional[str] = None
|
|
97
|
+
):
|
|
98
|
+
self.strict_mode = strict_mode
|
|
99
|
+
self.check_orphans = check_orphans
|
|
100
|
+
self.tag_pattern = re.compile(tag_pattern or self.DEFAULT_TAG_PATTERN)
|
|
101
|
+
# Document files to exclude from TAG validation
|
|
102
|
+
self.excluded_file_patterns = [
|
|
103
|
+
r"\.md$", # Markdown files
|
|
104
|
+
r"README", # README files
|
|
105
|
+
r"CHANGELOG", # CHANGELOG files
|
|
106
|
+
r"CONTRIBUTING", # CONTRIBUTING files
|
|
107
|
+
r"LICENSE", # LICENSE files
|
|
108
|
+
r"\.txt$", # Text files
|
|
109
|
+
r"\.rst$", # ReStructuredText files
|
|
110
|
+
r"test_.*\.py$", # Test files (test_*.py)
|
|
111
|
+
r".*_test\.py$", # Test files (*_test.py)
|
|
112
|
+
r"tests/", # Files in tests/ directory
|
|
113
|
+
r"validator\.py$", # Validator files (contain example TAGs in docstrings)
|
|
114
|
+
r"\.moai/", # Local project configuration files (exclude template validation)
|
|
115
|
+
r"fix_duplicate_tags\.py$", # Temporary fix script
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
def should_validate_file(self, filepath: str) -> bool:
|
|
119
|
+
"""Check if file should be validated for TAGs
|
|
120
|
+
|
|
121
|
+
Document files (*.md, README, CONTRIBUTING, etc.) are excluded
|
|
122
|
+
because they often contain example TAGs that are not actual code.
|
|
123
|
+
Local project files (.moai/) are excluded to avoid template conflicts.
|
|
124
|
+
|
|
125
|
+
For template distribution, only validate template files in src/moai_adk/templates/.
|
|
126
|
+
For testing, allow all Python files to be validated.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
filepath: File path to check
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
True if file should be validated, False if excluded
|
|
133
|
+
"""
|
|
134
|
+
# Exclude patterns first
|
|
135
|
+
for pattern in self.excluded_file_patterns:
|
|
136
|
+
if re.search(pattern, filepath):
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
# Allow all .py files for testing scenarios
|
|
140
|
+
if filepath.endswith('.py'):
|
|
141
|
+
return True
|
|
142
|
+
|
|
143
|
+
# Only validate template files, not regular source files
|
|
144
|
+
# This ensures template distribution doesn't have TAG conflicts
|
|
145
|
+
if "templates/" in filepath:
|
|
146
|
+
return True
|
|
147
|
+
|
|
148
|
+
# Validate only core framework files that should have unique TAGs
|
|
149
|
+
# This ensures template distribution doesn't have TAG conflicts
|
|
150
|
+
core_framework_patterns = [
|
|
151
|
+
r"src/moai_adk/core/tags/",
|
|
152
|
+
r"src/moai_adk/cli/commands/",
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
for pattern in core_framework_patterns:
|
|
156
|
+
if re.search(pattern, filepath):
|
|
157
|
+
return True
|
|
158
|
+
|
|
159
|
+
return False
|
|
160
|
+
|
|
161
|
+
def validate_format(self, tag: str) -> bool:
|
|
162
|
+
"""Validate TAG format
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
tag: TAG string (e.g., "@CODE:AUTH-API-001")
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
True if format is valid
|
|
169
|
+
"""
|
|
170
|
+
return bool(self.tag_pattern.match(tag))
|
|
171
|
+
|
|
172
|
+
def extract_tags(self, content: str) -> List[str]:
|
|
173
|
+
"""Extract all TAGs from content
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
content: File content
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
List of TAG strings
|
|
180
|
+
"""
|
|
181
|
+
matches = self.tag_pattern.findall(content)
|
|
182
|
+
# Convert tuples to full TAG strings
|
|
183
|
+
tags = [f"@{prefix}:{domain}" for prefix, domain in matches]
|
|
184
|
+
return tags
|
|
185
|
+
|
|
186
|
+
def validate_duplicates(self, files: List[str]) -> List[ValidationError]:
|
|
187
|
+
"""Detect duplicate TAGs
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
files: List of file paths to scan
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
List of validation errors for duplicates
|
|
194
|
+
"""
|
|
195
|
+
errors: List[ValidationError] = []
|
|
196
|
+
tag_locations: Dict[str, List[Tuple[str, int]]] = {}
|
|
197
|
+
|
|
198
|
+
for filepath in files:
|
|
199
|
+
# Skip document files (*.md, README, CONTRIBUTING, etc.)
|
|
200
|
+
if not self.should_validate_file(filepath):
|
|
201
|
+
continue
|
|
202
|
+
|
|
203
|
+
try:
|
|
204
|
+
path = Path(filepath)
|
|
205
|
+
if not path.exists() or not path.is_file():
|
|
206
|
+
continue
|
|
207
|
+
|
|
208
|
+
content = path.read_text(encoding="utf-8", errors="ignore")
|
|
209
|
+
lines = content.splitlines()
|
|
210
|
+
|
|
211
|
+
for line_num, line in enumerate(lines, start=1):
|
|
212
|
+
tags = self.extract_tags(line)
|
|
213
|
+
for tag in tags:
|
|
214
|
+
if tag not in tag_locations:
|
|
215
|
+
tag_locations[tag] = []
|
|
216
|
+
tag_locations[tag].append((filepath, line_num))
|
|
217
|
+
|
|
218
|
+
except Exception:
|
|
219
|
+
# Skip files that can't be read
|
|
220
|
+
continue
|
|
221
|
+
|
|
222
|
+
# Find duplicates
|
|
223
|
+
for tag, locations in tag_locations.items():
|
|
224
|
+
if len(locations) > 1:
|
|
225
|
+
errors.append(ValidationError(
|
|
226
|
+
message="Duplicate TAG found",
|
|
227
|
+
tag=tag,
|
|
228
|
+
locations=locations
|
|
229
|
+
))
|
|
230
|
+
|
|
231
|
+
return errors
|
|
232
|
+
|
|
233
|
+
def validate_orphans(self, files: List[str]) -> List[ValidationWarning]:
|
|
234
|
+
"""Detect orphan TAGs
|
|
235
|
+
|
|
236
|
+
Orphan TAGs are:
|
|
237
|
+
- @CODE without corresponding @TEST
|
|
238
|
+
- @TEST without corresponding @CODE
|
|
239
|
+
- @SPEC without implementation
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
files: List of file paths to scan
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
List of validation warnings
|
|
246
|
+
"""
|
|
247
|
+
if not self.check_orphans:
|
|
248
|
+
return []
|
|
249
|
+
|
|
250
|
+
warnings: List[ValidationWarning] = []
|
|
251
|
+
|
|
252
|
+
# Collect all TAGs by type and domain
|
|
253
|
+
tags_by_type: Dict[str, Dict[str, List[Tuple[str, int]]]] = {
|
|
254
|
+
"SPEC": {},
|
|
255
|
+
"CODE": {},
|
|
256
|
+
"TEST": {},
|
|
257
|
+
"DOC": {}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
for filepath in files:
|
|
261
|
+
# Skip document files (*.md, README, CONTRIBUTING, etc.)
|
|
262
|
+
if not self.should_validate_file(filepath):
|
|
263
|
+
continue
|
|
264
|
+
|
|
265
|
+
try:
|
|
266
|
+
path = Path(filepath)
|
|
267
|
+
if not path.exists() or not path.is_file():
|
|
268
|
+
continue
|
|
269
|
+
|
|
270
|
+
content = path.read_text(encoding="utf-8", errors="ignore")
|
|
271
|
+
lines = content.splitlines()
|
|
272
|
+
|
|
273
|
+
for line_num, line in enumerate(lines, start=1):
|
|
274
|
+
matches = self.tag_pattern.findall(line)
|
|
275
|
+
for prefix, domain in matches:
|
|
276
|
+
if domain not in tags_by_type[prefix]:
|
|
277
|
+
tags_by_type[prefix][domain] = []
|
|
278
|
+
tags_by_type[prefix][domain].append((filepath, line_num))
|
|
279
|
+
|
|
280
|
+
except Exception:
|
|
281
|
+
continue
|
|
282
|
+
|
|
283
|
+
# Check for orphans
|
|
284
|
+
# CODE without TEST
|
|
285
|
+
for domain, locations in tags_by_type["CODE"].items():
|
|
286
|
+
if domain not in tags_by_type["TEST"]:
|
|
287
|
+
for filepath, line_num in locations:
|
|
288
|
+
warnings.append(ValidationWarning(
|
|
289
|
+
message="CODE TAG without corresponding TEST",
|
|
290
|
+
tag=f"@CODE:{domain}",
|
|
291
|
+
location=(filepath, line_num)
|
|
292
|
+
))
|
|
293
|
+
|
|
294
|
+
# TEST without CODE
|
|
295
|
+
for domain, locations in tags_by_type["TEST"].items():
|
|
296
|
+
if domain not in tags_by_type["CODE"]:
|
|
297
|
+
for filepath, line_num in locations:
|
|
298
|
+
warnings.append(ValidationWarning(
|
|
299
|
+
message="TEST TAG without corresponding CODE",
|
|
300
|
+
tag=f"@TEST:{domain}",
|
|
301
|
+
location=(filepath, line_num)
|
|
302
|
+
))
|
|
303
|
+
|
|
304
|
+
return warnings
|
|
305
|
+
|
|
306
|
+
def get_staged_files(self, repo_path: str = ".") -> List[str]:
|
|
307
|
+
"""Get list of staged files from git
|
|
308
|
+
|
|
309
|
+
Args:
|
|
310
|
+
repo_path: Git repository path
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
List of staged file paths
|
|
314
|
+
"""
|
|
315
|
+
try:
|
|
316
|
+
result = subprocess.run(
|
|
317
|
+
["git", "diff", "--name-only", "--cached"],
|
|
318
|
+
cwd=repo_path,
|
|
319
|
+
capture_output=True,
|
|
320
|
+
text=True,
|
|
321
|
+
timeout=5,
|
|
322
|
+
check=True
|
|
323
|
+
)
|
|
324
|
+
files = [
|
|
325
|
+
line.strip()
|
|
326
|
+
for line in result.stdout.splitlines()
|
|
327
|
+
if line.strip()
|
|
328
|
+
]
|
|
329
|
+
return files
|
|
330
|
+
except Exception:
|
|
331
|
+
return []
|
|
332
|
+
|
|
333
|
+
def validate_files(self, files: List[str]) -> ValidationResult:
|
|
334
|
+
"""Validate list of files
|
|
335
|
+
|
|
336
|
+
Main validation method that runs all checks:
|
|
337
|
+
- Format validation
|
|
338
|
+
- Duplicate detection
|
|
339
|
+
- Orphan detection
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
files: List of file paths to validate
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
ValidationResult with errors and warnings
|
|
346
|
+
"""
|
|
347
|
+
if not files:
|
|
348
|
+
return ValidationResult(is_valid=True)
|
|
349
|
+
|
|
350
|
+
# Check for duplicates
|
|
351
|
+
errors = self.validate_duplicates(files)
|
|
352
|
+
|
|
353
|
+
# Check for orphans
|
|
354
|
+
warnings = self.validate_orphans(files)
|
|
355
|
+
|
|
356
|
+
# In strict mode, warnings become errors
|
|
357
|
+
if self.strict_mode and warnings:
|
|
358
|
+
is_valid = False
|
|
359
|
+
else:
|
|
360
|
+
is_valid = len(errors) == 0
|
|
361
|
+
|
|
362
|
+
return ValidationResult(
|
|
363
|
+
is_valid=is_valid,
|
|
364
|
+
errors=errors,
|
|
365
|
+
warnings=warnings
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def main():
|
|
370
|
+
"""CLI entry point for pre-commit hook"""
|
|
371
|
+
import argparse
|
|
372
|
+
import sys
|
|
373
|
+
|
|
374
|
+
parser = argparse.ArgumentParser(
|
|
375
|
+
description="Validate TAG annotations in git staged files"
|
|
376
|
+
)
|
|
377
|
+
parser.add_argument(
|
|
378
|
+
"--files",
|
|
379
|
+
nargs="*",
|
|
380
|
+
help="Files to validate (default: git staged files)"
|
|
381
|
+
)
|
|
382
|
+
parser.add_argument(
|
|
383
|
+
"--strict",
|
|
384
|
+
action="store_true",
|
|
385
|
+
help="Treat warnings as errors"
|
|
386
|
+
)
|
|
387
|
+
parser.add_argument(
|
|
388
|
+
"--no-orphan-check",
|
|
389
|
+
action="store_true",
|
|
390
|
+
help="Disable orphan TAG checking"
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
args = parser.parse_args()
|
|
394
|
+
|
|
395
|
+
validator = PreCommitValidator(
|
|
396
|
+
strict_mode=args.strict,
|
|
397
|
+
check_orphans=not args.no_orphan_check
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
# Get files to validate
|
|
401
|
+
if args.files:
|
|
402
|
+
files = args.files
|
|
403
|
+
else:
|
|
404
|
+
files = validator.get_staged_files()
|
|
405
|
+
|
|
406
|
+
if not files:
|
|
407
|
+
print("No files to validate.")
|
|
408
|
+
sys.exit(0)
|
|
409
|
+
|
|
410
|
+
# Run validation
|
|
411
|
+
result = validator.validate_files(files)
|
|
412
|
+
|
|
413
|
+
# Print results
|
|
414
|
+
print(result.format())
|
|
415
|
+
|
|
416
|
+
# Exit with error code if validation failed
|
|
417
|
+
sys.exit(0 if result.is_valid else 1)
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
if __name__ == "__main__":
|
|
421
|
+
main()
|