moai-adk 0.34.0__py3-none-any.whl → 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- moai_adk/__main__.py +136 -5
- moai_adk/astgrep/__init__.py +37 -0
- moai_adk/astgrep/analyzer.py +522 -0
- moai_adk/astgrep/models.py +124 -0
- moai_adk/astgrep/rules.py +179 -0
- moai_adk/cli/commands/analyze.py +11 -2
- moai_adk/cli/commands/doctor.py +7 -1
- moai_adk/cli/commands/init.py +321 -11
- moai_adk/cli/commands/language.py +7 -1
- moai_adk/cli/commands/rank.py +449 -0
- moai_adk/cli/commands/status.py +7 -1
- moai_adk/cli/commands/switch.py +325 -0
- moai_adk/cli/commands/update.py +296 -23
- moai_adk/cli/prompts/init_prompts.py +362 -66
- moai_adk/cli/prompts/translations/__init__.py +573 -0
- moai_adk/cli/ui/prompts.py +61 -2
- moai_adk/cli/worktree/cli.py +106 -1
- moai_adk/cli/worktree/manager.py +155 -0
- moai_adk/core/config/unified.py +244 -63
- moai_adk/core/credentials.py +264 -0
- moai_adk/core/error_recovery_system.py +22 -4
- moai_adk/core/git/conflict_detector.py +10 -1
- moai_adk/core/git/event_detector.py +16 -5
- moai_adk/core/integration/engine.py +2 -2
- moai_adk/core/integration/integration_tester.py +5 -5
- moai_adk/core/language_config_resolver.py +9 -3
- moai_adk/core/merge/analyzer.py +509 -324
- moai_adk/core/migration/alfred_to_moai_migrator.py +7 -1
- moai_adk/core/migration/backup_manager.py +54 -4
- moai_adk/core/migration/file_migrator.py +174 -2
- moai_adk/core/migration/interactive_checkbox_ui.py +42 -31
- moai_adk/core/migration/version_detector.py +123 -19
- moai_adk/core/migration/version_migrator.py +44 -9
- moai_adk/core/model_allocator.py +241 -0
- moai_adk/core/project/backup_utils.py +12 -2
- moai_adk/core/project/initializer.py +44 -87
- moai_adk/core/project/phase_executor.py +95 -33
- moai_adk/core/project/validator.py +16 -1
- moai_adk/core/quality/trust_checker.py +30 -10
- moai_adk/core/rollback_manager.py +60 -25
- moai_adk/core/template/backup.py +88 -6
- moai_adk/core/template/config.py +33 -9
- moai_adk/core/template/merger.py +34 -8
- moai_adk/core/template/processor.py +334 -11
- moai_adk/core/template_engine.py +10 -1
- moai_adk/core/template_variable_synchronizer.py +16 -2
- moai_adk/core/version_sync.py +54 -6
- moai_adk/foundation/__init__.py +1 -20
- moai_adk/foundation/testing.py +1 -1
- moai_adk/loop/__init__.py +54 -0
- moai_adk/loop/controller.py +305 -0
- moai_adk/loop/feedback.py +230 -0
- moai_adk/loop/state.py +209 -0
- moai_adk/loop/storage.py +220 -0
- moai_adk/lsp/__init__.py +70 -0
- moai_adk/lsp/client.py +320 -0
- moai_adk/lsp/models.py +261 -0
- moai_adk/lsp/protocol.py +404 -0
- moai_adk/lsp/server_manager.py +248 -0
- moai_adk/project/configuration.py +8 -1
- moai_adk/py.typed +0 -0
- moai_adk/ralph/__init__.py +37 -0
- moai_adk/ralph/engine.py +307 -0
- moai_adk/rank/__init__.py +21 -0
- moai_adk/rank/auth.py +425 -0
- moai_adk/rank/client.py +557 -0
- moai_adk/rank/config.py +147 -0
- moai_adk/rank/hook.py +1503 -0
- moai_adk/rank/py.typed +0 -0
- moai_adk/statusline/__init__.py +3 -0
- moai_adk/statusline/enhanced_output_style_detector.py +5 -5
- moai_adk/statusline/main.py +20 -1
- moai_adk/statusline/memory_collector.py +268 -0
- moai_adk/statusline/renderer.py +54 -38
- moai_adk/tag_system/__init__.py +48 -0
- moai_adk/tag_system/atomic_ops.py +117 -0
- moai_adk/tag_system/linkage.py +335 -0
- moai_adk/tag_system/parser.py +176 -0
- moai_adk/tag_system/validator.py +200 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +19 -3
- moai_adk/templates/.claude/agents/moai/builder-command.md +62 -16
- moai_adk/templates/.claude/agents/moai/builder-plugin.md +763 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +21 -5
- moai_adk/templates/.claude/agents/moai/expert-backend.md +103 -39
- moai_adk/templates/.claude/agents/moai/expert-debug.md +9 -3
- moai_adk/templates/.claude/agents/moai/expert-devops.md +16 -14
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +45 -31
- moai_adk/templates/.claude/agents/moai/expert-performance.md +13 -9
- moai_adk/templates/.claude/agents/moai/expert-refactoring.md +228 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +19 -3
- moai_adk/templates/.claude/agents/moai/expert-testing.md +13 -9
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +8 -2
- moai_adk/templates/.claude/agents/moai/manager-docs.md +10 -5
- moai_adk/templates/.claude/agents/moai/manager-git.md +99 -27
- moai_adk/templates/.claude/agents/moai/manager-project.md +87 -7
- moai_adk/templates/.claude/agents/moai/manager-quality.md +22 -5
- moai_adk/templates/.claude/agents/moai/manager-spec.md +8 -2
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +45 -14
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +16 -3
- moai_adk/templates/.claude/commands/moai/0-project.md +239 -1185
- moai_adk/templates/.claude/commands/moai/1-plan.md +383 -363
- moai_adk/templates/.claude/commands/moai/2-run.md +254 -347
- moai_adk/templates/.claude/commands/moai/3-sync.md +174 -100
- moai_adk/templates/.claude/commands/moai/9-feedback.md +49 -33
- moai_adk/templates/.claude/commands/moai/alfred.md +339 -0
- moai_adk/templates/.claude/commands/moai/cancel-loop.md +163 -0
- moai_adk/templates/.claude/commands/moai/fix.md +264 -0
- moai_adk/templates/.claude/commands/moai/loop.md +363 -0
- moai_adk/templates/.claude/hooks/moai/lib/README.md +143 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +37 -81
- moai_adk/templates/.claude/hooks/moai/lib/alfred_detector.py +105 -0
- moai_adk/templates/.claude/hooks/moai/lib/atomic_write.py +122 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +4 -1
- moai_adk/templates/.claude/hooks/moai/lib/common.py +35 -5
- moai_adk/templates/.claude/hooks/moai/lib/config.py +376 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +24 -28
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +14 -14
- moai_adk/templates/.claude/hooks/moai/lib/enhanced_output_style_detector.py +372 -0
- moai_adk/templates/.claude/hooks/moai/lib/exceptions.py +171 -0
- moai_adk/templates/.claude/hooks/moai/lib/file_utils.py +95 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_collector.py +190 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +15 -13
- moai_adk/templates/.claude/hooks/moai/lib/language_detector.py +298 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +125 -25
- moai_adk/templates/.claude/hooks/moai/lib/main.py +341 -0
- moai_adk/templates/.claude/hooks/moai/lib/memory_collector.py +268 -0
- moai_adk/templates/.claude/hooks/moai/lib/metrics_tracker.py +78 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +9 -7
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +204 -13
- moai_adk/templates/.claude/hooks/moai/lib/project.py +23 -14
- moai_adk/templates/.claude/hooks/moai/lib/renderer.py +359 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_linkage.py +333 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_parser.py +176 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_validator.py +200 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +5 -5
- moai_adk/templates/.claude/hooks/moai/lib/tool_registry.py +896 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +30 -18
- moai_adk/templates/.claude/hooks/moai/lib/update_checker.py +129 -0
- moai_adk/templates/.claude/hooks/moai/lib/version_reader.py +741 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__ast_grep_scan.py +276 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__code_formatter.py +255 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__coverage_guard.py +325 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__linter.py +315 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__lsp_diagnostic.py +508 -0
- moai_adk/templates/.claude/hooks/moai/pre_commit__tag_validator.py +287 -0
- moai_adk/templates/.claude/hooks/moai/pre_tool__security_guard.py +268 -0
- moai_adk/templates/.claude/hooks/moai/pre_tool__tdd_enforcer.py +208 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +93 -61
- moai_adk/templates/.claude/hooks/moai/session_end__rank_submit.py +69 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +165 -70
- moai_adk/templates/.claude/hooks/moai/shared/utils/announcement_translator.py +206 -0
- moai_adk/templates/.claude/hooks/moai/stop__loop_controller.py +621 -0
- moai_adk/templates/.claude/output-styles/moai/alfred.md +758 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +86 -3
- moai_adk/templates/.claude/output-styles/moai/yoda.md +2 -2
- moai_adk/templates/.claude/settings.json +154 -77
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +252 -198
- moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +169 -323
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +39 -27
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +115 -125
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +150 -150
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +182 -175
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +198 -138
- moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +226 -320
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +43 -222
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +75 -219
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +103 -463
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/component-architecture.md +723 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/nextjs16-patterns.md +713 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/performance-optimization.md +694 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/react19-patterns.md +591 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/state-management.md +680 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/vue35-patterns.md +802 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +118 -339
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +74 -377
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +299 -70
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +205 -182
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/advanced-agent-patterns.md +370 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-cli-reference-official.md +420 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +32 -22
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-devcontainers-official.md +381 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-discover-plugins-official.md +379 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-headless-official.md +378 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +110 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugin-marketplaces-official.md +308 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugins-official.md +640 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sandboxing-official.md +282 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +425 -71
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-statusline-official.md +293 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +325 -143
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +96 -316
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +116 -294
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-advanced.md +279 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-implementation.md +267 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +121 -650
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/patterns.md +22 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-ears-format.md +200 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +37 -730
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-tdd-implementation.md +275 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +77 -819
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-implementation.md +244 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-validation.md +219 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +14 -18
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +86 -270
- moai_adk/templates/.claude/skills/moai-framework-electron/SKILL.md +288 -0
- moai_adk/templates/.claude/skills/moai-framework-electron/examples.md +2082 -0
- moai_adk/templates/.claude/skills/moai-framework-electron/reference.md +1649 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +76 -582
- moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +1239 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/modules/advanced-patterns.md +401 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +1136 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +82 -436
- moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +585 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/aspnet-core.md +627 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/blazor-components.md +767 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/cqrs-validation.md +626 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/csharp12-features.md +580 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/efcore-patterns.md +622 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +403 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +65 -542
- moai_adk/templates/.claude/skills/moai-lang-elixir/examples.md +1171 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/modules/advanced-patterns.md +531 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/reference.md +889 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +32 -405
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +114 -293
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +83 -307
- moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +179 -0
- moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +973 -0
- moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +1543 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +42 -279
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +94 -556
- moai_adk/templates/.claude/skills/moai-lang-php/examples.md +1608 -0
- moai_adk/templates/.claude/skills/moai-lang-php/modules/advanced-patterns.md +538 -0
- moai_adk/templates/.claude/skills/moai-lang-php/reference.md +1323 -0
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +108 -358
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +84 -482
- moai_adk/templates/.claude/skills/moai-lang-r/examples.md +1154 -0
- moai_adk/templates/.claude/skills/moai-lang-r/modules/advanced-patterns.md +489 -0
- moai_adk/templates/.claude/skills/moai-lang-r/reference.md +1087 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +106 -610
- moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +1106 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/modules/advanced-patterns.md +309 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/modules/testing-patterns.md +306 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +1024 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +51 -265
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +106 -442
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/akka-actors.md +479 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/cats-effect.md +489 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/functional-programming.md +460 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/spark-data.md +498 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/zio-patterns.md +541 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +88 -457
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/combine-reactive.md +256 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/concurrency.md +270 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/swift6-features.md +265 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/swiftui-patterns.md +314 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +75 -283
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +97 -252
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +64 -240
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +331 -12
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +330 -37
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +90 -287
- moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +200 -206
- moai_adk/templates/.claude/skills/moai-platform-auth0/examples.md +2446 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/adaptive-mfa.md +233 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/akamai-integration.md +214 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/application-credentials.md +280 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-log-events.md +224 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-overview.md +140 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/bot-detection.md +144 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/breached-password-detection.md +187 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/brute-force-protection.md +189 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/certifications.md +282 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/compliance-overview.md +263 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/continuous-session-protection.md +307 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/customize-mfa.md +177 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/dpop-implementation.md +283 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/fapi-implementation.md +259 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/gdpr-compliance.md +313 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/guardian-configuration.md +269 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/highly-regulated-identity.md +272 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/jwt-fundamentals.md +248 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mdl-verification.md +210 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-api-management.md +278 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-factors.md +226 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-overview.md +174 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mtls-sender-constraining.md +316 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/ropg-flow-mfa.md +216 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-center.md +325 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-guidance.md +277 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/state-parameters.md +177 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/step-up-authentication.md +251 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/suspicious-ip-throttling.md +240 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/tenant-access-control.md +179 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/webauthn-fido.md +235 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/reference.md +224 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +75 -330
- moai_adk/templates/.claude/skills/moai-platform-clerk/examples.md +1426 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/modules/advanced-patterns.md +417 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/reference.md +273 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +100 -340
- moai_adk/templates/.claude/skills/moai-platform-convex/examples.md +506 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/auth-integration.md +421 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/file-storage.md +474 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/reactive-queries.md +302 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/server-functions.md +452 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/reference.md +385 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +113 -326
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/examples.md +514 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/custom-claims.md +374 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/phone-auth.md +372 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/social-auth.md +339 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/reference.md +382 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +71 -302
- moai_adk/templates/.claude/skills/moai-platform-firestore/examples.md +445 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/offline-cache.md +392 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/realtime-listeners.md +441 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/security-rules.md +352 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/transactions.md +452 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/reference.md +322 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +101 -412
- moai_adk/templates/.claude/skills/moai-platform-neon/examples.md +470 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/auto-scaling.md +349 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/branching-workflows.md +354 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/connection-pooling.md +412 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/pitr-backups.md +458 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/reference.md +272 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +96 -327
- moai_adk/templates/.claude/skills/moai-platform-railway/examples.md +539 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/docker-deployment.md +261 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/multi-service.md +291 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/networking-domains.md +338 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/volumes-storage.md +353 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/reference.md +374 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +103 -428
- moai_adk/templates/.claude/skills/moai-platform-supabase/examples.md +502 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/auth-integration.md +384 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/edge-functions.md +371 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/postgresql-pgvector.md +231 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/realtime-presence.md +354 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/row-level-security.md +286 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/storage-cdn.md +319 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/typescript-patterns.md +453 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/reference.md +284 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +96 -446
- moai_adk/templates/.claude/skills/moai-platform-vercel/examples.md +502 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/analytics-speed.md +348 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/deployment-config.md +344 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/edge-functions.md +222 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/isr-caching.md +306 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/kv-storage.md +399 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/reference.md +360 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/SKILL.md +193 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/examples.md +1099 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/language-specific.md +307 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/pattern-syntax.md +237 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/refactoring-patterns.md +260 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/security-rules.md +239 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/reference.md +288 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/go.yml +90 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/python.yml +101 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/typescript.yml +83 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/complexity-check.yml +94 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/deprecated-apis.yml +84 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/secrets-detection.yml +89 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/sql-injection.yml +45 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/xss-prevention.yml +50 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/sgconfig.yml +54 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +225 -423
- moai_adk/templates/.claude/skills/moai-workflow-loop/SKILL.md +197 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/examples.md +1063 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/reference.md +1414 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +211 -314
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +15 -43
- moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +119 -316
- moai_adk/templates/.claude/skills/moai-workflow-spec/modules/advanced-patterns.md +237 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +96 -203
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +201 -388
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +52 -3
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +263 -806
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/context7-integration.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/review-workflows.md +500 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/relevance-analysis.md +154 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/safety-analysis.md +148 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/scoring-algorithms.md +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/timeliness-analysis.md +168 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/truthfulness-analysis.md +136 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/usability-analysis.md +153 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework.md +257 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +191 -1344
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/analysis-patterns.md +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/core-classes.md +299 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/tool-integration.md +380 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/debugging-workflows.md +451 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/error-analysis.md +442 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/optimization-patterns.md +473 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/profiling-techniques.md +481 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/ai-optimization.md +241 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/bottleneck-detection.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/optimization-plan.md +315 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/profiler-core.md +277 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/real-time-monitoring.md +187 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +287 -1194
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/quality-metrics.md +415 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/ai-workflows.md +620 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/patterns.md +692 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/security-analysis.md +429 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +262 -1192
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/static-analysis.md +438 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd/core-classes.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/advanced-features.md +494 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/red-green-refactor.md +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-generation.md +471 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-patterns.md +371 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +227 -1222
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/trust5-validation.md +428 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/SKILL.md +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/integration-patterns.md +149 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/moai-adk-integration.md +245 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-advanced.md +310 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-development.md +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-workflows.md +302 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/registry-architecture.md +271 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/resource-optimization.md +300 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/tools-integration.md +280 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/troubleshooting.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-commands.md +296 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-management.md +217 -0
- moai_adk/templates/.git-hooks/pre-push +162 -59
- moai_adk/templates/.github/workflows/ci-universal.yml +934 -133
- moai_adk/templates/.gitignore +65 -107
- moai_adk/templates/.lsp.json +152 -0
- moai_adk/templates/.mcp.json +2 -20
- moai_adk/templates/.moai/announcements/en.json +18 -0
- moai_adk/templates/.moai/announcements/ja.json +18 -0
- moai_adk/templates/.moai/announcements/ko.json +18 -0
- moai_adk/templates/.moai/announcements/zh.json +18 -0
- moai_adk/templates/.moai/config/config.yaml +8 -2
- moai_adk/templates/.moai/config/multilingual-triggers.yaml +213 -0
- moai_adk/templates/.moai/config/sections/language.yaml +2 -2
- moai_adk/templates/.moai/config/sections/llm.yaml +41 -0
- moai_adk/templates/.moai/config/sections/pricing.yaml +30 -0
- moai_adk/templates/.moai/config/sections/project.yaml +2 -2
- moai_adk/templates/.moai/config/sections/quality.yaml +43 -5
- moai_adk/templates/.moai/config/sections/ralph.yaml +55 -0
- moai_adk/templates/.moai/config/sections/system.yaml +46 -1
- moai_adk/templates/.moai/config/sections/user.yaml +1 -1
- moai_adk/templates/.moai/config/statusline-config.yaml +2 -2
- moai_adk/templates/.moai/llm-configs/glm.json +22 -0
- moai_adk/templates/CLAUDE.ja.md +343 -0
- moai_adk/templates/CLAUDE.ko.md +343 -0
- moai_adk/templates/CLAUDE.md +200 -499
- moai_adk/templates/CLAUDE.zh.md +343 -0
- moai_adk/utils/common.py +37 -0
- moai_adk/version.py +1 -1
- moai_adk-1.1.0.dist-info/METADATA +2443 -0
- moai_adk-1.1.0.dist-info/RECORD +701 -0
- {moai_adk-0.34.0.dist-info → moai_adk-1.1.0.dist-info}/entry_points.txt +2 -0
- moai_adk-1.1.0.dist-info/licenses/LICENSE +99 -0
- moai_adk/core/config/auto_spec_config.py +0 -340
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +0 -901
- moai_adk/core/spec/confidence_scoring.py +0 -680
- moai_adk/core/spec/ears_template_engine.py +0 -1247
- moai_adk/core/spec/quality_validator.py +0 -687
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +0 -670
- moai_adk/templates/.claude/agents/moai/expert-database.md +0 -777
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +0 -1041
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +0 -458
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +0 -1607
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +0 -789
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +0 -469
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +0 -1032
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +0 -438
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +0 -431
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/design-system-tokens.md +0 -405
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +0 -336
- moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +0 -402
- moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +0 -607
- moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +0 -300
- moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +0 -537
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +0 -520
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +0 -574
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +0 -317
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +0 -663
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +0 -190
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +0 -175
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +0 -196
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +0 -17
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +0 -158
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +0 -340
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +0 -713
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +0 -538
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +0 -1336
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +0 -730
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +0 -608
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +0 -1005
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +0 -436
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +0 -411
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +0 -982
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +0 -778
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +0 -646
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +0 -782
- moai_adk/templates/.moai/config/questions/_schema.yaml +0 -151
- moai_adk/templates/.moai/config/questions/tab0-init.yaml +0 -251
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +0 -108
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +0 -81
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +0 -634
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +0 -170
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +0 -87
- moai_adk/templates/.moai/scripts/setup-glm.py +0 -136
- moai_adk-0.34.0.dist-info/METADATA +0 -2999
- moai_adk-0.34.0.dist-info/RECORD +0 -463
- moai_adk-0.34.0.dist-info/licenses/LICENSE +0 -21
- /moai_adk/foundation/{git.py → git/__init__.py} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-mermaid/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-mermaid/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-nextra/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-jit-docs/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-jit-docs/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-testing/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-testing/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/{moai-worktree → moai-workflow-worktree}/examples.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-worktree → moai-workflow-worktree}/reference.md +0 -0
- {moai_adk-0.34.0.dist-info → moai_adk-1.1.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""Atomic file operations for TAG System.
|
|
2
|
+
|
|
3
|
+
Provides safe file write operations with atomic semantics
|
|
4
|
+
to prevent race conditions and data corruption.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
import tempfile
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def atomic_write_text(
|
|
17
|
+
file_path: Path | str,
|
|
18
|
+
content: str,
|
|
19
|
+
encoding: str = "utf-8",
|
|
20
|
+
make_dirs: bool = True,
|
|
21
|
+
) -> bool:
|
|
22
|
+
"""Atomically write text content to a file.
|
|
23
|
+
|
|
24
|
+
Uses write-to-temp-then-rename pattern to prevent race conditions
|
|
25
|
+
and partial writes from corrupting data.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
file_path: Path to the file
|
|
29
|
+
content: Content to write
|
|
30
|
+
encoding: File encoding (default: utf-8)
|
|
31
|
+
make_dirs: Create parent directories if needed (default: True)
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
True if write succeeded, False otherwise
|
|
35
|
+
"""
|
|
36
|
+
path = Path(file_path)
|
|
37
|
+
|
|
38
|
+
if make_dirs:
|
|
39
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
# Write to temporary file first
|
|
43
|
+
fd, temp_path = tempfile.mkstemp(dir=path.parent, prefix=".tmp_", suffix=path.suffix or ".tmp")
|
|
44
|
+
try:
|
|
45
|
+
# Write content to temp file
|
|
46
|
+
with os.fdopen(fd, "w", encoding=encoding) as f:
|
|
47
|
+
f.write(content)
|
|
48
|
+
|
|
49
|
+
# Atomic rename (overwrites target if exists)
|
|
50
|
+
os.replace(temp_path, path)
|
|
51
|
+
return True
|
|
52
|
+
except Exception:
|
|
53
|
+
# Clean up temp file on error
|
|
54
|
+
try:
|
|
55
|
+
os.unlink(temp_path)
|
|
56
|
+
except OSError:
|
|
57
|
+
pass
|
|
58
|
+
return False
|
|
59
|
+
except (OSError, ValueError):
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def atomic_write_json(
|
|
64
|
+
file_path: Path | str,
|
|
65
|
+
data: Any,
|
|
66
|
+
indent: int = 2,
|
|
67
|
+
encoding: str = "utf-8",
|
|
68
|
+
ensure_ascii: bool = True,
|
|
69
|
+
make_dirs: bool = True,
|
|
70
|
+
) -> bool:
|
|
71
|
+
"""Atomically write JSON data to a file.
|
|
72
|
+
|
|
73
|
+
Uses write-to-temp-then-rename pattern to prevent race conditions
|
|
74
|
+
and partial writes from corrupting data.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
file_path: Path to the file
|
|
78
|
+
data: Data to serialize as JSON
|
|
79
|
+
indent: JSON indentation (default: 2)
|
|
80
|
+
encoding: File encoding (default: utf-8)
|
|
81
|
+
ensure_ascii: Escape non-ASCII characters (default: True)
|
|
82
|
+
make_dirs: Create parent directories if needed (default: True)
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
True if write succeeded, False otherwise
|
|
86
|
+
"""
|
|
87
|
+
path = Path(file_path)
|
|
88
|
+
|
|
89
|
+
if make_dirs:
|
|
90
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
# Write to temporary file first
|
|
94
|
+
fd, temp_path = tempfile.mkstemp(dir=path.parent, prefix=".tmp_", suffix=".json")
|
|
95
|
+
try:
|
|
96
|
+
# Write JSON to temp file
|
|
97
|
+
with os.fdopen(fd, "w", encoding=encoding) as f:
|
|
98
|
+
json.dump(data, f, indent=indent, ensure_ascii=ensure_ascii)
|
|
99
|
+
|
|
100
|
+
# Atomic rename (overwrites target if exists)
|
|
101
|
+
os.replace(temp_path, path)
|
|
102
|
+
return True
|
|
103
|
+
except Exception:
|
|
104
|
+
# Clean up temp file on error
|
|
105
|
+
try:
|
|
106
|
+
os.unlink(temp_path)
|
|
107
|
+
except OSError:
|
|
108
|
+
pass
|
|
109
|
+
return False
|
|
110
|
+
except (OSError, ValueError, TypeError):
|
|
111
|
+
return False
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
__all__ = [
|
|
115
|
+
"atomic_write_text",
|
|
116
|
+
"atomic_write_json",
|
|
117
|
+
]
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"""TAG linkage manager module for TAG System v2.0.
|
|
2
|
+
|
|
3
|
+
Implements T4: Linkage Manager for bidirectional TAG↔CODE mapping
|
|
4
|
+
with atomic database operations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import logging
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from . import atomic_ops, validator
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Re-export atomic_write functions for tests
|
|
20
|
+
atomic_write_text = atomic_ops.atomic_write_text
|
|
21
|
+
atomic_write_json = atomic_ops.atomic_write_json
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def spec_document_exists(spec_id: str) -> bool:
|
|
25
|
+
"""Check if SPEC document exists in .moai/specs/.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
spec_id: SPEC identifier to check
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
True if SPEC document exists, False otherwise
|
|
32
|
+
"""
|
|
33
|
+
# Get specs directory from current working directory
|
|
34
|
+
specs_dir = Path.cwd() / ".moai" / "specs"
|
|
35
|
+
|
|
36
|
+
if not specs_dir.exists():
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
# Check for SPEC directory
|
|
40
|
+
spec_dir = specs_dir / spec_id
|
|
41
|
+
return spec_dir.exists() and spec_dir.is_dir()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class LinkageManager:
|
|
45
|
+
"""Manage bidirectional TAG↔CODE mapping database.
|
|
46
|
+
|
|
47
|
+
Provides atomic database operations for TAG tracking,
|
|
48
|
+
with support for TAG→Files and File→TAGs lookups.
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
db_path: Path to linkage database file
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(self, db_path: Path) -> None:
|
|
55
|
+
"""Initialize linkage manager.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
db_path: Path to linkage database JSON file
|
|
59
|
+
"""
|
|
60
|
+
self.db_path = Path(db_path)
|
|
61
|
+
self._ensure_database()
|
|
62
|
+
|
|
63
|
+
def _ensure_database(self) -> None:
|
|
64
|
+
"""Ensure database file exists with proper structure."""
|
|
65
|
+
if not self.db_path.exists():
|
|
66
|
+
# Create new database with empty structure
|
|
67
|
+
self._write_database({"tags": [], "files": {}})
|
|
68
|
+
|
|
69
|
+
def _load_database(self) -> dict[str, Any]:
|
|
70
|
+
"""Load database from disk.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Database dictionary with 'tags' and 'files' keys
|
|
74
|
+
"""
|
|
75
|
+
try:
|
|
76
|
+
if not self.db_path.exists():
|
|
77
|
+
return {"tags": [], "files": {}}
|
|
78
|
+
|
|
79
|
+
with open(self.db_path, "r", encoding="utf-8") as f:
|
|
80
|
+
data = json.load(f)
|
|
81
|
+
|
|
82
|
+
# Validate structure
|
|
83
|
+
if not isinstance(data, dict):
|
|
84
|
+
logger.warning(f"Invalid database structure in {self.db_path}")
|
|
85
|
+
return {"tags": [], "files": {}}
|
|
86
|
+
|
|
87
|
+
if "tags" not in data:
|
|
88
|
+
data["tags"] = []
|
|
89
|
+
if "files" not in data:
|
|
90
|
+
data["files"] = {}
|
|
91
|
+
|
|
92
|
+
return data
|
|
93
|
+
|
|
94
|
+
except (json.JSONDecodeError, OSError) as e:
|
|
95
|
+
logger.error(f"Error loading database {self.db_path}: {e}")
|
|
96
|
+
return {"tags": [], "files": {}}
|
|
97
|
+
|
|
98
|
+
def _write_database(self, data: dict[str, Any]) -> bool:
|
|
99
|
+
"""Write database to disk atomically.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
data: Database dictionary to write
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
True if write succeeded, False otherwise
|
|
106
|
+
"""
|
|
107
|
+
return atomic_write_json(self.db_path, data)
|
|
108
|
+
|
|
109
|
+
def add_tag(self, tag: validator.TAG) -> bool:
|
|
110
|
+
"""Add TAG to linkage database.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
tag: TAG object to add
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
True if TAG added successfully, False otherwise
|
|
117
|
+
|
|
118
|
+
Examples:
|
|
119
|
+
>>> tag = TAG("SPEC-AUTH-001", Path("auth.py"), 10)
|
|
120
|
+
>>> manager.add_tag(tag)
|
|
121
|
+
True
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
data = self._load_database()
|
|
125
|
+
|
|
126
|
+
# Create TAG entry
|
|
127
|
+
tag_entry = {
|
|
128
|
+
"spec_id": tag.spec_id,
|
|
129
|
+
"verb": tag.verb,
|
|
130
|
+
"file_path": str(tag.file_path),
|
|
131
|
+
"line": tag.line,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Check for duplicate
|
|
135
|
+
if tag_entry not in data["tags"]:
|
|
136
|
+
data["tags"].append(tag_entry)
|
|
137
|
+
|
|
138
|
+
# Update file index
|
|
139
|
+
file_key = str(tag.file_path)
|
|
140
|
+
if file_key not in data["files"]:
|
|
141
|
+
data["files"][file_key] = []
|
|
142
|
+
|
|
143
|
+
if tag.spec_id not in data["files"][file_key]:
|
|
144
|
+
data["files"][file_key].append(tag.spec_id)
|
|
145
|
+
|
|
146
|
+
# Write database atomically
|
|
147
|
+
return self._write_database(data)
|
|
148
|
+
|
|
149
|
+
except Exception as e:
|
|
150
|
+
logger.error(f"Error adding TAG to database: {e}")
|
|
151
|
+
return False
|
|
152
|
+
|
|
153
|
+
def remove_tag(self, tag: validator.TAG) -> bool:
|
|
154
|
+
"""Remove specific TAG from database.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
tag: TAG object to remove
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
True if TAG removed successfully, False otherwise
|
|
161
|
+
"""
|
|
162
|
+
try:
|
|
163
|
+
data = self._load_database()
|
|
164
|
+
|
|
165
|
+
tag_entry = {
|
|
166
|
+
"spec_id": tag.spec_id,
|
|
167
|
+
"verb": tag.verb,
|
|
168
|
+
"file_path": str(tag.file_path),
|
|
169
|
+
"line": tag.line,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
# Remove from tags list
|
|
173
|
+
if tag_entry in data["tags"]:
|
|
174
|
+
data["tags"].remove(tag_entry)
|
|
175
|
+
|
|
176
|
+
# Update file index
|
|
177
|
+
file_key = str(tag.file_path)
|
|
178
|
+
if file_key in data["files"] and tag.spec_id in data["files"][file_key]:
|
|
179
|
+
data["files"][file_key].remove(tag.spec_id)
|
|
180
|
+
|
|
181
|
+
# Clean up empty file entries
|
|
182
|
+
if not data["files"][file_key]:
|
|
183
|
+
del data["files"][file_key]
|
|
184
|
+
|
|
185
|
+
return self._write_database(data)
|
|
186
|
+
|
|
187
|
+
except Exception as e:
|
|
188
|
+
logger.error(f"Error removing TAG from database: {e}")
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
def remove_file_tags(self, file_path: Path) -> bool:
|
|
192
|
+
"""Remove all TAGs for a file.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
file_path: Path to file whose TAGs should be removed
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
True if TAGs removed successfully, False otherwise
|
|
199
|
+
|
|
200
|
+
Examples:
|
|
201
|
+
>>> manager.remove_file_tags(Path("deleted.py"))
|
|
202
|
+
True
|
|
203
|
+
"""
|
|
204
|
+
try:
|
|
205
|
+
data = self._load_database()
|
|
206
|
+
|
|
207
|
+
file_key = str(file_path)
|
|
208
|
+
|
|
209
|
+
# Remove all TAGs for this file
|
|
210
|
+
data["tags"] = [tag for tag in data["tags"] if tag["file_path"] != file_key]
|
|
211
|
+
|
|
212
|
+
# Remove file index
|
|
213
|
+
if file_key in data["files"]:
|
|
214
|
+
del data["files"][file_key]
|
|
215
|
+
|
|
216
|
+
return self._write_database(data)
|
|
217
|
+
|
|
218
|
+
except Exception as e:
|
|
219
|
+
logger.error(f"Error removing file TAGs: {e}")
|
|
220
|
+
return False
|
|
221
|
+
|
|
222
|
+
def get_all_tags(self) -> list[dict[str, Any]]:
|
|
223
|
+
"""Get all TAGs in database.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
List of TAG dictionaries
|
|
227
|
+
"""
|
|
228
|
+
data = self._load_database()
|
|
229
|
+
return data.get("tags", [])
|
|
230
|
+
|
|
231
|
+
def get_code_locations(self, spec_id: str) -> list[dict[str, Any]]:
|
|
232
|
+
"""Get all code locations for a SPEC-ID.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
spec_id: SPEC identifier to query
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
List of location dictionaries with file_path, line, and verb
|
|
239
|
+
|
|
240
|
+
Examples:
|
|
241
|
+
>>> locations = manager.get_code_locations("SPEC-AUTH-001")
|
|
242
|
+
>>> len(locations)
|
|
243
|
+
3
|
|
244
|
+
"""
|
|
245
|
+
data = self._load_database()
|
|
246
|
+
tags = data.get("tags", [])
|
|
247
|
+
|
|
248
|
+
# Filter TAGs by spec_id
|
|
249
|
+
locations = [
|
|
250
|
+
{
|
|
251
|
+
"file_path": tag["file_path"],
|
|
252
|
+
"line": tag["line"],
|
|
253
|
+
"verb": tag["verb"],
|
|
254
|
+
}
|
|
255
|
+
for tag in tags
|
|
256
|
+
if tag["spec_id"] == spec_id
|
|
257
|
+
]
|
|
258
|
+
|
|
259
|
+
return locations
|
|
260
|
+
|
|
261
|
+
def get_tags_by_file(self, file_path: Path) -> list[dict[str, Any]]:
|
|
262
|
+
"""Get all TAGs for a specific file.
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
file_path: Path to file
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
List of TAG dictionaries for the file
|
|
269
|
+
|
|
270
|
+
Examples:
|
|
271
|
+
>>> tags = manager.get_tags_by_file(Path("auth.py"))
|
|
272
|
+
>>> len(tags)
|
|
273
|
+
2
|
|
274
|
+
"""
|
|
275
|
+
data = self._load_database()
|
|
276
|
+
tags = data.get("tags", [])
|
|
277
|
+
file_key = str(file_path)
|
|
278
|
+
|
|
279
|
+
# Filter TAGs by file_path
|
|
280
|
+
return [
|
|
281
|
+
{
|
|
282
|
+
"spec_id": tag["spec_id"],
|
|
283
|
+
"verb": tag["verb"],
|
|
284
|
+
"file_path": tag["file_path"],
|
|
285
|
+
"line": tag["line"],
|
|
286
|
+
}
|
|
287
|
+
for tag in tags
|
|
288
|
+
if tag["file_path"] == file_key
|
|
289
|
+
]
|
|
290
|
+
|
|
291
|
+
def get_all_spec_ids(self) -> list[str]:
|
|
292
|
+
"""Get all unique SPEC-IDs in database.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
Sorted list of unique SPEC-ID strings
|
|
296
|
+
"""
|
|
297
|
+
data = self._load_database()
|
|
298
|
+
tags = data.get("tags", [])
|
|
299
|
+
|
|
300
|
+
spec_ids = {tag["spec_id"] for tag in tags}
|
|
301
|
+
return sorted(spec_ids)
|
|
302
|
+
|
|
303
|
+
def find_orphaned_tags(self) -> list[dict[str, Any]]:
|
|
304
|
+
"""Find TAGs referencing nonexistent SPEC documents.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
List of orphaned TAG dictionaries
|
|
308
|
+
|
|
309
|
+
Examples:
|
|
310
|
+
>>> orphans = manager.find_orphaned_tags()
|
|
311
|
+
>>> len(orphans)
|
|
312
|
+
1
|
|
313
|
+
"""
|
|
314
|
+
data = self._load_database()
|
|
315
|
+
tags = data.get("tags", [])
|
|
316
|
+
|
|
317
|
+
orphans = [tag for tag in tags if not spec_document_exists(tag["spec_id"])]
|
|
318
|
+
|
|
319
|
+
return orphans
|
|
320
|
+
|
|
321
|
+
def clear(self) -> bool:
|
|
322
|
+
"""Clear all TAGs from database.
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
True if database cleared successfully, False otherwise
|
|
326
|
+
"""
|
|
327
|
+
return self._write_database({"tags": [], "files": {}})
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
__all__ = [
|
|
331
|
+
"spec_document_exists",
|
|
332
|
+
"LinkageManager",
|
|
333
|
+
"atomic_write_json",
|
|
334
|
+
"atomic_write_text",
|
|
335
|
+
]
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""TAG parser module for TAG System v2.0.
|
|
2
|
+
|
|
3
|
+
Implements T2: TAG Parser for extracting TAG annotations from
|
|
4
|
+
Python source code comments using AST parsing.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import ast
|
|
10
|
+
import logging
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import List
|
|
13
|
+
|
|
14
|
+
from . import validator
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def extract_tags_from_source(source: str, file_path: Path) -> List[validator.TAG]:
|
|
20
|
+
"""Extract all @SPEC TAGs from Python source code.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
source: Python source code as string
|
|
24
|
+
file_path: Path to the source file
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
List of TAG objects found in the source
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
>>> source = "# @SPEC SPEC-AUTH-001\\ndef func(): pass"
|
|
31
|
+
>>> tags = extract_tags_from_source(source, Path("test.py"))
|
|
32
|
+
>>> len(tags)
|
|
33
|
+
1
|
|
34
|
+
"""
|
|
35
|
+
tags: List[validator.TAG] = []
|
|
36
|
+
|
|
37
|
+
if not isinstance(source, str):
|
|
38
|
+
return tags
|
|
39
|
+
|
|
40
|
+
# Split source into lines and extract TAGs from comments
|
|
41
|
+
lines = source.splitlines()
|
|
42
|
+
|
|
43
|
+
for line_number, line in enumerate(lines, start=1):
|
|
44
|
+
# Handle both standalone comments and inline comments
|
|
45
|
+
# Find the comment portion if it exists
|
|
46
|
+
comment_start = line.find("#")
|
|
47
|
+
|
|
48
|
+
if comment_start == -1:
|
|
49
|
+
# No comment in this line
|
|
50
|
+
continue
|
|
51
|
+
|
|
52
|
+
# Extract the comment portion (from # to end of line)
|
|
53
|
+
comment_portion = line[comment_start:]
|
|
54
|
+
|
|
55
|
+
# Parse TAG from comment
|
|
56
|
+
tag = validator.parse_tag_string(comment_portion, file_path, line_number)
|
|
57
|
+
|
|
58
|
+
if tag is not None:
|
|
59
|
+
tags.append(tag)
|
|
60
|
+
|
|
61
|
+
return tags
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def extract_tags_from_file(file_path: Path) -> List[validator.TAG]:
|
|
65
|
+
"""Extract all @SPEC TAGs from a Python file.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
file_path: Path to the Python file
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
List of TAG objects found in the file, empty list if file doesn't exist or has errors
|
|
72
|
+
|
|
73
|
+
Examples:
|
|
74
|
+
>>> tags = extract_tags_from_file(Path("auth.py"))
|
|
75
|
+
>>> len(tags)
|
|
76
|
+
2
|
|
77
|
+
"""
|
|
78
|
+
if not isinstance(file_path, Path):
|
|
79
|
+
file_path = Path(file_path)
|
|
80
|
+
|
|
81
|
+
# Check if file exists
|
|
82
|
+
if not file_path.exists():
|
|
83
|
+
logger.warning(f"File not found: {file_path}")
|
|
84
|
+
return []
|
|
85
|
+
|
|
86
|
+
# Check if file is readable
|
|
87
|
+
if not file_path.is_file():
|
|
88
|
+
logger.warning(f"Not a file: {file_path}")
|
|
89
|
+
return []
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
# Read file content
|
|
93
|
+
source = file_path.read_text(encoding="utf-8")
|
|
94
|
+
|
|
95
|
+
# Validate Python syntax
|
|
96
|
+
try:
|
|
97
|
+
ast.parse(source)
|
|
98
|
+
except SyntaxError as e:
|
|
99
|
+
logger.warning(f"Syntax error in {file_path}: {e}")
|
|
100
|
+
return []
|
|
101
|
+
|
|
102
|
+
# Extract TAGs
|
|
103
|
+
return extract_tags_from_source(source, file_path)
|
|
104
|
+
|
|
105
|
+
except Exception as e:
|
|
106
|
+
logger.error(f"Error reading file {file_path}: {e}")
|
|
107
|
+
return []
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def extract_tags_from_files(file_paths: List[Path]) -> List[validator.TAG]:
|
|
111
|
+
"""Extract TAGs from multiple files.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
file_paths: List of file paths to process
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
List of all TAGs found across all files
|
|
118
|
+
|
|
119
|
+
Examples:
|
|
120
|
+
>>> files = [Path("a.py"), Path("b.py")]
|
|
121
|
+
>>> tags = extract_tags_from_files(files)
|
|
122
|
+
>>> len(tags)
|
|
123
|
+
5
|
|
124
|
+
"""
|
|
125
|
+
all_tags: List[validator.TAG] = []
|
|
126
|
+
|
|
127
|
+
for file_path in file_paths:
|
|
128
|
+
tags = extract_tags_from_file(file_path)
|
|
129
|
+
all_tags.extend(tags)
|
|
130
|
+
|
|
131
|
+
return all_tags
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def extract_tags_from_directory(
|
|
135
|
+
directory: Path,
|
|
136
|
+
pattern: str = "*.py",
|
|
137
|
+
recursive: bool = True,
|
|
138
|
+
) -> List[validator.TAG]:
|
|
139
|
+
"""Extract TAGs from all Python files in a directory.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
directory: Directory path to search
|
|
143
|
+
pattern: File pattern to match (default: "*.py")
|
|
144
|
+
recursive: Whether to search recursively (default: True)
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
List of all TAGs found in matching files
|
|
148
|
+
|
|
149
|
+
Examples:
|
|
150
|
+
>>> tags = extract_tags_from_directory(Path("src/"))
|
|
151
|
+
>>> len(tags)
|
|
152
|
+
42
|
|
153
|
+
"""
|
|
154
|
+
if not isinstance(directory, Path):
|
|
155
|
+
directory = Path(directory)
|
|
156
|
+
|
|
157
|
+
if not directory.exists() or not directory.is_dir():
|
|
158
|
+
logger.warning(f"Not a directory: {directory}")
|
|
159
|
+
return []
|
|
160
|
+
|
|
161
|
+
# Find matching files
|
|
162
|
+
if recursive:
|
|
163
|
+
files = list(directory.rglob(pattern))
|
|
164
|
+
else:
|
|
165
|
+
files = list(directory.glob(pattern))
|
|
166
|
+
|
|
167
|
+
# Extract TAGs from all files
|
|
168
|
+
return extract_tags_from_files(files)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
__all__ = [
|
|
172
|
+
"extract_tags_from_source",
|
|
173
|
+
"extract_tags_from_file",
|
|
174
|
+
"extract_tags_from_files",
|
|
175
|
+
"extract_tags_from_directory",
|
|
176
|
+
]
|