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
moai_adk/core/config/unified.py
CHANGED
|
@@ -13,13 +13,20 @@ Features:
|
|
|
13
13
|
- Deep merge for nested configs
|
|
14
14
|
- Configuration migration between versions
|
|
15
15
|
- Domain-specific facades for different subsystems
|
|
16
|
+
- Modular section-based YAML configuration (new in v0.36.0)
|
|
16
17
|
|
|
17
18
|
Design Philosophy:
|
|
18
|
-
-
|
|
19
|
+
- Primary: Modular section files `.moai/config/sections/*.yaml`
|
|
20
|
+
- Fallback: Legacy monolithic `.moai/config/config.yaml` or `config.json`
|
|
19
21
|
- Best patterns from StatuslineConfig, UnifiedConfigManager, ConfigurationManager
|
|
20
22
|
- Backward compatible with existing ConfigManager interfaces
|
|
21
23
|
- Performance optimized with caching and minimal I/O
|
|
22
24
|
|
|
25
|
+
Configuration Architecture:
|
|
26
|
+
- New projects: Modular sections (language.yaml, user.yaml, project.yaml, etc.)
|
|
27
|
+
- Legacy projects: Monolithic config.json/config.yaml (auto-migrated on update)
|
|
28
|
+
- Priority: Section files override monolithic config if both exist
|
|
29
|
+
|
|
23
30
|
Usage:
|
|
24
31
|
>>> from moai_adk.core.config.unified import get_unified_config
|
|
25
32
|
>>> config = get_unified_config()
|
|
@@ -95,62 +102,59 @@ class UnifiedConfigManager:
|
|
|
95
102
|
Initialize configuration manager (called once by singleton).
|
|
96
103
|
|
|
97
104
|
Args:
|
|
98
|
-
config_path: Optional path to config file
|
|
105
|
+
config_path: Optional path to config file (legacy mode) or sections directory
|
|
99
106
|
"""
|
|
100
107
|
# Set config path with auto-detection
|
|
101
108
|
if config_path:
|
|
102
109
|
self._config_path = Path(config_path)
|
|
103
110
|
else:
|
|
104
|
-
# Auto-detect
|
|
111
|
+
# Auto-detect configuration strategy
|
|
105
112
|
base_path = Path.cwd() / ".moai" / "config"
|
|
106
|
-
|
|
107
|
-
json_path = base_path / "config.json"
|
|
113
|
+
sections_dir = base_path / "sections"
|
|
108
114
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
self._config_path = json_path
|
|
115
|
+
# Priority 1: Section-based configuration (new approach)
|
|
116
|
+
if sections_dir.exists() and sections_dir.is_dir():
|
|
117
|
+
self._config_path = sections_dir
|
|
113
118
|
else:
|
|
114
|
-
#
|
|
115
|
-
|
|
119
|
+
# Priority 2: Monolithic YAML (legacy)
|
|
120
|
+
yaml_path = base_path / "config.yaml"
|
|
121
|
+
json_path = base_path / "config.json"
|
|
122
|
+
|
|
123
|
+
if YAML_AVAILABLE and yaml_path.exists():
|
|
124
|
+
self._config_path = yaml_path
|
|
125
|
+
elif json_path.exists():
|
|
126
|
+
self._config_path = json_path
|
|
127
|
+
else:
|
|
128
|
+
# Default to sections for new projects
|
|
129
|
+
self._config_path = sections_dir if YAML_AVAILABLE else yaml_path
|
|
116
130
|
|
|
117
131
|
# Load configuration
|
|
118
132
|
self._load_config()
|
|
119
133
|
|
|
120
134
|
def _load_config(self) -> None:
|
|
121
135
|
"""
|
|
122
|
-
Load configuration from file with caching.
|
|
136
|
+
Load configuration from file or sections with caching.
|
|
123
137
|
|
|
124
138
|
Implements cache invalidation based on file modification time.
|
|
125
139
|
Falls back to default configuration if file doesn't exist.
|
|
126
|
-
Supports
|
|
140
|
+
Supports three modes:
|
|
141
|
+
1. Section-based YAML (new): Load from .moai/config/sections/*.yaml
|
|
142
|
+
2. Monolithic YAML (legacy): Load from .moai/config/config.yaml
|
|
143
|
+
3. Monolithic JSON (legacy): Load from .moai/config/config.json
|
|
127
144
|
"""
|
|
128
145
|
try:
|
|
129
|
-
# Check if
|
|
146
|
+
# Check if path exists
|
|
130
147
|
if not self._config_path.exists():
|
|
131
|
-
logger.warning(f"Config
|
|
148
|
+
logger.warning(f"Config path not found: {self._config_path}")
|
|
132
149
|
self._config = self._get_default_config()
|
|
133
150
|
return
|
|
134
151
|
|
|
135
|
-
#
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
# Load from file (auto-detect format)
|
|
142
|
-
with open(self._config_path, "r", encoding="utf-8") as f:
|
|
143
|
-
if self._config_path.suffix == ".yaml" or self._config_path.suffix == ".yml":
|
|
144
|
-
if not YAML_AVAILABLE:
|
|
145
|
-
raise ImportError("PyYAML is required for YAML config files. Install with: pip install pyyaml")
|
|
146
|
-
self._config = yaml.safe_load(f) or {}
|
|
147
|
-
else:
|
|
148
|
-
self._config = json.load(f)
|
|
149
|
-
|
|
150
|
-
# Update cache timestamp
|
|
151
|
-
self._last_modified = current_mtime
|
|
152
|
-
|
|
153
|
-
logger.debug(f"Loaded config from {self._config_path}")
|
|
152
|
+
# Section-based configuration (new approach)
|
|
153
|
+
if self._config_path.is_dir():
|
|
154
|
+
self._load_from_sections()
|
|
155
|
+
else:
|
|
156
|
+
# Monolithic configuration (legacy)
|
|
157
|
+
self._load_from_monolithic()
|
|
154
158
|
|
|
155
159
|
except (
|
|
156
160
|
json.JSONDecodeError,
|
|
@@ -161,6 +165,69 @@ class UnifiedConfigManager:
|
|
|
161
165
|
logger.error(f"Failed to load config: {e}")
|
|
162
166
|
self._config = self._get_default_config()
|
|
163
167
|
|
|
168
|
+
def _load_from_sections(self) -> None:
|
|
169
|
+
"""
|
|
170
|
+
Load configuration from modular section YAML files.
|
|
171
|
+
|
|
172
|
+
Loads and merges all *.yaml files from sections directory:
|
|
173
|
+
- sections/language.yaml
|
|
174
|
+
- sections/user.yaml
|
|
175
|
+
- sections/project.yaml
|
|
176
|
+
- sections/system.yaml
|
|
177
|
+
- sections/git-strategy.yaml
|
|
178
|
+
- sections/quality.yaml
|
|
179
|
+
"""
|
|
180
|
+
# Check cache validity (use directory mtime)
|
|
181
|
+
current_mtime = self._config_path.stat().st_mtime
|
|
182
|
+
if self._last_modified and current_mtime == self._last_modified:
|
|
183
|
+
# Cache is still valid
|
|
184
|
+
return
|
|
185
|
+
|
|
186
|
+
if not YAML_AVAILABLE:
|
|
187
|
+
raise ImportError("PyYAML is required for section-based config. Install with: pip install pyyaml")
|
|
188
|
+
|
|
189
|
+
# Merge all section files
|
|
190
|
+
merged_config: dict[str, Any] = {}
|
|
191
|
+
section_files = sorted(self._config_path.glob("*.yaml"))
|
|
192
|
+
|
|
193
|
+
for section_file in section_files:
|
|
194
|
+
try:
|
|
195
|
+
with open(section_file, "r", encoding="utf-8") as f:
|
|
196
|
+
section_data = yaml.safe_load(f) or {}
|
|
197
|
+
merged_config = self._deep_merge(merged_config, section_data)
|
|
198
|
+
logger.debug(f"Loaded section: {section_file.name}")
|
|
199
|
+
except Exception as e:
|
|
200
|
+
logger.warning(f"Failed to load section {section_file.name}: {e}")
|
|
201
|
+
|
|
202
|
+
self._config = merged_config
|
|
203
|
+
self._last_modified = current_mtime
|
|
204
|
+
logger.debug(f"Loaded config from {len(section_files)} section files")
|
|
205
|
+
|
|
206
|
+
def _load_from_monolithic(self) -> None:
|
|
207
|
+
"""
|
|
208
|
+
Load configuration from single monolithic file (legacy).
|
|
209
|
+
|
|
210
|
+
Supports both YAML and JSON formats.
|
|
211
|
+
"""
|
|
212
|
+
# Check cache validity
|
|
213
|
+
current_mtime = self._config_path.stat().st_mtime
|
|
214
|
+
if self._last_modified and current_mtime == self._last_modified:
|
|
215
|
+
# Cache is still valid
|
|
216
|
+
return
|
|
217
|
+
|
|
218
|
+
# Load from file (auto-detect format)
|
|
219
|
+
with open(self._config_path, "r", encoding="utf-8") as f:
|
|
220
|
+
if self._config_path.suffix == ".yaml" or self._config_path.suffix == ".yml":
|
|
221
|
+
if not YAML_AVAILABLE:
|
|
222
|
+
raise ImportError("PyYAML is required for YAML config files. Install with: pip install pyyaml")
|
|
223
|
+
self._config = yaml.safe_load(f) or {}
|
|
224
|
+
else:
|
|
225
|
+
self._config = json.load(f)
|
|
226
|
+
|
|
227
|
+
# Update cache timestamp
|
|
228
|
+
self._last_modified = current_mtime
|
|
229
|
+
logger.debug(f"Loaded config from {self._config_path}")
|
|
230
|
+
|
|
164
231
|
def get(self, key: str, default: Any = None) -> Any:
|
|
165
232
|
"""
|
|
166
233
|
Get configuration value with dot-notation support.
|
|
@@ -238,7 +305,7 @@ class UnifiedConfigManager:
|
|
|
238
305
|
|
|
239
306
|
def save(self, backup: bool = True) -> bool:
|
|
240
307
|
"""
|
|
241
|
-
Save configuration to file with atomic write.
|
|
308
|
+
Save configuration to file or sections with atomic write.
|
|
242
309
|
|
|
243
310
|
Args:
|
|
244
311
|
backup: If True, create backup before saving (default: True)
|
|
@@ -247,42 +314,130 @@ class UnifiedConfigManager:
|
|
|
247
314
|
bool: True if save successful, False otherwise
|
|
248
315
|
|
|
249
316
|
Pattern: Temp file → Atomic rename (prevents corruption)
|
|
317
|
+
|
|
318
|
+
Note: For section-based configs, saves to individual section files.
|
|
319
|
+
For monolithic configs, saves to single file.
|
|
250
320
|
"""
|
|
251
321
|
try:
|
|
252
|
-
#
|
|
253
|
-
if
|
|
254
|
-
self.
|
|
322
|
+
# Section-based configuration
|
|
323
|
+
if self._config_path.is_dir():
|
|
324
|
+
return self._save_to_sections(backup)
|
|
325
|
+
else:
|
|
326
|
+
# Monolithic configuration (legacy)
|
|
327
|
+
return self._save_to_monolithic(backup)
|
|
255
328
|
|
|
256
|
-
|
|
257
|
-
|
|
329
|
+
except (OSError, PermissionError) as e:
|
|
330
|
+
logger.error(f"Failed to save config: {e}")
|
|
331
|
+
return False
|
|
332
|
+
|
|
333
|
+
def _save_to_sections(self, backup: bool) -> bool:
|
|
334
|
+
"""
|
|
335
|
+
Save configuration to modular section YAML files.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
backup: If True, create backup before saving
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
bool: True if successful
|
|
342
|
+
"""
|
|
343
|
+
if not YAML_AVAILABLE:
|
|
344
|
+
raise ImportError("PyYAML is required for section-based config. Install with: pip install pyyaml")
|
|
345
|
+
|
|
346
|
+
# Create backup if requested
|
|
347
|
+
if backup and self._config_path.exists():
|
|
348
|
+
self._create_backup()
|
|
349
|
+
|
|
350
|
+
# Define section mapping (top-level keys to section files)
|
|
351
|
+
section_mapping = {
|
|
352
|
+
"language": "language.yaml",
|
|
353
|
+
"user": "user.yaml",
|
|
354
|
+
"project": "project.yaml",
|
|
355
|
+
"moai": "system.yaml",
|
|
356
|
+
"github": "system.yaml",
|
|
357
|
+
"git": "git-strategy.yaml",
|
|
358
|
+
"quality": "quality.yaml",
|
|
359
|
+
"tdd": "quality.yaml",
|
|
360
|
+
"hooks": "system.yaml",
|
|
361
|
+
"session": "system.yaml",
|
|
362
|
+
# New in v1.1.0: Multi-LLM, pricing, and Ralph sections
|
|
363
|
+
"llm": "llm.yaml",
|
|
364
|
+
"pricing": "pricing.yaml",
|
|
365
|
+
"ralph": "ralph.yaml",
|
|
366
|
+
"service": "pricing.yaml", # Alias for pricing
|
|
367
|
+
# Document management (from config.yaml)
|
|
368
|
+
"document_management": "system.yaml",
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
# Group config data by section file
|
|
372
|
+
section_data: Dict[str, Dict[str, Any]] = {}
|
|
373
|
+
for key, value in self._config.items():
|
|
374
|
+
section_file = section_mapping.get(key, "system.yaml")
|
|
375
|
+
if section_file not in section_data:
|
|
376
|
+
section_data[section_file] = {}
|
|
377
|
+
section_data[section_file][key] = value
|
|
378
|
+
|
|
379
|
+
# Write each section file atomically
|
|
380
|
+
for section_file, data in section_data.items():
|
|
381
|
+
section_path = self._config_path / section_file
|
|
382
|
+
temp_path = section_path.with_suffix(".tmp")
|
|
258
383
|
|
|
259
|
-
# Write to temp file (auto-detect format)
|
|
260
384
|
with open(temp_path, "w", encoding="utf-8") as f:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
allow_unicode=True,
|
|
269
|
-
sort_keys=False,
|
|
270
|
-
)
|
|
271
|
-
else:
|
|
272
|
-
json.dump(self._config, f, indent=2, ensure_ascii=False)
|
|
385
|
+
yaml.safe_dump(
|
|
386
|
+
data,
|
|
387
|
+
f,
|
|
388
|
+
default_flow_style=False,
|
|
389
|
+
allow_unicode=True,
|
|
390
|
+
sort_keys=False,
|
|
391
|
+
)
|
|
273
392
|
|
|
274
393
|
# Atomic rename
|
|
275
|
-
temp_path.replace(
|
|
394
|
+
temp_path.replace(section_path)
|
|
276
395
|
|
|
277
|
-
|
|
278
|
-
|
|
396
|
+
# Update cache timestamp
|
|
397
|
+
self._last_modified = self._config_path.stat().st_mtime
|
|
398
|
+
logger.info(f"Saved config to {len(section_data)} section files")
|
|
399
|
+
return True
|
|
279
400
|
|
|
280
|
-
|
|
281
|
-
|
|
401
|
+
def _save_to_monolithic(self, backup: bool) -> bool:
|
|
402
|
+
"""
|
|
403
|
+
Save configuration to single monolithic file (legacy).
|
|
282
404
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
405
|
+
Args:
|
|
406
|
+
backup: If True, create backup before saving
|
|
407
|
+
|
|
408
|
+
Returns:
|
|
409
|
+
bool: True if successful
|
|
410
|
+
"""
|
|
411
|
+
# Create backup if requested
|
|
412
|
+
if backup and self._config_path.exists():
|
|
413
|
+
self._create_backup()
|
|
414
|
+
|
|
415
|
+
# Atomic write pattern: temp file → rename
|
|
416
|
+
temp_path = self._config_path.with_suffix(".tmp")
|
|
417
|
+
|
|
418
|
+
# Write to temp file (auto-detect format)
|
|
419
|
+
with open(temp_path, "w", encoding="utf-8") as f:
|
|
420
|
+
if self._config_path.suffix == ".yaml" or self._config_path.suffix == ".yml":
|
|
421
|
+
if not YAML_AVAILABLE:
|
|
422
|
+
raise ImportError("PyYAML is required for YAML config files. Install with: pip install pyyaml")
|
|
423
|
+
yaml.safe_dump(
|
|
424
|
+
self._config,
|
|
425
|
+
f,
|
|
426
|
+
default_flow_style=False,
|
|
427
|
+
allow_unicode=True,
|
|
428
|
+
sort_keys=False,
|
|
429
|
+
)
|
|
430
|
+
else:
|
|
431
|
+
json.dump(self._config, f, indent=2, ensure_ascii=False)
|
|
432
|
+
|
|
433
|
+
# Atomic rename
|
|
434
|
+
temp_path.replace(self._config_path)
|
|
435
|
+
|
|
436
|
+
# Update cache timestamp
|
|
437
|
+
self._last_modified = self._config_path.stat().st_mtime
|
|
438
|
+
|
|
439
|
+
logger.info(f"Saved config to {self._config_path}")
|
|
440
|
+
return True
|
|
286
441
|
|
|
287
442
|
def _create_backup(self) -> None:
|
|
288
443
|
"""Create timestamped backup of config file."""
|
|
@@ -393,8 +548,34 @@ def get_unified_config(
|
|
|
393
548
|
# Convenience functions for common operations
|
|
394
549
|
@lru_cache(maxsize=1)
|
|
395
550
|
def get_config_path() -> Path:
|
|
396
|
-
"""
|
|
397
|
-
|
|
551
|
+
"""
|
|
552
|
+
Get path to configuration file or sections directory.
|
|
553
|
+
|
|
554
|
+
Returns:
|
|
555
|
+
Path: Path to sections directory (new) or config file (legacy)
|
|
556
|
+
|
|
557
|
+
Note: Prioritizes section-based config over monolithic files.
|
|
558
|
+
Legacy projects may still use config.json or config.yaml.
|
|
559
|
+
"""
|
|
560
|
+
base_path = Path.cwd() / ".moai" / "config"
|
|
561
|
+
sections_dir = base_path / "sections"
|
|
562
|
+
|
|
563
|
+
# Priority 1: Section-based configuration (new approach)
|
|
564
|
+
if sections_dir.exists() and sections_dir.is_dir():
|
|
565
|
+
return sections_dir
|
|
566
|
+
|
|
567
|
+
# Priority 2: Monolithic YAML (legacy)
|
|
568
|
+
yaml_path = base_path / "config.yaml"
|
|
569
|
+
if yaml_path.exists():
|
|
570
|
+
return yaml_path
|
|
571
|
+
|
|
572
|
+
# Priority 3: Monolithic JSON (legacy)
|
|
573
|
+
json_path = base_path / "config.json"
|
|
574
|
+
if json_path.exists():
|
|
575
|
+
return json_path
|
|
576
|
+
|
|
577
|
+
# Default: Prefer sections for new projects
|
|
578
|
+
return sections_dir if YAML_AVAILABLE else yaml_path
|
|
398
579
|
|
|
399
580
|
|
|
400
581
|
def get_config_value(key: str, default: Any = None) -> Any:
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"""Global credentials management for MoAI-ADK.
|
|
2
|
+
|
|
3
|
+
Stores API keys:
|
|
4
|
+
- GLM API key: ~/.moai/.env.glm (dotenv format)
|
|
5
|
+
- Anthropic API key: ~/.moai/credentials.yaml (YAML format)
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import stat
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import yaml
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_credentials_path() -> Path:
|
|
16
|
+
"""Get the global credentials file path.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
Path to ~/.moai/credentials.yaml
|
|
20
|
+
"""
|
|
21
|
+
return Path.home() / ".moai" / "credentials.yaml"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_env_glm_path() -> Path:
|
|
25
|
+
"""Get the GLM API key file path.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Path to ~/.moai/.env.glm
|
|
29
|
+
"""
|
|
30
|
+
return Path.home() / ".moai" / ".env.glm"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def glm_env_exists() -> bool:
|
|
34
|
+
"""Check if GLM API key file exists.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
True if ~/.moai/.env.glm exists
|
|
38
|
+
"""
|
|
39
|
+
return get_env_glm_path().exists()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def load_glm_key_from_env() -> str | None:
|
|
43
|
+
"""Load GLM API key from ~/.moai/.env.glm.
|
|
44
|
+
|
|
45
|
+
The file format is dotenv style: GLM_API_KEY=xxx
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
GLM API key or None if not found
|
|
49
|
+
"""
|
|
50
|
+
env_path = get_env_glm_path()
|
|
51
|
+
|
|
52
|
+
if not env_path.exists():
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
content = env_path.read_text().strip()
|
|
57
|
+
for line in content.splitlines():
|
|
58
|
+
line = line.strip()
|
|
59
|
+
if line.startswith("#") or not line:
|
|
60
|
+
continue
|
|
61
|
+
if line.startswith("GLM_API_KEY="):
|
|
62
|
+
# Remove quotes if present
|
|
63
|
+
value = line.split("=", 1)[1].strip()
|
|
64
|
+
if value.startswith('"') and value.endswith('"'):
|
|
65
|
+
value = value[1:-1]
|
|
66
|
+
elif value.startswith("'") and value.endswith("'"):
|
|
67
|
+
value = value[1:-1]
|
|
68
|
+
return value if value else None
|
|
69
|
+
return None
|
|
70
|
+
except OSError:
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def save_glm_key_to_env(key: str) -> None:
|
|
75
|
+
"""Save GLM API key to ~/.moai/.env.glm.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
key: GLM API key to save
|
|
79
|
+
"""
|
|
80
|
+
env_path = get_env_glm_path()
|
|
81
|
+
|
|
82
|
+
# Ensure directory exists
|
|
83
|
+
env_path.parent.mkdir(parents=True, exist_ok=True)
|
|
84
|
+
|
|
85
|
+
# Write in dotenv format
|
|
86
|
+
content = f'# GLM API Key for MoAI-ADK\n# Generated by moai-adk\nGLM_API_KEY="{key}"\n'
|
|
87
|
+
env_path.write_text(content)
|
|
88
|
+
|
|
89
|
+
# Set file permissions to owner-only (chmod 600)
|
|
90
|
+
os.chmod(env_path, stat.S_IRUSR | stat.S_IWUSR)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def load_credentials() -> dict[str, str | None]:
|
|
94
|
+
"""Load credentials from ~/.moai/credentials.yaml.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
Dict with api keys (values may be None if not set)
|
|
98
|
+
"""
|
|
99
|
+
creds_path = get_credentials_path()
|
|
100
|
+
|
|
101
|
+
if not creds_path.exists():
|
|
102
|
+
return {"anthropic_api_key": None, "glm_api_key": None}
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
data = yaml.safe_load(creds_path.read_text()) or {}
|
|
106
|
+
return {
|
|
107
|
+
"anthropic_api_key": data.get("anthropic_api_key"),
|
|
108
|
+
"glm_api_key": data.get("glm_api_key"),
|
|
109
|
+
}
|
|
110
|
+
except (yaml.YAMLError, OSError):
|
|
111
|
+
return {"anthropic_api_key": None, "glm_api_key": None}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def save_credentials(
|
|
115
|
+
anthropic_api_key: str | None = None,
|
|
116
|
+
glm_api_key: str | None = None,
|
|
117
|
+
*,
|
|
118
|
+
merge: bool = True,
|
|
119
|
+
) -> None:
|
|
120
|
+
"""Save credentials to ~/.moai/credentials.yaml.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
anthropic_api_key: Anthropic API key (None to skip)
|
|
124
|
+
glm_api_key: GLM API key (None to skip)
|
|
125
|
+
merge: If True, merge with existing credentials. If False, overwrite.
|
|
126
|
+
"""
|
|
127
|
+
creds_path = get_credentials_path()
|
|
128
|
+
|
|
129
|
+
# Ensure directory exists
|
|
130
|
+
creds_path.parent.mkdir(parents=True, exist_ok=True)
|
|
131
|
+
|
|
132
|
+
# Load existing if merge mode
|
|
133
|
+
if merge:
|
|
134
|
+
existing = load_credentials()
|
|
135
|
+
else:
|
|
136
|
+
existing = {"anthropic_api_key": None, "glm_api_key": None}
|
|
137
|
+
|
|
138
|
+
# Build final data with new values taking precedence
|
|
139
|
+
data_to_save: dict[str, str] = {}
|
|
140
|
+
|
|
141
|
+
# Add anthropic key
|
|
142
|
+
final_anthropic = anthropic_api_key if anthropic_api_key is not None else existing.get("anthropic_api_key")
|
|
143
|
+
if final_anthropic:
|
|
144
|
+
data_to_save["anthropic_api_key"] = final_anthropic
|
|
145
|
+
|
|
146
|
+
# Add GLM key
|
|
147
|
+
final_glm = glm_api_key if glm_api_key is not None else existing.get("glm_api_key")
|
|
148
|
+
if final_glm:
|
|
149
|
+
data_to_save["glm_api_key"] = final_glm
|
|
150
|
+
|
|
151
|
+
# Write with secure permissions
|
|
152
|
+
creds_path.write_text(yaml.safe_dump(data_to_save, default_flow_style=False))
|
|
153
|
+
|
|
154
|
+
# Set file permissions to owner-only (chmod 600)
|
|
155
|
+
os.chmod(creds_path, stat.S_IRUSR | stat.S_IWUSR)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def get_glm_api_key() -> str | None:
|
|
159
|
+
"""Get GLM API key from multiple sources.
|
|
160
|
+
|
|
161
|
+
Priority:
|
|
162
|
+
1. ~/.moai/.env.glm (explicit user config takes precedence)
|
|
163
|
+
2. ~/.moai/credentials.yaml (legacy, for backward compatibility)
|
|
164
|
+
3. Environment variable GLM_API_KEY (fallback for CI/CD or shell export)
|
|
165
|
+
|
|
166
|
+
Note: .env.glm file is prioritized over environment variable because
|
|
167
|
+
users explicitly save keys there via 'moai glm' command. Environment
|
|
168
|
+
variables may contain stale values from previous sessions.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
GLM API key or None if not found
|
|
172
|
+
"""
|
|
173
|
+
# Check .env.glm file first (user's explicit choice)
|
|
174
|
+
env_glm_key = load_glm_key_from_env()
|
|
175
|
+
if env_glm_key:
|
|
176
|
+
return env_glm_key
|
|
177
|
+
|
|
178
|
+
# Fall back to credentials.yaml (legacy)
|
|
179
|
+
creds = load_credentials()
|
|
180
|
+
creds_key = creds.get("glm_api_key")
|
|
181
|
+
if creds_key:
|
|
182
|
+
return creds_key
|
|
183
|
+
|
|
184
|
+
# Finally check environment variable (for CI/CD or manual export)
|
|
185
|
+
env_key = os.environ.get("GLM_API_KEY")
|
|
186
|
+
if env_key:
|
|
187
|
+
return env_key
|
|
188
|
+
|
|
189
|
+
return None
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def get_anthropic_api_key() -> str | None:
|
|
193
|
+
"""Get Anthropic API key from credentials or environment.
|
|
194
|
+
|
|
195
|
+
Priority:
|
|
196
|
+
1. Environment variable ANTHROPIC_API_KEY
|
|
197
|
+
2. ~/.moai/credentials.yaml
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
Anthropic API key or None if not found
|
|
201
|
+
"""
|
|
202
|
+
# Check environment first
|
|
203
|
+
env_key = os.environ.get("ANTHROPIC_API_KEY")
|
|
204
|
+
if env_key:
|
|
205
|
+
return env_key
|
|
206
|
+
|
|
207
|
+
# Fall back to credentials file
|
|
208
|
+
creds = load_credentials()
|
|
209
|
+
return creds.get("anthropic_api_key")
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def remove_glm_key_from_shell_config() -> dict[str, bool]:
|
|
213
|
+
"""Remove GLM_API_KEY export from shell config files.
|
|
214
|
+
|
|
215
|
+
Removes lines matching 'export GLM_API_KEY=' from ~/.zshrc and ~/.bashrc.
|
|
216
|
+
Creates a backup before modifying.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
Dict with shell config names as keys and True if modified, False otherwise.
|
|
220
|
+
Example: {"zshrc": True, "bashrc": False}
|
|
221
|
+
"""
|
|
222
|
+
import re
|
|
223
|
+
import shutil
|
|
224
|
+
|
|
225
|
+
results: dict[str, bool] = {}
|
|
226
|
+
shell_configs = [
|
|
227
|
+
(Path.home() / ".zshrc", "zshrc"),
|
|
228
|
+
(Path.home() / ".bashrc", "bashrc"),
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
# Pattern to match: export GLM_API_KEY=... (with optional quotes)
|
|
232
|
+
pattern = re.compile(r"^\s*export\s+GLM_API_KEY\s*=.*$", re.MULTILINE)
|
|
233
|
+
|
|
234
|
+
for config_path, config_name in shell_configs:
|
|
235
|
+
if not config_path.exists():
|
|
236
|
+
results[config_name] = False
|
|
237
|
+
continue
|
|
238
|
+
|
|
239
|
+
try:
|
|
240
|
+
original_content = config_path.read_text()
|
|
241
|
+
|
|
242
|
+
# Check if pattern exists
|
|
243
|
+
if not pattern.search(original_content):
|
|
244
|
+
results[config_name] = False
|
|
245
|
+
continue
|
|
246
|
+
|
|
247
|
+
# Create backup before modifying
|
|
248
|
+
backup_path = config_path.with_suffix(f"{config_path.suffix}.moai-backup")
|
|
249
|
+
shutil.copy2(config_path, backup_path)
|
|
250
|
+
|
|
251
|
+
# Remove the export line(s)
|
|
252
|
+
new_content = pattern.sub("", original_content)
|
|
253
|
+
|
|
254
|
+
# Clean up multiple consecutive empty lines
|
|
255
|
+
new_content = re.sub(r"\n{3,}", "\n\n", new_content)
|
|
256
|
+
|
|
257
|
+
# Write back
|
|
258
|
+
config_path.write_text(new_content)
|
|
259
|
+
results[config_name] = True
|
|
260
|
+
|
|
261
|
+
except OSError:
|
|
262
|
+
results[config_name] = False
|
|
263
|
+
|
|
264
|
+
return results
|