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
@@ -0,0 +1,470 @@
1
+ """Selective Restorer for MoAI-ADK Custom Elements
2
+
3
+ This module provides functionality to restore selected custom elements from backup
4
+ during MoAI-ADK updates. It handles safe file restoration with conflict detection
5
+ and detailed reporting of restoration results.
6
+
7
+ Key Features:
8
+ - Preserves unselected elements (fixes disappearing issue)
9
+ - Only overwrites/creates selected elements from backup
10
+ - Never deletes existing files that aren't being restored
11
+ - Maintains all other custom elements intact
12
+ - Safe restoration with rollback capabilities
13
+
14
+ The restorer works with the existing MoAI-ADK backup system and ensures that
15
+ only explicitly selected elements are modified, preserving all other files.
16
+ """
17
+
18
+ import logging
19
+ import shutil
20
+ from pathlib import Path
21
+ from typing import Any, Dict, List, Optional, Tuple
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class SelectiveRestorer:
27
+ """Restores selected custom elements from backup.
28
+
29
+ This class handles the actual file restoration process, copying selected elements
30
+ from backup to their original locations with proper conflict handling and reporting.
31
+ """
32
+
33
+ def __init__(self, project_path: Path, backup_path: Optional[Path] = None):
34
+ """Initialize the selective restorer.
35
+
36
+ Args:
37
+ project_path: Path to the MoAI-ADK project directory
38
+ backup_path: Path to the backup directory (auto-detected if not provided)
39
+ """
40
+ self.project_path = project_path
41
+ self.backup_path = backup_path or self._find_latest_backup()
42
+ self.restoration_log: List[Dict[str, str]] = []
43
+
44
+ def _find_latest_backup(self) -> Optional[Path]:
45
+ """Find the latest backup directory.
46
+
47
+ Returns:
48
+ Path to the latest backup directory, or None if no backup found
49
+ """
50
+ # Look for .moai-backups directory
51
+ backups_dir = self.project_path / ".moai-backups"
52
+ if not backups_dir.exists():
53
+ return None
54
+
55
+ # Find all backup directories and sort by modification time
56
+ backup_dirs = []
57
+ for item in backups_dir.iterdir():
58
+ if item.is_dir() and item.name.startswith("pre-update-backup_"):
59
+ backup_dirs.append((item.stat().st_mtime, item))
60
+
61
+ if not backup_dirs:
62
+ return None
63
+
64
+ # Return the most recent backup
65
+ backup_dirs.sort(reverse=True)
66
+ return backup_dirs[0][1] # Return the Path object
67
+
68
+ def restore_elements(self, selected_elements: List[str]) -> Tuple[bool, Dict[str, Any]]:
69
+ """Restore selected custom elements from backup.
70
+
71
+ Args:
72
+ selected_elements: List of element paths to restore
73
+
74
+ Returns:
75
+ Tuple of (success_status, restoration_stats)
76
+
77
+ Example:
78
+ >>> restorer = SelectiveRestorer("/project")
79
+ >>> success, stats = restorer.restore_elements([
80
+ ... ".claude/agents/my-agent.md",
81
+ ... ".claude/skills/my-skill/"
82
+ ... ])
83
+ >>> print(f"Restoration {'success' if success else 'failed'}: {stats}")
84
+ """
85
+ if not selected_elements:
86
+ logger.info("No elements selected for restoration.")
87
+ return True, {"total": 0, "success": 0, "failed": 0}
88
+
89
+ print(f"\nšŸš€ Restoring {len(selected_elements)} selected elements...")
90
+ print("-" * 50)
91
+
92
+ # Group elements by type for organized restoration
93
+ element_groups = self._group_elements_by_type(selected_elements)
94
+
95
+ # Track restoration statistics
96
+ stats: Dict[str, Any] = {"total": 0, "success": 0, "failed": 0, "by_type": {}}
97
+
98
+ # Restore each type of element
99
+ for element_type, elements in element_groups.items():
100
+ print(f"\nšŸ“‚ Restoring {element_type}s...")
101
+ type_stats = self._restore_element_type(element_type, elements)
102
+ by_type: Dict[str, Dict[str, int]] = stats["by_type"]
103
+ by_type[element_type] = type_stats
104
+ total_count: int = stats["total"]
105
+ success_count: int = stats["success"]
106
+ failed_count: int = stats["failed"]
107
+ stats["total"] = total_count + type_stats["total"]
108
+ stats["success"] = success_count + type_stats["success"]
109
+ stats["failed"] = failed_count + type_stats["failed"]
110
+
111
+ # Display final summary
112
+ self._display_restoration_summary(stats)
113
+
114
+ # Log restoration details
115
+ self._log_restoration_details(selected_elements, stats)
116
+
117
+ is_success: bool = stats["failed"] == 0
118
+ if is_success:
119
+ logger.info(f"Successfully restored {stats['success']} elements")
120
+ else:
121
+ logger.warning(f"Failed to restore {stats['failed']} elements")
122
+
123
+ return is_success, stats
124
+
125
+ def _group_elements_by_type(self, selected_elements: List[str]) -> Dict[str, List[Path]]:
126
+ """Group selected elements by their type.
127
+
128
+ Args:
129
+ selected_elements: List of element paths
130
+
131
+ Returns:
132
+ Dictionary with element types as keys and lists of element paths as values
133
+ """
134
+ groups: Dict[str, List[Path]] = {
135
+ "agents": [],
136
+ "commands": [],
137
+ "skills": [],
138
+ "hooks": [],
139
+ "unknown": [],
140
+ }
141
+
142
+ for element_path in selected_elements:
143
+ path = Path(element_path)
144
+ parts = path.parts
145
+
146
+ if "agents" in parts:
147
+ groups["agents"].append(path)
148
+ elif "commands" in parts and "moai" in parts:
149
+ groups["commands"].append(path)
150
+ elif "commands" in parts:
151
+ groups["commands"].append(path)
152
+ elif "skills" in parts:
153
+ groups["skills"].append(path)
154
+ elif "hooks" in parts and "moai" in parts:
155
+ groups["hooks"].append(path)
156
+ elif "hooks" in parts:
157
+ groups["hooks"].append(path)
158
+ else:
159
+ logger.warning(f"Unknown element type for: {element_path}")
160
+ groups["unknown"].append(path)
161
+
162
+ return groups
163
+
164
+ def _restore_element_type(self, element_type: str, elements: List[Path]) -> Dict[str, int]:
165
+ """Restore elements of a specific type.
166
+
167
+ Args:
168
+ element_type: Type of elements to restore
169
+ elements: List of element paths to restore
170
+
171
+ Returns:
172
+ Statistics for this restoration type
173
+ """
174
+ stats = {"total": len(elements), "success": 0, "failed": 0}
175
+
176
+ for element_path in elements:
177
+ try:
178
+ success = self._restore_single_element(element_path, element_type)
179
+ if success:
180
+ stats["success"] += 1
181
+ print(f" āœ“ {element_path.name}")
182
+ else:
183
+ stats["failed"] += 1
184
+ print(f" āœ— Failed: {element_path.name}")
185
+ except Exception as e:
186
+ stats["failed"] += 1
187
+ print(f" āœ— Error: {element_path.name} - {e}")
188
+ logger.error(f"Error restoring {element_path}: {e}")
189
+
190
+ return stats
191
+
192
+ def _normalize_element_path(self, element_path: Path) -> Optional[Path]:
193
+ """Normalize element path to be relative to project structure.
194
+
195
+ Handles both absolute and relative paths correctly:
196
+ - Absolute paths: extracts the relevant portion (.claude/ or .moai/)
197
+ - Relative paths: validates and returns as-is
198
+
199
+ Args:
200
+ element_path: Path to normalize (can be absolute or relative)
201
+
202
+ Returns:
203
+ Normalized relative path, or None if normalization fails
204
+ """
205
+ element_str = str(element_path)
206
+
207
+ # Handle absolute paths
208
+ if element_path.is_absolute():
209
+ # Extract .claude/ or .moai/ portion from absolute paths
210
+ for safe_prefix in [".claude/", ".moai/"]:
211
+ if safe_prefix in element_str:
212
+ try:
213
+ # Split on the safe prefix and take the portion after it
214
+ _, relative_part = element_str.split(safe_prefix, 1)
215
+ # Reconstruct the relative path
216
+ normalized_path = Path(safe_prefix.rstrip("/")) / relative_part
217
+ logger.debug(f"Normalized absolute path {element_path} -> {normalized_path}")
218
+ return normalized_path
219
+ except (ValueError, IndexError):
220
+ logger.warning(f"Failed to extract relative path from {element_path}")
221
+ continue
222
+
223
+ # If no safe prefix found in absolute path, this is suspicious
224
+ logger.error(f"Absolute path {element_path} doesn't contain .claude/ or .moai/ prefixes")
225
+ return None
226
+
227
+ # Handle relative paths
228
+ else:
229
+ # Ensure relative path starts with .claude or .moai
230
+ if not (element_str.startswith(".claude/") or element_str.startswith(".moai/")):
231
+ logger.error(f"Relative path {element_path} must start with .claude/ or .moai/")
232
+ return None
233
+
234
+ logger.debug(f"Relative path already normalized: {element_path}")
235
+ return element_path
236
+
237
+ def _validate_element_path(self, relative_path: Path) -> bool:
238
+ """Validate an element path for security and correctness.
239
+
240
+ Args:
241
+ relative_path: Relative path to validate
242
+
243
+ Returns:
244
+ True if path is valid and safe, False otherwise
245
+ """
246
+ path_str = str(relative_path)
247
+
248
+ # Security check: prevent path traversal attacks
249
+ if ".." in path_str:
250
+ logger.error(f"Path traversal attempt detected in: {path_str}")
251
+ return False
252
+
253
+ # Ensure path starts with allowed prefixes
254
+ allowed_prefixes = [".claude/", ".moai/"]
255
+ if not any(path_str.startswith(prefix) for prefix in allowed_prefixes):
256
+ logger.error(f"Path {path_str} doesn't start with allowed prefix: {allowed_prefixes}")
257
+ return False
258
+
259
+ # Additional validation: check for suspicious patterns
260
+ suspicious_patterns = ["//", "~", "$"]
261
+ for pattern in suspicious_patterns:
262
+ if pattern in path_str:
263
+ logger.warning(f"Suspicious pattern '{pattern}' found in path: {path_str}")
264
+
265
+ return True
266
+
267
+ def _restore_single_element(self, element_path: Path, element_type: str) -> bool:
268
+ """Restore a single element from backup.
269
+
270
+ Args:
271
+ element_path: Path to restore the element to (can be absolute or relative)
272
+ element_type: Type of element (for target directory creation)
273
+
274
+ Returns:
275
+ True if restoration succeeded, False otherwise
276
+ """
277
+ # Normalize element path to get relative path within project structure
278
+ relative_path = self._normalize_element_path(element_path)
279
+ if relative_path is None:
280
+ logger.error(f"Failed to normalize element path: {element_path}")
281
+ return False
282
+
283
+ # Validate the normalized path for security
284
+ if not self._validate_element_path(relative_path):
285
+ logger.error(f"Invalid element path: {relative_path}")
286
+ return False
287
+
288
+ # Create absolute target path
289
+ target_path = self.project_path / relative_path
290
+ backup_source = self.backup_path / relative_path
291
+
292
+ # Ensure backup source exists
293
+ if not backup_source.exists():
294
+ logger.warning(f"Backup not found for: {relative_path}")
295
+ return False
296
+
297
+ # Create target directory if needed
298
+ target_dir = target_path.parent
299
+ target_dir.mkdir(parents=True, exist_ok=True)
300
+
301
+ # Handle conflicts
302
+ if target_path.exists():
303
+ if not self._handle_file_conflict(target_path, backup_source):
304
+ logger.warning(f"Conflict handling failed for: {relative_path}")
305
+ return False
306
+
307
+ # Perform the restoration
308
+ try:
309
+ if backup_source.is_dir():
310
+ # For directories (skills)
311
+ shutil.copytree(backup_source, target_path, dirs_exist_ok=True)
312
+ else:
313
+ # For files
314
+ shutil.copy2(backup_source, target_path)
315
+
316
+ # Record successful restoration
317
+ self.restoration_log.append(
318
+ {
319
+ "path": str(element_path),
320
+ "type": element_type,
321
+ "status": "success",
322
+ "timestamp": str(backup_source.stat().st_mtime),
323
+ }
324
+ )
325
+
326
+ logger.info(f"Restored: {relative_path}")
327
+ return True
328
+
329
+ except Exception as e:
330
+ logger.error(f"Failed to restore {relative_path}: {e}")
331
+ return False
332
+
333
+ def _handle_file_conflict(self, target_path: Path, backup_source: Path) -> bool:
334
+ """Handle file or directory conflict during restoration.
335
+
336
+ Args:
337
+ target_path: Path to target file/directory (existing)
338
+ backup_source: Path to backup source file/directory
339
+
340
+ Returns:
341
+ True if conflict handled successfully, False otherwise
342
+ """
343
+ try:
344
+ # Handle directory conflicts (skills are directories)
345
+ if target_path.is_dir() and backup_source.is_dir():
346
+ # Directories - backup target directory and return True
347
+ backup_target = target_path.parent / f"{target_path.name}.backup_dir"
348
+ try:
349
+ if backup_target.exists():
350
+ shutil.rmtree(backup_target)
351
+ shutil.copytree(target_path, backup_target, dirs_exist_ok=True)
352
+ logger.debug(f"Backed up directory: {target_path} -> {backup_target}")
353
+ return True
354
+ except Exception as e:
355
+ logger.error(f"Failed to backup directory {target_path}: {e}")
356
+ return False
357
+
358
+ # Handle file conflicts
359
+ if not target_path.is_file() or not backup_source.is_file():
360
+ # Mixed types or non-existent, skip comparison
361
+ logger.debug(f"Skipping conflict check for non-file: {target_path}")
362
+ return True
363
+
364
+ # Compare file contents
365
+ target_content = target_path.read_text(encoding="utf-8", errors="ignore")
366
+ backup_content = backup_source.read_text(encoding="utf-8", errors="ignore")
367
+
368
+ if target_content == backup_content:
369
+ # Files are identical, no conflict
370
+ logger.debug(f"No conflict detected for: {target_path}")
371
+ return True
372
+
373
+ # Files differ, prompt for action
374
+ print(f"\nāš ļø Conflict detected for: {target_path.name}")
375
+ print(" Target file exists and differs from backup")
376
+
377
+ # For now, we'll backup the target and restore the backup
378
+ backup_target = target_path.with_suffix(".backup")
379
+ try:
380
+ shutil.copy2(target_path, backup_target)
381
+ print(f" Backed up to: {backup_target.name}")
382
+ logger.info(f"Backed up conflicting file: {backup_target}")
383
+ return True
384
+ except Exception as e:
385
+ logger.error(f"Failed to backup conflicting file {target_path}: {e}")
386
+ return False
387
+
388
+ except Exception as e:
389
+ logger.error(f"Error handling file conflict for {target_path}: {e}")
390
+ return False
391
+
392
+ def _display_restoration_summary(self, stats: Dict[str, int]) -> None:
393
+ """Display summary of restoration results.
394
+
395
+ Args:
396
+ stats: Restoration statistics dictionary
397
+ """
398
+ print("\n" + "=" * 50)
399
+ print("šŸŽ‰ Restoration Complete")
400
+ print("=" * 50)
401
+ print(f"Total elements: {stats['total']}")
402
+ print(f"āœ… Successfully restored: {stats['success']}")
403
+
404
+ if stats["failed"] > 0:
405
+ print(f"āŒ Failed to restore: {stats['failed']}")
406
+
407
+ # Show breakdown by type
408
+ if "by_type" in stats:
409
+ print("\nšŸ“Š By Type:")
410
+ by_type_stats: Dict[str, Dict[str, int]] = stats["by_type"] # type: ignore[assignment]
411
+ for element_type, type_stats in by_type_stats.items():
412
+ if type_stats["total"] > 0:
413
+ status_icon = "āœ…" if type_stats["failed"] == 0 else "āŒ"
414
+ print(f" {element_type.title()}: {type_stats['success']}/{type_stats['total']} {status_icon}")
415
+
416
+ def _log_restoration_details(self, selected_elements: List[str], stats: Dict[str, int]) -> None:
417
+ """Log detailed restoration information for debugging.
418
+
419
+ Args:
420
+ selected_elements: List of elements that were selected for restoration
421
+ stats: Restoration statistics
422
+ """
423
+ logger.info(
424
+ f"Restoration completed - Total: {stats['total']}, Success: {stats['success']}, Failed: {stats['failed']}"
425
+ )
426
+
427
+ if stats["failed"] > 0:
428
+ failed_elements = [elem for elem in selected_elements if not self._was_restoration_successful(Path(elem))]
429
+ logger.warning(f"Failed elements: {failed_elements}")
430
+
431
+ # Log all restoration attempts from the log
432
+ for entry in self.restoration_log:
433
+ if entry["status"] == "success":
434
+ logger.debug(f"āœ“ Restored: {entry['path']} ({entry['type']})")
435
+ else:
436
+ logger.warning(f"āœ— Failed: {entry['path']} ({entry['type']})")
437
+
438
+ def _was_restoration_successful(self, element_path: Path) -> bool:
439
+ """Check if an element was successfully restored.
440
+
441
+ Args:
442
+ element_path: Path to check
443
+
444
+ Returns:
445
+ True if element was restored successfully
446
+ """
447
+ for entry in self.restoration_log:
448
+ if str(Path(entry["path"])) == str(element_path) and entry["status"] == "success":
449
+ return True
450
+ return False
451
+
452
+
453
+ def create_selective_restorer(project_path: str | Path, backup_path: Optional[Path] = None) -> SelectiveRestorer:
454
+ """Factory function to create a SelectiveRestorer.
455
+
456
+ Args:
457
+ project_path: Path to the MoAI-ADK project directory
458
+ backup_path: Path to backup directory (auto-detected if not provided)
459
+
460
+ Returns:
461
+ Configured SelectiveRestorer instance
462
+
463
+ Example:
464
+ >>> restorer = create_selective_restorer("/path/to/project")
465
+ >>> success, stats = restorer.restore_elements([
466
+ ... ".claude/agents/my-agent.md"
467
+ ... ])
468
+ >>> print(f"Restoration result: {'success' if success else 'failed'}")
469
+ """
470
+ return SelectiveRestorer(Path(project_path).resolve(), backup_path)
@@ -0,0 +1,74 @@
1
+ """Template utilities for MoAI-ADK migration system.
2
+
3
+ This module provides utility functions for working with MoAI-ADK templates,
4
+ including functions to get template element names for comparison with user-created elements.
5
+ """
6
+
7
+ from pathlib import Path
8
+ from typing import Set
9
+
10
+
11
+ def _get_template_skill_names() -> Set[str]:
12
+ """Get skill names from the fresh installation template.
13
+
14
+ Returns:
15
+ Set of skill directory names found in the template
16
+ """
17
+ template_path = Path(__file__).parent.parent.parent / "templates" / ".claude" / "skills"
18
+ skill_names = set()
19
+
20
+ if template_path.exists():
21
+ for skill_dir in template_path.iterdir():
22
+ if skill_dir.is_dir() and skill_dir.name.startswith("moai-"):
23
+ skill_names.add(skill_dir.name)
24
+
25
+ return skill_names
26
+
27
+
28
+ def _get_template_command_names() -> Set[str]:
29
+ """Get command names from the fresh installation template.
30
+
31
+ Returns:
32
+ Set of command file names found in the template
33
+ """
34
+ template_path = Path(__file__).parent.parent.parent / "templates" / ".claude" / "commands" / "moai"
35
+ command_names = set()
36
+
37
+ if template_path.exists():
38
+ for cmd_file in template_path.glob("*.md"):
39
+ command_names.add(cmd_file.name)
40
+
41
+ return command_names
42
+
43
+
44
+ def _get_template_agent_names() -> Set[str]:
45
+ """Get agent names from the fresh installation template.
46
+
47
+ Returns:
48
+ Set of agent file names found in the template
49
+ """
50
+ template_path = Path(__file__).parent.parent.parent / "templates" / ".claude" / "agents"
51
+ agent_names = set()
52
+
53
+ if template_path.exists():
54
+ for agent_file in template_path.rglob("*.md"):
55
+ if agent_file.parent.name == "moai":
56
+ agent_names.add(agent_file.name)
57
+
58
+ return agent_names
59
+
60
+
61
+ def _get_template_hook_names() -> Set[str]:
62
+ """Get hook names from the fresh installation template.
63
+
64
+ Returns:
65
+ Set of hook file names found in the template
66
+ """
67
+ template_path = Path(__file__).parent.parent.parent / "templates" / ".claude" / "hooks" / "moai"
68
+ hook_names = set()
69
+
70
+ if template_path.exists():
71
+ for hook_file in template_path.rglob("*.py"):
72
+ hook_names.add(hook_file.name)
73
+
74
+ return hook_names