moai-adk 0.35.1__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 (502) hide show
  1. moai_adk/__init__.py +10 -0
  2. moai_adk/__main__.py +199 -0
  3. moai_adk/cli/__init__.py +6 -0
  4. moai_adk/cli/commands/__init__.py +17 -0
  5. moai_adk/cli/commands/analyze.py +116 -0
  6. moai_adk/cli/commands/doctor.py +272 -0
  7. moai_adk/cli/commands/init.py +372 -0
  8. moai_adk/cli/commands/language.py +248 -0
  9. moai_adk/cli/commands/status.py +104 -0
  10. moai_adk/cli/commands/update.py +2686 -0
  11. moai_adk/cli/main.py +13 -0
  12. moai_adk/cli/prompts/__init__.py +5 -0
  13. moai_adk/cli/prompts/init_prompts.py +219 -0
  14. moai_adk/cli/spec_status.py +263 -0
  15. moai_adk/cli/ui/__init__.py +44 -0
  16. moai_adk/cli/ui/progress.py +422 -0
  17. moai_adk/cli/ui/prompts.py +389 -0
  18. moai_adk/cli/ui/theme.py +129 -0
  19. moai_adk/cli/worktree/__init__.py +27 -0
  20. moai_adk/cli/worktree/__main__.py +31 -0
  21. moai_adk/cli/worktree/cli.py +683 -0
  22. moai_adk/cli/worktree/exceptions.py +89 -0
  23. moai_adk/cli/worktree/manager.py +493 -0
  24. moai_adk/cli/worktree/models.py +65 -0
  25. moai_adk/cli/worktree/registry.py +422 -0
  26. moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
  27. moai_adk/core/__init__.py +1 -0
  28. moai_adk/core/analysis/__init__.py +9 -0
  29. moai_adk/core/analysis/session_analyzer.py +400 -0
  30. moai_adk/core/claude_integration.py +393 -0
  31. moai_adk/core/command_helpers.py +270 -0
  32. moai_adk/core/comprehensive_monitoring_system.py +1183 -0
  33. moai_adk/core/config/__init__.py +19 -0
  34. moai_adk/core/config/auto_spec_config.py +340 -0
  35. moai_adk/core/config/migration.py +244 -0
  36. moai_adk/core/config/unified.py +436 -0
  37. moai_adk/core/context_manager.py +273 -0
  38. moai_adk/core/diagnostics/__init__.py +19 -0
  39. moai_adk/core/diagnostics/slash_commands.py +159 -0
  40. moai_adk/core/enterprise_features.py +1404 -0
  41. moai_adk/core/error_recovery_system.py +1902 -0
  42. moai_adk/core/event_driven_hook_system.py +1371 -0
  43. moai_adk/core/git/__init__.py +31 -0
  44. moai_adk/core/git/branch.py +25 -0
  45. moai_adk/core/git/branch_manager.py +129 -0
  46. moai_adk/core/git/checkpoint.py +134 -0
  47. moai_adk/core/git/commit.py +67 -0
  48. moai_adk/core/git/conflict_detector.py +413 -0
  49. moai_adk/core/git/event_detector.py +79 -0
  50. moai_adk/core/git/manager.py +216 -0
  51. moai_adk/core/hooks/post_tool_auto_spec_completion.py +901 -0
  52. moai_adk/core/input_validation_middleware.py +1006 -0
  53. moai_adk/core/integration/__init__.py +22 -0
  54. moai_adk/core/integration/engine.py +157 -0
  55. moai_adk/core/integration/integration_tester.py +226 -0
  56. moai_adk/core/integration/models.py +88 -0
  57. moai_adk/core/integration/utils.py +211 -0
  58. moai_adk/core/issue_creator.py +305 -0
  59. moai_adk/core/jit_context_loader.py +956 -0
  60. moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
  61. moai_adk/core/language_config.py +202 -0
  62. moai_adk/core/language_config_resolver.py +572 -0
  63. moai_adk/core/language_validator.py +543 -0
  64. moai_adk/core/mcp/setup.py +116 -0
  65. moai_adk/core/merge/__init__.py +9 -0
  66. moai_adk/core/merge/analyzer.py +605 -0
  67. moai_adk/core/migration/__init__.py +18 -0
  68. moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
  69. moai_adk/core/migration/backup_manager.py +277 -0
  70. moai_adk/core/migration/custom_element_scanner.py +358 -0
  71. moai_adk/core/migration/file_migrator.py +209 -0
  72. moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
  73. moai_adk/core/migration/selective_restorer.py +470 -0
  74. moai_adk/core/migration/template_utils.py +74 -0
  75. moai_adk/core/migration/user_selection_ui.py +338 -0
  76. moai_adk/core/migration/version_detector.py +139 -0
  77. moai_adk/core/migration/version_migrator.py +228 -0
  78. moai_adk/core/performance/__init__.py +6 -0
  79. moai_adk/core/performance/cache_system.py +316 -0
  80. moai_adk/core/performance/parallel_processor.py +116 -0
  81. moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
  82. moai_adk/core/project/__init__.py +1 -0
  83. moai_adk/core/project/backup_utils.py +70 -0
  84. moai_adk/core/project/checker.py +300 -0
  85. moai_adk/core/project/detector.py +293 -0
  86. moai_adk/core/project/initializer.py +387 -0
  87. moai_adk/core/project/phase_executor.py +716 -0
  88. moai_adk/core/project/validator.py +139 -0
  89. moai_adk/core/quality/__init__.py +6 -0
  90. moai_adk/core/quality/trust_checker.py +377 -0
  91. moai_adk/core/quality/validators/__init__.py +6 -0
  92. moai_adk/core/quality/validators/base_validator.py +19 -0
  93. moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
  94. moai_adk/core/robust_json_parser.py +611 -0
  95. moai_adk/core/rollback_manager.py +918 -0
  96. moai_adk/core/session_manager.py +651 -0
  97. moai_adk/core/skill_loading_system.py +579 -0
  98. moai_adk/core/spec/confidence_scoring.py +680 -0
  99. moai_adk/core/spec/ears_template_engine.py +1247 -0
  100. moai_adk/core/spec/quality_validator.py +687 -0
  101. moai_adk/core/spec_status_manager.py +478 -0
  102. moai_adk/core/template/__init__.py +7 -0
  103. moai_adk/core/template/backup.py +174 -0
  104. moai_adk/core/template/config.py +191 -0
  105. moai_adk/core/template/languages.py +43 -0
  106. moai_adk/core/template/merger.py +233 -0
  107. moai_adk/core/template/processor.py +1200 -0
  108. moai_adk/core/template_engine.py +310 -0
  109. moai_adk/core/template_variable_synchronizer.py +417 -0
  110. moai_adk/core/unified_permission_manager.py +745 -0
  111. moai_adk/core/user_behavior_analytics.py +851 -0
  112. moai_adk/core/version_sync.py +429 -0
  113. moai_adk/foundation/__init__.py +56 -0
  114. moai_adk/foundation/backend.py +1027 -0
  115. moai_adk/foundation/database.py +1115 -0
  116. moai_adk/foundation/devops.py +1585 -0
  117. moai_adk/foundation/ears.py +431 -0
  118. moai_adk/foundation/frontend.py +870 -0
  119. moai_adk/foundation/git/commit_templates.py +557 -0
  120. moai_adk/foundation/git.py +376 -0
  121. moai_adk/foundation/langs.py +484 -0
  122. moai_adk/foundation/ml_ops.py +1162 -0
  123. moai_adk/foundation/testing.py +1524 -0
  124. moai_adk/foundation/trust/trust_principles.py +676 -0
  125. moai_adk/foundation/trust/validation_checklist.py +1573 -0
  126. moai_adk/project/__init__.py +0 -0
  127. moai_adk/project/configuration.py +1084 -0
  128. moai_adk/project/documentation.py +566 -0
  129. moai_adk/project/schema.py +447 -0
  130. moai_adk/statusline/__init__.py +38 -0
  131. moai_adk/statusline/alfred_detector.py +105 -0
  132. moai_adk/statusline/config.py +376 -0
  133. moai_adk/statusline/enhanced_output_style_detector.py +372 -0
  134. moai_adk/statusline/git_collector.py +190 -0
  135. moai_adk/statusline/main.py +322 -0
  136. moai_adk/statusline/metrics_tracker.py +78 -0
  137. moai_adk/statusline/renderer.py +343 -0
  138. moai_adk/statusline/update_checker.py +129 -0
  139. moai_adk/statusline/version_reader.py +741 -0
  140. moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +714 -0
  141. moai_adk/templates/.claude/agents/moai/builder-agent.md +474 -0
  142. moai_adk/templates/.claude/agents/moai/builder-command.md +1172 -0
  143. moai_adk/templates/.claude/agents/moai/builder-plugin.md +637 -0
  144. moai_adk/templates/.claude/agents/moai/builder-skill.md +666 -0
  145. moai_adk/templates/.claude/agents/moai/expert-backend.md +899 -0
  146. moai_adk/templates/.claude/agents/moai/expert-database.md +777 -0
  147. moai_adk/templates/.claude/agents/moai/expert-debug.md +401 -0
  148. moai_adk/templates/.claude/agents/moai/expert-devops.md +720 -0
  149. moai_adk/templates/.claude/agents/moai/expert-frontend.md +734 -0
  150. moai_adk/templates/.claude/agents/moai/expert-performance.md +657 -0
  151. moai_adk/templates/.claude/agents/moai/expert-security.md +513 -0
  152. moai_adk/templates/.claude/agents/moai/expert-testing.md +733 -0
  153. moai_adk/templates/.claude/agents/moai/expert-uiux.md +1041 -0
  154. moai_adk/templates/.claude/agents/moai/manager-claude-code.md +432 -0
  155. moai_adk/templates/.claude/agents/moai/manager-docs.md +573 -0
  156. moai_adk/templates/.claude/agents/moai/manager-git.md +1060 -0
  157. moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
  158. moai_adk/templates/.claude/agents/moai/manager-quality.md +624 -0
  159. moai_adk/templates/.claude/agents/moai/manager-spec.md +809 -0
  160. moai_adk/templates/.claude/agents/moai/manager-strategy.md +780 -0
  161. moai_adk/templates/.claude/agents/moai/manager-tdd.md +784 -0
  162. moai_adk/templates/.claude/agents/moai/mcp-context7.md +458 -0
  163. moai_adk/templates/.claude/agents/moai/mcp-figma.md +1607 -0
  164. moai_adk/templates/.claude/agents/moai/mcp-notion.md +789 -0
  165. moai_adk/templates/.claude/agents/moai/mcp-playwright.md +469 -0
  166. moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +1032 -0
  167. moai_adk/templates/.claude/commands/moai/0-project.md +1386 -0
  168. moai_adk/templates/.claude/commands/moai/1-plan.md +1427 -0
  169. moai_adk/templates/.claude/commands/moai/2-run.md +943 -0
  170. moai_adk/templates/.claude/commands/moai/3-sync.md +1324 -0
  171. moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
  172. moai_adk/templates/.claude/hooks/__init__.py +8 -0
  173. moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
  174. moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
  175. moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
  176. moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
  177. moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
  178. moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
  179. moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
  180. moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
  181. moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
  182. moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
  183. moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
  184. moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
  185. moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
  186. moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
  187. moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
  188. moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
  189. moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +1083 -0
  190. moai_adk/templates/.claude/output-styles/moai/r2d2.md +560 -0
  191. moai_adk/templates/.claude/output-styles/moai/yoda.md +359 -0
  192. moai_adk/templates/.claude/settings.json +172 -0
  193. moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +307 -0
  194. moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +431 -0
  195. moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/batch_generate.py +560 -0
  196. moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/generate_image.py +362 -0
  197. moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +249 -0
  198. moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +406 -0
  199. moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
  200. moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
  201. moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
  202. moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
  203. moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
  204. moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +328 -0
  205. moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +320 -0
  206. moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +718 -0
  207. moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +464 -0
  208. moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +323 -0
  209. moai_adk/templates/.claude/skills/moai-domain-database/examples.md +830 -0
  210. moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
  211. moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
  212. moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
  213. moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
  214. moai_adk/templates/.claude/skills/moai-domain-database/reference.md +545 -0
  215. moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +497 -0
  216. moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +968 -0
  217. moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +664 -0
  218. moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +455 -0
  219. moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
  220. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
  221. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
  222. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
  223. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
  224. moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
  225. moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +492 -0
  226. moai_adk/templates/.claude/skills/moai-formats-data/examples.md +804 -0
  227. moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
  228. moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
  229. moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
  230. moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
  231. moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
  232. moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
  233. moai_adk/templates/.claude/skills/moai-formats-data/reference.md +585 -0
  234. moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +202 -0
  235. moai_adk/templates/.claude/skills/moai-foundation-claude/examples.md +732 -0
  236. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
  237. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
  238. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
  239. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
  240. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
  241. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
  242. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
  243. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
  244. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
  245. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
  246. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
  247. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
  248. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
  249. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
  250. moai_adk/templates/.claude/skills/moai-foundation-claude/reference.md +209 -0
  251. moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +441 -0
  252. moai_adk/templates/.claude/skills/moai-foundation-context/examples.md +1048 -0
  253. moai_adk/templates/.claude/skills/moai-foundation-context/reference.md +246 -0
  254. moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +420 -0
  255. moai_adk/templates/.claude/skills/moai-foundation-core/examples.md +358 -0
  256. moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
  257. moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +359 -0
  258. moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
  259. moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
  260. moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
  261. moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
  262. moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
  263. moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
  264. moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
  265. moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
  266. moai_adk/templates/.claude/skills/moai-foundation-core/reference.md +478 -0
  267. moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +315 -0
  268. moai_adk/templates/.claude/skills/moai-foundation-philosopher/examples.md +228 -0
  269. moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/assumption-matrix.md +80 -0
  270. moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/cognitive-bias.md +199 -0
  271. moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/first-principles.md +140 -0
  272. moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/trade-off-analysis.md +154 -0
  273. moai_adk/templates/.claude/skills/moai-foundation-philosopher/reference.md +157 -0
  274. moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +364 -0
  275. moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
  276. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
  277. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
  278. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
  279. moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
  280. moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
  281. moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
  282. moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
  283. moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
  284. moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +649 -0
  285. moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +478 -0
  286. moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +612 -0
  287. moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +477 -0
  288. moai_adk/templates/.claude/skills/moai-lang-flutter/examples.md +1090 -0
  289. moai_adk/templates/.claude/skills/moai-lang-flutter/reference.md +686 -0
  290. moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +376 -0
  291. moai_adk/templates/.claude/skills/moai-lang-go/examples.md +919 -0
  292. moai_adk/templates/.claude/skills/moai-lang-go/reference.md +737 -0
  293. moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +385 -0
  294. moai_adk/templates/.claude/skills/moai-lang-java/examples.md +864 -0
  295. moai_adk/templates/.claude/skills/moai-lang-java/reference.md +291 -0
  296. moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +382 -0
  297. moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +1006 -0
  298. moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +562 -0
  299. moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +644 -0
  300. moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +481 -0
  301. moai_adk/templates/.claude/skills/moai-lang-python/examples.md +977 -0
  302. moai_adk/templates/.claude/skills/moai-lang-python/reference.md +804 -0
  303. moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +579 -0
  304. moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +687 -0
  305. moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +372 -0
  306. moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +659 -0
  307. moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +504 -0
  308. moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +497 -0
  309. moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +633 -0
  310. moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +423 -0
  311. moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +497 -0
  312. moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +918 -0
  313. moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +672 -0
  314. moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +368 -0
  315. moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +1089 -0
  316. moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +731 -0
  317. moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +300 -0
  318. moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
  319. moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
  320. moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
  321. moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
  322. moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +319 -0
  323. moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
  324. moai_adk/templates/.claude/skills/moai-library-nextra/examples.md +592 -0
  325. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
  326. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
  327. moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
  328. moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
  329. moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
  330. moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
  331. moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
  332. moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
  333. moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
  334. moai_adk/templates/.claude/skills/moai-library-nextra/reference.md +379 -0
  335. moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +372 -0
  336. moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
  337. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
  338. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
  339. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
  340. moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
  341. moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
  342. moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +402 -0
  343. moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +607 -0
  344. moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +300 -0
  345. moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +537 -0
  346. moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +291 -0
  347. moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +390 -0
  348. moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +398 -0
  349. moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +379 -0
  350. moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +358 -0
  351. moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +467 -0
  352. moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +377 -0
  353. moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +466 -0
  354. moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +482 -0
  355. moai_adk/templates/.claude/skills/moai-plugin-builder/SKILL.md +474 -0
  356. moai_adk/templates/.claude/skills/moai-plugin-builder/examples.md +621 -0
  357. moai_adk/templates/.claude/skills/moai-plugin-builder/migration.md +341 -0
  358. moai_adk/templates/.claude/skills/moai-plugin-builder/reference.md +463 -0
  359. moai_adk/templates/.claude/skills/moai-plugin-builder/validation.md +373 -0
  360. moai_adk/templates/.claude/skills/moai-security-auth0/SKILL.md +275 -0
  361. moai_adk/templates/.claude/skills/moai-security-auth0/modules/adaptive-mfa.md +233 -0
  362. moai_adk/templates/.claude/skills/moai-security-auth0/modules/akamai-integration.md +215 -0
  363. moai_adk/templates/.claude/skills/moai-security-auth0/modules/application-credentials.md +280 -0
  364. moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-log-events.md +225 -0
  365. moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-overview.md +140 -0
  366. moai_adk/templates/.claude/skills/moai-security-auth0/modules/bot-detection.md +144 -0
  367. moai_adk/templates/.claude/skills/moai-security-auth0/modules/breached-password-detection.md +187 -0
  368. moai_adk/templates/.claude/skills/moai-security-auth0/modules/brute-force-protection.md +189 -0
  369. moai_adk/templates/.claude/skills/moai-security-auth0/modules/certifications.md +282 -0
  370. moai_adk/templates/.claude/skills/moai-security-auth0/modules/compliance-overview.md +263 -0
  371. moai_adk/templates/.claude/skills/moai-security-auth0/modules/continuous-session-protection.md +307 -0
  372. moai_adk/templates/.claude/skills/moai-security-auth0/modules/customize-mfa.md +178 -0
  373. moai_adk/templates/.claude/skills/moai-security-auth0/modules/dpop-implementation.md +283 -0
  374. moai_adk/templates/.claude/skills/moai-security-auth0/modules/fapi-implementation.md +259 -0
  375. moai_adk/templates/.claude/skills/moai-security-auth0/modules/gdpr-compliance.md +313 -0
  376. moai_adk/templates/.claude/skills/moai-security-auth0/modules/guardian-configuration.md +269 -0
  377. moai_adk/templates/.claude/skills/moai-security-auth0/modules/highly-regulated-identity.md +272 -0
  378. moai_adk/templates/.claude/skills/moai-security-auth0/modules/jwt-fundamentals.md +248 -0
  379. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mdl-verification.md +211 -0
  380. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-api-management.md +278 -0
  381. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-factors.md +226 -0
  382. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-overview.md +174 -0
  383. moai_adk/templates/.claude/skills/moai-security-auth0/modules/mtls-sender-constraining.md +316 -0
  384. moai_adk/templates/.claude/skills/moai-security-auth0/modules/ropg-flow-mfa.md +217 -0
  385. moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-center.md +325 -0
  386. moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-guidance.md +277 -0
  387. moai_adk/templates/.claude/skills/moai-security-auth0/modules/state-parameters.md +178 -0
  388. moai_adk/templates/.claude/skills/moai-security-auth0/modules/step-up-authentication.md +251 -0
  389. moai_adk/templates/.claude/skills/moai-security-auth0/modules/suspicious-ip-throttling.md +240 -0
  390. moai_adk/templates/.claude/skills/moai-security-auth0/modules/tenant-access-control.md +180 -0
  391. moai_adk/templates/.claude/skills/moai-security-auth0/modules/webauthn-fido.md +235 -0
  392. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +449 -0
  393. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
  394. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/examples.md +544 -0
  395. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
  396. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/reference.md +307 -0
  397. moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
  398. moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +390 -0
  399. moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
  400. moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
  401. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
  402. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
  403. moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
  404. moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +175 -0
  405. moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
  406. moai_adk/templates/.claude/skills/moai-workflow-project/examples.md +547 -0
  407. moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
  408. moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
  409. moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
  410. moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
  411. moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
  412. moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
  413. moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
  414. moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
  415. moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
  416. moai_adk/templates/.claude/skills/moai-workflow-project/reference.md +275 -0
  417. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
  418. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1434 -0
  419. moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
  420. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
  421. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
  422. moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +92 -0
  423. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
  424. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
  425. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
  426. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
  427. moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
  428. moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
  429. moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +534 -0
  430. moai_adk/templates/.claude/skills/moai-workflow-spec/examples.md +900 -0
  431. moai_adk/templates/.claude/skills/moai-workflow-spec/reference.md +704 -0
  432. moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +377 -0
  433. moai_adk/templates/.claude/skills/moai-workflow-templates/examples.md +552 -0
  434. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
  435. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
  436. moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
  437. moai_adk/templates/.claude/skills/moai-workflow-templates/reference.md +346 -0
  438. moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
  439. moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +456 -0
  440. moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
  441. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
  442. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
  443. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
  444. moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
  445. moai_adk/templates/.claude/skills/moai-workflow-testing/examples.md +672 -0
  446. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
  447. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
  448. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
  449. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
  450. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
  451. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
  452. moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
  453. moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
  454. moai_adk/templates/.claude/skills/moai-workflow-testing/reference.md +440 -0
  455. moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
  456. moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
  457. moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
  458. moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +411 -0
  459. moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
  460. moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
  461. moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
  462. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
  463. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
  464. moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
  465. moai_adk/templates/.git-hooks/pre-commit +128 -0
  466. moai_adk/templates/.git-hooks/pre-push +365 -0
  467. moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
  468. moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
  469. moai_adk/templates/.github/workflows/spec-issue-sync.yml +337 -0
  470. moai_adk/templates/.gitignore +222 -0
  471. moai_adk/templates/.mcp.json +13 -0
  472. moai_adk/templates/.moai/config/config.yaml +58 -0
  473. moai_adk/templates/.moai/config/questions/_schema.yaml +174 -0
  474. moai_adk/templates/.moai/config/questions/tab0-init.yaml +251 -0
  475. moai_adk/templates/.moai/config/questions/tab1-user.yaml +107 -0
  476. moai_adk/templates/.moai/config/questions/tab2-project.yaml +79 -0
  477. moai_adk/templates/.moai/config/questions/tab3-git.yaml +632 -0
  478. moai_adk/templates/.moai/config/questions/tab4-quality.yaml +182 -0
  479. moai_adk/templates/.moai/config/questions/tab5-system.yaml +96 -0
  480. moai_adk/templates/.moai/config/sections/git-strategy.yaml +116 -0
  481. moai_adk/templates/.moai/config/sections/language.yaml +11 -0
  482. moai_adk/templates/.moai/config/sections/project.yaml +13 -0
  483. moai_adk/templates/.moai/config/sections/quality.yaml +17 -0
  484. moai_adk/templates/.moai/config/sections/system.yaml +24 -0
  485. moai_adk/templates/.moai/config/sections/user.yaml +5 -0
  486. moai_adk/templates/.moai/config/statusline-config.yaml +92 -0
  487. moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
  488. moai_adk/templates/CLAUDE.md +642 -0
  489. moai_adk/utils/__init__.py +30 -0
  490. moai_adk/utils/banner.py +38 -0
  491. moai_adk/utils/common.py +294 -0
  492. moai_adk/utils/link_validator.py +241 -0
  493. moai_adk/utils/logger.py +147 -0
  494. moai_adk/utils/safe_file_reader.py +206 -0
  495. moai_adk/utils/timeout.py +160 -0
  496. moai_adk/utils/toon_utils.py +256 -0
  497. moai_adk/version.py +22 -0
  498. moai_adk-0.35.1.dist-info/METADATA +3018 -0
  499. moai_adk-0.35.1.dist-info/RECORD +502 -0
  500. moai_adk-0.35.1.dist-info/WHEEL +4 -0
  501. moai_adk-0.35.1.dist-info/entry_points.txt +3 -0
  502. moai_adk-0.35.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,918 @@
1
+ """
2
+ Rollback Manager for Research Integration Changes
3
+
4
+ Provides comprehensive rollback system for:
5
+ - Configuration backup and restore
6
+ - Version management
7
+ - Safe rollback procedures
8
+ - Integration with existing MoAI-ADK backup systems
9
+ - Research-specific rollback operations
10
+
11
+ Supports:
12
+ - Full system rollback
13
+ - Component-specific rollback
14
+ - Incremental rollback
15
+ - Emergency rollback
16
+ - Rollback validation and verification
17
+ """
18
+
19
+ import hashlib
20
+ import json
21
+ import logging
22
+ import os
23
+ import shutil
24
+ import sys
25
+ from dataclasses import asdict, dataclass
26
+ from datetime import datetime, timezone
27
+ from pathlib import Path
28
+ from typing import Any, Dict, List, Tuple
29
+
30
+ # Configure logging
31
+ logging.basicConfig(level=logging.INFO)
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ @dataclass
36
+ class RollbackPoint:
37
+ """Represents a rollback point with metadata"""
38
+
39
+ id: str
40
+ timestamp: datetime
41
+ description: str
42
+ changes: List[str]
43
+ backup_path: str
44
+ checksum: str
45
+ metadata: Dict[str, Any]
46
+
47
+
48
+ @dataclass
49
+ class RollbackResult:
50
+ """Result of a rollback operation"""
51
+
52
+ success: bool
53
+ rollback_point_id: str
54
+ message: str
55
+ restored_files: List[str]
56
+ failed_files: List[str] = None
57
+ validation_results: Dict[str, Any] = None
58
+
59
+
60
+ class RollbackManager:
61
+ """Comprehensive rollback management system"""
62
+
63
+ def __init__(self, project_root: Path = None):
64
+ self.project_root = project_root or Path.cwd()
65
+ self.backup_root = self.project_root / ".moai" / "rollbacks"
66
+ self.config_backup_dir = self.backup_root / "config"
67
+ self.code_backup_dir = self.backup_root / "code"
68
+ self.docs_backup_dir = self.backup_root / "docs"
69
+ self.registry_file = self.backup_root / "rollback_registry.json"
70
+
71
+ # Create backup directories
72
+ self.backup_root.mkdir(parents=True, exist_ok=True)
73
+ self.config_backup_dir.mkdir(parents=True, exist_ok=True)
74
+ self.code_backup_dir.mkdir(parents=True, exist_ok=True)
75
+ self.docs_backup_dir.mkdir(parents=True, exist_ok=True)
76
+
77
+ # Load existing registry
78
+ self.registry = self._load_registry()
79
+
80
+ # Research-specific paths
81
+ self.research_dirs = [
82
+ self.project_root / ".claude" / "skills",
83
+ self.project_root / ".claude" / "agents",
84
+ self.project_root / ".claude" / "commands",
85
+ self.project_root / ".claude" / "hooks",
86
+ ]
87
+
88
+ def create_rollback_point(self, description: str, changes: List[str] = None) -> str:
89
+ """
90
+ Create a rollback point before making changes
91
+
92
+ Args:
93
+ description: Description of the changes being made
94
+ changes: List of specific changes (files modified, components updated)
95
+
96
+ Returns:
97
+ Rollback point ID
98
+ """
99
+ rollback_id = self._generate_rollback_id()
100
+ timestamp = datetime.now(timezone.utc)
101
+
102
+ logger.info(f"Creating rollback point {rollback_id}: {description}")
103
+
104
+ try:
105
+ # Create backup directory for this rollback point
106
+ rollback_dir = self.backup_root / rollback_id
107
+ rollback_dir.mkdir(parents=True, exist_ok=True)
108
+
109
+ # Backup configuration files
110
+ config_backup_path = self._backup_configuration(rollback_dir)
111
+
112
+ # Backup research components
113
+ research_backup_path = self._backup_research_components(rollback_dir)
114
+
115
+ # Backup project files
116
+ code_backup_path = self._backup_code_files(rollback_dir)
117
+
118
+ # Create checksum for integrity verification
119
+ checksum = self._calculate_backup_checksum(rollback_dir)
120
+
121
+ # Create rollback point record
122
+ rollback_point = RollbackPoint(
123
+ id=rollback_id,
124
+ timestamp=timestamp,
125
+ description=description,
126
+ changes=changes or [],
127
+ backup_path=str(rollback_dir),
128
+ checksum=checksum,
129
+ metadata={
130
+ "config_backup": config_backup_path,
131
+ "research_backup": research_backup_path,
132
+ "code_backup": code_backup_path,
133
+ "project_root": str(self.project_root),
134
+ "created_by": "rollback_manager",
135
+ "version": "1.0.0",
136
+ },
137
+ )
138
+
139
+ # Register rollback point
140
+ self.registry[rollback_id] = asdict(rollback_point)
141
+ self._save_registry()
142
+
143
+ logger.info(f"Rollback point {rollback_id} created successfully")
144
+ return rollback_id
145
+
146
+ except Exception as e:
147
+ logger.error(f"Failed to create rollback point: {str(e)}")
148
+ # Cleanup partial backup
149
+ self._cleanup_partial_backup(rollback_id)
150
+ raise
151
+
152
+ def rollback_to_point(
153
+ self,
154
+ rollback_id: str,
155
+ validate_before: bool = True,
156
+ validate_after: bool = True,
157
+ ) -> RollbackResult:
158
+ """
159
+ Rollback to a specific rollback point
160
+
161
+ Args:
162
+ rollback_id: ID of rollback point to restore
163
+ validate_before: Validate rollback point before restoration
164
+ validate_after: Validate system after restoration
165
+
166
+ Returns:
167
+ RollbackResult with operation details
168
+ """
169
+ if rollback_id not in self.registry:
170
+ return RollbackResult(
171
+ success=False,
172
+ rollback_point_id=rollback_id,
173
+ message=f"Rollback point {rollback_id} not found",
174
+ restored_files=[],
175
+ )
176
+
177
+ logger.info(f"Rolling back to point {rollback_id}")
178
+
179
+ try:
180
+ rollback_point = RollbackPoint(**self.registry[rollback_id])
181
+
182
+ # Pre-rollback validation
183
+ if validate_before:
184
+ validation_result = self._validate_rollback_point(rollback_point)
185
+ if not validation_result["valid"]:
186
+ return RollbackResult(
187
+ success=False,
188
+ rollback_point_id=rollback_id,
189
+ message=f"Rollback point validation failed: {validation_result['message']}",
190
+ restored_files=[],
191
+ )
192
+
193
+ # Perform rollback
194
+ restored_files, failed_files = self._perform_rollback(rollback_point)
195
+
196
+ # Post-rollback validation
197
+ validation_results = {}
198
+ if validate_after:
199
+ validation_results = self._validate_system_after_rollback()
200
+
201
+ # Update registry with rollback info
202
+ self._mark_rollback_as_used(rollback_id)
203
+
204
+ success = len(failed_files) == 0
205
+
206
+ result = RollbackResult(
207
+ success=success,
208
+ rollback_point_id=rollback_id,
209
+ message=f"Rollback {'completed successfully' if success else 'completed with errors'}",
210
+ restored_files=restored_files,
211
+ failed_files=failed_files or [],
212
+ validation_results=validation_results,
213
+ )
214
+
215
+ logger.info(f"Rollback {rollback_id} completed. Success: {success}")
216
+ return result
217
+
218
+ except Exception as e:
219
+ logger.error(f"Rollback failed: {str(e)}")
220
+ return RollbackResult(
221
+ success=False,
222
+ rollback_point_id=rollback_id,
223
+ message=f"Rollback failed with error: {str(e)}",
224
+ restored_files=[],
225
+ )
226
+
227
+ def rollback_research_integration(self, component_type: str = None, component_name: str = None) -> RollbackResult:
228
+ """
229
+ Specialized rollback for research integration changes
230
+
231
+ Args:
232
+ component_type: Type of component (skills, agents, commands, hooks)
233
+ component_name: Specific component name to rollback
234
+
235
+ Returns:
236
+ RollbackResult with operation details
237
+ """
238
+ logger.info(f"Rolling back research integration: {component_type}:{component_name}")
239
+
240
+ try:
241
+ # Find relevant rollback points for research integration
242
+ research_rollback_points = self._find_research_rollback_points(component_type, component_name)
243
+
244
+ if not research_rollback_points:
245
+ return RollbackResult(
246
+ success=False,
247
+ rollback_point_id="",
248
+ message="No suitable rollback points found for research integration",
249
+ restored_files=[],
250
+ )
251
+
252
+ # Use the most recent suitable rollback point
253
+ latest_rollback = max(research_rollback_points, key=lambda x: x["timestamp"])
254
+
255
+ # Perform targeted rollback
256
+ restored_files, failed_files = self._perform_research_rollback(
257
+ latest_rollback, component_type, component_name
258
+ )
259
+
260
+ # Validate research components
261
+ validation_results = self._validate_research_components()
262
+
263
+ success = len(failed_files) == 0
264
+
265
+ return RollbackResult(
266
+ success=success,
267
+ rollback_point_id=latest_rollback["id"],
268
+ message=f"Research integration rollback "
269
+ f"{'completed successfully' if success else 'completed with errors'}",
270
+ restored_files=restored_files,
271
+ failed_files=failed_files or [],
272
+ validation_results=validation_results,
273
+ )
274
+
275
+ except Exception as e:
276
+ logger.error(f"Research integration rollback failed: {str(e)}")
277
+ return RollbackResult(
278
+ success=False,
279
+ rollback_point_id="",
280
+ message=f"Research integration rollback failed: {str(e)}",
281
+ restored_files=[],
282
+ )
283
+
284
+ def list_rollback_points(self, limit: int = 10) -> List[Dict[str, Any]]:
285
+ """
286
+ List available rollback points
287
+
288
+ Args:
289
+ limit: Maximum number of rollback points to return
290
+
291
+ Returns:
292
+ List of rollback point information
293
+ """
294
+ rollback_points = []
295
+
296
+ for rollback_id, rollback_data in self.registry.items():
297
+ rollback_points.append(
298
+ {
299
+ "id": rollback_id,
300
+ "timestamp": rollback_data["timestamp"],
301
+ "description": rollback_data["description"],
302
+ "changes_count": len(rollback_data.get("changes", [])),
303
+ "used": rollback_data.get("used", False),
304
+ }
305
+ )
306
+
307
+ # Sort by timestamp (newest first) and limit
308
+ rollback_points.sort(key=lambda x: x["timestamp"], reverse=True)
309
+ return rollback_points[:limit]
310
+
311
+ def validate_rollback_system(self) -> Dict[str, Any]:
312
+ """
313
+ Validate the rollback system integrity
314
+
315
+ Returns:
316
+ Validation results with system health information
317
+ """
318
+ issues: List[str] = []
319
+ recommendations: List[str] = []
320
+ validation_results = {
321
+ "system_healthy": True,
322
+ "issues": issues,
323
+ "recommendations": recommendations,
324
+ "rollback_points_count": len(self.registry),
325
+ "backup_size": self._calculate_backup_size(),
326
+ "last_rollback": None,
327
+ }
328
+
329
+ try:
330
+ # Check backup directories exist
331
+ required_dirs = [
332
+ self.backup_root,
333
+ self.config_backup_dir,
334
+ self.code_backup_dir,
335
+ self.docs_backup_dir,
336
+ ]
337
+
338
+ for dir_path in required_dirs:
339
+ if not dir_path.exists():
340
+ issues.append(f"Missing backup directory: {dir_path}")
341
+ validation_results["system_healthy"] = False
342
+
343
+ # Validate rollback points
344
+ invalid_rollback_points: List[str] = []
345
+ for rollback_id, rollback_data in self.registry.items():
346
+ backup_path = Path(rollback_data["backup_path"])
347
+ if not backup_path.exists():
348
+ invalid_rollback_points.append(rollback_id)
349
+
350
+ if invalid_rollback_points:
351
+ issues.append(f"Invalid rollback points: {invalid_rollback_points}")
352
+ validation_results["system_healthy"] = False
353
+
354
+ # Check available disk space
355
+ backup_size: int = validation_results["backup_size"] # type: ignore[assignment]
356
+ free_space = shutil.disk_usage(self.backup_root).free
357
+ if backup_size > free_space * 0.8: # Using more than 80% of free space
358
+ recommendations.append("Consider cleaning up old rollback points")
359
+
360
+ # Check last rollback
361
+ if self.registry:
362
+ last_rollback = max(self.registry.values(), key=lambda x: x["timestamp"])
363
+ validation_results["last_rollback"] = last_rollback["timestamp"]
364
+
365
+ except Exception as e:
366
+ validation_results["system_healthy"] = False
367
+ issues.append(f"Validation error: {str(e)}")
368
+
369
+ return validation_results
370
+
371
+ def cleanup_old_rollbacks(self, keep_count: int = 10, dry_run: bool = True) -> Dict[str, Any]:
372
+ """
373
+ Clean up old rollback points
374
+
375
+ Args:
376
+ keep_count: Number of recent rollback points to keep
377
+ dry_run: If True, only show what would be deleted
378
+
379
+ Returns:
380
+ Cleanup operation results
381
+ """
382
+ rollback_points = list(self.registry.values())
383
+ rollback_points.sort(key=lambda x: x["timestamp"], reverse=True)
384
+
385
+ # Keep the most recent rollback points
386
+ to_keep = rollback_points[:keep_count]
387
+ to_delete = rollback_points[keep_count:]
388
+
389
+ if dry_run:
390
+ return {
391
+ "dry_run": True,
392
+ "would_delete_count": len(to_delete),
393
+ "would_keep_count": len(to_keep),
394
+ "would_free_space": sum(self._get_directory_size(Path(rp["backup_path"])) for rp in to_delete),
395
+ }
396
+
397
+ # Perform actual cleanup
398
+ deleted_count = 0
399
+ freed_space = 0
400
+
401
+ for rollback_point in to_delete:
402
+ try:
403
+ backup_path = Path(rollback_point["backup_path"])
404
+ if backup_path.exists():
405
+ size = self._get_directory_size(backup_path)
406
+ shutil.rmtree(backup_path)
407
+ freed_space += size
408
+
409
+ # Remove from registry
410
+ del self.registry[rollback_point["id"]]
411
+ deleted_count += 1
412
+
413
+ except Exception as e:
414
+ logger.warning(f"Failed to delete rollback point {rollback_point['id']}: {str(e)}")
415
+
416
+ # Save updated registry
417
+ self._save_registry()
418
+
419
+ return {
420
+ "dry_run": False,
421
+ "deleted_count": deleted_count,
422
+ "kept_count": len(to_keep),
423
+ "freed_space": freed_space,
424
+ }
425
+
426
+ def _generate_rollback_id(self) -> str:
427
+ """Generate unique rollback point ID"""
428
+ timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
429
+ random_suffix = hashlib.md5(os.urandom(4), usedforsecurity=False).hexdigest()[:8]
430
+ return f"rollback_{timestamp}_{random_suffix}"
431
+
432
+ def _load_registry(self) -> Dict[str, Any]:
433
+ """Load rollback registry from file"""
434
+ if self.registry_file.exists():
435
+ try:
436
+ with open(self.registry_file, "r", encoding="utf-8") as f:
437
+ return json.load(f)
438
+ except Exception as e:
439
+ logger.warning(f"Failed to load rollback registry: {str(e)}")
440
+
441
+ return {}
442
+
443
+ def _save_registry(self):
444
+ """Save rollback registry to file"""
445
+ try:
446
+ with open(self.registry_file, "w", encoding="utf-8") as f:
447
+ json.dump(self.registry, f, indent=2, default=str, ensure_ascii=False)
448
+ except Exception as e:
449
+ logger.error(f"Failed to save rollback registry: {str(e)}")
450
+ raise
451
+
452
+ def _backup_configuration(self, rollback_dir: Path) -> str:
453
+ """Backup configuration files"""
454
+ config_backup_path = rollback_dir / "config"
455
+ config_backup_path.mkdir(parents=True, exist_ok=True)
456
+
457
+ # Backup .moai/config/config.json
458
+ config_file = self.project_root / ".moai" / "config" / "config.json"
459
+ if config_file.exists():
460
+ shutil.copy2(config_file, config_backup_path / "config.json")
461
+
462
+ # Backup .claude/settings.json
463
+ settings_file = self.project_root / ".claude" / "settings.json"
464
+ if settings_file.exists():
465
+ shutil.copy2(settings_file, config_backup_path / "settings.json")
466
+
467
+ # Backup .claude/settings.local.json
468
+ local_settings_file = self.project_root / ".claude" / "settings.local.json"
469
+ if local_settings_file.exists():
470
+ shutil.copy2(local_settings_file, config_backup_path / "settings.local.json")
471
+
472
+ return str(config_backup_path)
473
+
474
+ def _backup_research_components(self, rollback_dir: Path) -> str:
475
+ """Backup research-specific components"""
476
+ research_backup_path = rollback_dir / "research"
477
+ research_backup_path.mkdir(parents=True, exist_ok=True)
478
+
479
+ for research_dir in self.research_dirs:
480
+ if research_dir.exists():
481
+ dir_name = research_dir.name
482
+ target_dir = research_backup_path / dir_name
483
+ shutil.copytree(research_dir, target_dir, dirs_exist_ok=True)
484
+
485
+ return str(research_backup_path)
486
+
487
+ def _backup_code_files(self, rollback_dir: Path) -> str:
488
+ """Backup important code files"""
489
+ code_backup_path = rollback_dir / "code"
490
+ code_backup_path.mkdir(parents=True, exist_ok=True)
491
+
492
+ # Backup source code
493
+ src_dir = self.project_root / "src"
494
+ if src_dir.exists():
495
+ shutil.copytree(src_dir, code_backup_path / "src", dirs_exist_ok=True)
496
+
497
+ # Backup tests
498
+ tests_dir = self.project_root / "tests"
499
+ if tests_dir.exists():
500
+ shutil.copytree(tests_dir, code_backup_path / "tests", dirs_exist_ok=True)
501
+
502
+ # Backup documentation
503
+ docs_dir = self.project_root / "docs"
504
+ if docs_dir.exists():
505
+ shutil.copytree(docs_dir, code_backup_path / "docs", dirs_exist_ok=True)
506
+
507
+ return str(code_backup_path)
508
+
509
+ def _calculate_backup_checksum(self, backup_dir: Path) -> str:
510
+ """Calculate checksum for backup integrity verification"""
511
+ checksum_hash = hashlib.sha256()
512
+
513
+ for file_path in backup_dir.rglob("*"):
514
+ if file_path.is_file():
515
+ with open(file_path, "rb") as f:
516
+ # Update hash with file content and path
517
+ checksum_hash.update(f.read())
518
+ checksum_hash.update(str(file_path.relative_to(backup_dir)).encode())
519
+
520
+ return checksum_hash.hexdigest()
521
+
522
+ def _validate_rollback_point(self, rollback_point: RollbackPoint) -> Dict[str, Any]:
523
+ """Validate rollback point before restoration"""
524
+ warnings: List[str] = []
525
+ validation_result = {
526
+ "valid": True,
527
+ "message": "Rollback point is valid",
528
+ "warnings": warnings,
529
+ }
530
+
531
+ try:
532
+ # Check backup directory exists
533
+ backup_path = Path(rollback_point.backup_path)
534
+ if not backup_path.exists():
535
+ validation_result["valid"] = False
536
+ validation_result["message"] = "Backup directory not found"
537
+ return validation_result
538
+
539
+ # Verify checksum
540
+ current_checksum = self._calculate_backup_checksum(backup_path)
541
+ if current_checksum != rollback_point.checksum:
542
+ warnings.append("Backup checksum mismatch - possible corruption")
543
+
544
+ # Check essential files exist
545
+ required_files = [
546
+ backup_path / "config" / "config.json",
547
+ backup_path / "research",
548
+ ]
549
+
550
+ missing_files = [f for f in required_files if not f.exists()]
551
+ if missing_files:
552
+ warnings.append(f"Missing backup files: {missing_files}")
553
+
554
+ except Exception as e:
555
+ validation_result["valid"] = False
556
+ validation_result["message"] = f"Validation error: {str(e)}"
557
+
558
+ return validation_result
559
+
560
+ def _perform_rollback(self, rollback_point: RollbackPoint) -> Tuple[List[str], List[str]]:
561
+ """Perform the actual rollback operation"""
562
+ backup_path = Path(rollback_point.backup_path)
563
+ restored_files: List[str] = []
564
+ failed_files: List[str] = []
565
+
566
+ try:
567
+ # Restore configuration
568
+ config_backup = backup_path / "config"
569
+ if config_backup.exists():
570
+ for config_file in config_backup.rglob("*"):
571
+ if config_file.is_file():
572
+ target_path = self.project_root / ".moai" / config_file.relative_to(config_backup)
573
+ target_path.parent.mkdir(parents=True, exist_ok=True)
574
+ try:
575
+ shutil.copy2(config_file, target_path)
576
+ restored_files.append(str(target_path))
577
+ except Exception as e:
578
+ failed_files.append(f"{target_path}: {str(e)}")
579
+
580
+ # Restore research components
581
+ research_backup = backup_path / "research"
582
+ if research_backup.exists():
583
+ for research_file in research_backup.rglob("*"):
584
+ if research_file.is_file():
585
+ target_path = self.project_root / research_file.relative_to(research_backup)
586
+ target_path.parent.mkdir(parents=True, exist_ok=True)
587
+ try:
588
+ shutil.copy2(research_file, target_path)
589
+ restored_files.append(str(target_path))
590
+ except Exception as e:
591
+ failed_files.append(f"{target_path}: {str(e)}")
592
+
593
+ # Restore code files
594
+ code_backup = backup_path / "code"
595
+ if code_backup.exists():
596
+ for code_file in code_backup.rglob("*"):
597
+ if code_file.is_file():
598
+ target_path = self.project_root / code_file.relative_to(code_backup)
599
+ target_path.parent.mkdir(parents=True, exist_ok=True)
600
+ try:
601
+ shutil.copy2(code_file, target_path)
602
+ restored_files.append(str(target_path))
603
+ except Exception as e:
604
+ failed_files.append(f"{target_path}: {str(e)}")
605
+
606
+ except Exception as e:
607
+ logger.error(f"Rollback operation failed: {str(e)}")
608
+ failed_files.append(f"rollback_operation: {str(e)}")
609
+
610
+ return restored_files, failed_files
611
+
612
+ def _perform_research_rollback(
613
+ self,
614
+ rollback_point: Dict[str, Any],
615
+ component_type: str = None,
616
+ component_name: str = None,
617
+ ) -> Tuple[List[str], List[str]]:
618
+ """Perform targeted research component rollback"""
619
+ backup_path = Path(rollback_point["backup_path"])
620
+ research_backup = backup_path / "research"
621
+
622
+ restored_files: List[str] = []
623
+ failed_files: List[str] = []
624
+
625
+ if not research_backup.exists():
626
+ failed_files.append("research_backup: Research backup not found")
627
+ return restored_files, failed_files
628
+
629
+ try:
630
+ # Restore specific component or all research components
631
+ if component_type:
632
+ component_backup_dir = research_backup / component_type
633
+ if component_backup_dir.exists():
634
+ target_dir = self.project_root / ".claude" / component_type
635
+
636
+ if component_name:
637
+ # Restore specific component
638
+ component_file = component_backup_dir / f"{component_name}.md"
639
+ if component_file.exists():
640
+ target_file = target_dir / f"{component_name}.md"
641
+ target_file.parent.mkdir(parents=True, exist_ok=True)
642
+ shutil.copy2(component_file, target_file)
643
+ restored_files.append(str(target_file))
644
+ else:
645
+ failed_files.append(f"{component_name}: Component file not found in backup")
646
+ else:
647
+ # Restore entire component type
648
+ if target_dir.exists():
649
+ shutil.rmtree(target_dir)
650
+ shutil.copytree(component_backup_dir, target_dir)
651
+ restored_files.append(str(target_dir))
652
+ else:
653
+ failed_files.append(f"{component_type}: Component type not found in backup")
654
+ else:
655
+ # Restore all research components
656
+ for research_dir in research_backup.iterdir():
657
+ if research_dir.is_dir():
658
+ target_dir = self.project_root / ".claude" / research_dir.name
659
+ if target_dir.exists():
660
+ shutil.rmtree(target_dir)
661
+ shutil.copytree(research_dir, target_dir)
662
+ restored_files.append(str(target_dir))
663
+
664
+ except Exception as e:
665
+ logger.error(f"Research rollback failed: {str(e)}")
666
+ failed_files.append(f"research_rollback: {str(e)}")
667
+
668
+ return restored_files, failed_files
669
+
670
+ def _validate_system_after_rollback(self) -> Dict[str, Any]:
671
+ """Validate system state after rollback"""
672
+ issues: List[str] = []
673
+ validation_results = {
674
+ "config_valid": True,
675
+ "research_valid": True,
676
+ "issues": issues,
677
+ }
678
+
679
+ try:
680
+ # Validate configuration
681
+ config_file = self.project_root / ".moai" / "config" / "config.json"
682
+ if config_file.exists():
683
+ try:
684
+ with open(config_file, "r", encoding="utf-8") as f:
685
+ json.load(f) # Validate JSON syntax
686
+ except json.JSONDecodeError:
687
+ validation_results["config_valid"] = False
688
+ issues.append("Invalid JSON in config.json")
689
+ else:
690
+ validation_results["config_valid"] = False
691
+ issues.append("config.json not found")
692
+
693
+ # Validate research components
694
+ for research_dir in self.research_dirs:
695
+ if research_dir.exists():
696
+ # Check for readable files
697
+ for file_path in research_dir.rglob("*.md"):
698
+ try:
699
+ with open(file_path, "r", encoding="utf-8") as f:
700
+ f.read() # Validate file can be read
701
+ except Exception as e:
702
+ validation_results["research_valid"] = False
703
+ issues.append(f"Cannot read {file_path}: {str(e)}")
704
+
705
+ except Exception as e:
706
+ issues.append(f"Validation error: {str(e)}")
707
+
708
+ return validation_results
709
+
710
+ def _validate_research_components(self) -> Dict[str, Any]:
711
+ """Validate research components after rollback"""
712
+ issues: List[str] = []
713
+ validation_results = {
714
+ "skills_valid": True,
715
+ "agents_valid": True,
716
+ "commands_valid": True,
717
+ "hooks_valid": True,
718
+ "issues": issues,
719
+ }
720
+
721
+ component_checks = [
722
+ ("skills", "Skills", self.project_root / ".claude" / "skills"),
723
+ ("agents", "Agents", self.project_root / ".claude" / "agents"),
724
+ ("commands", "Commands", self.project_root / ".claude" / "commands"),
725
+ ("hooks", "Hooks", self.project_root / ".claude" / "hooks"),
726
+ ]
727
+
728
+ for component_key, component_name, component_path in component_checks:
729
+ if component_path.exists():
730
+ # Check component structure
731
+ files = list(component_path.rglob("*.md"))
732
+ if not files:
733
+ validation_results[f"{component_key}_valid"] = False
734
+ issues.append(f"{component_name} directory is empty")
735
+
736
+ # Validate file content
737
+ for file_path in files[:5]: # Check first 5 files
738
+ try:
739
+ with open(file_path, "r", encoding="utf-8") as f:
740
+ content = f.read()
741
+ if not content.strip():
742
+ validation_results[f"{component_key}_valid"] = False
743
+ issues.append(f"Empty file: {file_path}")
744
+ except Exception as e:
745
+ validation_results[f"{component_key}_valid"] = False
746
+ issues.append(f"Cannot read {file_path}: {str(e)}")
747
+ else:
748
+ validation_results[f"{component_key}_valid"] = False
749
+ issues.append(f"{component_name} directory not found")
750
+
751
+ return validation_results
752
+
753
+ def _find_research_rollback_points(
754
+ self, component_type: str = None, component_name: str = None
755
+ ) -> List[Dict[str, Any]]:
756
+ """Find rollback points related to research integration"""
757
+ research_rollback_points = []
758
+
759
+ for rollback_id, rollback_data in self.registry.items():
760
+ # Check if rollback point has research backup
761
+ backup_path = Path(rollback_data["backup_path"])
762
+ research_backup = backup_path / "research"
763
+
764
+ if not research_backup.exists():
765
+ continue
766
+
767
+ # Check for specific component match
768
+ if component_type:
769
+ component_backup = research_backup / component_type
770
+ if component_backup.exists():
771
+ if component_name:
772
+ component_file = component_backup / f"{component_name}.md"
773
+ if component_file.exists():
774
+ research_rollback_points.append(rollback_data)
775
+ else:
776
+ research_rollback_points.append(rollback_data)
777
+ else:
778
+ # Include any rollback with research components
779
+ research_rollback_points.append(rollback_data)
780
+
781
+ return research_rollback_points
782
+
783
+ def _mark_rollback_as_used(self, rollback_id: str):
784
+ """Mark rollback point as used in registry"""
785
+ if rollback_id in self.registry:
786
+ self.registry[rollback_id]["used"] = True
787
+ self.registry[rollback_id]["used_timestamp"] = datetime.now(timezone.utc).isoformat()
788
+ self._save_registry()
789
+
790
+ def _cleanup_partial_backup(self, rollback_id: str):
791
+ """Clean up partial backup if creation failed"""
792
+ try:
793
+ backup_dir = self.backup_root / rollback_id
794
+ if backup_dir.exists():
795
+ shutil.rmtree(backup_dir)
796
+ except Exception as e:
797
+ logger.warning(f"Failed to cleanup partial backup {rollback_id}: {str(e)}")
798
+
799
+ def _calculate_backup_size(self) -> int:
800
+ """Calculate total size of all backups"""
801
+ total_size = 0
802
+ for rollback_id, rollback_data in self.registry.items():
803
+ backup_path = Path(rollback_data["backup_path"])
804
+ if backup_path.exists():
805
+ total_size += self._get_directory_size(backup_path)
806
+ return total_size
807
+
808
+ def _get_directory_size(self, directory: Path) -> int:
809
+ """Get total size of directory in bytes"""
810
+ total_size = 0
811
+ try:
812
+ for file_path in directory.rglob("*"):
813
+ if file_path.is_file():
814
+ total_size += file_path.stat().st_size
815
+ except Exception:
816
+ pass # Ignore errors in size calculation
817
+ return total_size
818
+
819
+
820
+ # Command-line interface for rollback manager
821
+ def main():
822
+ """Command-line interface for rollback operations"""
823
+ import argparse
824
+
825
+ parser = argparse.ArgumentParser(description="MoAI-ADK Rollback Manager")
826
+ subparsers = parser.add_subparsers(dest="command", help="Available commands")
827
+
828
+ # Create rollback point
829
+ create_parser = subparsers.add_parser("create", help="Create rollback point")
830
+ create_parser.add_argument("description", help="Description of changes")
831
+ create_parser.add_argument("--changes", nargs="*", help="List of changes")
832
+
833
+ # List rollback points
834
+ list_parser = subparsers.add_parser("list", help="List rollback points")
835
+ list_parser.add_argument("--limit", type=int, default=10, help="Maximum number to show")
836
+
837
+ # Perform rollback
838
+ rollback_parser = subparsers.add_parser("rollback", help="Rollback to point")
839
+ rollback_parser.add_argument("rollback_id", help="Rollback point ID")
840
+ rollback_parser.add_argument("--no-validate", action="store_true", help="Skip validation")
841
+
842
+ # Research rollback
843
+ research_parser = subparsers.add_parser("research-rollback", help="Rollback research components")
844
+ research_parser.add_argument("--type", help="Component type (skills, agents, commands, hooks)")
845
+ research_parser.add_argument("--name", help="Component name")
846
+
847
+ # Validate system
848
+ subparsers.add_parser("validate", help="Validate rollback system")
849
+
850
+ # Cleanup
851
+ cleanup_parser = subparsers.add_parser("cleanup", help="Cleanup old rollback points")
852
+ cleanup_parser.add_argument("--keep", type=int, default=10, help="Number to keep")
853
+ cleanup_parser.add_argument("--execute", action="store_true", help="Execute cleanup (default: dry run)")
854
+
855
+ args = parser.parse_args()
856
+
857
+ if not args.command:
858
+ parser.print_help()
859
+ return
860
+
861
+ # Initialize rollback manager
862
+ rollback_manager = RollbackManager()
863
+
864
+ try:
865
+ if args.command == "create":
866
+ rollback_id = rollback_manager.create_rollback_point(args.description, args.changes)
867
+ print(f"Rollback point created: {rollback_id}")
868
+
869
+ elif args.command == "list":
870
+ rollback_points = rollback_manager.list_rollback_points(args.limit)
871
+ print(f"Available rollback points (showing {len(rollback_points)}):")
872
+ for rp in rollback_points:
873
+ status = "USED" if rp["used"] else "AVAILABLE"
874
+ print(f" {rp['id']} - {rp['description']} ({status})")
875
+
876
+ elif args.command == "rollback":
877
+ result = rollback_manager.rollback_to_point(args.rollback_id, validate_before=not args.no_validate)
878
+ if result.success:
879
+ print("Rollback completed successfully")
880
+ print(f"Restored {len(result.restored_files)} files")
881
+ else:
882
+ print(f"Rollback failed: {result.message}")
883
+
884
+ elif args.command == "research-rollback":
885
+ result = rollback_manager.rollback_research_integration(args.type, args.name)
886
+ if result.success:
887
+ print("Research rollback completed successfully")
888
+ else:
889
+ print(f"Research rollback failed: {result.message}")
890
+
891
+ elif args.command == "validate":
892
+ validation = rollback_manager.validate_rollback_system()
893
+ print(f"Rollback system health: {'HEALTHY' if validation['system_healthy'] else 'UNHEALTHY'}")
894
+ if validation["issues"]:
895
+ print("Issues found:")
896
+ for issue in validation["issues"]:
897
+ print(f" - {issue}")
898
+ if validation["recommendations"]:
899
+ print("Recommendations:")
900
+ for rec in validation["recommendations"]:
901
+ print(f" - {rec}")
902
+
903
+ elif args.command == "cleanup":
904
+ result = rollback_manager.cleanup_old_rollbacks(args.keep, dry_run=not args.execute)
905
+ if result["dry_run"]:
906
+ print(f"Dry run: Would delete {result['would_delete_count']} rollback points")
907
+ print(f"Would free {result['would_free_space'] / 1024 / 1024:.1f} MB")
908
+ else:
909
+ print(f"Deleted {result['deleted_count']} rollback points")
910
+ print(f"Freed {result['freed_space'] / 1024 / 1024:.1f} MB")
911
+
912
+ except Exception as e:
913
+ print(f"Error: {str(e)}")
914
+ sys.exit(1)
915
+
916
+
917
+ if __name__ == "__main__":
918
+ main()