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,89 @@
1
+ """Custom exceptions for Git Worktree CLI."""
2
+
3
+ from pathlib import Path
4
+
5
+
6
+ class WorktreeError(Exception):
7
+ """Base exception for worktree operations."""
8
+
9
+ pass
10
+
11
+
12
+ class WorktreeExistsError(WorktreeError):
13
+ """Raised when trying to create a worktree that already exists."""
14
+
15
+ def __init__(self, spec_id: str, path: Path) -> None:
16
+ """Initialize exception with spec ID and path.
17
+
18
+ Args:
19
+ spec_id: The SPEC ID that already has a worktree.
20
+ path: The path of the existing worktree.
21
+ """
22
+ self.spec_id = spec_id
23
+ self.path = path
24
+ super().__init__(f"Worktree for '{spec_id}' already exists at {path}")
25
+
26
+
27
+ class WorktreeNotFoundError(WorktreeError):
28
+ """Raised when trying to access a nonexistent worktree."""
29
+
30
+ def __init__(self, spec_id: str) -> None:
31
+ """Initialize exception with spec ID.
32
+
33
+ Args:
34
+ spec_id: The SPEC ID that was not found.
35
+ """
36
+ self.spec_id = spec_id
37
+ super().__init__(f"Worktree for '{spec_id}' not found")
38
+
39
+
40
+ class UncommittedChangesError(WorktreeError):
41
+ """Raised when trying to remove a worktree with uncommitted changes."""
42
+
43
+ def __init__(self, spec_id: str) -> None:
44
+ """Initialize exception with spec ID.
45
+
46
+ Args:
47
+ spec_id: The SPEC ID with uncommitted changes.
48
+ """
49
+ self.spec_id = spec_id
50
+ super().__init__(f"Worktree for '{spec_id}' has uncommitted changes. Use --force to remove anyway.")
51
+
52
+
53
+ class GitOperationError(WorktreeError):
54
+ """Raised when a Git operation fails."""
55
+
56
+ def __init__(self, message: str) -> None:
57
+ """Initialize exception with error message.
58
+
59
+ Args:
60
+ message: Description of the Git operation error.
61
+ """
62
+ super().__init__(f"Git operation failed: {message}")
63
+
64
+
65
+ class MergeConflictError(WorktreeError):
66
+ """Raised when a merge conflict occurs during sync."""
67
+
68
+ def __init__(self, spec_id: str, conflicted_files: list[str]) -> None:
69
+ """Initialize exception with conflict details.
70
+
71
+ Args:
72
+ spec_id: The SPEC ID with merge conflicts.
73
+ conflicted_files: List of files with conflicts.
74
+ """
75
+ self.spec_id = spec_id
76
+ self.conflicted_files = conflicted_files
77
+ super().__init__(f"Merge conflict in worktree '{spec_id}'. Conflicted files: {', '.join(conflicted_files)}")
78
+
79
+
80
+ class RegistryInconsistencyError(WorktreeError):
81
+ """Raised when registry state is inconsistent with actual Git worktrees."""
82
+
83
+ def __init__(self, message: str) -> None:
84
+ """Initialize exception with error message.
85
+
86
+ Args:
87
+ message: Description of the inconsistency.
88
+ """
89
+ super().__init__(f"Registry inconsistency: {message}")
@@ -0,0 +1,490 @@
1
+ """Core manager for Git worktree operations."""
2
+
3
+ from datetime import datetime
4
+ from pathlib import Path
5
+ from typing import List
6
+
7
+ from git import Repo
8
+
9
+ from moai_adk.cli.worktree.exceptions import (
10
+ GitOperationError,
11
+ MergeConflictError,
12
+ UncommittedChangesError,
13
+ WorktreeExistsError,
14
+ WorktreeNotFoundError,
15
+ )
16
+ from moai_adk.cli.worktree.models import WorktreeInfo
17
+ from moai_adk.cli.worktree.registry import WorktreeRegistry
18
+
19
+
20
+ class WorktreeManager:
21
+ """Manages Git worktrees for parallel SPEC development.
22
+
23
+ This class provides high-level operations for creating, removing,
24
+ switching, and maintaining Git worktrees. It integrates with
25
+ GitPython for Git operations and WorktreeRegistry for metadata
26
+ persistence.
27
+ """
28
+
29
+ def __init__(self, repo_path: Path, worktree_root: Path) -> None:
30
+ """Initialize the worktree manager.
31
+
32
+ Args:
33
+ repo_path: Path to the main Git repository.
34
+ worktree_root: Root directory for all worktrees.
35
+ """
36
+ self.repo = Repo(repo_path)
37
+ self.worktree_root = Path(worktree_root)
38
+ self.registry = WorktreeRegistry(self.worktree_root)
39
+
40
+ def create(
41
+ self,
42
+ spec_id: str,
43
+ branch_name: str | None = None,
44
+ base_branch: str = "main",
45
+ force: bool = False,
46
+ ) -> WorktreeInfo:
47
+ """Create a new worktree for a SPEC.
48
+
49
+ Creates a new Git worktree and registers it in the registry.
50
+
51
+ Args:
52
+ spec_id: SPEC ID (e.g., 'SPEC-AUTH-001').
53
+ branch_name: Custom branch name (defaults to spec_id).
54
+ base_branch: Base branch to create from (defaults to 'main').
55
+ force: Force creation even if worktree exists.
56
+
57
+ Returns:
58
+ WorktreeInfo for the created worktree.
59
+
60
+ Raises:
61
+ WorktreeExistsError: If worktree already exists (unless force=True).
62
+ GitOperationError: If Git operation fails.
63
+ """
64
+ # Check if worktree already exists
65
+ existing = self.registry.get(spec_id)
66
+ if existing and not force:
67
+ raise WorktreeExistsError(spec_id, existing.path)
68
+
69
+ # If force and exists, remove first
70
+ if existing and force:
71
+ try:
72
+ self.remove(spec_id, force=True)
73
+ except WorktreeNotFoundError:
74
+ pass
75
+
76
+ # Determine branch name
77
+ if branch_name is None:
78
+ branch_name = f"feature/{spec_id}"
79
+
80
+ # Create worktree path
81
+ worktree_path = self.worktree_root / spec_id
82
+
83
+ try:
84
+ # Create parent directory if needed
85
+ self.worktree_root.mkdir(parents=True, exist_ok=True)
86
+
87
+ # Fetch latest
88
+ try:
89
+ self.repo.remotes.origin.fetch()
90
+ except Exception:
91
+ # No origin or fetch fails, continue with local
92
+ pass
93
+
94
+ # Check if branch exists, if not create it
95
+ try:
96
+ self.repo.heads[base_branch]
97
+ except IndexError:
98
+ # Branch doesn't exist locally, try to fetch
99
+ try:
100
+ self.repo.remotes.origin.fetch(base_branch)
101
+ except Exception:
102
+ pass
103
+
104
+ # Create branch if it doesn't exist
105
+ if branch_name not in [h.name for h in self.repo.heads]:
106
+ try:
107
+ self.repo.create_head(branch_name, base_branch)
108
+ except Exception as e:
109
+ # If create fails, check if it already exists
110
+ if branch_name not in [h.name for h in self.repo.heads]:
111
+ raise GitOperationError(f"Failed to create branch: {e}")
112
+
113
+ # Create worktree using git command
114
+ try:
115
+ self.repo.git.worktree("add", str(worktree_path), branch_name)
116
+ except Exception as e:
117
+ raise GitOperationError(f"Failed to create worktree: {e}")
118
+
119
+ # Create WorktreeInfo
120
+ now = datetime.now().isoformat() + "Z"
121
+ info = WorktreeInfo(
122
+ spec_id=spec_id,
123
+ path=worktree_path,
124
+ branch=branch_name,
125
+ created_at=now,
126
+ last_accessed=now,
127
+ status="active",
128
+ )
129
+
130
+ # Register in registry
131
+ self.registry.register(info)
132
+
133
+ return info
134
+
135
+ except WorktreeExistsError:
136
+ raise
137
+ except GitOperationError:
138
+ raise
139
+ except Exception as e:
140
+ raise GitOperationError(f"Failed to create worktree: {e}")
141
+
142
+ def remove(self, spec_id: str, force: bool = False) -> None:
143
+ """Remove a worktree.
144
+
145
+ Args:
146
+ spec_id: SPEC ID of worktree to remove.
147
+ force: Force removal even with uncommitted changes.
148
+
149
+ Raises:
150
+ WorktreeNotFoundError: If worktree doesn't exist.
151
+ UncommittedChangesError: If worktree has uncommitted changes (unless force=True).
152
+ GitOperationError: If Git operation fails.
153
+ """
154
+ info = self.registry.get(spec_id)
155
+ if not info:
156
+ raise WorktreeNotFoundError(spec_id)
157
+
158
+ try:
159
+ # Check for uncommitted changes
160
+ if not force:
161
+ try:
162
+ status = self.repo.git.status("--porcelain", spec_id)
163
+ if status.strip():
164
+ raise UncommittedChangesError(spec_id)
165
+ except Exception:
166
+ # Ignore status check errors
167
+ pass
168
+
169
+ # Remove worktree
170
+ try:
171
+ self.repo.git.worktree("remove", str(info.path), "--force")
172
+ except Exception:
173
+ # Try to remove directory manually if git command fails
174
+ import shutil
175
+
176
+ if info.path.exists():
177
+ shutil.rmtree(info.path)
178
+
179
+ # Unregister from registry
180
+ self.registry.unregister(spec_id)
181
+
182
+ except (WorktreeNotFoundError, UncommittedChangesError):
183
+ raise
184
+ except GitOperationError:
185
+ raise
186
+ except Exception as e:
187
+ raise GitOperationError(f"Failed to remove worktree: {e}")
188
+
189
+ def list(self) -> list["WorktreeInfo"]:
190
+ """List all worktrees.
191
+
192
+ Returns:
193
+ List of WorktreeInfo instances.
194
+ """
195
+ return self.registry.list_all()
196
+
197
+ def sync(
198
+ self,
199
+ spec_id: str,
200
+ base_branch: str = "main",
201
+ rebase: bool = False,
202
+ ff_only: bool = False,
203
+ auto_resolve: bool = False,
204
+ ) -> None:
205
+ """Sync worktree with base branch.
206
+
207
+ Fetches latest changes from base branch and merges them.
208
+
209
+ Args:
210
+ spec_id: SPEC ID of worktree to sync.
211
+ base_branch: Branch to sync from (defaults to 'main').
212
+ rebase: Use rebase instead of merge.
213
+ ff_only: Only sync if fast-forward is possible.
214
+ auto_resolve: Automatically attempt to resolve conflicts.
215
+
216
+ Raises:
217
+ WorktreeNotFoundError: If worktree doesn't exist.
218
+ MergeConflictError: If merge conflict occurs and auto_resolve is False.
219
+ GitOperationError: If Git operation fails.
220
+ """
221
+ info = self.registry.get(spec_id)
222
+ if not info:
223
+ raise WorktreeNotFoundError(spec_id)
224
+
225
+ try:
226
+ # Change to worktree directory
227
+ worktree_repo = Repo(info.path)
228
+
229
+ # Fetch latest
230
+ try:
231
+ worktree_repo.remotes.origin.fetch()
232
+ except Exception:
233
+ pass
234
+
235
+ # Sync with preferred strategy
236
+ try:
237
+ # Determine target branch (try remote first, then local)
238
+ target_branch = None
239
+ for candidate in [f"origin/{base_branch}", base_branch]:
240
+ try:
241
+ worktree_repo.git.rev_parse(candidate)
242
+ target_branch = candidate
243
+ break
244
+ except Exception:
245
+ continue
246
+
247
+ if not target_branch:
248
+ raise GitOperationError(
249
+ f"Base branch '{base_branch}' not found (tried origin/{base_branch}, {base_branch})"
250
+ )
251
+
252
+ if ff_only:
253
+ # Fast-forward only
254
+ worktree_repo.git.merge(target_branch, "--ff-only")
255
+ elif rebase:
256
+ # Rebase strategy
257
+ worktree_repo.git.rebase(target_branch)
258
+ else:
259
+ # Default merge strategy with conflict handling
260
+ worktree_repo.git.merge(target_branch)
261
+ except Exception as e:
262
+ # Handle merge conflicts and provide auto-abort/auto-resolve
263
+ try:
264
+ status = worktree_repo.git.status("--porcelain")
265
+ conflicted = [
266
+ line.split()[-1]
267
+ for line in status.split("\n")
268
+ if line.startswith("UU")
269
+ or line.startswith("DD")
270
+ or line.startswith("AA")
271
+ or line.startswith("DU")
272
+ ]
273
+
274
+ if conflicted:
275
+ if auto_resolve:
276
+ # Attempt auto-resolution of conflicts
277
+ try:
278
+ # Try common conflict resolution strategies
279
+ for file_path in conflicted:
280
+ try:
281
+ # Strategy 1: Accept current changes (ours)
282
+ worktree_repo.git.checkout("--ours", file_path)
283
+ worktree_repo.git.add(file_path)
284
+ except Exception:
285
+ # Strategy 2: Accept incoming changes (theirs) if ours fails
286
+ try:
287
+ worktree_repo.git.checkout("--theirs", file_path)
288
+ worktree_repo.git.add(file_path)
289
+ except Exception:
290
+ # Strategy 3: Remove conflict markers and keep both
291
+ try:
292
+ # Simple conflict marker removal - keep both versions
293
+ file_full_path = info.path / file_path
294
+ if file_full_path.exists():
295
+ with open(file_full_path, "r") as f:
296
+ content = f.read()
297
+
298
+ # Remove conflict markers and keep both versions
299
+ lines = content.split("\n")
300
+ cleaned_lines = []
301
+ skip_next = False
302
+ in_conflict = False
303
+
304
+ for line in lines:
305
+ if "<<<<<<<" in line or ">>>>>>>" in line:
306
+ in_conflict = True
307
+ continue
308
+ elif "======" in line:
309
+ skip_next = True
310
+ in_conflict = False
311
+ continue
312
+ elif skip_next:
313
+ skip_next = False
314
+ continue
315
+ elif not in_conflict:
316
+ cleaned_lines.append(line)
317
+
318
+ with open(file_full_path, "w") as f:
319
+ f.write("\n".join(cleaned_lines))
320
+
321
+ worktree_repo.git.add(file_path)
322
+ except Exception:
323
+ pass
324
+
325
+ # Stage resolved files
326
+ worktree_repo.git.add(".")
327
+
328
+ # Commit the merge resolution
329
+ worktree_repo.git.commit(
330
+ "-m",
331
+ f"Auto-resolved conflicts during sync of {spec_id}",
332
+ )
333
+
334
+ except Exception as resolve_error:
335
+ # Auto-resolution failed, fall back to manual conflict
336
+ try:
337
+ worktree_repo.git.merge("--abort")
338
+ except Exception:
339
+ pass
340
+ try:
341
+ worktree_repo.git.rebase("--abort")
342
+ except Exception:
343
+ pass
344
+ conflict_list = conflicted if isinstance(conflicted, list) else [str(conflicted)]
345
+ error_msg = f"auto-resolve failed: {resolve_error}"
346
+ raise MergeConflictError(spec_id, conflict_list + [error_msg])
347
+ else:
348
+ # Auto-abort merge/rebase on conflicts
349
+ try:
350
+ worktree_repo.git.merge("--abort")
351
+ except Exception:
352
+ pass
353
+ try:
354
+ worktree_repo.git.rebase("--abort")
355
+ except Exception:
356
+ pass
357
+
358
+ raise MergeConflictError(spec_id, conflicted)
359
+
360
+ # If no conflicts but sync failed, raise general error
361
+ raise GitOperationError(f"Failed to sync worktree: {e}")
362
+
363
+ except MergeConflictError:
364
+ raise
365
+ except Exception:
366
+ # If conflict detection fails, still try to clean up
367
+ try:
368
+ worktree_repo.git.merge("--abort")
369
+ except Exception:
370
+ pass
371
+ try:
372
+ worktree_repo.git.rebase("--abort")
373
+ except Exception:
374
+ pass
375
+ raise GitOperationError(f"Failed to sync worktree: {e}")
376
+
377
+ # Update last accessed time
378
+ info.last_accessed = datetime.now().isoformat() + "Z"
379
+ self.registry.register(info)
380
+
381
+ except (WorktreeNotFoundError, MergeConflictError):
382
+ raise
383
+ except GitOperationError:
384
+ raise
385
+ except Exception as e:
386
+ raise GitOperationError(f"Failed to sync worktree: {e}")
387
+
388
+ def clean_merged(self) -> List[str]:
389
+ """Clean up worktrees for merged branches.
390
+
391
+ Removes worktrees whose branches have been merged to main.
392
+
393
+ Returns:
394
+ List of spec_ids that were cleaned up.
395
+ """
396
+ cleaned = []
397
+
398
+ try:
399
+ # Get list of merged branches
400
+ try:
401
+ merged_branches = self.repo.git.branch("--merged", "main").split("\n")
402
+ merged_branches = [b.strip().lstrip("*").strip() for b in merged_branches]
403
+ except Exception:
404
+ merged_branches = []
405
+
406
+ # Check each worktree
407
+ for info in self.list():
408
+ if info.branch in merged_branches:
409
+ try:
410
+ self.remove(info.spec_id, force=True)
411
+ cleaned.append(info.spec_id)
412
+ except Exception:
413
+ pass
414
+
415
+ except Exception:
416
+ pass
417
+
418
+ return cleaned
419
+
420
+ def auto_resolve_conflicts(self, worktree_repo: Repo, spec_id: str, conflicted_files: List[str]) -> None:
421
+ """Automatically resolve conflicts in worktree.
422
+
423
+ Args:
424
+ worktree_repo: Git repository object for the worktree.
425
+ spec_id: SPEC ID for error reporting.
426
+ conflicted_files: List of conflicted files.
427
+
428
+ Raises:
429
+ GitOperationError: If auto-resolution fails.
430
+ """
431
+ try:
432
+ # Try common conflict resolution strategies
433
+ for file_path in conflicted_files:
434
+ try:
435
+ # Strategy 1: Accept current changes (ours)
436
+ worktree_repo.git.checkout("--ours", file_path)
437
+ worktree_repo.git.add(file_path)
438
+ except Exception:
439
+ # Strategy 2: Accept incoming changes (theirs) if ours fails
440
+ try:
441
+ worktree_repo.git.checkout("--theirs", file_path)
442
+ worktree_repo.git.add(file_path)
443
+ except Exception:
444
+ # Strategy 3: Remove conflict markers and keep both
445
+ try:
446
+ # Simple conflict marker removal - keep both versions
447
+
448
+ worktree_path = Path(worktree_repo.working_dir)
449
+ file_full_path = worktree_path / file_path
450
+
451
+ if file_full_path.exists():
452
+ with open(file_full_path, "r") as f:
453
+ content = f.read()
454
+
455
+ # Remove conflict markers and keep both versions
456
+ lines = content.split("\n")
457
+ cleaned_lines = []
458
+ skip_next = False
459
+ in_conflict = False
460
+
461
+ for line in lines:
462
+ if "<<<<<<<" in line or ">>>>>>>" in line:
463
+ in_conflict = True
464
+ continue
465
+ elif "======" in line:
466
+ skip_next = True
467
+ in_conflict = False
468
+ continue
469
+ elif skip_next:
470
+ skip_next = False
471
+ continue
472
+ elif not in_conflict:
473
+ cleaned_lines.append(line)
474
+
475
+ with open(file_full_path, "w") as f:
476
+ f.write("\n".join(cleaned_lines))
477
+
478
+ worktree_repo.git.add(file_path)
479
+ except Exception:
480
+ pass
481
+
482
+ # Stage resolved files
483
+ worktree_repo.git.add(".")
484
+
485
+ # Commit the merge resolution
486
+ worktree_repo.git.commit("-m", f"Auto-resolved conflicts during sync of {spec_id}")
487
+
488
+ except Exception as e:
489
+ # Auto-resolution failed, raise error for manual intervention
490
+ raise GitOperationError(f"Auto-resolution failed for {spec_id}: {e}")
@@ -0,0 +1,65 @@
1
+ """Data models for Git Worktree CLI."""
2
+
3
+ from dataclasses import dataclass
4
+ from pathlib import Path
5
+
6
+
7
+ @dataclass
8
+ class WorktreeInfo:
9
+ """Metadata information for a Git worktree.
10
+
11
+ This dataclass stores all essential information about a managed worktree,
12
+ including its location, associated branch, creation time, and status.
13
+ """
14
+
15
+ spec_id: str
16
+ """The SPEC ID associated with this worktree (e.g., 'SPEC-AUTH-001')."""
17
+
18
+ path: Path
19
+ """Absolute path to the worktree directory."""
20
+
21
+ branch: str
22
+ """The Git branch associated with this worktree."""
23
+
24
+ created_at: str
25
+ """ISO 8601 timestamp of worktree creation."""
26
+
27
+ last_accessed: str
28
+ """ISO 8601 timestamp of last access."""
29
+
30
+ status: str
31
+ """Current status of the worktree ('active', 'merged', 'stale')."""
32
+
33
+ def to_dict(self) -> dict:
34
+ """Convert WorktreeInfo to dictionary for JSON serialization.
35
+
36
+ Returns:
37
+ Dictionary with all worktree metadata.
38
+ """
39
+ return {
40
+ "spec_id": self.spec_id,
41
+ "path": str(self.path),
42
+ "branch": self.branch,
43
+ "created_at": self.created_at,
44
+ "last_accessed": self.last_accessed,
45
+ "status": self.status,
46
+ }
47
+
48
+ @classmethod
49
+ def from_dict(cls, data: dict) -> "WorktreeInfo":
50
+ """Create WorktreeInfo from dictionary (JSON deserialization).
51
+
52
+ Args:
53
+ data: Dictionary containing worktree metadata.
54
+
55
+ Returns:
56
+ New WorktreeInfo instance.
57
+ """
58
+ return cls(
59
+ spec_id=data["spec_id"],
60
+ path=Path(data["path"]),
61
+ branch=data["branch"],
62
+ created_at=data["created_at"],
63
+ last_accessed=data["last_accessed"],
64
+ status=data["status"],
65
+ )