moai-adk 0.34.0__py3-none-any.whl → 1.1.0__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.
Files changed (524) hide show
  1. moai_adk/__main__.py +136 -5
  2. moai_adk/astgrep/__init__.py +37 -0
  3. moai_adk/astgrep/analyzer.py +522 -0
  4. moai_adk/astgrep/models.py +124 -0
  5. moai_adk/astgrep/rules.py +179 -0
  6. moai_adk/cli/commands/analyze.py +11 -2
  7. moai_adk/cli/commands/doctor.py +7 -1
  8. moai_adk/cli/commands/init.py +321 -11
  9. moai_adk/cli/commands/language.py +7 -1
  10. moai_adk/cli/commands/rank.py +449 -0
  11. moai_adk/cli/commands/status.py +7 -1
  12. moai_adk/cli/commands/switch.py +325 -0
  13. moai_adk/cli/commands/update.py +296 -23
  14. moai_adk/cli/prompts/init_prompts.py +362 -66
  15. moai_adk/cli/prompts/translations/__init__.py +573 -0
  16. moai_adk/cli/ui/prompts.py +61 -2
  17. moai_adk/cli/worktree/cli.py +106 -1
  18. moai_adk/cli/worktree/manager.py +155 -0
  19. moai_adk/core/config/unified.py +244 -63
  20. moai_adk/core/credentials.py +264 -0
  21. moai_adk/core/error_recovery_system.py +22 -4
  22. moai_adk/core/git/conflict_detector.py +10 -1
  23. moai_adk/core/git/event_detector.py +16 -5
  24. moai_adk/core/integration/engine.py +2 -2
  25. moai_adk/core/integration/integration_tester.py +5 -5
  26. moai_adk/core/language_config_resolver.py +9 -3
  27. moai_adk/core/merge/analyzer.py +509 -324
  28. moai_adk/core/migration/alfred_to_moai_migrator.py +7 -1
  29. moai_adk/core/migration/backup_manager.py +54 -4
  30. moai_adk/core/migration/file_migrator.py +174 -2
  31. moai_adk/core/migration/interactive_checkbox_ui.py +42 -31
  32. moai_adk/core/migration/version_detector.py +123 -19
  33. moai_adk/core/migration/version_migrator.py +44 -9
  34. moai_adk/core/model_allocator.py +241 -0
  35. moai_adk/core/project/backup_utils.py +12 -2
  36. moai_adk/core/project/initializer.py +44 -87
  37. moai_adk/core/project/phase_executor.py +95 -33
  38. moai_adk/core/project/validator.py +16 -1
  39. moai_adk/core/quality/trust_checker.py +30 -10
  40. moai_adk/core/rollback_manager.py +60 -25
  41. moai_adk/core/template/backup.py +88 -6
  42. moai_adk/core/template/config.py +33 -9
  43. moai_adk/core/template/merger.py +34 -8
  44. moai_adk/core/template/processor.py +334 -11
  45. moai_adk/core/template_engine.py +10 -1
  46. moai_adk/core/template_variable_synchronizer.py +16 -2
  47. moai_adk/core/version_sync.py +54 -6
  48. moai_adk/foundation/__init__.py +1 -20
  49. moai_adk/foundation/testing.py +1 -1
  50. moai_adk/loop/__init__.py +54 -0
  51. moai_adk/loop/controller.py +305 -0
  52. moai_adk/loop/feedback.py +230 -0
  53. moai_adk/loop/state.py +209 -0
  54. moai_adk/loop/storage.py +220 -0
  55. moai_adk/lsp/__init__.py +70 -0
  56. moai_adk/lsp/client.py +320 -0
  57. moai_adk/lsp/models.py +261 -0
  58. moai_adk/lsp/protocol.py +404 -0
  59. moai_adk/lsp/server_manager.py +248 -0
  60. moai_adk/project/configuration.py +8 -1
  61. moai_adk/py.typed +0 -0
  62. moai_adk/ralph/__init__.py +37 -0
  63. moai_adk/ralph/engine.py +307 -0
  64. moai_adk/rank/__init__.py +21 -0
  65. moai_adk/rank/auth.py +425 -0
  66. moai_adk/rank/client.py +557 -0
  67. moai_adk/rank/config.py +147 -0
  68. moai_adk/rank/hook.py +1503 -0
  69. moai_adk/rank/py.typed +0 -0
  70. moai_adk/statusline/__init__.py +3 -0
  71. moai_adk/statusline/enhanced_output_style_detector.py +5 -5
  72. moai_adk/statusline/main.py +20 -1
  73. moai_adk/statusline/memory_collector.py +268 -0
  74. moai_adk/statusline/renderer.py +54 -38
  75. moai_adk/tag_system/__init__.py +48 -0
  76. moai_adk/tag_system/atomic_ops.py +117 -0
  77. moai_adk/tag_system/linkage.py +335 -0
  78. moai_adk/tag_system/parser.py +176 -0
  79. moai_adk/tag_system/validator.py +200 -0
  80. moai_adk/templates/.claude/agents/moai/builder-agent.md +19 -3
  81. moai_adk/templates/.claude/agents/moai/builder-command.md +62 -16
  82. moai_adk/templates/.claude/agents/moai/builder-plugin.md +763 -0
  83. moai_adk/templates/.claude/agents/moai/builder-skill.md +21 -5
  84. moai_adk/templates/.claude/agents/moai/expert-backend.md +103 -39
  85. moai_adk/templates/.claude/agents/moai/expert-debug.md +9 -3
  86. moai_adk/templates/.claude/agents/moai/expert-devops.md +16 -14
  87. moai_adk/templates/.claude/agents/moai/expert-frontend.md +45 -31
  88. moai_adk/templates/.claude/agents/moai/expert-performance.md +13 -9
  89. moai_adk/templates/.claude/agents/moai/expert-refactoring.md +228 -0
  90. moai_adk/templates/.claude/agents/moai/expert-security.md +19 -3
  91. moai_adk/templates/.claude/agents/moai/expert-testing.md +13 -9
  92. moai_adk/templates/.claude/agents/moai/manager-claude-code.md +8 -2
  93. moai_adk/templates/.claude/agents/moai/manager-docs.md +10 -5
  94. moai_adk/templates/.claude/agents/moai/manager-git.md +99 -27
  95. moai_adk/templates/.claude/agents/moai/manager-project.md +87 -7
  96. moai_adk/templates/.claude/agents/moai/manager-quality.md +22 -5
  97. moai_adk/templates/.claude/agents/moai/manager-spec.md +8 -2
  98. moai_adk/templates/.claude/agents/moai/manager-strategy.md +45 -14
  99. moai_adk/templates/.claude/agents/moai/manager-tdd.md +16 -3
  100. moai_adk/templates/.claude/commands/moai/0-project.md +239 -1185
  101. moai_adk/templates/.claude/commands/moai/1-plan.md +383 -363
  102. moai_adk/templates/.claude/commands/moai/2-run.md +254 -347
  103. moai_adk/templates/.claude/commands/moai/3-sync.md +174 -100
  104. moai_adk/templates/.claude/commands/moai/9-feedback.md +49 -33
  105. moai_adk/templates/.claude/commands/moai/alfred.md +339 -0
  106. moai_adk/templates/.claude/commands/moai/cancel-loop.md +163 -0
  107. moai_adk/templates/.claude/commands/moai/fix.md +264 -0
  108. moai_adk/templates/.claude/commands/moai/loop.md +363 -0
  109. moai_adk/templates/.claude/hooks/moai/lib/README.md +143 -0
  110. moai_adk/templates/.claude/hooks/moai/lib/__init__.py +37 -81
  111. moai_adk/templates/.claude/hooks/moai/lib/alfred_detector.py +105 -0
  112. moai_adk/templates/.claude/hooks/moai/lib/atomic_write.py +122 -0
  113. moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +4 -1
  114. moai_adk/templates/.claude/hooks/moai/lib/common.py +35 -5
  115. moai_adk/templates/.claude/hooks/moai/lib/config.py +376 -0
  116. moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +24 -28
  117. moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +14 -14
  118. moai_adk/templates/.claude/hooks/moai/lib/enhanced_output_style_detector.py +372 -0
  119. moai_adk/templates/.claude/hooks/moai/lib/exceptions.py +171 -0
  120. moai_adk/templates/.claude/hooks/moai/lib/file_utils.py +95 -0
  121. moai_adk/templates/.claude/hooks/moai/lib/git_collector.py +190 -0
  122. moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +15 -13
  123. moai_adk/templates/.claude/hooks/moai/lib/language_detector.py +298 -0
  124. moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +125 -25
  125. moai_adk/templates/.claude/hooks/moai/lib/main.py +341 -0
  126. moai_adk/templates/.claude/hooks/moai/lib/memory_collector.py +268 -0
  127. moai_adk/templates/.claude/hooks/moai/lib/metrics_tracker.py +78 -0
  128. moai_adk/templates/.claude/hooks/moai/lib/models.py +9 -7
  129. moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +204 -13
  130. moai_adk/templates/.claude/hooks/moai/lib/project.py +23 -14
  131. moai_adk/templates/.claude/hooks/moai/lib/renderer.py +359 -0
  132. moai_adk/templates/.claude/hooks/moai/lib/tag_linkage.py +333 -0
  133. moai_adk/templates/.claude/hooks/moai/lib/tag_parser.py +176 -0
  134. moai_adk/templates/.claude/hooks/moai/lib/tag_validator.py +200 -0
  135. moai_adk/templates/.claude/hooks/moai/lib/timeout.py +5 -5
  136. moai_adk/templates/.claude/hooks/moai/lib/tool_registry.py +896 -0
  137. moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +30 -18
  138. moai_adk/templates/.claude/hooks/moai/lib/update_checker.py +129 -0
  139. moai_adk/templates/.claude/hooks/moai/lib/version_reader.py +741 -0
  140. moai_adk/templates/.claude/hooks/moai/post_tool__ast_grep_scan.py +276 -0
  141. moai_adk/templates/.claude/hooks/moai/post_tool__code_formatter.py +255 -0
  142. moai_adk/templates/.claude/hooks/moai/post_tool__coverage_guard.py +325 -0
  143. moai_adk/templates/.claude/hooks/moai/post_tool__linter.py +315 -0
  144. moai_adk/templates/.claude/hooks/moai/post_tool__lsp_diagnostic.py +508 -0
  145. moai_adk/templates/.claude/hooks/moai/pre_commit__tag_validator.py +287 -0
  146. moai_adk/templates/.claude/hooks/moai/pre_tool__security_guard.py +268 -0
  147. moai_adk/templates/.claude/hooks/moai/pre_tool__tdd_enforcer.py +208 -0
  148. moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +93 -61
  149. moai_adk/templates/.claude/hooks/moai/session_end__rank_submit.py +69 -0
  150. moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +165 -70
  151. moai_adk/templates/.claude/hooks/moai/shared/utils/announcement_translator.py +206 -0
  152. moai_adk/templates/.claude/hooks/moai/stop__loop_controller.py +621 -0
  153. moai_adk/templates/.claude/output-styles/moai/alfred.md +758 -0
  154. moai_adk/templates/.claude/output-styles/moai/r2d2.md +86 -3
  155. moai_adk/templates/.claude/output-styles/moai/yoda.md +2 -2
  156. moai_adk/templates/.claude/settings.json +154 -77
  157. moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +252 -198
  158. moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +169 -323
  159. moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +39 -27
  160. moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +115 -125
  161. moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +150 -150
  162. moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +182 -175
  163. moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +198 -138
  164. moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +226 -320
  165. moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +43 -222
  166. moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +75 -219
  167. moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +103 -463
  168. moai_adk/templates/.claude/skills/moai-domain-frontend/modules/component-architecture.md +723 -0
  169. moai_adk/templates/.claude/skills/moai-domain-frontend/modules/nextjs16-patterns.md +713 -0
  170. moai_adk/templates/.claude/skills/moai-domain-frontend/modules/performance-optimization.md +694 -0
  171. moai_adk/templates/.claude/skills/moai-domain-frontend/modules/react19-patterns.md +591 -0
  172. moai_adk/templates/.claude/skills/moai-domain-frontend/modules/state-management.md +680 -0
  173. moai_adk/templates/.claude/skills/moai-domain-frontend/modules/vue35-patterns.md +802 -0
  174. moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +118 -339
  175. moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +74 -377
  176. moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +299 -70
  177. moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +205 -182
  178. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/advanced-agent-patterns.md +370 -0
  179. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-cli-reference-official.md +420 -0
  180. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +32 -22
  181. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-devcontainers-official.md +381 -0
  182. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-discover-plugins-official.md +379 -0
  183. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-headless-official.md +378 -0
  184. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +110 -0
  185. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugin-marketplaces-official.md +308 -0
  186. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugins-official.md +640 -0
  187. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sandboxing-official.md +282 -0
  188. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +425 -71
  189. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-statusline-official.md +293 -0
  190. moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +325 -143
  191. moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +96 -316
  192. moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +116 -294
  193. moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-advanced.md +279 -0
  194. moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-implementation.md +267 -0
  195. moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +121 -650
  196. moai_adk/templates/.claude/skills/moai-foundation-core/modules/patterns.md +22 -0
  197. moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-ears-format.md +200 -0
  198. moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +37 -730
  199. moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-tdd-implementation.md +275 -0
  200. moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +77 -819
  201. moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-implementation.md +244 -0
  202. moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-validation.md +219 -0
  203. moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +14 -18
  204. moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +86 -270
  205. moai_adk/templates/.claude/skills/moai-framework-electron/SKILL.md +288 -0
  206. moai_adk/templates/.claude/skills/moai-framework-electron/examples.md +2082 -0
  207. moai_adk/templates/.claude/skills/moai-framework-electron/reference.md +1649 -0
  208. moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +76 -582
  209. moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +1239 -0
  210. moai_adk/templates/.claude/skills/moai-lang-cpp/modules/advanced-patterns.md +401 -0
  211. moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +1136 -0
  212. moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +82 -436
  213. moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +585 -0
  214. moai_adk/templates/.claude/skills/moai-lang-csharp/modules/aspnet-core.md +627 -0
  215. moai_adk/templates/.claude/skills/moai-lang-csharp/modules/blazor-components.md +767 -0
  216. moai_adk/templates/.claude/skills/moai-lang-csharp/modules/cqrs-validation.md +626 -0
  217. moai_adk/templates/.claude/skills/moai-lang-csharp/modules/csharp12-features.md +580 -0
  218. moai_adk/templates/.claude/skills/moai-lang-csharp/modules/efcore-patterns.md +622 -0
  219. moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +403 -0
  220. moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +65 -542
  221. moai_adk/templates/.claude/skills/moai-lang-elixir/examples.md +1171 -0
  222. moai_adk/templates/.claude/skills/moai-lang-elixir/modules/advanced-patterns.md +531 -0
  223. moai_adk/templates/.claude/skills/moai-lang-elixir/reference.md +889 -0
  224. moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +32 -405
  225. moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +114 -293
  226. moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +83 -307
  227. moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +179 -0
  228. moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +973 -0
  229. moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +1543 -0
  230. moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +42 -279
  231. moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +94 -556
  232. moai_adk/templates/.claude/skills/moai-lang-php/examples.md +1608 -0
  233. moai_adk/templates/.claude/skills/moai-lang-php/modules/advanced-patterns.md +538 -0
  234. moai_adk/templates/.claude/skills/moai-lang-php/reference.md +1323 -0
  235. moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +108 -358
  236. moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +84 -482
  237. moai_adk/templates/.claude/skills/moai-lang-r/examples.md +1154 -0
  238. moai_adk/templates/.claude/skills/moai-lang-r/modules/advanced-patterns.md +489 -0
  239. moai_adk/templates/.claude/skills/moai-lang-r/reference.md +1087 -0
  240. moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +106 -610
  241. moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +1106 -0
  242. moai_adk/templates/.claude/skills/moai-lang-ruby/modules/advanced-patterns.md +309 -0
  243. moai_adk/templates/.claude/skills/moai-lang-ruby/modules/testing-patterns.md +306 -0
  244. moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +1024 -0
  245. moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +51 -265
  246. moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +106 -442
  247. moai_adk/templates/.claude/skills/moai-lang-scala/modules/akka-actors.md +479 -0
  248. moai_adk/templates/.claude/skills/moai-lang-scala/modules/cats-effect.md +489 -0
  249. moai_adk/templates/.claude/skills/moai-lang-scala/modules/functional-programming.md +460 -0
  250. moai_adk/templates/.claude/skills/moai-lang-scala/modules/spark-data.md +498 -0
  251. moai_adk/templates/.claude/skills/moai-lang-scala/modules/zio-patterns.md +541 -0
  252. moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +88 -457
  253. moai_adk/templates/.claude/skills/moai-lang-swift/modules/combine-reactive.md +256 -0
  254. moai_adk/templates/.claude/skills/moai-lang-swift/modules/concurrency.md +270 -0
  255. moai_adk/templates/.claude/skills/moai-lang-swift/modules/swift6-features.md +265 -0
  256. moai_adk/templates/.claude/skills/moai-lang-swift/modules/swiftui-patterns.md +314 -0
  257. moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +75 -283
  258. moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +97 -252
  259. moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +64 -240
  260. moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +331 -12
  261. moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +330 -37
  262. moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +90 -287
  263. moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +200 -206
  264. moai_adk/templates/.claude/skills/moai-platform-auth0/examples.md +2446 -0
  265. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/adaptive-mfa.md +233 -0
  266. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/akamai-integration.md +214 -0
  267. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/application-credentials.md +280 -0
  268. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-log-events.md +224 -0
  269. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-overview.md +140 -0
  270. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/bot-detection.md +144 -0
  271. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/breached-password-detection.md +187 -0
  272. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/brute-force-protection.md +189 -0
  273. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/certifications.md +282 -0
  274. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/compliance-overview.md +263 -0
  275. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/continuous-session-protection.md +307 -0
  276. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/customize-mfa.md +177 -0
  277. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/dpop-implementation.md +283 -0
  278. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/fapi-implementation.md +259 -0
  279. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/gdpr-compliance.md +313 -0
  280. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/guardian-configuration.md +269 -0
  281. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/highly-regulated-identity.md +272 -0
  282. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/jwt-fundamentals.md +248 -0
  283. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mdl-verification.md +210 -0
  284. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-api-management.md +278 -0
  285. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-factors.md +226 -0
  286. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-overview.md +174 -0
  287. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mtls-sender-constraining.md +316 -0
  288. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/ropg-flow-mfa.md +216 -0
  289. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-center.md +325 -0
  290. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-guidance.md +277 -0
  291. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/state-parameters.md +177 -0
  292. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/step-up-authentication.md +251 -0
  293. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/suspicious-ip-throttling.md +240 -0
  294. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/tenant-access-control.md +179 -0
  295. moai_adk/templates/.claude/skills/moai-platform-auth0/modules/webauthn-fido.md +235 -0
  296. moai_adk/templates/.claude/skills/moai-platform-auth0/reference.md +224 -0
  297. moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +75 -330
  298. moai_adk/templates/.claude/skills/moai-platform-clerk/examples.md +1426 -0
  299. moai_adk/templates/.claude/skills/moai-platform-clerk/modules/advanced-patterns.md +417 -0
  300. moai_adk/templates/.claude/skills/moai-platform-clerk/reference.md +273 -0
  301. moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +100 -340
  302. moai_adk/templates/.claude/skills/moai-platform-convex/examples.md +506 -0
  303. moai_adk/templates/.claude/skills/moai-platform-convex/modules/auth-integration.md +421 -0
  304. moai_adk/templates/.claude/skills/moai-platform-convex/modules/file-storage.md +474 -0
  305. moai_adk/templates/.claude/skills/moai-platform-convex/modules/reactive-queries.md +302 -0
  306. moai_adk/templates/.claude/skills/moai-platform-convex/modules/server-functions.md +452 -0
  307. moai_adk/templates/.claude/skills/moai-platform-convex/reference.md +385 -0
  308. moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +113 -326
  309. moai_adk/templates/.claude/skills/moai-platform-firebase-auth/examples.md +514 -0
  310. moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/custom-claims.md +374 -0
  311. moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/phone-auth.md +372 -0
  312. moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/social-auth.md +339 -0
  313. moai_adk/templates/.claude/skills/moai-platform-firebase-auth/reference.md +382 -0
  314. moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +71 -302
  315. moai_adk/templates/.claude/skills/moai-platform-firestore/examples.md +445 -0
  316. moai_adk/templates/.claude/skills/moai-platform-firestore/modules/offline-cache.md +392 -0
  317. moai_adk/templates/.claude/skills/moai-platform-firestore/modules/realtime-listeners.md +441 -0
  318. moai_adk/templates/.claude/skills/moai-platform-firestore/modules/security-rules.md +352 -0
  319. moai_adk/templates/.claude/skills/moai-platform-firestore/modules/transactions.md +452 -0
  320. moai_adk/templates/.claude/skills/moai-platform-firestore/reference.md +322 -0
  321. moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +101 -412
  322. moai_adk/templates/.claude/skills/moai-platform-neon/examples.md +470 -0
  323. moai_adk/templates/.claude/skills/moai-platform-neon/modules/auto-scaling.md +349 -0
  324. moai_adk/templates/.claude/skills/moai-platform-neon/modules/branching-workflows.md +354 -0
  325. moai_adk/templates/.claude/skills/moai-platform-neon/modules/connection-pooling.md +412 -0
  326. moai_adk/templates/.claude/skills/moai-platform-neon/modules/pitr-backups.md +458 -0
  327. moai_adk/templates/.claude/skills/moai-platform-neon/reference.md +272 -0
  328. moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +96 -327
  329. moai_adk/templates/.claude/skills/moai-platform-railway/examples.md +539 -0
  330. moai_adk/templates/.claude/skills/moai-platform-railway/modules/docker-deployment.md +261 -0
  331. moai_adk/templates/.claude/skills/moai-platform-railway/modules/multi-service.md +291 -0
  332. moai_adk/templates/.claude/skills/moai-platform-railway/modules/networking-domains.md +338 -0
  333. moai_adk/templates/.claude/skills/moai-platform-railway/modules/volumes-storage.md +353 -0
  334. moai_adk/templates/.claude/skills/moai-platform-railway/reference.md +374 -0
  335. moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +103 -428
  336. moai_adk/templates/.claude/skills/moai-platform-supabase/examples.md +502 -0
  337. moai_adk/templates/.claude/skills/moai-platform-supabase/modules/auth-integration.md +384 -0
  338. moai_adk/templates/.claude/skills/moai-platform-supabase/modules/edge-functions.md +371 -0
  339. moai_adk/templates/.claude/skills/moai-platform-supabase/modules/postgresql-pgvector.md +231 -0
  340. moai_adk/templates/.claude/skills/moai-platform-supabase/modules/realtime-presence.md +354 -0
  341. moai_adk/templates/.claude/skills/moai-platform-supabase/modules/row-level-security.md +286 -0
  342. moai_adk/templates/.claude/skills/moai-platform-supabase/modules/storage-cdn.md +319 -0
  343. moai_adk/templates/.claude/skills/moai-platform-supabase/modules/typescript-patterns.md +453 -0
  344. moai_adk/templates/.claude/skills/moai-platform-supabase/reference.md +284 -0
  345. moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +96 -446
  346. moai_adk/templates/.claude/skills/moai-platform-vercel/examples.md +502 -0
  347. moai_adk/templates/.claude/skills/moai-platform-vercel/modules/analytics-speed.md +348 -0
  348. moai_adk/templates/.claude/skills/moai-platform-vercel/modules/deployment-config.md +344 -0
  349. moai_adk/templates/.claude/skills/moai-platform-vercel/modules/edge-functions.md +222 -0
  350. moai_adk/templates/.claude/skills/moai-platform-vercel/modules/isr-caching.md +306 -0
  351. moai_adk/templates/.claude/skills/moai-platform-vercel/modules/kv-storage.md +399 -0
  352. moai_adk/templates/.claude/skills/moai-platform-vercel/reference.md +360 -0
  353. moai_adk/templates/.claude/skills/moai-tool-ast-grep/SKILL.md +193 -0
  354. moai_adk/templates/.claude/skills/moai-tool-ast-grep/examples.md +1099 -0
  355. moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/language-specific.md +307 -0
  356. moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/pattern-syntax.md +237 -0
  357. moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/refactoring-patterns.md +260 -0
  358. moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/security-rules.md +239 -0
  359. moai_adk/templates/.claude/skills/moai-tool-ast-grep/reference.md +288 -0
  360. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/go.yml +90 -0
  361. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/python.yml +101 -0
  362. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/typescript.yml +83 -0
  363. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/complexity-check.yml +94 -0
  364. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/deprecated-apis.yml +84 -0
  365. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/secrets-detection.yml +89 -0
  366. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/sql-injection.yml +45 -0
  367. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/xss-prevention.yml +50 -0
  368. moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/sgconfig.yml +54 -0
  369. moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +225 -423
  370. moai_adk/templates/.claude/skills/moai-workflow-loop/SKILL.md +197 -0
  371. moai_adk/templates/.claude/skills/moai-workflow-loop/examples.md +1063 -0
  372. moai_adk/templates/.claude/skills/moai-workflow-loop/reference.md +1414 -0
  373. moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +211 -314
  374. moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +15 -43
  375. moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +119 -316
  376. moai_adk/templates/.claude/skills/moai-workflow-spec/modules/advanced-patterns.md +237 -0
  377. moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +96 -203
  378. moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +201 -388
  379. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +52 -3
  380. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +263 -806
  381. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/context7-integration.md +286 -0
  382. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/review-workflows.md +500 -0
  383. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/relevance-analysis.md +154 -0
  384. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/safety-analysis.md +148 -0
  385. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/scoring-algorithms.md +196 -0
  386. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/timeliness-analysis.md +168 -0
  387. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/truthfulness-analysis.md +136 -0
  388. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/usability-analysis.md +153 -0
  389. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework.md +257 -0
  390. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +191 -1344
  391. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/analysis-patterns.md +340 -0
  392. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/core-classes.md +299 -0
  393. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/tool-integration.md +380 -0
  394. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/debugging-workflows.md +451 -0
  395. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/error-analysis.md +442 -0
  396. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/optimization-patterns.md +473 -0
  397. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/profiling-techniques.md +481 -0
  398. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/ai-optimization.md +241 -0
  399. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/bottleneck-detection.md +397 -0
  400. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/optimization-plan.md +315 -0
  401. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/profiler-core.md +277 -0
  402. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/real-time-monitoring.md +187 -0
  403. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +287 -1194
  404. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/quality-metrics.md +415 -0
  405. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/ai-workflows.md +620 -0
  406. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/patterns.md +692 -0
  407. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/security-analysis.md +429 -0
  408. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +262 -1192
  409. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/static-analysis.md +438 -0
  410. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd/core-classes.md +397 -0
  411. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/advanced-features.md +494 -0
  412. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/red-green-refactor.md +316 -0
  413. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-generation.md +471 -0
  414. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-patterns.md +371 -0
  415. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +227 -1222
  416. moai_adk/templates/.claude/skills/moai-workflow-testing/modules/trust5-validation.md +428 -0
  417. moai_adk/templates/.claude/skills/moai-workflow-worktree/SKILL.md +228 -0
  418. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/integration-patterns.md +149 -0
  419. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/moai-adk-integration.md +245 -0
  420. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-advanced.md +310 -0
  421. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-development.md +202 -0
  422. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-workflows.md +302 -0
  423. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/registry-architecture.md +271 -0
  424. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/resource-optimization.md +300 -0
  425. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/tools-integration.md +280 -0
  426. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/troubleshooting.md +397 -0
  427. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-commands.md +296 -0
  428. moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-management.md +217 -0
  429. moai_adk/templates/.git-hooks/pre-push +162 -59
  430. moai_adk/templates/.github/workflows/ci-universal.yml +934 -133
  431. moai_adk/templates/.gitignore +65 -107
  432. moai_adk/templates/.lsp.json +152 -0
  433. moai_adk/templates/.mcp.json +2 -20
  434. moai_adk/templates/.moai/announcements/en.json +18 -0
  435. moai_adk/templates/.moai/announcements/ja.json +18 -0
  436. moai_adk/templates/.moai/announcements/ko.json +18 -0
  437. moai_adk/templates/.moai/announcements/zh.json +18 -0
  438. moai_adk/templates/.moai/config/config.yaml +8 -2
  439. moai_adk/templates/.moai/config/multilingual-triggers.yaml +213 -0
  440. moai_adk/templates/.moai/config/sections/language.yaml +2 -2
  441. moai_adk/templates/.moai/config/sections/llm.yaml +41 -0
  442. moai_adk/templates/.moai/config/sections/pricing.yaml +30 -0
  443. moai_adk/templates/.moai/config/sections/project.yaml +2 -2
  444. moai_adk/templates/.moai/config/sections/quality.yaml +43 -5
  445. moai_adk/templates/.moai/config/sections/ralph.yaml +55 -0
  446. moai_adk/templates/.moai/config/sections/system.yaml +46 -1
  447. moai_adk/templates/.moai/config/sections/user.yaml +1 -1
  448. moai_adk/templates/.moai/config/statusline-config.yaml +2 -2
  449. moai_adk/templates/.moai/llm-configs/glm.json +22 -0
  450. moai_adk/templates/CLAUDE.ja.md +343 -0
  451. moai_adk/templates/CLAUDE.ko.md +343 -0
  452. moai_adk/templates/CLAUDE.md +200 -499
  453. moai_adk/templates/CLAUDE.zh.md +343 -0
  454. moai_adk/utils/common.py +37 -0
  455. moai_adk/version.py +1 -1
  456. moai_adk-1.1.0.dist-info/METADATA +2443 -0
  457. moai_adk-1.1.0.dist-info/RECORD +701 -0
  458. {moai_adk-0.34.0.dist-info → moai_adk-1.1.0.dist-info}/entry_points.txt +2 -0
  459. moai_adk-1.1.0.dist-info/licenses/LICENSE +99 -0
  460. moai_adk/core/config/auto_spec_config.py +0 -340
  461. moai_adk/core/hooks/post_tool_auto_spec_completion.py +0 -901
  462. moai_adk/core/spec/confidence_scoring.py +0 -680
  463. moai_adk/core/spec/ears_template_engine.py +0 -1247
  464. moai_adk/core/spec/quality_validator.py +0 -687
  465. moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +0 -670
  466. moai_adk/templates/.claude/agents/moai/expert-database.md +0 -777
  467. moai_adk/templates/.claude/agents/moai/expert-uiux.md +0 -1041
  468. moai_adk/templates/.claude/agents/moai/mcp-context7.md +0 -458
  469. moai_adk/templates/.claude/agents/moai/mcp-figma.md +0 -1607
  470. moai_adk/templates/.claude/agents/moai/mcp-notion.md +0 -789
  471. moai_adk/templates/.claude/agents/moai/mcp-playwright.md +0 -469
  472. moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +0 -1032
  473. moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +0 -438
  474. moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +0 -431
  475. moai_adk/templates/.claude/skills/moai-domain-uiux/modules/design-system-tokens.md +0 -405
  476. moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +0 -336
  477. moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +0 -402
  478. moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +0 -607
  479. moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +0 -300
  480. moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +0 -537
  481. moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +0 -520
  482. moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +0 -574
  483. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +0 -317
  484. moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +0 -663
  485. moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +0 -190
  486. moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +0 -175
  487. moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +0 -196
  488. moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +0 -17
  489. moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +0 -158
  490. moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +0 -340
  491. moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +0 -713
  492. moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +0 -538
  493. moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +0 -1336
  494. moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +0 -730
  495. moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +0 -608
  496. moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +0 -1005
  497. moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +0 -436
  498. moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +0 -411
  499. moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +0 -982
  500. moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +0 -778
  501. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +0 -646
  502. moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +0 -782
  503. moai_adk/templates/.moai/config/questions/_schema.yaml +0 -151
  504. moai_adk/templates/.moai/config/questions/tab0-init.yaml +0 -251
  505. moai_adk/templates/.moai/config/questions/tab1-user.yaml +0 -108
  506. moai_adk/templates/.moai/config/questions/tab2-project.yaml +0 -81
  507. moai_adk/templates/.moai/config/questions/tab3-git.yaml +0 -634
  508. moai_adk/templates/.moai/config/questions/tab4-quality.yaml +0 -170
  509. moai_adk/templates/.moai/config/questions/tab5-system.yaml +0 -87
  510. moai_adk/templates/.moai/scripts/setup-glm.py +0 -136
  511. moai_adk-0.34.0.dist-info/METADATA +0 -2999
  512. moai_adk-0.34.0.dist-info/RECORD +0 -463
  513. moai_adk-0.34.0.dist-info/licenses/LICENSE +0 -21
  514. /moai_adk/foundation/{git.py → git/__init__.py} +0 -0
  515. /moai_adk/templates/.claude/skills/moai-library-mermaid/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
  516. /moai_adk/templates/.claude/skills/moai-library-mermaid/{optimization.md → modules/optimization.md} +0 -0
  517. /moai_adk/templates/.claude/skills/moai-library-nextra/{optimization.md → modules/optimization.md} +0 -0
  518. /moai_adk/templates/.claude/skills/moai-workflow-jit-docs/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
  519. /moai_adk/templates/.claude/skills/moai-workflow-jit-docs/{optimization.md → modules/optimization.md} +0 -0
  520. /moai_adk/templates/.claude/skills/moai-workflow-testing/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
  521. /moai_adk/templates/.claude/skills/moai-workflow-testing/{optimization.md → modules/optimization.md} +0 -0
  522. /moai_adk/templates/.claude/skills/{moai-worktree → moai-workflow-worktree}/examples.md +0 -0
  523. /moai_adk/templates/.claude/skills/{moai-worktree → moai-workflow-worktree}/reference.md +0 -0
  524. {moai_adk-0.34.0.dist-info → moai_adk-1.1.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,1171 @@
1
+ # Elixir Production-Ready Code Examples
2
+
3
+ ## Complete Phoenix Application
4
+
5
+ ### Project Structure
6
+
7
+ ```
8
+ phoenix_app/
9
+ ├── lib/
10
+ │ ├── my_app/
11
+ │ │ ├── application.ex
12
+ │ │ ├── repo.ex
13
+ │ │ ├── accounts/
14
+ │ │ │ ├── user.ex
15
+ │ │ │ └── user_token.ex
16
+ │ │ ├── mailer.ex
17
+ │ │ └── workers/
18
+ │ │ └── email_worker.ex
19
+ │ └── my_app_web/
20
+ │ ├── endpoint.ex
21
+ │ ├── router.ex
22
+ │ ├── telemetry.ex
23
+ │ ├── components/
24
+ │ │ ├── core_components.ex
25
+ │ │ └── layouts.ex
26
+ │ ├── controllers/
27
+ │ │ ├── user_controller.ex
28
+ │ │ └── user_json.ex
29
+ │ └── live/
30
+ │ ├── user_live/
31
+ │ │ ├── index.ex
32
+ │ │ ├── show.ex
33
+ │ │ └── form_component.ex
34
+ │ └── user_auth.ex
35
+ ├── test/
36
+ │ ├── my_app/
37
+ │ │ └── accounts_test.exs
38
+ │ ├── my_app_web/
39
+ │ │ ├── controllers/
40
+ │ │ │ └── user_controller_test.exs
41
+ │ │ └── live/
42
+ │ │ └── user_live_test.exs
43
+ │ ├── support/
44
+ │ │ ├── conn_case.ex
45
+ │ │ ├── data_case.ex
46
+ │ │ └── fixtures/
47
+ │ │ └── accounts_fixtures.ex
48
+ │ └── test_helper.exs
49
+ ├── priv/
50
+ │ └── repo/
51
+ │ ├── migrations/
52
+ │ └── seeds.exs
53
+ ├── config/
54
+ │ ├── config.exs
55
+ │ ├── dev.exs
56
+ │ ├── test.exs
57
+ │ ├── prod.exs
58
+ │ └── runtime.exs
59
+ ├── mix.exs
60
+ └── Dockerfile
61
+ ```
62
+
63
+ ### Application Entry Point
64
+
65
+ ```elixir
66
+ # lib/my_app/application.ex
67
+ defmodule MyApp.Application do
68
+ @moduledoc false
69
+
70
+ use Application
71
+
72
+ @impl true
73
+ def start(_type, _args) do
74
+ children = [
75
+ # Telemetry supervisor
76
+ MyAppWeb.Telemetry,
77
+
78
+ # Database connection
79
+ MyApp.Repo,
80
+
81
+ # PubSub system
82
+ {Phoenix.PubSub, name: MyApp.PubSub},
83
+
84
+ # Finch HTTP client
85
+ {Finch, name: MyApp.Finch},
86
+
87
+ # Background job processing
88
+ {Oban, Application.fetch_env!(:my_app, Oban)},
89
+
90
+ # Presence tracking
91
+ MyAppWeb.Presence,
92
+
93
+ # Endpoint - must be last
94
+ MyAppWeb.Endpoint
95
+ ]
96
+
97
+ opts = [strategy: :one_for_one, name: MyApp.Supervisor]
98
+ Supervisor.start_link(children, opts)
99
+ end
100
+
101
+ @impl true
102
+ def config_change(changed, _new, removed) do
103
+ MyAppWeb.Endpoint.config_change(changed, removed)
104
+ :ok
105
+ end
106
+ end
107
+ ```
108
+
109
+ ### Configuration
110
+
111
+ ```elixir
112
+ # config/config.exs
113
+ import Config
114
+
115
+ config :my_app,
116
+ ecto_repos: [MyApp.Repo],
117
+ generators: [timestamp_type: :utc_datetime]
118
+
119
+ config :my_app, MyApp.Repo,
120
+ migration_primary_key: [type: :binary_id],
121
+ migration_timestamps: [type: :utc_datetime]
122
+
123
+ config :my_app, MyAppWeb.Endpoint,
124
+ url: [host: "localhost"],
125
+ adapter: Bandit.PhoenixAdapter,
126
+ render_errors: [
127
+ formats: [html: MyAppWeb.ErrorHTML, json: MyAppWeb.ErrorJSON],
128
+ layout: false
129
+ ],
130
+ pubsub_server: MyApp.PubSub,
131
+ live_view: [signing_salt: "YOUR_SECRET"]
132
+
133
+ config :my_app, Oban,
134
+ engine: Oban.Engines.Basic,
135
+ queues: [default: 10, mailers: 20, events: 50],
136
+ repo: MyApp.Repo
137
+
138
+ config :esbuild,
139
+ version: "0.17.11",
140
+ my_app: [
141
+ args: ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets),
142
+ cd: Path.expand("../assets", __DIR__),
143
+ env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
144
+ ]
145
+
146
+ config :tailwind,
147
+ version: "3.4.0",
148
+ my_app: [
149
+ args: ~w(
150
+ --config=tailwind.config.js
151
+ --input=css/app.css
152
+ --output=../priv/static/assets/app.css
153
+ ),
154
+ cd: Path.expand("../assets", __DIR__)
155
+ ]
156
+
157
+ import_config "#{config_env()}.exs"
158
+ ```
159
+
160
+ ```elixir
161
+ # config/runtime.exs
162
+ import Config
163
+
164
+ if config_env() == :prod do
165
+ database_url =
166
+ System.get_env("DATABASE_URL") ||
167
+ raise """
168
+ environment variable DATABASE_URL is missing.
169
+ For example: ecto://USER:PASS@HOST/DATABASE
170
+ """
171
+
172
+ config :my_app, MyApp.Repo,
173
+ url: database_url,
174
+ pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
175
+ ssl: true,
176
+ ssl_opts: [
177
+ verify: :verify_peer,
178
+ cacertfile: "/etc/ssl/cert.pem",
179
+ server_name_indication: ~c"myapp.fly.dev",
180
+ customize_hostname_check: [
181
+ match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
182
+ ]
183
+ ]
184
+
185
+ secret_key_base =
186
+ System.get_env("SECRET_KEY_BASE") ||
187
+ raise """
188
+ environment variable SECRET_KEY_BASE is missing.
189
+ You can generate one by calling: mix phx.gen.secret
190
+ """
191
+
192
+ host = System.get_env("PHX_HOST") || "example.com"
193
+ port = String.to_integer(System.get_env("PORT") || "4000")
194
+
195
+ config :my_app, MyAppWeb.Endpoint,
196
+ url: [host: host, port: 443, scheme: "https"],
197
+ http: [
198
+ ip: {0, 0, 0, 0, 0, 0, 0, 0},
199
+ port: port
200
+ ],
201
+ secret_key_base: secret_key_base
202
+ end
203
+ ```
204
+
205
+ ### Ecto Schema and Changeset
206
+
207
+ ```elixir
208
+ # lib/my_app/accounts/user.ex
209
+ defmodule MyApp.Accounts.User do
210
+ use Ecto.Schema
211
+ import Ecto.Changeset
212
+
213
+ @primary_key {:id, :binary_id, autogenerate: true}
214
+ @foreign_key_type :binary_id
215
+
216
+ schema "users" do
217
+ field :email, :string
218
+ field :name, :string
219
+ field :password, :string, virtual: true, redact: true
220
+ field :hashed_password, :string, redact: true
221
+ field :confirmed_at, :utc_datetime
222
+ field :is_admin, :boolean, default: false
223
+
224
+ has_many :tokens, MyApp.Accounts.UserToken
225
+ has_many :posts, MyApp.Blog.Post
226
+
227
+ timestamps(type: :utc_datetime)
228
+ end
229
+
230
+ @doc """
231
+ A user changeset for registration.
232
+ """
233
+ def registration_changeset(user, attrs, opts \\ []) do
234
+ user
235
+ |> cast(attrs, [:email, :name, :password])
236
+ |> validate_email(opts)
237
+ |> validate_name()
238
+ |> validate_password(opts)
239
+ end
240
+
241
+ defp validate_email(changeset, opts) do
242
+ changeset
243
+ |> validate_required([:email])
244
+ |> validate_format(:email, ~r/^[^\s]+@[^\s]+$/, message: "must have the @ sign and no spaces")
245
+ |> validate_length(:email, max: 160)
246
+ |> maybe_validate_unique_email(opts)
247
+ end
248
+
249
+ defp validate_name(changeset) do
250
+ changeset
251
+ |> validate_required([:name])
252
+ |> validate_length(:name, min: 2, max: 100)
253
+ end
254
+
255
+ defp validate_password(changeset, opts) do
256
+ changeset
257
+ |> validate_required([:password])
258
+ |> validate_length(:password, min: 12, max: 72)
259
+ |> validate_format(:password, ~r/[a-z]/, message: "at least one lower case character")
260
+ |> validate_format(:password, ~r/[A-Z]/, message: "at least one upper case character")
261
+ |> validate_format(:password, ~r/[!?@#$%^&*_0-9]/, message: "at least one digit or punctuation character")
262
+ |> maybe_hash_password(opts)
263
+ end
264
+
265
+ defp maybe_hash_password(changeset, opts) do
266
+ hash_password? = Keyword.get(opts, :hash_password, true)
267
+ password = get_change(changeset, :password)
268
+
269
+ if hash_password? && password && changeset.valid? do
270
+ changeset
271
+ |> validate_length(:password, max: 72, count: :bytes)
272
+ |> put_change(:hashed_password, Bcrypt.hash_pwd_salt(password))
273
+ |> delete_change(:password)
274
+ else
275
+ changeset
276
+ end
277
+ end
278
+
279
+ defp maybe_validate_unique_email(changeset, opts) do
280
+ if Keyword.get(opts, :validate_email, true) do
281
+ changeset
282
+ |> unsafe_validate_unique(:email, MyApp.Repo)
283
+ |> unique_constraint(:email)
284
+ else
285
+ changeset
286
+ end
287
+ end
288
+
289
+ @doc """
290
+ A user changeset for changing the email.
291
+ """
292
+ def email_changeset(user, attrs, opts \\ []) do
293
+ user
294
+ |> cast(attrs, [:email])
295
+ |> validate_email(opts)
296
+ |> case do
297
+ %{changes: %{email: _}} = changeset -> changeset
298
+ %{} = changeset -> add_error(changeset, :email, "did not change")
299
+ end
300
+ end
301
+
302
+ @doc """
303
+ Verifies the password.
304
+ """
305
+ def valid_password?(%MyApp.Accounts.User{hashed_password: hashed_password}, password)
306
+ when is_binary(hashed_password) and byte_size(password) > 0 do
307
+ Bcrypt.verify_pass(password, hashed_password)
308
+ end
309
+
310
+ def valid_password?(_, _) do
311
+ Bcrypt.no_user_verify()
312
+ false
313
+ end
314
+ end
315
+ ```
316
+
317
+ ### Context Module
318
+
319
+ ```elixir
320
+ # lib/my_app/accounts.ex
321
+ defmodule MyApp.Accounts do
322
+ @moduledoc """
323
+ The Accounts context.
324
+ """
325
+
326
+ import Ecto.Query, warn: false
327
+ alias MyApp.Repo
328
+ alias MyApp.Accounts.{User, UserToken}
329
+
330
+ ## User Registration
331
+
332
+ @doc """
333
+ Registers a user.
334
+ """
335
+ def register_user(attrs) do
336
+ %User{}
337
+ |> User.registration_changeset(attrs)
338
+ |> Repo.insert()
339
+ end
340
+
341
+ ## User Queries
342
+
343
+ @doc """
344
+ Gets a user by email.
345
+ """
346
+ def get_user_by_email(email) when is_binary(email) do
347
+ Repo.get_by(User, email: email)
348
+ end
349
+
350
+ @doc """
351
+ Gets a user by email and password.
352
+ """
353
+ def get_user_by_email_and_password(email, password)
354
+ when is_binary(email) and is_binary(password) do
355
+ user = Repo.get_by(User, email: email)
356
+ if User.valid_password?(user, password), do: user
357
+ end
358
+
359
+ @doc """
360
+ Gets a single user.
361
+ """
362
+ def get_user!(id), do: Repo.get!(User, id)
363
+
364
+ @doc """
365
+ Lists all users with optional filters.
366
+ """
367
+ def list_users(filters \\ %{}) do
368
+ User
369
+ |> apply_filters(filters)
370
+ |> Repo.all()
371
+ end
372
+
373
+ defp apply_filters(query, filters) do
374
+ Enum.reduce(filters, query, fn
375
+ {:search, term}, query ->
376
+ pattern = "%#{term}%"
377
+ where(query, [u], ilike(u.name, ^pattern) or ilike(u.email, ^pattern))
378
+
379
+ {:is_admin, value}, query ->
380
+ where(query, [u], u.is_admin == ^value)
381
+
382
+ {:confirmed, true}, query ->
383
+ where(query, [u], not is_nil(u.confirmed_at))
384
+
385
+ {:confirmed, false}, query ->
386
+ where(query, [u], is_nil(u.confirmed_at))
387
+
388
+ _, query ->
389
+ query
390
+ end)
391
+ end
392
+
393
+ @doc """
394
+ Paginated user listing.
395
+ """
396
+ def list_users_paginated(page \\ 1, per_page \\ 20) do
397
+ offset = (page - 1) * per_page
398
+
399
+ query =
400
+ from u in User,
401
+ order_by: [desc: u.inserted_at],
402
+ limit: ^per_page,
403
+ offset: ^offset
404
+
405
+ users = Repo.all(query)
406
+ total_count = Repo.aggregate(User, :count, :id)
407
+
408
+ %{
409
+ users: users,
410
+ page: page,
411
+ per_page: per_page,
412
+ total_count: total_count,
413
+ total_pages: ceil(total_count / per_page)
414
+ }
415
+ end
416
+
417
+ ## User Updates
418
+
419
+ @doc """
420
+ Updates a user.
421
+ """
422
+ def update_user(%User{} = user, attrs) do
423
+ user
424
+ |> User.email_changeset(attrs)
425
+ |> Repo.update()
426
+ end
427
+
428
+ @doc """
429
+ Confirms a user by setting `confirmed_at`.
430
+ """
431
+ def confirm_user(user) do
432
+ user
433
+ |> Ecto.Changeset.change(confirmed_at: DateTime.utc_now() |> DateTime.truncate(:second))
434
+ |> Repo.update()
435
+ end
436
+
437
+ ## Session Tokens
438
+
439
+ @doc """
440
+ Generates a session token.
441
+ """
442
+ def generate_user_session_token(user) do
443
+ {token, user_token} = UserToken.build_session_token(user)
444
+ Repo.insert!(user_token)
445
+ token
446
+ end
447
+
448
+ @doc """
449
+ Gets the user with the given signed token.
450
+ """
451
+ def get_user_by_session_token(token) do
452
+ {:ok, query} = UserToken.verify_session_token_query(token)
453
+ Repo.one(query)
454
+ end
455
+
456
+ @doc """
457
+ Deletes the signed token with the given context.
458
+ """
459
+ def delete_user_session_token(token) do
460
+ Repo.delete_all(UserToken.by_token_and_context_query(token, "session"))
461
+ :ok
462
+ end
463
+ end
464
+ ```
465
+
466
+ ### Phoenix Controller
467
+
468
+ ```elixir
469
+ # lib/my_app_web/controllers/user_controller.ex
470
+ defmodule MyAppWeb.UserController do
471
+ use MyAppWeb, :controller
472
+
473
+ alias MyApp.Accounts
474
+ alias MyApp.Accounts.User
475
+
476
+ action_fallback MyAppWeb.FallbackController
477
+
478
+ def index(conn, params) do
479
+ page = Map.get(params, "page", "1") |> String.to_integer()
480
+ per_page = Map.get(params, "per_page", "20") |> String.to_integer()
481
+
482
+ result = Accounts.list_users_paginated(page, per_page)
483
+ render(conn, :index, result)
484
+ end
485
+
486
+ def create(conn, %{"user" => user_params}) do
487
+ with {:ok, %User{} = user} <- Accounts.register_user(user_params) do
488
+ conn
489
+ |> put_status(:created)
490
+ |> put_resp_header("location", ~p"/api/users/#{user}")
491
+ |> render(:show, user: user)
492
+ end
493
+ end
494
+
495
+ def show(conn, %{"id" => id}) do
496
+ user = Accounts.get_user!(id)
497
+ render(conn, :show, user: user)
498
+ end
499
+
500
+ def update(conn, %{"id" => id, "user" => user_params}) do
501
+ user = Accounts.get_user!(id)
502
+
503
+ with {:ok, %User{} = user} <- Accounts.update_user(user, user_params) do
504
+ render(conn, :show, user: user)
505
+ end
506
+ end
507
+
508
+ def delete(conn, %{"id" => id}) do
509
+ user = Accounts.get_user!(id)
510
+
511
+ with {:ok, %User{}} <- Accounts.delete_user(user) do
512
+ send_resp(conn, :no_content, "")
513
+ end
514
+ end
515
+ end
516
+ ```
517
+
518
+ ```elixir
519
+ # lib/my_app_web/controllers/user_json.ex
520
+ defmodule MyAppWeb.UserJSON do
521
+ alias MyApp.Accounts.User
522
+
523
+ @doc """
524
+ Renders a list of users.
525
+ """
526
+ def index(%{users: users, page: page, per_page: per_page, total_count: total_count, total_pages: total_pages}) do
527
+ %{
528
+ data: for(user <- users, do: data(user)),
529
+ pagination: %{
530
+ page: page,
531
+ per_page: per_page,
532
+ total_count: total_count,
533
+ total_pages: total_pages
534
+ }
535
+ }
536
+ end
537
+
538
+ @doc """
539
+ Renders a single user.
540
+ """
541
+ def show(%{user: user}) do
542
+ %{data: data(user)}
543
+ end
544
+
545
+ defp data(%User{} = user) do
546
+ %{
547
+ id: user.id,
548
+ email: user.email,
549
+ name: user.name,
550
+ is_admin: user.is_admin,
551
+ confirmed_at: user.confirmed_at,
552
+ inserted_at: user.inserted_at
553
+ }
554
+ end
555
+ end
556
+ ```
557
+
558
+ ### Phoenix LiveView
559
+
560
+ ```elixir
561
+ # lib/my_app_web/live/user_live/index.ex
562
+ defmodule MyAppWeb.UserLive.Index do
563
+ use MyAppWeb, :live_view
564
+
565
+ alias MyApp.Accounts
566
+ alias MyApp.Accounts.User
567
+
568
+ @impl true
569
+ def mount(_params, _session, socket) do
570
+ if connected?(socket) do
571
+ Phoenix.PubSub.subscribe(MyApp.PubSub, "users")
572
+ end
573
+
574
+ {:ok, stream(socket, :users, Accounts.list_users())}
575
+ end
576
+
577
+ @impl true
578
+ def handle_params(params, _url, socket) do
579
+ {:noreply, apply_action(socket, socket.assigns.live_action, params)}
580
+ end
581
+
582
+ defp apply_action(socket, :edit, %{"id" => id}) do
583
+ socket
584
+ |> assign(:page_title, "Edit User")
585
+ |> assign(:user, Accounts.get_user!(id))
586
+ end
587
+
588
+ defp apply_action(socket, :new, _params) do
589
+ socket
590
+ |> assign(:page_title, "New User")
591
+ |> assign(:user, %User{})
592
+ end
593
+
594
+ defp apply_action(socket, :index, _params) do
595
+ socket
596
+ |> assign(:page_title, "Listing Users")
597
+ |> assign(:user, nil)
598
+ end
599
+
600
+ @impl true
601
+ def handle_info({MyAppWeb.UserLive.FormComponent, {:saved, user}}, socket) do
602
+ {:noreply, stream_insert(socket, :users, user)}
603
+ end
604
+
605
+ @impl true
606
+ def handle_info({:user_created, user}, socket) do
607
+ {:noreply, stream_insert(socket, :users, user, at: 0)}
608
+ end
609
+
610
+ @impl true
611
+ def handle_event("delete", %{"id" => id}, socket) do
612
+ user = Accounts.get_user!(id)
613
+ {:ok, _} = Accounts.delete_user(user)
614
+
615
+ {:noreply, stream_delete(socket, :users, user)}
616
+ end
617
+
618
+ @impl true
619
+ def render(assigns) do
620
+ ~H"""
621
+ <.header>
622
+ Listing Users
623
+ <:actions>
624
+ <.link patch={~p"/users/new"}>
625
+ <.button>New User</.button>
626
+ </.link>
627
+ </:actions>
628
+ </.header>
629
+
630
+ <.table id="users" rows={@streams.users} row_click={fn {_id, user} -> JS.navigate(~p"/users/#{user}") end}>
631
+ <:col :let={{_id, user}} label="Name"><%= user.name %></:col>
632
+ <:col :let={{_id, user}} label="Email"><%= user.email %></:col>
633
+ <:col :let={{_id, user}} label="Confirmed">
634
+ <%= if user.confirmed_at, do: "Yes", else: "No" %>
635
+ </:col>
636
+ <:action :let={{_id, user}}>
637
+ <div class="sr-only">
638
+ <.link navigate={~p"/users/#{user}"}>Show</.link>
639
+ </div>
640
+ <.link patch={~p"/users/#{user}/edit"}>Edit</.link>
641
+ </:action>
642
+ <:action :let={{id, user}}>
643
+ <.link phx-click={JS.push("delete", value: %{id: user.id}) |> hide("##{id}")} data-confirm="Are you sure?">
644
+ Delete
645
+ </.link>
646
+ </:action>
647
+ </.table>
648
+
649
+ <.modal :if={@live_action in [:new, :edit]} id="user-modal" show on_cancel={JS.patch(~p"/users")}>
650
+ <.live_component
651
+ module={MyAppWeb.UserLive.FormComponent}
652
+ id={@user.id || :new}
653
+ title={@page_title}
654
+ action={@live_action}
655
+ user={@user}
656
+ patch={~p"/users"}
657
+ />
658
+ </.modal>
659
+ """
660
+ end
661
+ end
662
+ ```
663
+
664
+ ```elixir
665
+ # lib/my_app_web/live/user_live/form_component.ex
666
+ defmodule MyAppWeb.UserLive.FormComponent do
667
+ use MyAppWeb, :live_component
668
+
669
+ alias MyApp.Accounts
670
+
671
+ @impl true
672
+ def render(assigns) do
673
+ ~H"""
674
+ <div>
675
+ <.header>
676
+ <%= @title %>
677
+ <:subtitle>Use this form to manage user records in your database.</:subtitle>
678
+ </.header>
679
+
680
+ <.simple_form
681
+ for={@form}
682
+ id="user-form"
683
+ phx-target={@myself}
684
+ phx-change="validate"
685
+ phx-submit="save"
686
+ >
687
+ <.input field={@form[:name]} type="text" label="Name" />
688
+ <.input field={@form[:email]} type="email" label="Email" />
689
+ <.input :if={@action == :new} field={@form[:password]} type="password" label="Password" />
690
+ <:actions>
691
+ <.button phx-disable-with="Saving...">Save User</.button>
692
+ </:actions>
693
+ </.simple_form>
694
+ </div>
695
+ """
696
+ end
697
+
698
+ @impl true
699
+ def update(%{user: user} = assigns, socket) do
700
+ {:ok,
701
+ socket
702
+ |> assign(assigns)
703
+ |> assign_new(:form, fn ->
704
+ to_form(Accounts.change_user(user))
705
+ end)}
706
+ end
707
+
708
+ @impl true
709
+ def handle_event("validate", %{"user" => user_params}, socket) do
710
+ changeset = Accounts.change_user(socket.assigns.user, user_params)
711
+ {:noreply, assign(socket, form: to_form(changeset, action: :validate))}
712
+ end
713
+
714
+ def handle_event("save", %{"user" => user_params}, socket) do
715
+ save_user(socket, socket.assigns.action, user_params)
716
+ end
717
+
718
+ defp save_user(socket, :edit, user_params) do
719
+ case Accounts.update_user(socket.assigns.user, user_params) do
720
+ {:ok, user} ->
721
+ notify_parent({:saved, user})
722
+
723
+ {:noreply,
724
+ socket
725
+ |> put_flash(:info, "User updated successfully")
726
+ |> push_patch(to: socket.assigns.patch)}
727
+
728
+ {:error, %Ecto.Changeset{} = changeset} ->
729
+ {:noreply, assign(socket, form: to_form(changeset))}
730
+ end
731
+ end
732
+
733
+ defp save_user(socket, :new, user_params) do
734
+ case Accounts.register_user(user_params) do
735
+ {:ok, user} ->
736
+ notify_parent({:saved, user})
737
+ Phoenix.PubSub.broadcast(MyApp.PubSub, "users", {:user_created, user})
738
+
739
+ {:noreply,
740
+ socket
741
+ |> put_flash(:info, "User created successfully")
742
+ |> push_patch(to: socket.assigns.patch)}
743
+
744
+ {:error, %Ecto.Changeset{} = changeset} ->
745
+ {:noreply, assign(socket, form: to_form(changeset))}
746
+ end
747
+ end
748
+
749
+ defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
750
+ end
751
+ ```
752
+
753
+ ---
754
+
755
+ ## GenServer and OTP Patterns
756
+
757
+ ### GenServer with State Management
758
+
759
+ ```elixir
760
+ defmodule MyApp.Services.RateLimiter do
761
+ use GenServer
762
+ require Logger
763
+
764
+ @cleanup_interval :timer.seconds(60)
765
+
766
+ defstruct [:max_requests, :window_ms, :requests]
767
+
768
+ ## Client API
769
+
770
+ def start_link(opts) do
771
+ name = Keyword.get(opts, :name, __MODULE__)
772
+ GenServer.start_link(__MODULE__, opts, name: name)
773
+ end
774
+
775
+ def check_rate(server \\ __MODULE__, key, limit \\ nil) do
776
+ GenServer.call(server, {:check_rate, key, limit})
777
+ end
778
+
779
+ def reset(server \\ __MODULE__, key) do
780
+ GenServer.cast(server, {:reset, key})
781
+ end
782
+
783
+ ## Server Callbacks
784
+
785
+ @impl true
786
+ def init(opts) do
787
+ max_requests = Keyword.get(opts, :max_requests, 100)
788
+ window_ms = Keyword.get(opts, :window_ms, 60_000)
789
+
790
+ schedule_cleanup()
791
+
792
+ state = %__MODULE__{
793
+ max_requests: max_requests,
794
+ window_ms: window_ms,
795
+ requests: %{}
796
+ }
797
+
798
+ {:ok, state}
799
+ end
800
+
801
+ @impl true
802
+ def handle_call({:check_rate, key, limit}, _from, state) do
803
+ limit = limit || state.max_requests
804
+ now = System.monotonic_time(:millisecond)
805
+ cutoff = now - state.window_ms
806
+
807
+ # Get timestamps for this key, filtered by window
808
+ timestamps =
809
+ state.requests
810
+ |> Map.get(key, [])
811
+ |> Enum.filter(&(&1 > cutoff))
812
+
813
+ count = length(timestamps)
814
+
815
+ if count >= limit do
816
+ {:reply, {:error, :rate_limit_exceeded, count}, state}
817
+ else
818
+ new_timestamps = [now | timestamps]
819
+ new_requests = Map.put(state.requests, key, new_timestamps)
820
+ new_state = %{state | requests: new_requests}
821
+ {:reply, {:ok, count + 1}, new_state}
822
+ end
823
+ end
824
+
825
+ @impl true
826
+ def handle_cast({:reset, key}, state) do
827
+ new_requests = Map.delete(state.requests, key)
828
+ {:noreply, %{state | requests: new_requests}}
829
+ end
830
+
831
+ @impl true
832
+ def handle_info(:cleanup, state) do
833
+ now = System.monotonic_time(:millisecond)
834
+ cutoff = now - state.window_ms
835
+
836
+ new_requests =
837
+ state.requests
838
+ |> Enum.map(fn {key, timestamps} ->
839
+ {key, Enum.filter(timestamps, &(&1 > cutoff))}
840
+ end)
841
+ |> Enum.reject(fn {_key, timestamps} -> timestamps == [] end)
842
+ |> Map.new()
843
+
844
+ Logger.debug("Cleaned up rate limiter. Keys before: #{map_size(state.requests)}, after: #{map_size(new_requests)}")
845
+
846
+ schedule_cleanup()
847
+ {:noreply, %{state | requests: new_requests}}
848
+ end
849
+
850
+ defp schedule_cleanup do
851
+ Process.send_after(self(), :cleanup, @cleanup_interval)
852
+ end
853
+ end
854
+ ```
855
+
856
+ ### Dynamic Supervisor
857
+
858
+ ```elixir
859
+ defmodule MyApp.Workers.DynamicSupervisor do
860
+ use DynamicSupervisor
861
+
862
+ def start_link(init_arg) do
863
+ DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
864
+ end
865
+
866
+ @impl true
867
+ def init(_init_arg) do
868
+ DynamicSupervisor.init(strategy: :one_for_one)
869
+ end
870
+
871
+ def start_worker(user_id) do
872
+ spec = {MyApp.Workers.UserWorker, user_id: user_id}
873
+ DynamicSupervisor.start_child(__MODULE__, spec)
874
+ end
875
+
876
+ def stop_worker(pid) do
877
+ DynamicSupervisor.terminate_child(__MODULE__, pid)
878
+ end
879
+
880
+ def list_workers do
881
+ DynamicSupervisor.which_children(__MODULE__)
882
+ end
883
+ end
884
+
885
+ defmodule MyApp.Workers.UserWorker do
886
+ use GenServer, restart: :temporary
887
+
888
+ def start_link(opts) do
889
+ user_id = Keyword.fetch!(opts, :user_id)
890
+ GenServer.start_link(__MODULE__, user_id, name: via_tuple(user_id))
891
+ end
892
+
893
+ defp via_tuple(user_id) do
894
+ {:via, Registry, {MyApp.Registry, {__MODULE__, user_id}}}
895
+ end
896
+
897
+ @impl true
898
+ def init(user_id) do
899
+ {:ok, %{user_id: user_id, status: :idle}}
900
+ end
901
+
902
+ @impl true
903
+ def handle_call(:get_status, _from, state) do
904
+ {:reply, state.status, state}
905
+ end
906
+
907
+ @impl true
908
+ def handle_cast({:update_status, new_status}, state) do
909
+ {:noreply, %{state | status: new_status}}
910
+ end
911
+ end
912
+ ```
913
+
914
+ ---
915
+
916
+ ## Oban Background Jobs
917
+
918
+ ```elixir
919
+ # lib/my_app/workers/email_worker.ex
920
+ defmodule MyApp.Workers.EmailWorker do
921
+ use Oban.Worker, queue: :mailers, max_attempts: 3
922
+
923
+ alias MyApp.Mailer
924
+ alias MyApp.Emails
925
+
926
+ @impl Oban.Worker
927
+ def perform(%Oban.Job{args: %{"type" => "welcome", "user_id" => user_id}}) do
928
+ user = MyApp.Accounts.get_user!(user_id)
929
+
930
+ user
931
+ |> Emails.welcome_email()
932
+ |> Mailer.deliver()
933
+
934
+ :ok
935
+ end
936
+
937
+ def perform(%Oban.Job{args: %{"type" => "password_reset", "user_id" => user_id, "token" => token}}) do
938
+ user = MyApp.Accounts.get_user!(user_id)
939
+
940
+ user
941
+ |> Emails.password_reset_email(token)
942
+ |> Mailer.deliver()
943
+
944
+ :ok
945
+ end
946
+
947
+ # Schedule welcome email
948
+ def schedule_welcome_email(user_id) do
949
+ %{type: "welcome", user_id: user_id}
950
+ |> new()
951
+ |> Oban.insert()
952
+ end
953
+
954
+ # Schedule with delay
955
+ def schedule_password_reset(user_id, token, delay_seconds \\ 0) do
956
+ %{type: "password_reset", user_id: user_id, token: token}
957
+ |> new(schedule_in: delay_seconds)
958
+ |> Oban.insert()
959
+ end
960
+ end
961
+ ```
962
+
963
+ ---
964
+
965
+ ## ExUnit Testing
966
+
967
+ ```elixir
968
+ # test/my_app/accounts_test.exs
969
+ defmodule MyApp.AccountsTest do
970
+ use MyApp.DataCase
971
+
972
+ alias MyApp.Accounts
973
+
974
+ describe "register_user/1" do
975
+ test "registers user with valid data" do
976
+ valid_attrs = %{
977
+ email: "test@example.com",
978
+ name: "Test User",
979
+ password: "SecurePass123!"
980
+ }
981
+
982
+ assert {:ok, user} = Accounts.register_user(valid_attrs)
983
+ assert user.email == "test@example.com"
984
+ assert user.name == "Test User"
985
+ assert user.hashed_password != nil
986
+ assert user.password == nil
987
+ end
988
+
989
+ test "returns error with invalid email" do
990
+ invalid_attrs = %{
991
+ email: "invalid-email",
992
+ name: "Test User",
993
+ password: "SecurePass123!"
994
+ }
995
+
996
+ assert {:error, changeset} = Accounts.register_user(invalid_attrs)
997
+ assert "must have the @ sign and no spaces" in errors_on(changeset).email
998
+ end
999
+
1000
+ test "returns error with short password" do
1001
+ invalid_attrs = %{
1002
+ email: "test@example.com",
1003
+ name: "Test User",
1004
+ password: "short"
1005
+ }
1006
+
1007
+ assert {:error, changeset} = Accounts.register_user(invalid_attrs)
1008
+ assert "should be at least 12 character(s)" in errors_on(changeset).password
1009
+ end
1010
+ end
1011
+
1012
+ describe "get_user_by_email_and_password/2" do
1013
+ setup do
1014
+ user = user_fixture()
1015
+ %{user: user}
1016
+ end
1017
+
1018
+ test "returns user with correct password", %{user: user} do
1019
+ assert returned_user = Accounts.get_user_by_email_and_password(user.email, "Password123!")
1020
+ assert returned_user.id == user.id
1021
+ end
1022
+
1023
+ test "returns nil with wrong password", %{user: user} do
1024
+ assert Accounts.get_user_by_email_and_password(user.email, "wrongpass") == nil
1025
+ end
1026
+ end
1027
+ end
1028
+ ```
1029
+
1030
+ ```elixir
1031
+ # test/my_app_web/live/user_live_test.exs
1032
+ defmodule MyAppWeb.UserLiveTest do
1033
+ use MyAppWeb.ConnCase
1034
+
1035
+ import Phoenix.LiveViewTest
1036
+ import MyApp.AccountsFixtures
1037
+
1038
+ describe "Index" do
1039
+ setup [:create_user]
1040
+
1041
+ test "lists all users", %{conn: conn, user: user} do
1042
+ {:ok, _index_live, html} = live(conn, ~p"/users")
1043
+
1044
+ assert html =~ "Listing Users"
1045
+ assert html =~ user.email
1046
+ end
1047
+
1048
+ test "saves new user", %{conn: conn} do
1049
+ {:ok, index_live, _html} = live(conn, ~p"/users")
1050
+
1051
+ assert index_live |> element("a", "New User") |> render_click() =~
1052
+ "New User"
1053
+
1054
+ assert_patch(index_live, ~p"/users/new")
1055
+
1056
+ assert index_live
1057
+ |> form("#user-form", user: %{email: "invalid"})
1058
+ |> render_change() =~ "must have the @ sign"
1059
+
1060
+ assert index_live
1061
+ |> form("#user-form", user: valid_user_attributes())
1062
+ |> render_submit()
1063
+
1064
+ assert_patch(index_live, ~p"/users")
1065
+
1066
+ html = render(index_live)
1067
+ assert html =~ "User created successfully"
1068
+ assert html =~ "test@example.com"
1069
+ end
1070
+
1071
+ test "deletes user in listing", %{conn: conn, user: user} do
1072
+ {:ok, index_live, _html} = live(conn, ~p"/users")
1073
+
1074
+ assert index_live |> element("#users-#{user.id} a", "Delete") |> render_click()
1075
+ refute has_element?(index_live, "#users-#{user.id}")
1076
+ end
1077
+ end
1078
+
1079
+ defp create_user(_) do
1080
+ user = user_fixture()
1081
+ %{user: user}
1082
+ end
1083
+ end
1084
+ ```
1085
+
1086
+ ---
1087
+
1088
+ ## Production Dockerfile
1089
+
1090
+ ```dockerfile
1091
+ # Dockerfile
1092
+ ARG ELIXIR_VERSION=1.17.3
1093
+ ARG OTP_VERSION=27.1.2
1094
+ ARG DEBIAN_VERSION=bookworm-20241016-slim
1095
+
1096
+ FROM hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION} AS builder
1097
+
1098
+ # Install build dependencies
1099
+ RUN apt-get update -y && apt-get install -y build-essential git curl \
1100
+ && apt-get clean && rm -f /var/lib/apt/lists/*_*
1101
+
1102
+ # Prepare build directory
1103
+ WORKDIR /app
1104
+
1105
+ # Install hex + rebar
1106
+ RUN mix local.hex --force && \
1107
+ mix local.rebar --force
1108
+
1109
+ # Set build ENV
1110
+ ENV MIX_ENV="prod"
1111
+
1112
+ # Install mix dependencies
1113
+ COPY mix.exs mix.lock ./
1114
+ RUN mix deps.get --only $MIX_ENV
1115
+ RUN mkdir config
1116
+
1117
+ # Copy compile-time config files before compiling dependencies
1118
+ COPY config/config.exs config/${MIX_ENV}.exs config/
1119
+ RUN mix deps.compile
1120
+
1121
+ # Copy application code
1122
+ COPY priv priv
1123
+ COPY lib lib
1124
+ COPY assets assets
1125
+
1126
+ # Compile assets
1127
+ RUN mix assets.deploy
1128
+
1129
+ # Compile the release
1130
+ RUN mix compile
1131
+
1132
+ # Create release
1133
+ COPY config/runtime.exs config/
1134
+ COPY rel rel
1135
+ RUN mix release
1136
+
1137
+ # Start a new build stage for a smaller runtime image
1138
+ FROM debian:${DEBIAN_VERSION} AS runtime
1139
+
1140
+ RUN apt-get update -y && \
1141
+ apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates \
1142
+ && apt-get clean && rm -f /var/lib/apt/lists/*_*
1143
+
1144
+ # Set the locale
1145
+ RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
1146
+
1147
+ ENV LANG en_US.UTF-8
1148
+ ENV LANGUAGE en_US:en
1149
+ ENV LC_ALL en_US.UTF-8
1150
+
1151
+ WORKDIR "/app"
1152
+ RUN chown nobody /app
1153
+
1154
+ # Set runner ENV
1155
+ ENV MIX_ENV="prod"
1156
+
1157
+ # Copy built release
1158
+ COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/my_app ./
1159
+
1160
+ USER nobody
1161
+
1162
+ # Expose port
1163
+ EXPOSE 4000
1164
+
1165
+ CMD ["/app/bin/server"]
1166
+ ```
1167
+
1168
+ ---
1169
+
1170
+ Last Updated: 2026-01-10
1171
+ Version: 1.0.0