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,1005 @@
1
+ """
2
+ MoAI Menu Project - Template Optimizer Module
3
+
4
+ Advanced template analysis, optimization, and performance management system.
5
+ Integrates patterns from moai-project-template-optimizer skill with
6
+ intelligent analysis and automated optimization capabilities.
7
+ """
8
+
9
+ import json
10
+ import re
11
+ import shutil
12
+ from datetime import datetime
13
+ from pathlib import Path
14
+ from typing import Any, Dict, List, Tuple
15
+
16
+
17
+ class TemplateOptimizer:
18
+ """Advanced template optimization and performance analysis system."""
19
+
20
+ def __init__(self, project_root: str, config: Dict[str, Any]):
21
+ self.project_root = Path(project_root)
22
+ self.config = config
23
+ self.templates_dir = self.project_root / ".claude/skills/moai-menu-project/templates"
24
+ self.backups_dir = self.project_root / ".moai-backups"
25
+ self.optimization_cache = {}
26
+ self._ensure_directories()
27
+
28
+ def _ensure_directories(self):
29
+ """Ensure all necessary directories exist."""
30
+ self.templates_dir.mkdir(parents=True, exist_ok=True)
31
+ self.backups_dir.mkdir(parents=True, exist_ok=True)
32
+ (self.templates_dir / "optimized").mkdir(exist_ok=True)
33
+ (self.templates_dir / "benchmarks").mkdir(exist_ok=True)
34
+
35
+ def analyze_project_templates(self) -> Dict[str, Any]:
36
+ """
37
+ Perform comprehensive analysis of project templates.
38
+
39
+ Returns:
40
+ Analysis results with performance metrics and optimization recommendations
41
+ """
42
+
43
+ analysis_result = {
44
+ "timestamp": datetime.now().isoformat(),
45
+ "project_root": str(self.project_root),
46
+ "template_files": [],
47
+ "performance_metrics": {},
48
+ "optimization_opportunities": [],
49
+ "backup_recommendations": [],
50
+ "complexity_analysis": {},
51
+ "resource_usage": {},
52
+ }
53
+
54
+ # Discover template files
55
+ template_files = self._discover_template_files()
56
+ analysis_result["template_files"] = template_files
57
+
58
+ # Analyze each template file
59
+ for template_file in template_files:
60
+ file_analysis = self._analyze_template_file(template_file)
61
+ analysis_result["performance_metrics"][template_file["path"]] = file_analysis
62
+
63
+ # Identify optimization opportunities
64
+ analysis_result["optimization_opportunities"] = self._identify_optimization_opportunities(
65
+ analysis_result["performance_metrics"]
66
+ )
67
+
68
+ # Analyze overall project complexity
69
+ analysis_result["complexity_analysis"] = self._analyze_project_complexity(template_files)
70
+
71
+ # Calculate resource usage patterns
72
+ analysis_result["resource_usage"] = self._calculate_resource_usage(template_files)
73
+
74
+ # Generate backup recommendations
75
+ analysis_result["backup_recommendations"] = self._generate_backup_recommendations(analysis_result)
76
+
77
+ return analysis_result
78
+
79
+ def _discover_template_files(self) -> List[Dict[str, Any]]:
80
+ """Discover all template files in the project."""
81
+
82
+ template_files = []
83
+
84
+ # Common template file patterns
85
+ template_patterns = [
86
+ "**/*.template",
87
+ "**/*.tmpl",
88
+ "**/*.mustache",
89
+ "**/*.hbs",
90
+ "**/*.handlebars",
91
+ "**/*.jinja",
92
+ "**/*.jinja2",
93
+ "**/*.erb",
94
+ "**/*.liquid",
95
+ ]
96
+
97
+ # Search for template files
98
+ for pattern in template_patterns:
99
+ for file_path in self.project_root.glob(pattern):
100
+ if file_path.is_file():
101
+ relative_path = file_path.relative_to(self.project_root)
102
+
103
+ # Calculate file metrics
104
+ file_stats = file_path.stat()
105
+
106
+ template_files.append(
107
+ {
108
+ "path": str(relative_path),
109
+ "absolute_path": str(file_path),
110
+ "size_bytes": file_stats.st_size,
111
+ "modified_time": datetime.fromtimestamp(file_stats.st_mtime).isoformat(),
112
+ "type": self._determine_template_type(file_path),
113
+ "language": self._determine_template_language(file_path),
114
+ }
115
+ )
116
+
117
+ # Also check common template directories
118
+ template_dirs = [
119
+ "templates",
120
+ "template",
121
+ "views",
122
+ "layouts",
123
+ "_layouts",
124
+ "_includes",
125
+ "_templates",
126
+ ]
127
+
128
+ for template_dir in template_dirs:
129
+ dir_path = self.project_root / template_dir
130
+ if dir_path.exists() and dir_path.is_dir():
131
+ for file_path in dir_path.rglob("*"):
132
+ if file_path.is_file() and file_path.suffix in [
133
+ ".md",
134
+ ".html",
135
+ ".txt",
136
+ ".yml",
137
+ ".yaml",
138
+ ".json",
139
+ ]:
140
+ # Check if file contains template markers
141
+ content = file_path.read_text(encoding="utf-8", errors="ignore")
142
+ if self._contains_template_markers(content):
143
+ relative_path = file_path.relative_to(self.project_root)
144
+ file_stats = file_path.stat()
145
+
146
+ template_files.append(
147
+ {
148
+ "path": str(relative_path),
149
+ "absolute_path": str(file_path),
150
+ "size_bytes": file_stats.st_size,
151
+ "modified_time": datetime.fromtimestamp(file_stats.st_mtime).isoformat(),
152
+ "type": "content_template",
153
+ "language": "text",
154
+ }
155
+ )
156
+
157
+ return sorted(template_files, key=lambda x: x["path"])
158
+
159
+ def _determine_template_type(self, file_path: Path) -> str:
160
+ """Determine template type based on file extension and content."""
161
+
162
+ extension_map = {
163
+ ".mustache": "mustache",
164
+ ".hbs": "handlebars",
165
+ ".handlebars": "handlebars",
166
+ ".jinja": "jinja",
167
+ ".jinja2": "jinja2",
168
+ ".erb": "erb",
169
+ ".liquid": "liquid",
170
+ }
171
+
172
+ return extension_map.get(file_path.suffix.lower(), "unknown")
173
+
174
+ def _determine_template_language(self, file_path: Path) -> str:
175
+ """Determine the primary language used in template."""
176
+
177
+ try:
178
+ content = file_path.read_text(encoding="utf-8", errors="ignore")
179
+
180
+ # Look for language-specific markers
181
+ if any(marker in content for marker in ["{{", "{%", "{#"]):
182
+ return "jinja"
183
+ elif any(marker in content for marker in ["{{", "{{#", "{{/"]):
184
+ return "handlebars"
185
+ elif any(marker in content for marker in ["<%", "<%=", "<%-"]):
186
+ return "erb"
187
+ elif any(marker in content for marker in ["{{ ", "{% ", "{{-"]):
188
+ return "liquid"
189
+ else:
190
+ return "text"
191
+
192
+ except (UnicodeDecodeError, OSError):
193
+ return "binary"
194
+
195
+ def _contains_template_markers(self, content: str) -> bool:
196
+ """Check if content contains template markers."""
197
+
198
+ template_markers = [
199
+ "{{",
200
+ "}}", # Generic template markers
201
+ "{%",
202
+ "%}", # Jinja-like
203
+ "{{#",
204
+ "{{/", # Handlebars-like
205
+ "<%",
206
+ "%>", # ERB-like
207
+ "{{-",
208
+ "-}}", # Liquid-like
209
+ "{#",
210
+ "#}", # Comment markers
211
+ "[[",
212
+ "]]", # Angular-like
213
+ "${",
214
+ "}", # Variable interpolation
215
+ ]
216
+
217
+ return any(marker in content for marker in template_markers)
218
+
219
+ def _analyze_template_file(self, template_file: Dict[str, Any]) -> Dict[str, Any]:
220
+ """Analyze individual template file for performance and complexity."""
221
+
222
+ file_path = Path(template_file["absolute_path"])
223
+
224
+ analysis = {
225
+ "file_path": template_file["path"],
226
+ "size_metrics": self._analyze_file_size(file_path),
227
+ "complexity_metrics": self._analyze_template_complexity(file_path),
228
+ "performance_metrics": self._estimate_template_performance(file_path),
229
+ "optimization_potential": 0,
230
+ "recommendations": [],
231
+ }
232
+
233
+ # Calculate overall optimization potential
234
+ analysis["optimization_potential"] = self._calculate_optimization_potential(analysis)
235
+
236
+ # Generate specific recommendations
237
+ analysis["recommendations"] = self._generate_file_recommendations(analysis)
238
+
239
+ return analysis
240
+
241
+ def _analyze_file_size(self, file_path: Path) -> Dict[str, Any]:
242
+ """Analyze file size and content metrics."""
243
+
244
+ try:
245
+ content = file_path.read_text(encoding="utf-8")
246
+
247
+ lines = content.splitlines()
248
+
249
+ return {
250
+ "total_size_bytes": len(content.encode("utf-8")),
251
+ "character_count": len(content),
252
+ "line_count": len(lines),
253
+ "blank_lines": sum(1 for line in lines if not line.strip()),
254
+ "average_line_length": (sum(len(line) for line in lines) / len(lines) if lines else 0),
255
+ "max_line_length": max(len(line) for line in lines) if lines else 0,
256
+ }
257
+
258
+ except (UnicodeDecodeError, OSError):
259
+ return {
260
+ "total_size_bytes": file_path.stat().st_size,
261
+ "character_count": 0,
262
+ "line_count": 0,
263
+ "blank_lines": 0,
264
+ "average_line_length": 0,
265
+ "max_line_length": 0,
266
+ }
267
+
268
+ def _analyze_template_complexity(self, file_path: Path) -> Dict[str, Any]:
269
+ """Analyze template complexity metrics."""
270
+
271
+ try:
272
+ content = file_path.read_text(encoding="utf-8", errors="ignore")
273
+
274
+ complexity = {
275
+ "variable_count": 0,
276
+ "loop_count": 0,
277
+ "conditional_count": 0,
278
+ "include_count": 0,
279
+ "nested_level_max": 0,
280
+ "template_depth": 0,
281
+ }
282
+
283
+ # Count different template constructs
284
+ complexity["variable_count"] = len(re.findall(r"\{\{[^}]+\}\}", content))
285
+ complexity["loop_count"] = len(re.findall(r"\{%\s*for\s+.+\s+in\s+.+%\}", content))
286
+ complexity["conditional_count"] = len(re.findall(r"\{%\s*if\s+.+%\}", content))
287
+ complexity["include_count"] = len(re.findall(r"\{%\s*(include|extend|import)\s+.+%\}", content))
288
+
289
+ # Calculate nesting level
290
+ current_level = 0
291
+ max_level = 0
292
+
293
+ for char in content:
294
+ if char == "{":
295
+ if content[content.index(char) : content.index(char) + 2] in [
296
+ "{{",
297
+ "{%",
298
+ ]:
299
+ current_level += 1
300
+ max_level = max(max_level, current_level)
301
+ elif char == "}":
302
+ if current_level > 0:
303
+ current_level -= 1
304
+
305
+ complexity["nested_level_max"] = max_level
306
+ complexity["template_depth"] = self._calculate_template_depth(content)
307
+
308
+ except (UnicodeDecodeError, OSError):
309
+ complexity = {
310
+ "variable_count": 0,
311
+ "loop_count": 0,
312
+ "conditional_count": 0,
313
+ "include_count": 0,
314
+ "nested_level_max": 0,
315
+ "template_depth": 0,
316
+ }
317
+
318
+ return complexity
319
+
320
+ def _calculate_template_depth(self, content: str) -> int:
321
+ """Calculate template inheritance depth."""
322
+
323
+ # Look for extends, include, import statements
324
+ depth_patterns = [
325
+ r'\{%\s*extends\s+["\']([^"\']+)["\']\s*%\}',
326
+ r'\{%\s*include\s+["\']([^"\']+)["\']\s*%\}',
327
+ r'\{%\s*import\s+["\']([^"\']+)["\']\s*%\}',
328
+ ]
329
+
330
+ depth = 0
331
+ for pattern in depth_patterns:
332
+ matches = re.findall(pattern, content)
333
+ depth += len(matches)
334
+
335
+ return min(depth, 10) # Cap at reasonable maximum
336
+
337
+ def _estimate_template_performance(self, file_path: Path) -> Dict[str, Any]:
338
+ """Estimate template rendering performance."""
339
+
340
+ size_analysis = self._analyze_file_size(file_path)
341
+ complexity_analysis = self._analyze_template_complexity(file_path)
342
+
343
+ performance = {
344
+ "estimated_render_time_ms": 0,
345
+ "memory_usage_estimate_kb": 0,
346
+ "cpu_intensity": "low",
347
+ "cache_friendly": True,
348
+ "render_complexity_score": 0,
349
+ }
350
+
351
+ # Basic performance estimation based on size and complexity
352
+ base_time = 1.0 # Base render time in ms
353
+
354
+ # Add time for complexity
355
+ complexity_time = (
356
+ complexity_analysis["variable_count"] * 0.1
357
+ + complexity_analysis["loop_count"] * 2.0
358
+ + complexity_analysis["conditional_count"] * 0.5
359
+ + complexity_analysis["include_count"] * 1.0
360
+ )
361
+
362
+ # Add time for file size
363
+ size_time = size_analysis["total_size_bytes"] / 10000 # 10KB per ms
364
+
365
+ performance["estimated_render_time_ms"] = base_time + complexity_time + size_time
366
+
367
+ # Estimate memory usage
368
+ performance["memory_usage_estimate_kb"] = size_analysis["total_size_bytes"] / 1024
369
+
370
+ # Determine CPU intensity
371
+ if performance["estimated_render_time_ms"] > 100:
372
+ performance["cpu_intensity"] = "high"
373
+ elif performance["estimated_render_time_ms"] > 50:
374
+ performance["cpu_intensity"] = "medium"
375
+ else:
376
+ performance["cpu_intensity"] = "low"
377
+
378
+ # Check cache friendliness
379
+ performance["cache_friendly"] = (
380
+ complexity_analysis["variable_count"] < 50
381
+ and complexity_analysis["loop_count"] < 10
382
+ and performance["estimated_render_time_ms"] < 100
383
+ )
384
+
385
+ # Calculate render complexity score
386
+ performance["render_complexity_score"] = (
387
+ complexity_analysis["variable_count"] * 1
388
+ + complexity_analysis["loop_count"] * 3
389
+ + complexity_analysis["conditional_count"] * 2
390
+ + complexity_analysis["nested_level_max"] * 4
391
+ )
392
+
393
+ return performance
394
+
395
+ def _calculate_optimization_potential(self, file_analysis: Dict[str, Any]) -> float:
396
+ """Calculate optimization potential score (0-100)."""
397
+
398
+ potential = 0.0
399
+
400
+ # Size-based potential
401
+ size_metrics = file_analysis["size_metrics"]
402
+ if size_metrics["total_size_bytes"] > 50000: # 50KB
403
+ potential += 20
404
+ elif size_metrics["total_size_bytes"] > 20000: # 20KB
405
+ potential += 10
406
+
407
+ # Complexity-based potential
408
+ complexity_metrics = file_analysis["complexity_metrics"]
409
+ if complexity_metrics["nested_level_max"] > 5:
410
+ potential += 15
411
+ elif complexity_metrics["nested_level_max"] > 3:
412
+ potential += 8
413
+
414
+ if complexity_metrics["variable_count"] > 100:
415
+ potential += 10
416
+ elif complexity_metrics["variable_count"] > 50:
417
+ potential += 5
418
+
419
+ # Performance-based potential
420
+ performance_metrics = file_analysis["performance_metrics"]
421
+ if performance_metrics["estimated_render_time_ms"] > 100:
422
+ potential += 20
423
+ elif performance_metrics["estimated_render_time_ms"] > 50:
424
+ potential += 10
425
+
426
+ if not performance_metrics["cache_friendly"]:
427
+ potential += 15
428
+
429
+ return min(potential, 100) # Cap at 100
430
+
431
+ def _generate_file_recommendations(self, file_analysis: Dict[str, Any]) -> List[str]:
432
+ """Generate optimization recommendations for a file."""
433
+
434
+ recommendations = []
435
+
436
+ size_metrics = file_analysis["size_metrics"]
437
+ complexity_metrics = file_analysis["complexity_metrics"]
438
+ performance_metrics = file_analysis["performance_metrics"]
439
+
440
+ # Size recommendations
441
+ if size_metrics["total_size_bytes"] > 50000:
442
+ recommendations.append("Consider splitting large template into smaller components")
443
+
444
+ if size_metrics["max_line_length"] > 200:
445
+ recommendations.append("Break long lines for better readability")
446
+
447
+ # Complexity recommendations
448
+ if complexity_metrics["nested_level_max"] > 5:
449
+ recommendations.append("Reduce nesting level by extracting sub-templates")
450
+
451
+ if complexity_metrics["variable_count"] > 100:
452
+ recommendations.append("Consider consolidating related variables")
453
+
454
+ if complexity_metrics["loop_count"] > 10:
455
+ recommendations.append("Optimize loops and consider pagination for large datasets")
456
+
457
+ # Performance recommendations
458
+ if performance_metrics["estimated_render_time_ms"] > 100:
459
+ recommendations.append("Implement template caching for better performance")
460
+
461
+ if not performance_metrics["cache_friendly"]:
462
+ recommendations.append("Restructure template for better cache efficiency")
463
+
464
+ if performance_metrics["cpu_intensity"] == "high":
465
+ recommendations.append("Consider moving complex logic to template filters or functions")
466
+
467
+ return recommendations
468
+
469
+ def _identify_optimization_opportunities(self, performance_metrics: Dict[str, Any]) -> List[Dict[str, Any]]:
470
+ """Identify global optimization opportunities across all templates."""
471
+
472
+ opportunities = []
473
+
474
+ # Analyze patterns across all files
475
+ total_files = len(performance_metrics)
476
+ if total_files == 0:
477
+ return opportunities
478
+
479
+ # Calculate aggregate metrics
480
+ total_size = sum(metrics["size_metrics"]["total_size_bytes"] for metrics in performance_metrics.values())
481
+ avg_render_time = (
482
+ sum(metrics["performance_metrics"]["estimated_render_time_ms"] for metrics in performance_metrics.values())
483
+ / total_files
484
+ )
485
+ high_complexity_files = sum(
486
+ 1 for metrics in performance_metrics.values() if metrics["complexity_metrics"]["nested_level_max"] > 3
487
+ )
488
+
489
+ # Size optimization opportunities
490
+ if total_size > 100000: # 100KB total
491
+ opportunities.append(
492
+ {
493
+ "type": "size_optimization",
494
+ "priority": "high",
495
+ "description": f"Large total template size ({total_size / 1024:.1f}KB)",
496
+ "recommendation": "Consider consolidating shared templates and removing unused content",
497
+ "estimated_impact": "15-25% reduction in load time",
498
+ }
499
+ )
500
+
501
+ # Performance optimization opportunities
502
+ if avg_render_time > 50:
503
+ opportunities.append(
504
+ {
505
+ "type": "performance_optimization",
506
+ "priority": "medium",
507
+ "description": f"Average render time is high ({avg_render_time:.1f}ms)",
508
+ "recommendation": "Implement template caching and optimize complex templates",
509
+ "estimated_impact": "20-40% improvement in render time",
510
+ }
511
+ )
512
+
513
+ # Complexity optimization opportunities
514
+ if high_complexity_files > total_files * 0.3: # More than 30% files are complex
515
+ opportunities.append(
516
+ {
517
+ "type": "complexity_optimization",
518
+ "priority": "medium",
519
+ "description": f"High complexity in {high_complexity_files} of {total_files} templates",
520
+ "recommendation": "Extract complex logic into template filters and reduce nesting",
521
+ "estimated_impact": "Improved maintainability and 10-20% performance gain",
522
+ }
523
+ )
524
+
525
+ # Template reuse opportunities
526
+ template_types = {}
527
+ for metrics in performance_metrics.values():
528
+ file_path = Path(metrics["file_path"])
529
+ template_type = file_path.suffix
530
+ template_types[template_type] = template_types.get(template_type, 0) + 1
531
+
532
+ common_types = [t for t, count in template_types.items() if count > 3]
533
+ if common_types:
534
+ opportunities.append(
535
+ {
536
+ "type": "template_reuse",
537
+ "priority": "low",
538
+ "description": f"Multiple templates of type: {', '.join(common_types)}",
539
+ "recommendation": "Create base templates and use template inheritance",
540
+ "estimated_impact": "Reduced duplication and easier maintenance",
541
+ }
542
+ )
543
+
544
+ return sorted(
545
+ opportunities,
546
+ key=lambda x: {"high": 3, "medium": 2, "low": 1}.get(x["priority"], 0),
547
+ reverse=True,
548
+ )
549
+
550
+ def _analyze_project_complexity(self, template_files: List[Dict[str, Any]]) -> Dict[str, Any]:
551
+ """Analyze overall project template complexity."""
552
+
553
+ complexity_analysis = {
554
+ "total_files": len(template_files),
555
+ "total_size_bytes": sum(f["size_bytes"] for f in template_files),
556
+ "file_types": {},
557
+ "template_languages": {},
558
+ "average_file_size": 0,
559
+ "complexity_distribution": {"low": 0, "medium": 0, "high": 0},
560
+ }
561
+
562
+ if template_files:
563
+ complexity_analysis["average_file_size"] = complexity_analysis["total_size_bytes"] / len(template_files)
564
+
565
+ # Analyze file types
566
+ for template_file in template_files:
567
+ file_type = template_file["type"]
568
+ complexity_analysis["file_types"][file_type] = complexity_analysis["file_types"].get(file_type, 0) + 1
569
+
570
+ lang = template_file["language"]
571
+ complexity_analysis["template_languages"][lang] = complexity_analysis["template_languages"].get(lang, 0) + 1
572
+
573
+ return complexity_analysis
574
+
575
+ def _calculate_resource_usage(self, template_files: List[Dict[str, Any]]) -> Dict[str, Any]:
576
+ """Calculate resource usage patterns and predictions."""
577
+
578
+ resource_usage = {
579
+ "disk_usage": {
580
+ "total_bytes": sum(f["size_bytes"] for f in template_files),
581
+ "average_file_size": 0,
582
+ "largest_file": None,
583
+ },
584
+ "memory_estimates": {"peak_usage_kb": 0, "average_usage_kb": 0},
585
+ "performance_predictions": {
586
+ "concurrent_render_support": 0,
587
+ "recommended_cache_size_mb": 0,
588
+ },
589
+ }
590
+
591
+ if template_files:
592
+ resource_usage["disk_usage"]["average_file_size"] = resource_usage["disk_usage"]["total_bytes"] / len(
593
+ template_files
594
+ )
595
+ resource_usage["disk_usage"]["largest_file"] = max(template_files, key=lambda f: f["size_bytes"])["path"]
596
+
597
+ # Estimate memory usage (rough approximation: 3x file size for processing)
598
+ total_size_kb = resource_usage["disk_usage"]["total_bytes"] / 1024
599
+ resource_usage["memory_estimates"]["average_usage_kb"] = total_size_kb * 3
600
+ resource_usage["memory_estimates"]["peak_usage_kb"] = total_size_kb * 5
601
+
602
+ # Performance predictions
603
+ avg_file_size_kb = resource_usage["disk_usage"]["average_file_size"] / 1024
604
+ resource_usage["performance_predictions"]["concurrent_render_support"] = int(
605
+ 1000 / (avg_file_size_kb + 10)
606
+ ) # Rough estimate
607
+ resource_usage["performance_predictions"]["recommended_cache_size_mb"] = max(1, int(total_size_kb / 1024))
608
+
609
+ return resource_usage
610
+
611
+ def _generate_backup_recommendations(self, analysis_result: Dict[str, Any]) -> List[Dict[str, Any]]:
612
+ """Generate backup recommendations based on analysis."""
613
+
614
+ recommendations = []
615
+
616
+ template_count = len(analysis_result["template_files"])
617
+ total_size = analysis_result["complexity_analysis"]["total_size_bytes"]
618
+ optimization_opportunities = analysis_result["optimization_opportunities"]
619
+
620
+ # Create backup if optimization opportunities exist
621
+ if optimization_opportunities:
622
+ high_priority_ops = [op for op in optimization_opportunities if op["priority"] == "high"]
623
+
624
+ if high_priority_ops:
625
+ recommendations.append(
626
+ {
627
+ "type": "pre_optimization_backup",
628
+ "priority": "high",
629
+ "description": "Create backup before applying optimizations",
630
+ "reason": "High-impact optimizations detected",
631
+ "backup_size_estimate": total_size,
632
+ "recommended_backup_name": f"backup-{datetime.now().strftime('%Y-%m-%d')}-pre-optimization",
633
+ }
634
+ )
635
+
636
+ # Regular backup recommendations
637
+ if template_count > 10:
638
+ recommendations.append(
639
+ {
640
+ "type": "regular_backup",
641
+ "priority": "medium",
642
+ "description": "Regular backup recommended for large template collections",
643
+ "reason": f"{template_count} template files detected",
644
+ "backup_frequency": "weekly",
645
+ }
646
+ )
647
+
648
+ # Version control recommendations
649
+ if not (self.project_root / ".git").exists():
650
+ recommendations.append(
651
+ {
652
+ "type": "version_control",
653
+ "priority": "low",
654
+ "description": "Consider using Git for template version control",
655
+ "reason": "No version control system detected",
656
+ "suggested_action": "Initialize Git repository",
657
+ }
658
+ )
659
+
660
+ return recommendations
661
+
662
+ def create_optimized_templates(self, optimization_options: Dict[str, Any] = None) -> Dict[str, Any]:
663
+ """
664
+ Create optimized versions of templates.
665
+
666
+ Args:
667
+ optimization_options: Options for optimization process
668
+
669
+ Returns:
670
+ Optimization results and created files
671
+ """
672
+
673
+ if optimization_options is None:
674
+ optimization_options = {
675
+ "backup_first": True,
676
+ "apply_size_optimizations": True,
677
+ "apply_performance_optimizations": True,
678
+ "apply_complexity_optimizations": True,
679
+ "preserve_functionality": True,
680
+ }
681
+
682
+ optimization_result = {
683
+ "timestamp": datetime.now().isoformat(),
684
+ "options_used": optimization_options,
685
+ "backup_created": False,
686
+ "optimized_files": [],
687
+ "optimizations_applied": [],
688
+ "size_reduction": 0,
689
+ "performance_improvement": 0,
690
+ "errors": [],
691
+ }
692
+
693
+ # Create backup if requested
694
+ if optimization_options.get("backup_first", True):
695
+ backup_result = self._create_template_backup("pre-optimization")
696
+ optimization_result["backup_created"] = backup_result["success"]
697
+ optimization_result["backup_info"] = backup_result
698
+
699
+ # Analyze current templates
700
+ analysis = self.analyze_project_templates()
701
+
702
+ # Apply optimizations
703
+ for template_file in analysis["template_files"]:
704
+ file_optimization = self._optimize_template_file(template_file, optimization_options)
705
+
706
+ if file_optimization["success"]:
707
+ optimization_result["optimized_files"].append(file_optimization)
708
+ optimization_result["optimizations_applied"].extend(file_optimization["applied_optimizations"])
709
+ else:
710
+ optimization_result["errors"].append(
711
+ {
712
+ "file": template_file["path"],
713
+ "error": file_optimization.get("error", "Unknown error"),
714
+ }
715
+ )
716
+
717
+ # Calculate overall improvements
718
+ if optimization_result["optimized_files"]:
719
+ original_total_size = sum(f["size_bytes"] for f in analysis["template_files"])
720
+ optimized_total_size = sum(f["optimized_size_bytes"] for f in optimization_result["optimized_files"])
721
+
722
+ if original_total_size > 0:
723
+ optimization_result["size_reduction"] = (
724
+ (original_total_size - optimized_total_size) / original_total_size * 100
725
+ )
726
+
727
+ return optimization_result
728
+
729
+ def _create_template_backup(self, backup_name: str = None) -> Dict[str, Any]:
730
+ """Create backup of all template files."""
731
+
732
+ if backup_name is None:
733
+ backup_name = f"backup-{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}"
734
+
735
+ backup_path = self.backups_dir / backup_name
736
+ backup_path.mkdir(parents=True, exist_ok=True)
737
+
738
+ backup_result = {
739
+ "backup_name": backup_name,
740
+ "backup_path": str(backup_path),
741
+ "success": False,
742
+ "files_backed_up": 0,
743
+ "total_size_bytes": 0,
744
+ "created_at": datetime.now().isoformat(),
745
+ }
746
+
747
+ try:
748
+ # Discover and backup template files
749
+ template_files = self._discover_template_files()
750
+
751
+ for template_file in template_files:
752
+ source_path = Path(template_file["absolute_path"])
753
+ relative_path = Path(template_file["path"])
754
+ backup_file_path = backup_path / relative_path
755
+
756
+ # Ensure backup directory exists
757
+ backup_file_path.parent.mkdir(parents=True, exist_ok=True)
758
+
759
+ # Copy file
760
+ shutil.copy2(source_path, backup_file_path)
761
+ backup_result["files_backed_up"] += 1
762
+ backup_result["total_size_bytes"] += template_file["size_bytes"]
763
+
764
+ # Create backup metadata
765
+ metadata = {
766
+ "backup_name": backup_name,
767
+ "created_at": backup_result["created_at"],
768
+ "files_backed_up": backup_result["files_backed_up"],
769
+ "total_size_bytes": backup_result["total_size_bytes"],
770
+ "project_root": str(self.project_root),
771
+ "template_files": template_files,
772
+ }
773
+
774
+ metadata_path = backup_path / "backup-metadata.json"
775
+ metadata_path.write_text(json.dumps(metadata, indent=2, ensure_ascii=False), encoding="utf-8")
776
+
777
+ backup_result["success"] = True
778
+
779
+ except Exception as e:
780
+ backup_result["error"] = str(e)
781
+
782
+ return backup_result
783
+
784
+ def _optimize_template_file(self, template_file: Dict[str, Any], options: Dict[str, Any]) -> Dict[str, Any]:
785
+ """Optimize individual template file."""
786
+
787
+ file_path = Path(template_file["absolute_path"])
788
+ optimization_result = {
789
+ "file_path": template_file["path"],
790
+ "success": False,
791
+ "original_size_bytes": template_file["size_bytes"],
792
+ "optimized_size_bytes": 0,
793
+ "applied_optimizations": [],
794
+ "error": None,
795
+ }
796
+
797
+ try:
798
+ # Read original content
799
+ original_content = file_path.read_text(encoding="utf-8")
800
+ optimized_content = original_content
801
+ applied_optimizations = []
802
+
803
+ # Apply size optimizations
804
+ if options.get("apply_size_optimizations", True):
805
+ size_optimized, size_opts = self._apply_size_optimizations(optimized_content)
806
+ if size_optimized != optimized_content:
807
+ optimized_content = size_optimized
808
+ applied_optimizations.extend(size_opts)
809
+
810
+ # Apply performance optimizations
811
+ if options.get("apply_performance_optimizations", True):
812
+ perf_optimized, perf_opts = self._apply_performance_optimizations(optimized_content)
813
+ if perf_optimized != optimized_content:
814
+ optimized_content = perf_optimized
815
+ applied_optimizations.extend(perf_opts)
816
+
817
+ # Apply complexity optimizations
818
+ if options.get("apply_complexity_optimizations", True):
819
+ complexity_optimized, complexity_opts = self._apply_complexity_optimizations(optimized_content)
820
+ if complexity_optimized != optimized_content:
821
+ optimized_content = complexity_optimized
822
+ applied_optimizations.extend(complexity_opts)
823
+
824
+ # Write optimized version
825
+ if optimized_content != original_content:
826
+ # Create optimized version
827
+ optimized_dir = self.templates_dir / "optimized"
828
+ relative_path = file_path.relative_to(self.project_root)
829
+ optimized_file_path = optimized_dir / relative_path
830
+
831
+ optimized_file_path.parent.mkdir(parents=True, exist_ok=True)
832
+ optimized_file_path.write_text(optimized_content, encoding="utf-8")
833
+
834
+ optimization_result.update(
835
+ {
836
+ "success": True,
837
+ "optimized_size_bytes": len(optimized_content.encode("utf-8")),
838
+ "applied_optimizations": applied_optimizations,
839
+ "optimized_file_path": str(optimized_file_path),
840
+ }
841
+ )
842
+ else:
843
+ optimization_result["success"] = True
844
+ optimization_result["message"] = "No optimizations needed"
845
+
846
+ except Exception as e:
847
+ optimization_result["error"] = str(e)
848
+
849
+ return optimization_result
850
+
851
+ def _apply_size_optimizations(self, content: str) -> Tuple[str, List[str]]:
852
+ """Apply size reduction optimizations."""
853
+
854
+ optimized_content = content
855
+ applied_optimizations = []
856
+
857
+ # Remove excessive whitespace
858
+ original_lines = content.splitlines()
859
+ optimized_lines = []
860
+
861
+ for line in original_lines:
862
+ # Remove leading/trailing whitespace but preserve template indentation
863
+ stripped_line = line.rstrip()
864
+ if stripped_line or line.strip() == "":
865
+ optimized_lines.append(stripped_line)
866
+
867
+ optimized_content = "\n".join(optimized_lines)
868
+
869
+ if len(optimized_content) < len(content) * 0.95: # At least 5% reduction
870
+ applied_optimizations.append("whitespace_optimization")
871
+
872
+ # Remove redundant template markers
873
+ # (This would be more sophisticated in practice)
874
+ optimized_content = re.sub(r"\{\{\s+\{\{", "{{", optimized_content)
875
+ optimized_content = re.sub(r"\}\}\s+\}\}", "}}", optimized_content)
876
+
877
+ if optimized_content != content:
878
+ applied_optimizations.append("template_marker_optimization")
879
+
880
+ return optimized_content, applied_optimizations
881
+
882
+ def _apply_performance_optimizations(self, content: str) -> Tuple[str, List[str]]:
883
+ """Apply performance optimizations."""
884
+
885
+ optimized_content = content
886
+ applied_optimizations = []
887
+
888
+ # Optimize loop structures
889
+ # This is a simplified example - real optimization would be more sophisticated
890
+ original_content = optimized_content
891
+
892
+ # Replace complex inline conditions with template filters
893
+ optimized_content = re.sub(
894
+ r"\{\{\s*if\s+(.+?)\s*%\}\s*\{\{\s*(.+?)\s*\}\}\s*\{\%\s*else\s*%\}\s*\{\{\s*(.+?)\s*\}\}\s*\{\%\s*endif\s*%\}",
895
+ r'{{ \1 | default("\3") if \2 else "\3" }}',
896
+ optimized_content,
897
+ )
898
+
899
+ if optimized_content != original_content:
900
+ applied_optimizations.append("conditional_optimization")
901
+
902
+ # Cache expensive operations
903
+ optimized_content = re.sub(r"\{\{\s*(.+?)\|length\s*\}\}", r"{{ \1 | length }}", optimized_content)
904
+
905
+ return optimized_content, applied_optimizations
906
+
907
+ def _apply_complexity_optimizations(self, content: str) -> Tuple[str, List[str]]:
908
+ """Apply complexity reduction optimizations."""
909
+
910
+ optimized_content = content
911
+ applied_optimizations = []
912
+
913
+ # Extract complex nested structures into separate templates
914
+ # This is a simplified detection - real implementation would be more advanced
915
+
916
+ # Find deeply nested structures (simplified example)
917
+ nesting_level = 0
918
+ max_nesting = 0
919
+ lines = content.splitlines()
920
+
921
+ for line in lines:
922
+ open_blocks = line.count("{%") + line.count("{{")
923
+ close_blocks = line.count("%}") + line.count("}}")
924
+ nesting_level += open_blocks - close_blocks
925
+ max_nesting = max(max_nesting, nesting_level)
926
+
927
+ if max_nesting > 5:
928
+ applied_optimizations.append("complexity_reduction_needed")
929
+ # In practice, this would extract nested content to separate templates
930
+
931
+ return optimized_content, applied_optimizations
932
+
933
+ def benchmark_template_performance(self, template_paths: List[str] = None) -> Dict[str, Any]:
934
+ """
935
+ Benchmark template rendering performance.
936
+
937
+ Args:
938
+ template_paths: Specific templates to benchmark (all if None)
939
+
940
+ Returns:
941
+ Performance benchmark results
942
+ """
943
+
944
+ benchmark_result = {
945
+ "timestamp": datetime.now().isoformat(),
946
+ "benchmark_files": template_paths or [],
947
+ "performance_metrics": {},
948
+ "summary": {
949
+ "total_files_tested": 0,
950
+ "average_render_time_ms": 0,
951
+ "fastest_file": None,
952
+ "slowest_file": None,
953
+ },
954
+ }
955
+
956
+ # Get files to benchmark
957
+ if template_paths is None:
958
+ template_files = self._discover_template_files()
959
+ template_paths = [f["path"] for f in template_files]
960
+
961
+ benchmark_result["benchmark_files"] = template_paths
962
+ render_times = []
963
+
964
+ for template_path in template_paths:
965
+ file_path = self.project_root / template_path
966
+ if file_path.exists():
967
+ performance_metrics = self._estimate_template_performance(file_path)
968
+
969
+ benchmark_result["performance_metrics"][template_path] = {
970
+ "estimated_render_time_ms": performance_metrics["estimated_render_time_ms"],
971
+ "memory_usage_kb": performance_metrics["memory_usage_estimate_kb"],
972
+ "cpu_intensity": performance_metrics["cpu_intensity"],
973
+ "cache_friendly": performance_metrics["cache_friendly"],
974
+ "complexity_score": performance_metrics["render_complexity_score"],
975
+ }
976
+
977
+ render_times.append(performance_metrics["estimated_render_time_ms"])
978
+
979
+ # Calculate summary
980
+ if render_times:
981
+ benchmark_result["summary"]["total_files_tested"] = len(render_times)
982
+ benchmark_result["summary"]["average_render_time_ms"] = sum(render_times) / len(render_times)
983
+
984
+ # Find fastest and slowest files
985
+ min_time_idx = render_times.index(min(render_times))
986
+ max_time_idx = render_times.index(max(render_times))
987
+
988
+ benchmark_result["summary"]["fastest_file"] = {
989
+ "path": template_paths[min_time_idx],
990
+ "render_time_ms": min(render_times),
991
+ }
992
+
993
+ benchmark_result["summary"]["slowest_file"] = {
994
+ "path": template_paths[max_time_idx],
995
+ "render_time_ms": max(render_times),
996
+ }
997
+
998
+ # Save benchmark results
999
+ benchmark_dir = self.templates_dir / "benchmarks"
1000
+ benchmark_dir.mkdir(exist_ok=True)
1001
+
1002
+ benchmark_file = benchmark_dir / f"benchmark-{datetime.now().strftime('%Y%m%d-%H%M%S')}.json"
1003
+ benchmark_file.write_text(json.dumps(benchmark_result, indent=2, ensure_ascii=False), encoding="utf-8")
1004
+
1005
+ return benchmark_result