moai-adk 0.15.0__py3-none-any.whl → 0.25.4__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 -2
- moai_adk/__main__.py +85 -2
- moai_adk/cli/__init__.py +0 -1
- moai_adk/cli/commands/__init__.py +0 -1
- moai_adk/cli/commands/analyze.py +127 -0
- moai_adk/cli/commands/backup.py +5 -3
- moai_adk/cli/commands/doctor.py +35 -11
- moai_adk/cli/commands/improve_user_experience.py +348 -0
- moai_adk/cli/commands/init.py +150 -23
- moai_adk/cli/commands/language.py +269 -0
- moai_adk/cli/commands/migrate.py +158 -0
- moai_adk/cli/commands/status.py +13 -12
- moai_adk/cli/commands/update.py +364 -60
- moai_adk/cli/commands/validate_links.py +118 -0
- moai_adk/cli/main.py +3 -2
- moai_adk/cli/prompts/init_prompts.py +79 -82
- moai_adk/core/__init__.py +0 -1
- moai_adk/core/analysis/__init__.py +9 -0
- moai_adk/core/analysis/session_analyzer.py +439 -0
- moai_adk/core/claude_integration.py +421 -0
- moai_adk/core/command_helpers.py +270 -0
- moai_adk/core/config/__init__.py +6 -0
- moai_adk/core/config/auto_spec_config.py +346 -0
- moai_adk/core/config/migration.py +133 -12
- moai_adk/core/context_manager.py +279 -0
- moai_adk/core/diagnostics/slash_commands.py +0 -1
- moai_adk/core/error_recovery_system.py +1289 -0
- moai_adk/core/git/__init__.py +0 -1
- moai_adk/core/git/branch.py +0 -1
- moai_adk/core/git/branch_manager.py +4 -4
- moai_adk/core/git/checkpoint.py +1 -5
- moai_adk/core/git/commit.py +0 -1
- moai_adk/core/git/event_detector.py +3 -5
- moai_adk/core/git/manager.py +0 -1
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +925 -0
- moai_adk/core/integration/__init__.py +22 -0
- moai_adk/core/integration/engine.py +169 -0
- moai_adk/core/integration/integration_tester.py +225 -0
- moai_adk/core/integration/models.py +88 -0
- moai_adk/core/integration/utils.py +211 -0
- moai_adk/core/issue_creator.py +28 -18
- moai_adk/core/language_config.py +202 -0
- moai_adk/core/language_validator.py +556 -0
- moai_adk/core/mcp/setup.py +113 -0
- moai_adk/core/migration/__init__.py +18 -0
- moai_adk/core/migration/backup_manager.py +208 -0
- moai_adk/core/migration/file_migrator.py +218 -0
- moai_adk/core/migration/version_detector.py +143 -0
- moai_adk/core/migration/version_migrator.py +228 -0
- moai_adk/core/performance/__init__.py +6 -0
- moai_adk/core/performance/cache_system.py +318 -0
- moai_adk/core/performance/parallel_processor.py +116 -0
- moai_adk/core/project/__init__.py +0 -1
- moai_adk/core/project/backup_utils.py +2 -7
- moai_adk/core/project/checker.py +3 -3
- moai_adk/core/project/detector.py +20 -40
- moai_adk/core/project/initializer.py +42 -17
- moai_adk/core/project/phase_executor.py +415 -58
- moai_adk/core/project/validator.py +6 -25
- moai_adk/core/quality/__init__.py +1 -1
- moai_adk/core/quality/trust_checker.py +64 -110
- moai_adk/core/quality/validators/__init__.py +1 -1
- moai_adk/core/quality/validators/base_validator.py +1 -1
- moai_adk/core/rollback_manager.py +993 -0
- moai_adk/core/session_manager.py +667 -0
- moai_adk/core/spec/confidence_scoring.py +749 -0
- moai_adk/core/spec/ears_template_engine.py +1182 -0
- moai_adk/core/spec/quality_validator.py +721 -0
- moai_adk/core/spec_status_manager.py +488 -0
- moai_adk/core/template/__init__.py +0 -1
- moai_adk/core/template/backup.py +41 -1
- moai_adk/core/template/config.py +11 -12
- moai_adk/core/template/languages.py +0 -1
- moai_adk/core/template/merger.py +79 -22
- moai_adk/core/template/processor.py +614 -40
- moai_adk/core/template_engine.py +36 -27
- moai_adk/foundation/git/commit_templates.py +565 -0
- moai_adk/foundation/trust/trust_principles.py +725 -0
- moai_adk/foundation/trust/validation_checklist.py +1678 -0
- moai_adk/statusline/__init__.py +38 -0
- moai_adk/statusline/alfred_detector.py +107 -0
- moai_adk/statusline/config.py +364 -0
- moai_adk/statusline/enhanced_output_style_detector.py +364 -0
- moai_adk/statusline/git_collector.py +190 -0
- moai_adk/statusline/main.py +228 -0
- moai_adk/statusline/metrics_tracker.py +78 -0
- moai_adk/statusline/renderer.py +327 -0
- moai_adk/statusline/update_checker.py +135 -0
- moai_adk/statusline/version_reader.py +647 -0
- moai_adk/templates/.git-hooks/pre-commit +66 -0
- moai_adk/templates/.git-hooks/pre-push +116 -4
- moai_adk/templates/.github/workflows/moai-gitflow.yml +1 -7
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +0 -1
- moai_adk/templates/.gitignore +44 -0
- moai_adk/templates/.mcp.json +22 -0
- moai_adk/templates/CLAUDE.md +450 -1071
- moai_adk/utils/__init__.py +0 -1
- moai_adk/utils/banner.py +0 -1
- moai_adk/utils/common.py +308 -0
- moai_adk/utils/link_validator.py +249 -0
- moai_adk/utils/logger.py +4 -9
- moai_adk/utils/safe_file_reader.py +210 -0
- moai_adk/utils/user_experience.py +531 -0
- moai_adk-0.25.4.dist-info/METADATA +2279 -0
- moai_adk-0.25.4.dist-info/RECORD +112 -0
- moai_adk/core/tags/__init__.py +0 -86
- moai_adk/core/tags/ci_validator.py +0 -463
- moai_adk/core/tags/cli.py +0 -283
- moai_adk/core/tags/generator.py +0 -109
- moai_adk/core/tags/inserter.py +0 -99
- moai_adk/core/tags/mapper.py +0 -126
- moai_adk/core/tags/parser.py +0 -76
- moai_adk/core/tags/pre_commit_validator.py +0 -393
- moai_adk/core/tags/reporter.py +0 -956
- moai_adk/core/tags/tags.py +0 -149
- moai_adk/core/tags/validator.py +0 -897
- moai_adk/templates/.claude/agents/alfred/backend-expert.md +0 -319
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +0 -316
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +0 -208
- moai_adk/templates/.claude/agents/alfred/devops-expert.md +0 -464
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +0 -214
- moai_adk/templates/.claude/agents/alfred/frontend-expert.md +0 -357
- moai_adk/templates/.claude/agents/alfred/git-manager.md +0 -406
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +0 -423
- moai_adk/templates/.claude/agents/alfred/project-manager.md +0 -312
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +0 -343
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +0 -865
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +0 -392
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +0 -361
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +0 -428
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +0 -375
- moai_adk/templates/.claude/agents/alfred/ui-ux-expert.md +0 -571
- moai_adk/templates/.claude/commands/alfred/0-project.md +0 -1525
- moai_adk/templates/.claude/commands/alfred/1-plan.md +0 -802
- moai_adk/templates/.claude/commands/alfred/2-run.md +0 -709
- moai_adk/templates/.claude/commands/alfred/3-sync.md +0 -1009
- moai_adk/templates/.claude/commands/alfred/9-feedback.md +0 -149
- moai_adk/templates/.claude/hooks/alfred/core/project.py +0 -748
- moai_adk/templates/.claude/hooks/alfred/core/timeout.py +0 -136
- moai_adk/templates/.claude/hooks/alfred/core/ttl_cache.py +0 -108
- moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +0 -198
- moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py +0 -29
- moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +0 -94
- moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +0 -100
- moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +0 -94
- moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +0 -94
- moai_adk/templates/.claude/hooks/alfred/shared/core/__init__.py +0 -170
- moai_adk/templates/.claude/hooks/alfred/shared/core/checkpoint.py +0 -271
- moai_adk/templates/.claude/hooks/alfred/shared/core/context.py +0 -67
- moai_adk/templates/.claude/hooks/alfred/shared/core/project.py +0 -749
- moai_adk/templates/.claude/hooks/alfred/shared/core/tags.py +0 -230
- moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +0 -198
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/__init__.py +0 -21
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/notification.py +0 -154
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/session.py +0 -174
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/tool.py +0 -87
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/user.py +0 -61
- moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +0 -112
- moai_adk/templates/.claude/hooks/alfred/utils/__init__.py +0 -1
- moai_adk/templates/.claude/hooks/alfred/utils/timeout.py +0 -161
- moai_adk/templates/.claude/settings.json +0 -144
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/SKILL.md +0 -70
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/examples.md +0 -62
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/reference.md +0 -242
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/SKILL.md +0 -56
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/examples.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/reference.md +0 -444
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/SKILL.md +0 -62
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/examples.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/reference.md +0 -405
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/SKILL.md +0 -51
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/examples.md +0 -355
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/reference.md +0 -239
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/SKILL.md +0 -323
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/examples.md +0 -286
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/reference.md +0 -126
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/SKILL.md +0 -122
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-git-workflow/reference.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/SKILL.md +0 -74
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/reference.md +0 -269
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/SKILL.md +0 -237
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/examples.md +0 -615
- moai_adk/templates/.claude/skills/moai-alfred-interactive-questions/reference.md +0 -653
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/SKILL.md +0 -19
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/reference.md +0 -150
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-language-detection/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/SKILL.md +0 -198
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/examples.md +0 -431
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/reference.md +0 -141
- moai_adk/templates/.claude/skills/moai-alfred-practices/SKILL.md +0 -89
- moai_adk/templates/.claude/skills/moai-alfred-practices/examples.md +0 -122
- moai_adk/templates/.claude/skills/moai-alfred-practices/reference.md +0 -369
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/SKILL.md +0 -508
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/examples.md +0 -481
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/reference.md +0 -100
- moai_adk/templates/.claude/skills/moai-alfred-reporting/SKILL.md +0 -273
- moai_adk/templates/.claude/skills/moai-alfred-rules/SKILL.md +0 -77
- moai_adk/templates/.claude/skills/moai-alfred-rules/examples.md +0 -265
- moai_adk/templates/.claude/skills/moai-alfred-rules/reference.md +0 -539
- moai_adk/templates/.claude/skills/moai-alfred-session-state/SKILL.md +0 -19
- moai_adk/templates/.claude/skills/moai-alfred-session-state/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-session-state/reference.md +0 -84
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/README.md +0 -137
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/SKILL.md +0 -219
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples/validate-spec.sh +0 -161
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples.md +0 -541
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/reference.md +0 -622
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/SKILL.md +0 -115
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/reference.md +0 -348
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/SKILL.md +0 -19
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/reference.md +0 -211
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-alfred-trust-validation/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-alfred-workflow/SKILL.md +0 -288
- moai_adk/templates/.claude/skills/moai-cc-agents/SKILL.md +0 -269
- moai_adk/templates/.claude/skills/moai-cc-agents/templates/agent-template.md +0 -32
- moai_adk/templates/.claude/skills/moai-cc-claude-md/SKILL.md +0 -298
- moai_adk/templates/.claude/skills/moai-cc-claude-md/templates/CLAUDE-template.md +0 -26
- moai_adk/templates/.claude/skills/moai-cc-commands/SKILL.md +0 -307
- moai_adk/templates/.claude/skills/moai-cc-commands/templates/command-template.md +0 -21
- moai_adk/templates/.claude/skills/moai-cc-hooks/SKILL.md +0 -252
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/pre-bash-check.sh +0 -19
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/preserve-permissions.sh +0 -19
- moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/validate-bash-command.py +0 -24
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/SKILL.md +0 -199
- moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/templates/settings-mcp-template.json +0 -39
- moai_adk/templates/.claude/skills/moai-cc-memory/SKILL.md +0 -316
- moai_adk/templates/.claude/skills/moai-cc-memory/templates/session-summary-template.md +0 -18
- moai_adk/templates/.claude/skills/moai-cc-settings/SKILL.md +0 -263
- moai_adk/templates/.claude/skills/moai-cc-settings/templates/settings-complete-template.json +0 -30
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/SKILL.md +0 -19
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/examples.md +0 -4
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/reference.md +0 -218
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/CHECKLIST.md +0 -482
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/EXAMPLES.md +0 -278
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/INTERACTIVE-DISCOVERY.md +0 -524
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/METADATA.md +0 -477
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/PARALLEL-ANALYSIS-REPORT.md +0 -429
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/PYTHON-VERSION-MATRIX.md +0 -391
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-FACTORY-WORKFLOW.md +0 -431
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-UPDATE-ADVISOR.md +0 -577
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL.md +0 -271
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/STEP-BY-STEP-GUIDE.md +0 -466
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/STRUCTURE.md +0 -583
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/WEB-RESEARCH.md +0 -526
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/reference.md +0 -465
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/generate-structure.sh +0 -328
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/validate-skill.sh +0 -312
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/SKILL_TEMPLATE.md +0 -245
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/examples-template.md +0 -285
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/reference-template.md +0 -278
- moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/scripts-template.sh +0 -303
- moai_adk/templates/.claude/skills/moai-cc-skills/SKILL.md +0 -291
- moai_adk/templates/.claude/skills/moai-cc-skills/templates/SKILL-template.md +0 -15
- moai_adk/templates/.claude/skills/moai-design-systems/SKILL.md +0 -802
- moai_adk/templates/.claude/skills/moai-design-systems/examples.md +0 -1238
- moai_adk/templates/.claude/skills/moai-design-systems/reference.md +0 -673
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +0 -290
- moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +0 -1633
- moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +0 -660
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-cli-tool/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-data-science/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-data-science/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-data-science/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-database/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-database/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-devops/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-domain-devops/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-devops/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +0 -128
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-domain-ml/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-ml/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-ml/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-mobile-app/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-security/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-security/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-security/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-domain-web-api/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-domain-web-api/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-domain-web-api/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-essentials-debug/SKILL.md +0 -303
- moai_adk/templates/.claude/skills/moai-essentials-debug/examples.md +0 -1064
- moai_adk/templates/.claude/skills/moai-essentials-debug/reference.md +0 -1047
- moai_adk/templates/.claude/skills/moai-essentials-perf/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-perf/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-perf/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-essentials-refactor/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-refactor/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-refactor/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-essentials-review/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-essentials-review/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-essentials-review/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +0 -116
- moai_adk/templates/.claude/skills/moai-foundation-ears/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-ears/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-git/SKILL.md +0 -122
- moai_adk/templates/.claude/skills/moai-foundation-git/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-git/reference.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-langs/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-langs/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-langs/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-specs/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-specs/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-specs/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-tags/SKILL.md +0 -113
- moai_adk/templates/.claude/skills/moai-foundation-tags/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-foundation-tags/reference.md +0 -28
- moai_adk/templates/.claude/skills/moai-foundation-trust/SKILL.md +0 -307
- moai_adk/templates/.claude/skills/moai-foundation-trust/examples.md +0 -0
- moai_adk/templates/.claude/skills/moai-foundation-trust/reference.md +0 -1099
- moai_adk/templates/.claude/skills/moai-lang-c/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-c/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-c/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-dart/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-dart/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-dart/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +0 -127
- moai_adk/templates/.claude/skills/moai-lang-go/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-go/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +0 -126
- moai_adk/templates/.claude/skills/moai-lang-java/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-java/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +0 -125
- moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +0 -32
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +0 -126
- moai_adk/templates/.claude/skills/moai-lang-php/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-php/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +0 -433
- moai_adk/templates/.claude/skills/moai-lang-python/examples.md +0 -624
- moai_adk/templates/.claude/skills/moai-lang-python/reference.md +0 -316
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-r/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-r/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +0 -127
- moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +0 -125
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-shell/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-shell/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-shell/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-sql/SKILL.md +0 -124
- moai_adk/templates/.claude/skills/moai-lang-sql/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-sql/reference.md +0 -31
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +0 -123
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +0 -30
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +0 -133
- moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +0 -29
- moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +0 -34
- moai_adk/templates/.claude/skills/moai-project-documentation.md +0 -622
- moai_adk/templates/.github/workflows/c-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/cpp-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/csharp-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/dart-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/go-tag-validation.yml +0 -130
- moai_adk/templates/.github/workflows/java-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/javascript-tag-validation.yml +0 -135
- moai_adk/templates/.github/workflows/kotlin-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/php-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/python-tag-validation.yml +0 -118
- moai_adk/templates/.github/workflows/release.yml +0 -118
- moai_adk/templates/.github/workflows/ruby-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/rust-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/shell-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/swift-tag-validation.yml +0 -11
- moai_adk/templates/.github/workflows/tag-report.yml +0 -269
- moai_adk/templates/.github/workflows/tag-validation.yml +0 -186
- moai_adk/templates/.github/workflows/typescript-tag-validation.yml +0 -154
- moai_adk/templates/.moai/config.json +0 -115
- moai_adk/templates/workflows/go-tag-validation.yml +0 -30
- moai_adk/templates/workflows/javascript-tag-validation.yml +0 -41
- moai_adk/templates/workflows/python-tag-validation.yml +0 -42
- moai_adk/templates/workflows/typescript-tag-validation.yml +0 -31
- moai_adk-0.15.0.dist-info/METADATA +0 -3079
- moai_adk-0.15.0.dist-info/RECORD +0 -365
- {moai_adk-0.15.0.dist-info → moai_adk-0.25.4.dist-info}/WHEEL +0 -0
- {moai_adk-0.15.0.dist-info → moai_adk-0.25.4.dist-info}/entry_points.txt +0 -0
- {moai_adk-0.15.0.dist-info → moai_adk-0.25.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
"""
|
|
3
|
+
Enhanced Version reader for MoAI-ADK from config.json with performance optimizations
|
|
4
|
+
|
|
5
|
+
Refactored for improved performance, error handling, configurability, and caching strategies
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import json
|
|
10
|
+
import logging
|
|
11
|
+
import re
|
|
12
|
+
import time
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from datetime import datetime, timedelta
|
|
15
|
+
from enum import Enum
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Any, Dict, List, Optional
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class VersionSource(Enum):
|
|
23
|
+
"""Enum for version source tracking"""
|
|
24
|
+
|
|
25
|
+
CONFIG_FILE = "config_file"
|
|
26
|
+
FALLBACK = "fallback"
|
|
27
|
+
PACKAGE = "package"
|
|
28
|
+
CACHE = "cache"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class CacheEntry:
|
|
33
|
+
"""Cache entry with metadata"""
|
|
34
|
+
|
|
35
|
+
version: str
|
|
36
|
+
timestamp: datetime
|
|
37
|
+
source: VersionSource
|
|
38
|
+
access_count: int = 0
|
|
39
|
+
last_access: datetime = field(default_factory=datetime.now)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class VersionConfig:
|
|
44
|
+
"""Configuration for version reading behavior with enhanced options"""
|
|
45
|
+
|
|
46
|
+
# Cache configuration
|
|
47
|
+
cache_ttl_seconds: int = 60
|
|
48
|
+
cache_enabled: bool = True
|
|
49
|
+
cache_size: int = 50 # Maximum number of cached entries
|
|
50
|
+
enable_lru_cache: bool = True # Enable least recently used cache eviction
|
|
51
|
+
|
|
52
|
+
# Fallback configuration
|
|
53
|
+
fallback_version: str = "unknown"
|
|
54
|
+
fallback_source: VersionSource = VersionSource.FALLBACK
|
|
55
|
+
|
|
56
|
+
# Validation configuration
|
|
57
|
+
version_format_regex: str = r"^v?(\d+\.\d+\.\d+(-[a-zA-Z0-9]+)?)$"
|
|
58
|
+
enable_validation: bool = True
|
|
59
|
+
strict_validation: bool = False
|
|
60
|
+
|
|
61
|
+
# Performance configuration
|
|
62
|
+
enable_async: bool = True
|
|
63
|
+
enable_batch_reading: bool = True
|
|
64
|
+
batch_size: int = 10
|
|
65
|
+
timeout_seconds: int = 5
|
|
66
|
+
|
|
67
|
+
# Debug configuration
|
|
68
|
+
debug_mode: bool = False
|
|
69
|
+
enable_detailed_logging: bool = False
|
|
70
|
+
track_performance_metrics: bool = True
|
|
71
|
+
|
|
72
|
+
# Version field priority configuration
|
|
73
|
+
version_fields: List[str] = field(
|
|
74
|
+
default_factory=lambda: [
|
|
75
|
+
"project.version",
|
|
76
|
+
"moai.version",
|
|
77
|
+
"version",
|
|
78
|
+
"moai.template_version",
|
|
79
|
+
"template_version",
|
|
80
|
+
]
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class VersionReader:
|
|
85
|
+
"""
|
|
86
|
+
Enhanced version reader for MoAI-ADK with advanced caching,
|
|
87
|
+
performance optimization, and comprehensive error handling.
|
|
88
|
+
|
|
89
|
+
Features:
|
|
90
|
+
- Multi-level caching with LRU eviction strategy
|
|
91
|
+
- Configurable version field priority
|
|
92
|
+
- Async batch processing for better performance
|
|
93
|
+
- Comprehensive error handling and recovery
|
|
94
|
+
- Version format validation with customizable patterns
|
|
95
|
+
- Performance metrics tracking
|
|
96
|
+
- Graceful degradation strategies
|
|
97
|
+
- Source tracking for debugging
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
# Default configuration
|
|
101
|
+
DEFAULT_CONFIG = VersionConfig()
|
|
102
|
+
|
|
103
|
+
# Supported version fields in order of priority
|
|
104
|
+
DEFAULT_VERSION_FIELDS = [
|
|
105
|
+
"project.version",
|
|
106
|
+
"moai.version",
|
|
107
|
+
"version",
|
|
108
|
+
"moai.template_version",
|
|
109
|
+
"template_version",
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
def __init__(self, config: Optional[VersionConfig] = None):
|
|
113
|
+
"""
|
|
114
|
+
Initialize version reader with enhanced configuration.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
config: Version configuration object. If None, uses defaults.
|
|
118
|
+
"""
|
|
119
|
+
self.config = config or self.DEFAULT_CONFIG
|
|
120
|
+
self._config_path = Path.cwd() / ".moai" / "config" / "config.json"
|
|
121
|
+
|
|
122
|
+
# Enhanced caching with LRU support
|
|
123
|
+
self._cache: Dict[str, CacheEntry] = {}
|
|
124
|
+
self._cache_stats = {
|
|
125
|
+
"hits": 0,
|
|
126
|
+
"misses": 0,
|
|
127
|
+
"errors": 0,
|
|
128
|
+
"cache_hits_by_source": {
|
|
129
|
+
VersionSource.CONFIG_FILE.value: 0,
|
|
130
|
+
VersionSource.CACHE.value: 0,
|
|
131
|
+
VersionSource.FALLBACK.value: 0,
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# Performance tracking
|
|
136
|
+
self._performance_metrics = {
|
|
137
|
+
"read_times": [],
|
|
138
|
+
"validation_times": [],
|
|
139
|
+
"cache_operation_times": [],
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# Version field configuration (backwards compatibility)
|
|
143
|
+
self._version_fields = self.config.version_fields.copy()
|
|
144
|
+
self.VERSION_FIELDS = self._version_fields.copy()
|
|
145
|
+
|
|
146
|
+
# Pre-compile regex for performance
|
|
147
|
+
try:
|
|
148
|
+
self._version_pattern = re.compile(self.config.version_format_regex)
|
|
149
|
+
except re.error:
|
|
150
|
+
self._version_pattern = re.compile(self.DEFAULT_CONFIG.version_format_regex)
|
|
151
|
+
|
|
152
|
+
# Logging
|
|
153
|
+
self._logger = logging.getLogger(__name__)
|
|
154
|
+
|
|
155
|
+
# Backwards compatibility cache attributes
|
|
156
|
+
self._version_cache: Optional[str] = None
|
|
157
|
+
self._cache_time: Optional[datetime] = None
|
|
158
|
+
self._cache_ttl = timedelta(seconds=self.config.cache_ttl_seconds)
|
|
159
|
+
|
|
160
|
+
if self.config.debug_mode:
|
|
161
|
+
self._logger.info(f"VersionReader initialized with config: {self.config}")
|
|
162
|
+
|
|
163
|
+
def get_version(self) -> str:
|
|
164
|
+
"""
|
|
165
|
+
Get MoAI-ADK version from config with enhanced caching.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
Version string (e.g., "0.20.1" or "v0.20.1")
|
|
169
|
+
|
|
170
|
+
Raises:
|
|
171
|
+
VersionReadError: If version cannot be determined after fallbacks
|
|
172
|
+
"""
|
|
173
|
+
if self.config.enable_async:
|
|
174
|
+
return asyncio.run(self.get_version_async())
|
|
175
|
+
else:
|
|
176
|
+
return self.get_version_sync()
|
|
177
|
+
|
|
178
|
+
def get_version_sync(self) -> str:
|
|
179
|
+
"""
|
|
180
|
+
Synchronous version getter for performance-critical paths.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
Version string
|
|
184
|
+
"""
|
|
185
|
+
start_time = time.time()
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
# Check cache first
|
|
189
|
+
version = self._check_cache()
|
|
190
|
+
if version is not None:
|
|
191
|
+
self._cache_stats["hits"] += 1
|
|
192
|
+
self._cache_stats["cache_hits_by_source"][
|
|
193
|
+
VersionSource.CACHE.value
|
|
194
|
+
] += 1
|
|
195
|
+
return version
|
|
196
|
+
|
|
197
|
+
# Read from config file
|
|
198
|
+
version = self._read_version_from_config_sync()
|
|
199
|
+
if not version:
|
|
200
|
+
version = self._get_fallback_version()
|
|
201
|
+
self._update_cache(version, VersionSource.CONFIG_FILE)
|
|
202
|
+
self._cache_stats["misses"] += 1
|
|
203
|
+
return version
|
|
204
|
+
|
|
205
|
+
except Exception as e:
|
|
206
|
+
self._handle_read_error(e, start_time)
|
|
207
|
+
return self._get_fallback_version()
|
|
208
|
+
|
|
209
|
+
finally:
|
|
210
|
+
self._log_performance(start_time, "sync_read")
|
|
211
|
+
|
|
212
|
+
async def get_version_async(self) -> str:
|
|
213
|
+
"""
|
|
214
|
+
Async version getter for better performance.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
Version string
|
|
218
|
+
"""
|
|
219
|
+
start_time = time.time()
|
|
220
|
+
|
|
221
|
+
try:
|
|
222
|
+
# Check cache first
|
|
223
|
+
version = self._check_cache()
|
|
224
|
+
if version is not None:
|
|
225
|
+
self._cache_stats["hits"] += 1
|
|
226
|
+
self._cache_stats["cache_hits_by_source"][
|
|
227
|
+
VersionSource.CACHE.value
|
|
228
|
+
] += 1
|
|
229
|
+
return version
|
|
230
|
+
|
|
231
|
+
# Read from config file asynchronously
|
|
232
|
+
version = await self._read_version_from_config_async()
|
|
233
|
+
if not version:
|
|
234
|
+
version = self._get_fallback_version()
|
|
235
|
+
self._update_cache(version, VersionSource.CONFIG_FILE)
|
|
236
|
+
self._cache_stats["misses"] += 1
|
|
237
|
+
return version
|
|
238
|
+
|
|
239
|
+
except Exception as e:
|
|
240
|
+
self._handle_read_error(e, start_time)
|
|
241
|
+
return self._get_fallback_version()
|
|
242
|
+
|
|
243
|
+
finally:
|
|
244
|
+
self._log_performance(start_time, "async_read")
|
|
245
|
+
|
|
246
|
+
# Enhanced internal methods
|
|
247
|
+
def _check_cache(self) -> Optional[str]:
|
|
248
|
+
"""
|
|
249
|
+
Check cache for valid version entry.
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
Version string if cache is valid, None otherwise
|
|
253
|
+
"""
|
|
254
|
+
if not self.config.cache_enabled:
|
|
255
|
+
return None
|
|
256
|
+
|
|
257
|
+
# Check for existing cache entries
|
|
258
|
+
config_key = str(self._config_path)
|
|
259
|
+
if config_key in self._cache:
|
|
260
|
+
entry = self._cache[config_key]
|
|
261
|
+
|
|
262
|
+
# Check if cache entry is still valid
|
|
263
|
+
if self._is_cache_entry_valid(entry):
|
|
264
|
+
entry.access_count += 1
|
|
265
|
+
entry.last_access = datetime.now()
|
|
266
|
+
self._cache_stats["hits"] += 1
|
|
267
|
+
self._cache_stats["cache_hits_by_source"][
|
|
268
|
+
VersionSource.CACHE.value
|
|
269
|
+
] += 1
|
|
270
|
+
|
|
271
|
+
if self.config.debug_mode:
|
|
272
|
+
self._logger.debug(
|
|
273
|
+
f"Cache hit: {entry.version} (source: {entry.source.value})"
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
return entry.version
|
|
277
|
+
|
|
278
|
+
return None
|
|
279
|
+
|
|
280
|
+
def _is_cache_entry_valid(self, entry: CacheEntry) -> bool:
|
|
281
|
+
"""
|
|
282
|
+
Check if cache entry is still valid.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
entry: Cache entry to validate
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
True if cache entry is valid
|
|
289
|
+
"""
|
|
290
|
+
# Check TTL
|
|
291
|
+
if self.config.cache_enabled:
|
|
292
|
+
age = datetime.now() - entry.timestamp
|
|
293
|
+
if age.total_seconds() > self.config.cache_ttl_seconds:
|
|
294
|
+
return False
|
|
295
|
+
|
|
296
|
+
return True
|
|
297
|
+
|
|
298
|
+
def _update_cache(self, version: str, source: VersionSource) -> None:
|
|
299
|
+
"""
|
|
300
|
+
Update cache with new version entry.
|
|
301
|
+
|
|
302
|
+
Args:
|
|
303
|
+
version: Version string to cache
|
|
304
|
+
source: Source of the version
|
|
305
|
+
"""
|
|
306
|
+
if not self.config.cache_enabled:
|
|
307
|
+
return
|
|
308
|
+
|
|
309
|
+
config_key = str(self._config_path)
|
|
310
|
+
entry = CacheEntry(version=version, timestamp=datetime.now(), source=source)
|
|
311
|
+
|
|
312
|
+
self._cache[config_key] = entry
|
|
313
|
+
|
|
314
|
+
# Apply cache size limits with LRU eviction
|
|
315
|
+
if len(self._cache) > self.config.cache_size:
|
|
316
|
+
self._evict_oldest_cache_entry()
|
|
317
|
+
|
|
318
|
+
if self.config.debug_mode:
|
|
319
|
+
self._logger.debug(
|
|
320
|
+
f"Cache updated with version: {version} (source: {source.value})"
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
def _evict_oldest_cache_entry(self) -> None:
|
|
324
|
+
"""
|
|
325
|
+
Evict the least recently used cache entry.
|
|
326
|
+
"""
|
|
327
|
+
if not self.config.enable_lru_cache or len(self._cache) <= 1:
|
|
328
|
+
return
|
|
329
|
+
|
|
330
|
+
oldest_entry = None
|
|
331
|
+
oldest_key = None
|
|
332
|
+
|
|
333
|
+
for key, entry in self._cache.items():
|
|
334
|
+
if oldest_entry is None or entry.last_access < oldest_entry.last_access:
|
|
335
|
+
oldest_entry = entry
|
|
336
|
+
oldest_key = key
|
|
337
|
+
|
|
338
|
+
if oldest_key is not None:
|
|
339
|
+
del self._cache[oldest_key]
|
|
340
|
+
if self.config.debug_mode:
|
|
341
|
+
self._logger.debug(f"Evicted oldest cache entry: {oldest_key}")
|
|
342
|
+
|
|
343
|
+
def _handle_read_error(self, error: Exception, start_time: float) -> None:
|
|
344
|
+
"""
|
|
345
|
+
Handle read errors with enhanced logging and recovery.
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
error: Exception that occurred
|
|
349
|
+
start_time: When the operation started
|
|
350
|
+
"""
|
|
351
|
+
self._cache_stats["errors"] += 1
|
|
352
|
+
|
|
353
|
+
error_msg = f"Error reading version: {error}"
|
|
354
|
+
if self.config.debug_mode:
|
|
355
|
+
self._logger.error(error_msg, exc_info=True)
|
|
356
|
+
else:
|
|
357
|
+
self._logger.warning(error_msg)
|
|
358
|
+
|
|
359
|
+
self._log_performance(start_time, "error_read")
|
|
360
|
+
|
|
361
|
+
def _log_performance(self, start_time: float, operation: str) -> None:
|
|
362
|
+
"""
|
|
363
|
+
Log performance metrics for the operation.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
start_time: When the operation started
|
|
367
|
+
operation: Type of operation being logged
|
|
368
|
+
"""
|
|
369
|
+
if not self.config.track_performance_metrics:
|
|
370
|
+
return
|
|
371
|
+
|
|
372
|
+
duration = time.time() - start_time
|
|
373
|
+
metric_name = f"{operation}_duration"
|
|
374
|
+
|
|
375
|
+
if metric_name not in self._performance_metrics:
|
|
376
|
+
self._performance_metrics[metric_name] = []
|
|
377
|
+
|
|
378
|
+
self._performance_metrics[metric_name].append(duration)
|
|
379
|
+
|
|
380
|
+
if self.config.debug_mode:
|
|
381
|
+
self._logger.debug(f"Performance {operation}: {duration:.4f}s")
|
|
382
|
+
|
|
383
|
+
def get_performance_metrics(self) -> Dict[str, Any]:
|
|
384
|
+
"""
|
|
385
|
+
Get performance metrics for analysis.
|
|
386
|
+
|
|
387
|
+
Returns:
|
|
388
|
+
Dictionary containing performance metrics
|
|
389
|
+
"""
|
|
390
|
+
metrics = {
|
|
391
|
+
"cache_stats": self._cache_stats.copy(),
|
|
392
|
+
"cache_size": len(self._cache),
|
|
393
|
+
"max_cache_size": self.config.cache_size,
|
|
394
|
+
"performance_metrics": {},
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
# Calculate average times for each operation
|
|
398
|
+
for operation, times in self._performance_metrics.items():
|
|
399
|
+
if times:
|
|
400
|
+
metrics["performance_metrics"][operation] = {
|
|
401
|
+
"count": len(times),
|
|
402
|
+
"average": sum(times) / len(times),
|
|
403
|
+
"min": min(times),
|
|
404
|
+
"max": max(times),
|
|
405
|
+
"total": sum(times),
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return metrics
|
|
409
|
+
|
|
410
|
+
def _read_version_from_config_sync(self) -> str:
|
|
411
|
+
"""
|
|
412
|
+
Synchronous version of reading from .moai/config/config.json.
|
|
413
|
+
|
|
414
|
+
Returns:
|
|
415
|
+
Version string or empty string if not found
|
|
416
|
+
"""
|
|
417
|
+
try:
|
|
418
|
+
if not self._config_path.exists():
|
|
419
|
+
logger.debug(f"Config file not found: {self._config_path}")
|
|
420
|
+
return ""
|
|
421
|
+
|
|
422
|
+
try:
|
|
423
|
+
config_data = self._read_json_sync(self._config_path)
|
|
424
|
+
version = self._extract_version_from_config(config_data)
|
|
425
|
+
return version if version else ""
|
|
426
|
+
except json.JSONDecodeError as e:
|
|
427
|
+
logger.error(f"Invalid JSON in config {self._config_path}: {e}")
|
|
428
|
+
return ""
|
|
429
|
+
|
|
430
|
+
except Exception as e:
|
|
431
|
+
logger.error(f"Error reading version from config: {e}")
|
|
432
|
+
return ""
|
|
433
|
+
|
|
434
|
+
async def _read_version_from_config_async(self) -> str:
|
|
435
|
+
"""
|
|
436
|
+
Read version from .moai/config/config.json asynchronously.
|
|
437
|
+
|
|
438
|
+
Returns:
|
|
439
|
+
Version string or empty string if not found
|
|
440
|
+
"""
|
|
441
|
+
try:
|
|
442
|
+
if not await self._file_exists_async(self._config_path):
|
|
443
|
+
logger.debug(f"Config file not found: {self._config_path}")
|
|
444
|
+
return ""
|
|
445
|
+
|
|
446
|
+
try:
|
|
447
|
+
config_data = await self._read_json_async(self._config_path)
|
|
448
|
+
return self._extract_version_from_config(config_data)
|
|
449
|
+
except json.JSONDecodeError as e:
|
|
450
|
+
logger.error(f"Invalid JSON in config {self._config_path}: {e}")
|
|
451
|
+
return ""
|
|
452
|
+
|
|
453
|
+
except Exception as e:
|
|
454
|
+
logger.error(f"Error reading version from config: {e}")
|
|
455
|
+
return ""
|
|
456
|
+
|
|
457
|
+
def _extract_version_from_config(self, config: Dict[str, Any]) -> str:
|
|
458
|
+
"""
|
|
459
|
+
Extract version from config using multiple fallback strategies.
|
|
460
|
+
|
|
461
|
+
Args:
|
|
462
|
+
config: Configuration dictionary
|
|
463
|
+
|
|
464
|
+
Returns:
|
|
465
|
+
Version string or empty string
|
|
466
|
+
"""
|
|
467
|
+
# Try each version field in order of priority
|
|
468
|
+
for field_path in self.VERSION_FIELDS:
|
|
469
|
+
version = self._get_nested_value(config, field_path)
|
|
470
|
+
if version:
|
|
471
|
+
logger.debug(f"Found version in field '{field_path}': {version}")
|
|
472
|
+
return version
|
|
473
|
+
|
|
474
|
+
logger.debug("No version field found in config")
|
|
475
|
+
return ""
|
|
476
|
+
|
|
477
|
+
def _get_nested_value(
|
|
478
|
+
self, config: Dict[str, Any], field_path: str
|
|
479
|
+
) -> Optional[str]:
|
|
480
|
+
"""
|
|
481
|
+
Get nested value from config using dot notation.
|
|
482
|
+
|
|
483
|
+
Args:
|
|
484
|
+
config: Configuration dictionary
|
|
485
|
+
field_path: Dot-separated path (e.g., "moai.version")
|
|
486
|
+
|
|
487
|
+
Returns:
|
|
488
|
+
Value or None if not found
|
|
489
|
+
"""
|
|
490
|
+
keys = field_path.split(".")
|
|
491
|
+
current = config
|
|
492
|
+
|
|
493
|
+
for key in keys:
|
|
494
|
+
if isinstance(current, dict) and key in current:
|
|
495
|
+
current = current[key]
|
|
496
|
+
else:
|
|
497
|
+
return None
|
|
498
|
+
|
|
499
|
+
return str(current) if current is not None else None
|
|
500
|
+
|
|
501
|
+
def _format_short_version(self, version: str) -> str:
|
|
502
|
+
"""
|
|
503
|
+
Format short version by removing 'v' prefix if present.
|
|
504
|
+
|
|
505
|
+
Args:
|
|
506
|
+
version: Version string
|
|
507
|
+
|
|
508
|
+
Returns:
|
|
509
|
+
Short version string
|
|
510
|
+
"""
|
|
511
|
+
return version[1:] if version.startswith("v") else version
|
|
512
|
+
|
|
513
|
+
def _format_display_version(self, version: str) -> str:
|
|
514
|
+
"""
|
|
515
|
+
Format display version with proper formatting.
|
|
516
|
+
|
|
517
|
+
Args:
|
|
518
|
+
version: Version string
|
|
519
|
+
|
|
520
|
+
Returns:
|
|
521
|
+
Display version string
|
|
522
|
+
"""
|
|
523
|
+
if version == "unknown":
|
|
524
|
+
return "MoAI-ADK unknown version"
|
|
525
|
+
elif version.startswith("v"):
|
|
526
|
+
return f"MoAI-ADK {version}"
|
|
527
|
+
else:
|
|
528
|
+
return f"MoAI-ADK v{version}"
|
|
529
|
+
|
|
530
|
+
def _is_valid_version_format(self, version: str) -> bool:
|
|
531
|
+
"""
|
|
532
|
+
Validate version format using regex pattern.
|
|
533
|
+
|
|
534
|
+
Args:
|
|
535
|
+
version: Version string to validate
|
|
536
|
+
|
|
537
|
+
Returns:
|
|
538
|
+
True if version format is valid
|
|
539
|
+
"""
|
|
540
|
+
return bool(self._version_pattern.match(version))
|
|
541
|
+
|
|
542
|
+
def _get_fallback_version(self) -> str:
|
|
543
|
+
"""
|
|
544
|
+
Get fallback version with graceful degradation.
|
|
545
|
+
|
|
546
|
+
Returns:
|
|
547
|
+
Fallback version string
|
|
548
|
+
"""
|
|
549
|
+
fallback = self.config.fallback_version
|
|
550
|
+
self._logger.debug(f"Using fallback version: {fallback}")
|
|
551
|
+
return fallback
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
async def _file_exists_async(self, path: Path) -> bool:
|
|
555
|
+
"""Async file existence check"""
|
|
556
|
+
try:
|
|
557
|
+
loop = asyncio.get_event_loop()
|
|
558
|
+
return await loop.run_in_executor(None, path.exists)
|
|
559
|
+
except Exception:
|
|
560
|
+
return False
|
|
561
|
+
|
|
562
|
+
async def _read_json_async(self, path: Path) -> Dict[str, Any]:
|
|
563
|
+
"""Async JSON file reading"""
|
|
564
|
+
loop = asyncio.get_event_loop()
|
|
565
|
+
return await loop.run_in_executor(None, self._read_json_sync, path)
|
|
566
|
+
|
|
567
|
+
def _read_json_sync(self, path: Path) -> Dict[str, Any]:
|
|
568
|
+
"""Synchronous JSON file reading"""
|
|
569
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
570
|
+
return json.load(f)
|
|
571
|
+
|
|
572
|
+
# Backwards compatibility cache methods
|
|
573
|
+
def clear_cache(self) -> None:
|
|
574
|
+
"""Clear version cache (backwards compatibility)"""
|
|
575
|
+
self._version_cache = None
|
|
576
|
+
self._cache_time = None
|
|
577
|
+
logger.debug("Version cache cleared")
|
|
578
|
+
|
|
579
|
+
def get_cache_stats(self) -> Dict[str, int]:
|
|
580
|
+
"""
|
|
581
|
+
Get cache statistics (backwards compatibility).
|
|
582
|
+
|
|
583
|
+
Returns:
|
|
584
|
+
Dictionary with cache hit/miss/error counts
|
|
585
|
+
"""
|
|
586
|
+
return self._cache_stats.copy()
|
|
587
|
+
|
|
588
|
+
def get_cache_age_seconds(self) -> Optional[float]:
|
|
589
|
+
"""
|
|
590
|
+
Get cache age in seconds (backwards compatibility).
|
|
591
|
+
|
|
592
|
+
Returns:
|
|
593
|
+
Cache age in seconds, or None if no cached version
|
|
594
|
+
"""
|
|
595
|
+
if self._cache_time is None:
|
|
596
|
+
return None
|
|
597
|
+
return (datetime.now() - self._cache_time).total_seconds()
|
|
598
|
+
|
|
599
|
+
def is_cache_expired(self) -> bool:
|
|
600
|
+
"""
|
|
601
|
+
Check if cache is expired (backwards compatibility).
|
|
602
|
+
|
|
603
|
+
Returns:
|
|
604
|
+
True if cache is expired
|
|
605
|
+
"""
|
|
606
|
+
return not self._is_cache_valid()
|
|
607
|
+
|
|
608
|
+
def get_config(self) -> VersionConfig:
|
|
609
|
+
"""Get current configuration"""
|
|
610
|
+
return self.config
|
|
611
|
+
|
|
612
|
+
def update_config(self, config: VersionConfig) -> None:
|
|
613
|
+
"""
|
|
614
|
+
Update configuration.
|
|
615
|
+
|
|
616
|
+
Args:
|
|
617
|
+
config: New configuration object
|
|
618
|
+
"""
|
|
619
|
+
self.config = config
|
|
620
|
+
self._cache_ttl = timedelta(seconds=self.config.cache_ttl_seconds)
|
|
621
|
+
logger.debug("Version reader configuration updated")
|
|
622
|
+
|
|
623
|
+
def get_available_version_fields(self) -> list[str]:
|
|
624
|
+
"""
|
|
625
|
+
Get list of available version field paths.
|
|
626
|
+
|
|
627
|
+
Returns:
|
|
628
|
+
List of version field paths
|
|
629
|
+
"""
|
|
630
|
+
return self.VERSION_FIELDS.copy()
|
|
631
|
+
|
|
632
|
+
def set_custom_version_fields(self, fields: list[str]) -> None:
|
|
633
|
+
"""
|
|
634
|
+
Set custom version field paths.
|
|
635
|
+
|
|
636
|
+
Args:
|
|
637
|
+
fields: List of version field paths in order of priority
|
|
638
|
+
"""
|
|
639
|
+
self.VERSION_FIELDS = fields.copy()
|
|
640
|
+
self._version_fields = fields.copy() # Also update internal field list
|
|
641
|
+
logger.debug(f"Custom version fields set: {fields}")
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
class VersionReadError(Exception):
|
|
645
|
+
"""Exception raised when version cannot be read"""
|
|
646
|
+
|
|
647
|
+
pass
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# @CODE:DOC-TAG-004 | Component 1: Pre-commit hook for TAG validation
|
|
3
|
+
#
|
|
4
|
+
# This hook validates TAG annotations in staged files before commit.
|
|
5
|
+
# It checks:
|
|
6
|
+
# - TAG format (@DOC:DOMAIN-TYPE-NNN)
|
|
7
|
+
# - Duplicate TAG detection
|
|
8
|
+
# - Orphan TAG detection (warnings only)
|
|
9
|
+
#
|
|
10
|
+
# Exit codes:
|
|
11
|
+
# 0 - Validation passed
|
|
12
|
+
# 1 - Validation failed (duplicates or format errors)
|
|
13
|
+
|
|
14
|
+
set -e # Exit on error
|
|
15
|
+
|
|
16
|
+
# Colors for output
|
|
17
|
+
RED='\033[0;31m'
|
|
18
|
+
GREEN='\033[0;32m'
|
|
19
|
+
YELLOW='\033[1;33m'
|
|
20
|
+
NC='\033[0m' # No Color
|
|
21
|
+
|
|
22
|
+
# Get repository root
|
|
23
|
+
REPO_ROOT=$(git rev-parse --show-toplevel)
|
|
24
|
+
|
|
25
|
+
# Check if Python module is available
|
|
26
|
+
if ! python3 -c "import moai_adk.core.tags.pre_commit_validator" 2>/dev/null; then
|
|
27
|
+
echo -e "${YELLOW}Warning: moai_adk TAG validator not found.${NC}"
|
|
28
|
+
echo "Skipping TAG validation. Install moai_adk to enable validation."
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Get staged files
|
|
33
|
+
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
|
|
34
|
+
|
|
35
|
+
if [ -z "$STAGED_FILES" ]; then
|
|
36
|
+
echo -e "${GREEN}No staged files to validate.${NC}"
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
echo "🔍 Validating TAG annotations in staged files..."
|
|
41
|
+
|
|
42
|
+
# Run TAG validation
|
|
43
|
+
# Pass staged files as arguments to validator
|
|
44
|
+
python3 -m moai_adk.core.tags.pre_commit_validator \
|
|
45
|
+
--files $STAGED_FILES
|
|
46
|
+
|
|
47
|
+
VALIDATION_RESULT=$?
|
|
48
|
+
|
|
49
|
+
# Check result
|
|
50
|
+
if [ $VALIDATION_RESULT -eq 0 ]; then
|
|
51
|
+
echo -e "${GREEN}✓ TAG validation passed.${NC}"
|
|
52
|
+
exit 0
|
|
53
|
+
else
|
|
54
|
+
echo -e "${RED}✗ TAG validation failed.${NC}"
|
|
55
|
+
echo ""
|
|
56
|
+
echo "Commit blocked due to TAG validation errors."
|
|
57
|
+
echo ""
|
|
58
|
+
echo "To fix:"
|
|
59
|
+
echo " 1. Fix duplicate TAGs or format errors shown above"
|
|
60
|
+
echo " 2. Stage your changes with 'git add'"
|
|
61
|
+
echo " 3. Try committing again"
|
|
62
|
+
echo ""
|
|
63
|
+
echo "To skip this validation (not recommended):"
|
|
64
|
+
echo " git commit --no-verify"
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|