moai-adk 0.25.4__py3-none-any.whl → 0.32.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of moai-adk might be problematic. Click here for more details.

Files changed (378) hide show
  1. moai_adk/__init__.py +2 -5
  2. moai_adk/__main__.py +114 -82
  3. moai_adk/cli/__init__.py +6 -1
  4. moai_adk/cli/commands/__init__.py +1 -3
  5. moai_adk/cli/commands/analyze.py +5 -16
  6. moai_adk/cli/commands/doctor.py +6 -18
  7. moai_adk/cli/commands/init.py +56 -125
  8. moai_adk/cli/commands/language.py +14 -35
  9. moai_adk/cli/commands/status.py +9 -15
  10. moai_adk/cli/commands/update.py +1555 -190
  11. moai_adk/cli/prompts/init_prompts.py +112 -56
  12. moai_adk/cli/spec_status.py +263 -0
  13. moai_adk/cli/ui/__init__.py +44 -0
  14. moai_adk/cli/ui/progress.py +422 -0
  15. moai_adk/cli/ui/prompts.py +389 -0
  16. moai_adk/cli/ui/theme.py +129 -0
  17. moai_adk/cli/worktree/__init__.py +27 -0
  18. moai_adk/cli/worktree/__main__.py +31 -0
  19. moai_adk/cli/worktree/cli.py +672 -0
  20. moai_adk/cli/worktree/exceptions.py +89 -0
  21. moai_adk/cli/worktree/manager.py +490 -0
  22. moai_adk/cli/worktree/models.py +65 -0
  23. moai_adk/cli/worktree/registry.py +128 -0
  24. moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
  25. moai_adk/core/analysis/session_analyzer.py +17 -56
  26. moai_adk/core/claude_integration.py +26 -54
  27. moai_adk/core/command_helpers.py +10 -10
  28. moai_adk/core/comprehensive_monitoring_system.py +1183 -0
  29. moai_adk/core/config/auto_spec_config.py +5 -11
  30. moai_adk/core/config/migration.py +19 -9
  31. moai_adk/core/config/unified.py +436 -0
  32. moai_adk/core/context_manager.py +6 -12
  33. moai_adk/core/enterprise_features.py +1404 -0
  34. moai_adk/core/error_recovery_system.py +725 -112
  35. moai_adk/core/event_driven_hook_system.py +1371 -0
  36. moai_adk/core/git/__init__.py +8 -0
  37. moai_adk/core/git/branch_manager.py +3 -11
  38. moai_adk/core/git/checkpoint.py +1 -3
  39. moai_adk/core/git/conflict_detector.py +413 -0
  40. moai_adk/core/git/manager.py +91 -1
  41. moai_adk/core/hooks/post_tool_auto_spec_completion.py +56 -80
  42. moai_adk/core/input_validation_middleware.py +1006 -0
  43. moai_adk/core/integration/engine.py +6 -18
  44. moai_adk/core/integration/integration_tester.py +10 -9
  45. moai_adk/core/integration/utils.py +1 -1
  46. moai_adk/core/issue_creator.py +10 -28
  47. moai_adk/core/jit_context_loader.py +956 -0
  48. moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
  49. moai_adk/core/language_config_resolver.py +485 -0
  50. moai_adk/core/language_validator.py +28 -41
  51. moai_adk/core/mcp/setup.py +15 -12
  52. moai_adk/core/merge/__init__.py +9 -0
  53. moai_adk/core/merge/analyzer.py +481 -0
  54. moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
  55. moai_adk/core/migration/backup_manager.py +78 -9
  56. moai_adk/core/migration/custom_element_scanner.py +358 -0
  57. moai_adk/core/migration/file_migrator.py +8 -17
  58. moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
  59. moai_adk/core/migration/selective_restorer.py +470 -0
  60. moai_adk/core/migration/template_utils.py +74 -0
  61. moai_adk/core/migration/user_selection_ui.py +338 -0
  62. moai_adk/core/migration/version_detector.py +6 -10
  63. moai_adk/core/migration/version_migrator.py +3 -3
  64. moai_adk/core/performance/cache_system.py +8 -10
  65. moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
  66. moai_adk/core/project/checker.py +2 -4
  67. moai_adk/core/project/detector.py +1 -3
  68. moai_adk/core/project/initializer.py +135 -23
  69. moai_adk/core/project/phase_executor.py +54 -81
  70. moai_adk/core/project/validator.py +6 -12
  71. moai_adk/core/quality/trust_checker.py +9 -27
  72. moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
  73. moai_adk/core/robust_json_parser.py +611 -0
  74. moai_adk/core/rollback_manager.py +73 -148
  75. moai_adk/core/session_manager.py +10 -26
  76. moai_adk/core/skill_loading_system.py +579 -0
  77. moai_adk/core/spec/confidence_scoring.py +31 -100
  78. moai_adk/core/spec/ears_template_engine.py +351 -286
  79. moai_adk/core/spec/quality_validator.py +35 -69
  80. moai_adk/core/spec_status_manager.py +64 -74
  81. moai_adk/core/template/backup.py +45 -20
  82. moai_adk/core/template/config.py +112 -39
  83. moai_adk/core/template/merger.py +11 -19
  84. moai_adk/core/template/processor.py +253 -149
  85. moai_adk/core/template_engine.py +73 -40
  86. moai_adk/core/template_variable_synchronizer.py +417 -0
  87. moai_adk/core/unified_permission_manager.py +745 -0
  88. moai_adk/core/user_behavior_analytics.py +851 -0
  89. moai_adk/core/version_sync.py +429 -0
  90. moai_adk/foundation/__init__.py +56 -0
  91. moai_adk/foundation/backend.py +1027 -0
  92. moai_adk/foundation/database.py +1115 -0
  93. moai_adk/foundation/devops.py +1585 -0
  94. moai_adk/foundation/ears.py +431 -0
  95. moai_adk/foundation/frontend.py +870 -0
  96. moai_adk/foundation/git/commit_templates.py +4 -12
  97. moai_adk/foundation/git.py +376 -0
  98. moai_adk/foundation/langs.py +484 -0
  99. moai_adk/foundation/ml_ops.py +1162 -0
  100. moai_adk/foundation/testing.py +1524 -0
  101. moai_adk/foundation/trust/trust_principles.py +23 -72
  102. moai_adk/foundation/trust/validation_checklist.py +57 -162
  103. moai_adk/project/__init__.py +0 -0
  104. moai_adk/project/configuration.py +1084 -0
  105. moai_adk/project/documentation.py +566 -0
  106. moai_adk/project/schema.py +447 -0
  107. moai_adk/statusline/alfred_detector.py +1 -3
  108. moai_adk/statusline/config.py +13 -4
  109. moai_adk/statusline/enhanced_output_style_detector.py +23 -15
  110. moai_adk/statusline/main.py +51 -15
  111. moai_adk/statusline/renderer.py +104 -48
  112. moai_adk/statusline/update_checker.py +3 -9
  113. moai_adk/statusline/version_reader.py +140 -46
  114. moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +549 -0
  115. moai_adk/templates/.claude/agents/moai/builder-agent.md +445 -0
  116. moai_adk/templates/.claude/agents/moai/builder-command.md +1132 -0
  117. moai_adk/templates/.claude/agents/moai/builder-skill.md +601 -0
  118. moai_adk/templates/.claude/agents/moai/expert-backend.md +831 -0
  119. moai_adk/templates/.claude/agents/moai/expert-database.md +774 -0
  120. moai_adk/templates/.claude/agents/moai/expert-debug.md +396 -0
  121. moai_adk/templates/.claude/agents/moai/expert-devops.md +711 -0
  122. moai_adk/templates/.claude/agents/moai/expert-frontend.md +666 -0
  123. moai_adk/templates/.claude/agents/moai/expert-security.md +474 -0
  124. moai_adk/templates/.claude/agents/moai/expert-uiux.md +1038 -0
  125. moai_adk/templates/.claude/agents/moai/manager-claude-code.md +429 -0
  126. moai_adk/templates/.claude/agents/moai/manager-docs.md +570 -0
  127. moai_adk/templates/.claude/agents/moai/manager-git.md +937 -0
  128. moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
  129. moai_adk/templates/.claude/agents/moai/manager-quality.md +598 -0
  130. moai_adk/templates/.claude/agents/moai/manager-spec.md +713 -0
  131. moai_adk/templates/.claude/agents/moai/manager-strategy.md +600 -0
  132. moai_adk/templates/.claude/agents/moai/manager-tdd.md +603 -0
  133. moai_adk/templates/.claude/agents/moai/mcp-context7.md +369 -0
  134. moai_adk/templates/.claude/agents/moai/mcp-figma.md +1567 -0
  135. moai_adk/templates/.claude/agents/moai/mcp-notion.md +749 -0
  136. moai_adk/templates/.claude/agents/moai/mcp-playwright.md +427 -0
  137. moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +994 -0
  138. moai_adk/templates/.claude/commands/moai/0-project.md +1143 -0
  139. moai_adk/templates/.claude/commands/moai/1-plan.md +1435 -0
  140. moai_adk/templates/.claude/commands/moai/2-run.md +883 -0
  141. moai_adk/templates/.claude/commands/moai/3-sync.md +993 -0
  142. moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
  143. moai_adk/templates/.claude/hooks/__init__.py +8 -0
  144. moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
  145. moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
  146. moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
  147. moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
  148. moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
  149. moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
  150. moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
  151. moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
  152. moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
  153. moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
  154. moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
  155. moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
  156. moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
  157. moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
  158. moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
  159. moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
  160. moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +921 -0
  161. moai_adk/templates/.claude/output-styles/moai/r2d2.md +380 -0
  162. moai_adk/templates/.claude/output-styles/moai/yoda.md +338 -0
  163. moai_adk/templates/.claude/settings.json +172 -0
  164. moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +247 -0
  165. moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
  166. moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
  167. moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
  168. moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
  169. moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
  170. moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +319 -0
  171. moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +320 -0
  172. moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
  173. moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
  174. moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
  175. moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
  176. moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +496 -0
  177. moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +453 -0
  178. moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
  179. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
  180. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
  181. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/design-system-tokens.md +405 -0
  182. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
  183. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
  184. moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
  185. moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +491 -0
  186. moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
  187. moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
  188. moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
  189. moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
  190. moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
  191. moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
  192. moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +201 -0
  193. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
  194. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
  195. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
  196. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
  197. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
  198. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
  199. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
  200. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
  201. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
  202. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
  203. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
  204. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
  205. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
  206. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
  207. moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +438 -0
  208. moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +515 -0
  209. moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
  210. moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +346 -0
  211. moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
  212. moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
  213. moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
  214. moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
  215. moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
  216. moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
  217. moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
  218. moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
  219. moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +362 -0
  220. moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
  221. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
  222. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
  223. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
  224. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
  225. moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
  226. moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
  227. moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
  228. moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
  229. moai_adk/templates/.claude/skills/moai-integration-mcp/SKILL.md +352 -0
  230. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/README.md +52 -0
  231. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/error-handling.md +334 -0
  232. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/integration-patterns.md +310 -0
  233. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/security-authentication.md +256 -0
  234. moai_adk/templates/.claude/skills/moai-integration-mcp/modules/server-architecture.md +253 -0
  235. moai_adk/templates/.claude/skills/moai-lang-unified/README.md +133 -0
  236. moai_adk/templates/.claude/skills/moai-lang-unified/SKILL.md +296 -0
  237. moai_adk/templates/.claude/skills/moai-lang-unified/examples.md +1269 -0
  238. moai_adk/templates/.claude/skills/moai-lang-unified/reference.md +331 -0
  239. moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +298 -0
  240. moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
  241. moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
  242. moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
  243. moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
  244. moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +316 -0
  245. moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
  246. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
  247. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
  248. moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
  249. moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
  250. moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
  251. moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
  252. moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
  253. moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
  254. moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
  255. moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +370 -0
  256. moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
  257. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
  258. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
  259. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
  260. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
  261. moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
  262. moai_adk/templates/.claude/skills/moai-platform-baas/README.md +186 -0
  263. moai_adk/templates/.claude/skills/moai-platform-baas/SKILL.md +290 -0
  264. moai_adk/templates/.claude/skills/moai-platform-baas/examples.md +1225 -0
  265. moai_adk/templates/.claude/skills/moai-platform-baas/reference.md +567 -0
  266. moai_adk/templates/.claude/skills/moai-platform-baas/scripts/provider-selector.py +323 -0
  267. moai_adk/templates/.claude/skills/moai-platform-baas/templates/stack-config.yaml +204 -0
  268. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +446 -0
  269. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
  270. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
  271. moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
  272. moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +387 -0
  273. moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
  274. moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
  275. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
  276. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
  277. moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
  278. moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +135 -0
  279. moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
  280. moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
  281. moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
  282. moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
  283. moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
  284. moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
  285. moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
  286. moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
  287. moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
  288. moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
  289. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
  290. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1362 -0
  291. moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
  292. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
  293. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
  294. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +71 -0
  295. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
  296. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
  297. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
  298. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
  299. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
  300. moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
  301. moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +374 -0
  302. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
  303. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
  304. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
  305. moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
  306. moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +453 -0
  307. moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
  308. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
  309. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
  310. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
  311. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
  312. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
  313. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
  314. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
  315. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
  316. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
  317. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
  318. moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
  319. moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
  320. moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
  321. moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
  322. moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
  323. moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +410 -0
  324. moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
  325. moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
  326. moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
  327. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
  328. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
  329. moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
  330. moai_adk/templates/.git-hooks/pre-commit +103 -41
  331. moai_adk/templates/.git-hooks/pre-push +116 -21
  332. moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
  333. moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
  334. moai_adk/templates/.gitignore +184 -44
  335. moai_adk/templates/.mcp.json +7 -9
  336. moai_adk/templates/.moai/cache/personalization.json +10 -0
  337. moai_adk/templates/.moai/config/config.yaml +344 -0
  338. moai_adk/templates/.moai/config/presets/manual.yaml +28 -0
  339. moai_adk/templates/.moai/config/presets/personal.yaml +30 -0
  340. moai_adk/templates/.moai/config/presets/team.yaml +33 -0
  341. moai_adk/templates/.moai/config/questions/_schema.yaml +79 -0
  342. moai_adk/templates/.moai/config/questions/tab1-user.yaml +108 -0
  343. moai_adk/templates/.moai/config/questions/tab2-project.yaml +122 -0
  344. moai_adk/templates/.moai/config/questions/tab3-git.yaml +542 -0
  345. moai_adk/templates/.moai/config/questions/tab4-quality.yaml +167 -0
  346. moai_adk/templates/.moai/config/questions/tab5-system.yaml +152 -0
  347. moai_adk/templates/.moai/config/sections/git-strategy.yaml +40 -0
  348. moai_adk/templates/.moai/config/sections/language.yaml +11 -0
  349. moai_adk/templates/.moai/config/sections/project.yaml +13 -0
  350. moai_adk/templates/.moai/config/sections/quality.yaml +15 -0
  351. moai_adk/templates/.moai/config/sections/system.yaml +14 -0
  352. moai_adk/templates/.moai/config/sections/user.yaml +5 -0
  353. moai_adk/templates/.moai/config/statusline-config.yaml +86 -0
  354. moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
  355. moai_adk/templates/CLAUDE.md +382 -501
  356. moai_adk/utils/__init__.py +24 -1
  357. moai_adk/utils/banner.py +7 -10
  358. moai_adk/utils/common.py +16 -30
  359. moai_adk/utils/link_validator.py +4 -12
  360. moai_adk/utils/safe_file_reader.py +2 -6
  361. moai_adk/utils/timeout.py +160 -0
  362. moai_adk/utils/toon_utils.py +256 -0
  363. moai_adk/version.py +22 -0
  364. moai_adk-0.32.8.dist-info/METADATA +2478 -0
  365. moai_adk-0.32.8.dist-info/RECORD +396 -0
  366. {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/WHEEL +1 -1
  367. {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/entry_points.txt +1 -0
  368. moai_adk/cli/commands/backup.py +0 -82
  369. moai_adk/cli/commands/improve_user_experience.py +0 -348
  370. moai_adk/cli/commands/migrate.py +0 -158
  371. moai_adk/cli/commands/validate_links.py +0 -118
  372. moai_adk/templates/.github/workflows/moai-gitflow.yml +0 -413
  373. moai_adk/templates/.github/workflows/moai-release-create.yml +0 -100
  374. moai_adk/templates/.github/workflows/moai-release-pipeline.yml +0 -188
  375. moai_adk/utils/user_experience.py +0 -531
  376. moai_adk-0.25.4.dist-info/METADATA +0 -2279
  377. moai_adk-0.25.4.dist-info/RECORD +0 -112
  378. {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/licenses/LICENSE +0 -0
@@ -20,7 +20,7 @@ class AutoSpecConfig:
20
20
  def __init__(self, config_path: str = None):
21
21
  """Initialize the configuration reader."""
22
22
  self.config_path = config_path or self._get_default_config_path()
23
- self.config = {}
23
+ self.config: dict[str, Any] = {}
24
24
  self.load_config()
25
25
 
26
26
  def _get_default_config_path(self) -> str:
@@ -48,9 +48,7 @@ class AutoSpecConfig:
48
48
  # Extract auto-spec completion config
49
49
  self.config = self.config.get("auto_spec_completion", {})
50
50
 
51
- logger.info(
52
- f"Loaded auto-spec completion configuration from {self.config_path}"
53
- )
51
+ logger.info(f"Loaded auto-spec completion configuration from {self.config_path}")
54
52
 
55
53
  except FileNotFoundError:
56
54
  logger.warning(f"Configuration file not found: {self.config_path}")
@@ -174,7 +172,7 @@ class AutoSpecConfig:
174
172
 
175
173
  for pattern in excluded_patterns:
176
174
  # Convert pattern to lowercase for case-insensitive matching
177
- pattern_lower = pattern.lower()
175
+ pattern.lower()
178
176
 
179
177
  # Handle directory patterns
180
178
  if pattern.startswith("*/") and pattern.endswith("/*"):
@@ -300,9 +298,7 @@ class AutoSpecConfig:
300
298
  if not isinstance(quality_threshold["ears_compliance"], (int, float)):
301
299
  errors.append("quality_threshold.ears_compliance must be a number")
302
300
  elif not 0 <= quality_threshold["ears_compliance"] <= 1:
303
- errors.append(
304
- "quality_threshold.ears_compliance must be between 0 and 1"
305
- )
301
+ errors.append("quality_threshold.ears_compliance must be between 0 and 1")
306
302
 
307
303
  return errors
308
304
 
@@ -329,9 +325,7 @@ class AutoSpecConfig:
329
325
  with open(self.config_path, "w", encoding="utf-8") as f:
330
326
  json.dump(full_config, f, indent=2, ensure_ascii=False)
331
327
 
332
- logger.info(
333
- f"Saved auto-spec completion configuration to {self.config_path}"
334
- )
328
+ logger.info(f"Saved auto-spec completion configuration to {self.config_path}")
335
329
 
336
330
  except Exception as e:
337
331
  logger.error(f"Error saving configuration: {e}")
@@ -39,9 +39,7 @@ def migrate_config_to_nested_structure(config: dict[str, Any]) -> dict[str, Any]
39
39
  from ..language_config import LANGUAGE_CONFIG
40
40
 
41
41
  # Extract language names from enhanced config
42
- language_names = {
43
- code: info["native_name"] for code, info in LANGUAGE_CONFIG.items()
44
- }
42
+ language_names = {code: info["native_name"] for code, info in LANGUAGE_CONFIG.items()}
45
43
 
46
44
  language_name = language_names.get(conversation_language, "English")
47
45
 
@@ -51,6 +49,22 @@ def migrate_config_to_nested_structure(config: dict[str, Any]) -> dict[str, Any]
51
49
  "conversation_language_name": language_name,
52
50
  }
53
51
 
52
+ # 2. Language settings migration
53
+ # Old: "language": "ko"
54
+ # New: "language": {"conversation_language": "ko", "conversation_language_name": "Korean"}
55
+ if "language" in config and isinstance(config["language"], str):
56
+ old_lang = config["language"]
57
+ lang_names = {
58
+ "ko": "Korean",
59
+ "en": "English",
60
+ "ja": "Japanese",
61
+ "zh": "Chinese",
62
+ }
63
+ config["language"] = {
64
+ "conversation_language": old_lang,
65
+ "conversation_language_name": lang_names.get(old_lang, "English"),
66
+ }
67
+
54
68
  return config
55
69
 
56
70
 
@@ -106,9 +120,7 @@ def get_conversation_language_name(config: dict[str, Any]) -> str:
106
120
  from ..language_config import LANGUAGE_CONFIG
107
121
 
108
122
  # Extract language names from enhanced config
109
- language_names = {
110
- code: info["native_name"] for code, info in LANGUAGE_CONFIG.items()
111
- }
123
+ language_names = {code: info["native_name"] for code, info in LANGUAGE_CONFIG.items()}
112
124
  return language_names.get(language_code, "English")
113
125
 
114
126
 
@@ -164,9 +176,7 @@ def migrate_config_schema_v0_17_0(config: dict[str, Any]) -> dict[str, Any]:
164
176
  if "spec_git_workflow" not in github_config:
165
177
  github_config["spec_git_workflow"] = "per_spec"
166
178
  github_config["spec_git_workflow_configured"] = False
167
- github_config["spec_git_workflow_rationale"] = (
168
- "Ask per SPEC (flexible, user controls each workflow)"
169
- )
179
+ github_config["spec_git_workflow_rationale"] = "Ask per SPEC (flexible, user controls each workflow)"
170
180
 
171
181
  # Add notes for new fields if missing
172
182
  if "notes_new_fields" not in github_config:
@@ -0,0 +1,436 @@
1
+ """
2
+ Unified Configuration Manager for MoAI-ADK
3
+
4
+ Thread-safe singleton configuration manager that consolidates all config management
5
+ patterns from across the codebase into a single, robust implementation.
6
+
7
+ Features:
8
+ - Thread-safe singleton with double-checked locking
9
+ - Lazy loading with in-memory caching
10
+ - Atomic writes with backup creation
11
+ - Schema validation support
12
+ - Smart defaults with auto-detection
13
+ - Deep merge for nested configs
14
+ - Configuration migration between versions
15
+ - Domain-specific facades for different subsystems
16
+
17
+ Design Philosophy:
18
+ - Single source of truth for `.moai/config/config.yaml` (with JSON fallback)
19
+ - Best patterns from StatuslineConfig, UnifiedConfigManager, ConfigurationManager
20
+ - Backward compatible with existing ConfigManager interfaces
21
+ - Performance optimized with caching and minimal I/O
22
+
23
+ Usage:
24
+ >>> from moai_adk.core.config.unified import get_unified_config
25
+ >>> config = get_unified_config()
26
+ >>> timeout = config.get("hooks.timeout_ms", 2000)
27
+ >>> config.update({"hooks.timeout_ms": 3000})
28
+ >>> config.save()
29
+ """
30
+
31
+ import json
32
+ import logging
33
+ import shutil
34
+ import threading
35
+ from datetime import datetime
36
+ from functools import lru_cache
37
+ from pathlib import Path
38
+ from typing import Any, Dict, Optional, Union
39
+
40
+ try:
41
+ import yaml
42
+
43
+ YAML_AVAILABLE = True
44
+ except ImportError:
45
+ YAML_AVAILABLE = False
46
+
47
+ logger = logging.getLogger(__name__)
48
+
49
+
50
+ class UnifiedConfigManager:
51
+ """
52
+ Thread-safe singleton configuration manager for MoAI-ADK.
53
+
54
+ This class consolidates all configuration management patterns from:
55
+ - StatuslineConfig: Thread-safe singleton pattern
56
+ - UnifiedConfigManager (skills): Backup, migration, validation
57
+ - ConfigurationManager (project): Smart defaults, auto-detection
58
+ - ConfigManager (hooks): Convenience functions
59
+
60
+ Attributes:
61
+ _instance: Singleton instance
62
+ _config: Cached configuration dictionary
63
+ _lock: Thread lock for singleton pattern
64
+ _config_path: Path to configuration file
65
+ _last_modified: Last modification timestamp for cache invalidation
66
+ """
67
+
68
+ _instance: Optional["UnifiedConfigManager"] = None
69
+ _config: Dict[str, Any] = {}
70
+ _lock = threading.Lock()
71
+ _config_path: Optional[Path] = None
72
+ _last_modified: Optional[float] = None
73
+
74
+ def __new__(cls, config_path: Optional[Union[str, Path]] = None):
75
+ """
76
+ Create or return singleton instance with double-checked locking.
77
+
78
+ Args:
79
+ config_path: Optional path to config file (default: .moai/config/config.json)
80
+
81
+ Returns:
82
+ UnifiedConfigManager: Singleton instance
83
+ """
84
+ # Double-checked locking pattern for thread-safe singleton
85
+ if cls._instance is None:
86
+ with cls._lock:
87
+ # Double-check after acquiring lock
88
+ if cls._instance is None:
89
+ cls._instance = super().__new__(cls)
90
+ cls._instance._initialize(config_path)
91
+ return cls._instance
92
+
93
+ def _initialize(self, config_path: Optional[Union[str, Path]] = None) -> None:
94
+ """
95
+ Initialize configuration manager (called once by singleton).
96
+
97
+ Args:
98
+ config_path: Optional path to config file
99
+ """
100
+ # Set config path with auto-detection
101
+ if config_path:
102
+ self._config_path = Path(config_path)
103
+ else:
104
+ # Auto-detect YAML (preferred) or JSON (fallback)
105
+ base_path = Path.cwd() / ".moai" / "config"
106
+ yaml_path = base_path / "config.yaml"
107
+ json_path = base_path / "config.json"
108
+
109
+ if YAML_AVAILABLE and yaml_path.exists():
110
+ self._config_path = yaml_path
111
+ elif json_path.exists():
112
+ self._config_path = json_path
113
+ else:
114
+ # Default to YAML for new projects
115
+ self._config_path = yaml_path if YAML_AVAILABLE else json_path
116
+
117
+ # Load configuration
118
+ self._load_config()
119
+
120
+ def _load_config(self) -> None:
121
+ """
122
+ Load configuration from file with caching.
123
+
124
+ Implements cache invalidation based on file modification time.
125
+ Falls back to default configuration if file doesn't exist.
126
+ Supports both YAML (preferred) and JSON (legacy) formats.
127
+ """
128
+ try:
129
+ # Check if file exists
130
+ if not self._config_path.exists():
131
+ logger.warning(f"Config file not found: {self._config_path}")
132
+ self._config = self._get_default_config()
133
+ return
134
+
135
+ # Check cache validity
136
+ current_mtime = self._config_path.stat().st_mtime
137
+ if self._last_modified and current_mtime == self._last_modified:
138
+ # Cache is still valid
139
+ return
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}")
154
+
155
+ except (
156
+ json.JSONDecodeError,
157
+ yaml.YAMLError if YAML_AVAILABLE else Exception,
158
+ OSError,
159
+ UnicodeDecodeError,
160
+ ) as e:
161
+ logger.error(f"Failed to load config: {e}")
162
+ self._config = self._get_default_config()
163
+
164
+ def get(self, key: str, default: Any = None) -> Any:
165
+ """
166
+ Get configuration value with dot-notation support.
167
+
168
+ Args:
169
+ key: Configuration key (supports dot notation, e.g., "hooks.timeout_ms")
170
+ default: Default value if key not found
171
+
172
+ Returns:
173
+ Configuration value or default
174
+
175
+ Examples:
176
+ >>> config.get("hooks.timeout_ms", 2000)
177
+ 2000
178
+ >>> config.get("project.name")
179
+ "MoAI-ADK"
180
+ """
181
+ # Reload if file changed
182
+ self._reload_if_modified()
183
+
184
+ # Navigate nested dict with dot notation
185
+ keys = key.split(".")
186
+ value = self._config
187
+
188
+ for k in keys:
189
+ if isinstance(value, dict):
190
+ value = value.get(k)
191
+ if value is None:
192
+ return default
193
+ else:
194
+ return default
195
+
196
+ return value if value is not None else default
197
+
198
+ def set(self, key: str, value: Any) -> None:
199
+ """
200
+ Set configuration value with dot-notation support.
201
+
202
+ Args:
203
+ key: Configuration key (supports dot notation)
204
+ value: Value to set
205
+
206
+ Examples:
207
+ >>> config.set("hooks.timeout_ms", 3000)
208
+ >>> config.set("project.name", "MyProject")
209
+ """
210
+ # Navigate to parent dict
211
+ keys = key.split(".")
212
+ target = self._config
213
+
214
+ for k in keys[:-1]:
215
+ if k not in target:
216
+ target[k] = {}
217
+ target = target[k]
218
+
219
+ # Set value
220
+ target[keys[-1]] = value
221
+
222
+ def update(self, updates: Dict[str, Any], deep_merge: bool = True) -> None:
223
+ """
224
+ Update configuration with dictionary.
225
+
226
+ Args:
227
+ updates: Dictionary of updates
228
+ deep_merge: If True, recursively merge nested dicts (default: True)
229
+
230
+ Examples:
231
+ >>> config.update({"hooks": {"timeout_ms": 3000}})
232
+ >>> config.update({"project.name": "MyProject"}, deep_merge=False)
233
+ """
234
+ if deep_merge:
235
+ self._config = self._deep_merge(self._config, updates)
236
+ else:
237
+ self._config.update(updates)
238
+
239
+ def save(self, backup: bool = True) -> bool:
240
+ """
241
+ Save configuration to file with atomic write.
242
+
243
+ Args:
244
+ backup: If True, create backup before saving (default: True)
245
+
246
+ Returns:
247
+ bool: True if save successful, False otherwise
248
+
249
+ Pattern: Temp file → Atomic rename (prevents corruption)
250
+ """
251
+ try:
252
+ # Create backup if requested
253
+ if backup and self._config_path.exists():
254
+ self._create_backup()
255
+
256
+ # Atomic write pattern: temp file → rename
257
+ temp_path = self._config_path.with_suffix(".tmp")
258
+
259
+ # Write to temp file (auto-detect format)
260
+ with open(temp_path, "w", encoding="utf-8") as f:
261
+ if self._config_path.suffix == ".yaml" or self._config_path.suffix == ".yml":
262
+ if not YAML_AVAILABLE:
263
+ raise ImportError("PyYAML is required for YAML config files. Install with: pip install pyyaml")
264
+ yaml.safe_dump(
265
+ self._config,
266
+ f,
267
+ default_flow_style=False,
268
+ allow_unicode=True,
269
+ sort_keys=False,
270
+ )
271
+ else:
272
+ json.dump(self._config, f, indent=2, ensure_ascii=False)
273
+
274
+ # Atomic rename
275
+ temp_path.replace(self._config_path)
276
+
277
+ # Update cache timestamp
278
+ self._last_modified = self._config_path.stat().st_mtime
279
+
280
+ logger.info(f"Saved config to {self._config_path}")
281
+ return True
282
+
283
+ except (OSError, PermissionError) as e:
284
+ logger.error(f"Failed to save config: {e}")
285
+ return False
286
+
287
+ def _create_backup(self) -> None:
288
+ """Create timestamped backup of config file."""
289
+ try:
290
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
291
+ backup_dir = self._config_path.parent / "backups"
292
+ backup_dir.mkdir(parents=True, exist_ok=True)
293
+
294
+ backup_path = backup_dir / f"config_backup_{timestamp}.json"
295
+ shutil.copy2(self._config_path, backup_path)
296
+
297
+ logger.debug(f"Created backup: {backup_path}")
298
+
299
+ except (OSError, PermissionError) as e:
300
+ logger.warning(f"Failed to create backup: {e}")
301
+
302
+ def _reload_if_modified(self) -> None:
303
+ """Reload config if file has been modified."""
304
+ try:
305
+ if self._config_path.exists():
306
+ current_mtime = self._config_path.stat().st_mtime
307
+ if self._last_modified is None or current_mtime != self._last_modified:
308
+ self._load_config()
309
+ except OSError:
310
+ pass
311
+
312
+ @staticmethod
313
+ def _deep_merge(base: Dict[str, Any], updates: Dict[str, Any]) -> Dict[str, Any]:
314
+ """
315
+ Recursively merge two dictionaries.
316
+
317
+ Args:
318
+ base: Base dictionary
319
+ updates: Updates to merge
320
+
321
+ Returns:
322
+ Merged dictionary
323
+ """
324
+ result = base.copy()
325
+
326
+ for key, value in updates.items():
327
+ if key in result and isinstance(result[key], dict) and isinstance(value, dict):
328
+ result[key] = UnifiedConfigManager._deep_merge(result[key], value)
329
+ else:
330
+ result[key] = value
331
+
332
+ return result
333
+
334
+ @staticmethod
335
+ def _get_default_config() -> Dict[str, Any]:
336
+ """
337
+ Get default configuration when file doesn't exist.
338
+
339
+ Returns:
340
+ Default configuration dictionary
341
+ """
342
+ return {
343
+ "moai": {"version": "0.28.0", "update_check_frequency": "daily"},
344
+ "project": {"name": "MyProject", "initialized": False},
345
+ "hooks": {"timeout_ms": 2000, "graceful_degradation": True},
346
+ "session": {"suppress_setup_messages": False},
347
+ "language": {"conversation_language": "en", "agent_prompt_language": "en"},
348
+ }
349
+
350
+ def get_all(self) -> Dict[str, Any]:
351
+ """
352
+ Get entire configuration dictionary.
353
+
354
+ Returns:
355
+ Complete configuration dictionary
356
+ """
357
+ self._reload_if_modified()
358
+ return self._config.copy()
359
+
360
+ def reset_to_defaults(self) -> None:
361
+ """Reset configuration to defaults without saving."""
362
+ self._config = self._get_default_config()
363
+
364
+
365
+ # Module-level singleton instance
366
+ _unified_config_instance: Optional[UnifiedConfigManager] = None
367
+
368
+
369
+ def get_unified_config(
370
+ config_path: Optional[Union[str, Path]] = None,
371
+ ) -> UnifiedConfigManager:
372
+ """
373
+ Get or create unified configuration manager instance.
374
+
375
+ Args:
376
+ config_path: Optional path to config file
377
+
378
+ Returns:
379
+ UnifiedConfigManager: Singleton instance
380
+
381
+ Examples:
382
+ >>> config = get_unified_config()
383
+ >>> timeout = config.get("hooks.timeout_ms", 2000)
384
+ """
385
+ global _unified_config_instance
386
+
387
+ if _unified_config_instance is None:
388
+ _unified_config_instance = UnifiedConfigManager(config_path)
389
+
390
+ return _unified_config_instance
391
+
392
+
393
+ # Convenience functions for common operations
394
+ @lru_cache(maxsize=1)
395
+ def get_config_path() -> Path:
396
+ """Get path to configuration file."""
397
+ return Path.cwd() / ".moai" / "config" / "config.json"
398
+
399
+
400
+ def get_config_value(key: str, default: Any = None) -> Any:
401
+ """
402
+ Get configuration value (convenience function).
403
+
404
+ Args:
405
+ key: Configuration key with dot notation
406
+ default: Default value if key not found
407
+
408
+ Returns:
409
+ Configuration value or default
410
+ """
411
+ return get_unified_config().get(key, default)
412
+
413
+
414
+ def set_config_value(key: str, value: Any) -> None:
415
+ """
416
+ Set configuration value (convenience function).
417
+
418
+ Args:
419
+ key: Configuration key with dot notation
420
+ value: Value to set
421
+ """
422
+ config = get_unified_config()
423
+ config.set(key, value)
424
+
425
+
426
+ def save_config(backup: bool = True) -> bool:
427
+ """
428
+ Save configuration (convenience function).
429
+
430
+ Args:
431
+ backup: Create backup before saving
432
+
433
+ Returns:
434
+ bool: True if successful
435
+ """
436
+ return get_unified_config().save(backup)
@@ -37,9 +37,7 @@ def _is_path_within_root(abs_path: str, project_root: str) -> bool:
37
37
  real_abs_path = os.path.realpath(abs_path)
38
38
  real_project_root = os.path.realpath(project_root)
39
39
 
40
- return real_abs_path == real_project_root or real_abs_path.startswith(
41
- real_project_root + os.sep
42
- )
40
+ return real_abs_path == real_project_root or real_abs_path.startswith(real_project_root + os.sep)
43
41
  except OSError:
44
42
  return False
45
43
 
@@ -129,13 +127,11 @@ def save_phase_result(data: Dict[str, Any], target_path: str) -> None:
129
127
 
130
128
  try:
131
129
  # Create temp file in target directory for atomic rename
132
- temp_fd, temp_path = tempfile.mkstemp(
133
- dir=target_dir, prefix=".tmp_phase_", suffix=".json"
134
- )
130
+ temp_fd, temp_path = tempfile.mkstemp(dir=target_dir, prefix=".tmp_phase_", suffix=".json")
135
131
 
136
132
  # Write JSON to temp file
137
- with os.fdopen(temp_fd, "w") as f:
138
- json.dump(data, f, indent=2)
133
+ with os.fdopen(temp_fd, "w", encoding="utf-8") as f:
134
+ json.dump(data, f, indent=2, ensure_ascii=False)
139
135
 
140
136
  temp_fd = None # File handle is now closed
141
137
 
@@ -164,7 +160,7 @@ def load_phase_result(source_path: str) -> Dict[str, Any]:
164
160
  if not os.path.exists(source_path):
165
161
  raise FileNotFoundError(f"Phase result file not found: {source_path}")
166
162
 
167
- with open(source_path, "r") as f:
163
+ with open(source_path, "r", encoding="utf-8") as f:
168
164
  data = json.load(f)
169
165
 
170
166
  return data
@@ -261,9 +257,7 @@ class ContextManager:
261
257
  Phase result dictionary or None if no phase files exist
262
258
  """
263
259
  # List all phase files
264
- phase_files = sorted(
265
- [f for f in os.listdir(self.state_dir) if f.endswith(".json")]
266
- )
260
+ phase_files = sorted([f for f in os.listdir(self.state_dir) if f.endswith(".json")])
267
261
 
268
262
  if not phase_files:
269
263
  return None